|
1 | | -/* |
2 | | - * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. |
3 | | - * |
4 | | - * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | - * you may not use this file except in compliance with the License. |
6 | | - * You may obtain a copy of the License at |
7 | | - * |
8 | | - * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | - * |
10 | | - * Unless required by applicable law or agreed to in writing, software |
11 | | - * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | - * See the License for the specific language governing permissions and |
14 | | - * limitations under the License. |
15 | | - */ |
16 | | -package com.oracle.adbaoverjdbc; |
17 | | - |
18 | | -import jdk.incubator.sql2.AdbaConnectionProperty; |
19 | | -import jdk.incubator.sql2.Connection.Lifecycle; |
20 | | -import jdk.incubator.sql2.ConnectionProperty; |
21 | | -import jdk.incubator.sql2.Operation; |
22 | | -import jdk.incubator.sql2.ShardingKey; |
23 | | -import jdk.incubator.sql2.SqlException; |
24 | | -import jdk.incubator.sql2.TransactionOutcome; |
25 | | -import java.sql.DriverManager; |
26 | | -import java.sql.PreparedStatement; |
27 | | -import java.sql.SQLException; |
28 | | -import java.util.HashMap; |
29 | | -import java.util.HashSet; |
30 | | -import java.util.Map; |
31 | | -import java.util.Properties; |
32 | | -import java.util.Set; |
33 | | -import java.util.concurrent.CompletableFuture; |
34 | | -import java.util.concurrent.CompletionStage; |
35 | | -import java.util.concurrent.Executor; |
36 | | - |
37 | | -/** |
38 | | - * Connection is a subclass of OperationGroup. The member Operation stuff is mostly |
39 | | - * inherited from OperationGroup. There are a couple of differences. First the |
40 | | - * predecessor for all Connections is an already completed CompletableFuture, |
41 | | - * ROOT. Since ROOT is completed a Connection will begin executing as soon as it |
42 | | - * is submitted. Second, a Connection is not really a member of an OperationGroup |
43 | | - * so the code that handles submitting the Connection is a little different from |
44 | | - * OperationGroup. |
45 | | - * |
46 | | - * A Connection is also contains a java.sql.Connection and has methods to execute |
47 | | - * some JDBC actions. It might be a good idea to move the java.sql.Connection and |
48 | | - * associated actions to a separate class. |
49 | | - */ |
50 | | -class Connection extends OperationGroup<Object, Object> implements jdk.incubator.sql2.Connection { |
51 | | - |
52 | | - // STATIC |
53 | | - protected static final CompletionStage<Object> ROOT = CompletableFuture.completedFuture(null); |
54 | | - |
55 | | - static jdk.incubator.sql2.Connection newConnection(DataSource ds, |
56 | | - Map<ConnectionProperty, Object> properties) { |
57 | | - return new Connection(ds, properties); |
58 | | - } |
59 | | - |
60 | | - // FIELDS |
61 | | - private Lifecycle connectionLifecycle = Lifecycle.NEW; |
62 | | - private final Set<jdk.incubator.sql2.Connection.ConnectionLifecycleListener> lifecycleListeners; |
63 | | - private final DataSource dataSource; |
64 | | - private final Map<ConnectionProperty, Object> properties; |
65 | | - |
66 | | - private java.sql.Connection jdbcConnection; |
67 | | - |
68 | | - private final Executor executor; |
69 | | - private CompletableFuture<Object> connectionCF; |
70 | | - |
71 | | - // CONSTRUCTORS |
72 | | - private Connection(DataSource ds, |
73 | | - Map<ConnectionProperty, Object> properties) { |
74 | | - super(null, null); // hack as _this_ not allowed. See SimpleOperation constructor |
75 | | - this.lifecycleListeners = new HashSet<>(); |
76 | | - dataSource = ds; |
77 | | - this.properties = properties; |
78 | | - ConnectionProperty execProp = AdbaConnectionProperty.EXECUTOR; |
79 | | - executor = (Executor) properties.getOrDefault(execProp, execProp.defaultValue()); |
80 | | - } |
81 | | - |
82 | | - // PUBLIC |
83 | | - @Override |
84 | | - public Operation<Void> connectOperation() { |
85 | | - if (! isHeld()) { |
86 | | - throw new IllegalStateException("TODO"); |
87 | | - } |
88 | | - return com.oracle.adbaoverjdbc.SimpleOperation.<Void>newOperation(this, this, this::jdbcConnect); |
89 | | - } |
90 | | - |
91 | | - @Override |
92 | | - public Operation<Void> validationOperation(Validation depth) { |
93 | | - if (! isHeld()) { |
94 | | - throw new IllegalStateException("TODO"); |
95 | | - } |
96 | | - return com.oracle.adbaoverjdbc.SimpleOperation.<Void>newOperation(this, this, op -> jdbcValidate(op, depth)); |
97 | | - } |
98 | | - |
99 | | - @Override |
100 | | - public Operation<Void> closeOperation() { |
101 | | - if (! isHeld()) { |
102 | | - throw new IllegalStateException("TODO"); |
103 | | - } |
104 | | - return com.oracle.adbaoverjdbc.UnskippableOperation.<Void>newOperation(this, this, this::jdbcClose); //TODO cannot be skipped |
105 | | - } |
106 | | - |
107 | | - @Override |
108 | | - public <S, T> jdk.incubator.sql2.OperationGroup<S, T> operationGroup() { |
109 | | - if (!isHeld()) { |
110 | | - throw new IllegalStateException("TODO"); |
111 | | - } |
112 | | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
113 | | - } |
114 | | - |
115 | | - @Override |
116 | | - public Transaction transaction() { |
117 | | - if (! isHeld()) { |
118 | | - throw new IllegalStateException("TODO"); |
119 | | - } |
120 | | - return Transaction.createTransaction(this); |
121 | | - } |
122 | | - |
123 | | - @Override |
124 | | - public Connection registerLifecycleListener(ConnectionLifecycleListener listener) { |
125 | | - if (!connectionLifecycle.isActive()) { |
126 | | - throw new IllegalStateException("TODO"); |
127 | | - } |
128 | | - lifecycleListeners.add(listener); |
129 | | - return this; |
130 | | - } |
131 | | - |
132 | | - @Override |
133 | | - public Connection deregisterLifecycleListener(ConnectionLifecycleListener listener) { |
134 | | - if (!connectionLifecycle.isActive()) { |
135 | | - throw new IllegalStateException("TODO"); |
136 | | - } |
137 | | - lifecycleListeners.remove(listener); |
138 | | - return this; |
139 | | - } |
140 | | - |
141 | | - @Override |
142 | | - public Lifecycle getConnectionLifecycle() { |
143 | | - return connectionLifecycle; |
144 | | - } |
145 | | - |
146 | | - @Override |
147 | | - public jdk.incubator.sql2.Connection abort() { |
148 | | - setLifecycle(connectionLifecycle.abort()); |
149 | | - this.closeImmediate(); |
150 | | - return this; |
151 | | - } |
152 | | - |
153 | | - @Override |
154 | | - public Map<ConnectionProperty, Object> getProperties() { |
155 | | - Map<ConnectionProperty, Object> map = new HashMap<>(properties.size()); |
156 | | - properties.forEach((k, v) -> { |
157 | | - if (!k.isSensitive()) { |
158 | | - map.put(k, v); |
159 | | - } |
160 | | - }); |
161 | | - return map; |
162 | | - } |
163 | | - |
164 | | - @Override |
165 | | - public ShardingKey.Builder shardingKeyBuilder() { |
166 | | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
167 | | - } |
168 | | - |
169 | | - @Override |
170 | | - public jdk.incubator.sql2.Connection activate() { |
171 | | - setLifecycle(connectionLifecycle.activate()); |
172 | | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
173 | | - } |
174 | | - |
175 | | - @Override |
176 | | - public jdk.incubator.sql2.Connection deactivate() { |
177 | | - setLifecycle(connectionLifecycle.deactivate()); |
178 | | - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. |
179 | | - } |
180 | | - |
181 | | - |
182 | | - |
183 | | - |
184 | | - // INTERNAL |
185 | | - protected Connection setLifecycle(Lifecycle next) { |
186 | | - Lifecycle previous = connectionLifecycle; |
187 | | - connectionLifecycle = next; |
188 | | - if (previous != next) { |
189 | | - lifecycleListeners.stream().forEach(l -> l.lifecycleEvent(this, previous, next)); |
190 | | - } |
191 | | - return this; |
192 | | - } |
193 | | - |
194 | | - Connection closeImmediate() { |
195 | | - try { |
196 | | - if (jdbcConnection != null && !jdbcConnection.isClosed()) { |
197 | | - setLifecycle(connectionLifecycle.abort()); |
198 | | - jdbcConnection.abort(executor); // Connection.abort is not supposed to hang |
199 | | - //TODO should call connectionLifecycle.close() when abort completes. |
200 | | - } |
201 | | - } |
202 | | - catch (SQLException ex) { |
203 | | - throw new SqlException(ex.getMessage(), ex, ex.getSQLState(), ex.getErrorCode(), null, -1); |
204 | | - } |
205 | | - finally { |
206 | | - dataSource.deregisterConnection(this); |
207 | | - } |
208 | | - return this; |
209 | | - } |
210 | | - |
211 | | - @Override |
212 | | - protected Executor getExecutor() { |
213 | | - return executor; |
214 | | - } |
215 | | - |
216 | | - @Override |
217 | | - jdk.incubator.sql2.Submission<Object> submit(com.oracle.adbaoverjdbc.Operation<Object> op) { |
218 | | - if (op == this) { |
219 | | - // submitting the Connection OperationGroup |
220 | | - connectionCF = (CompletableFuture<Object>)attachErrorHandler(op.follows(ROOT, getExecutor())); |
221 | | - return com.oracle.adbaoverjdbc.Submission.submit(this::cancel, connectionCF); |
222 | | - } |
223 | | - else { |
224 | | - return super.submit(op); |
225 | | - } |
226 | | - } |
227 | | - |
228 | | - protected <V> V connectionPropertyValue(ConnectionProperty prop) { |
229 | | - V value = (V)properties.get(prop); |
230 | | - if (value == null) return (V)prop.defaultValue(); |
231 | | - else return value; |
232 | | - } |
233 | | - |
234 | | - |
235 | | - |
236 | | - |
237 | | - // JDBC operations. These are all blocking |
238 | | - |
239 | | - private Void jdbcConnect(com.oracle.adbaoverjdbc.Operation<Void> op) { |
240 | | - try { |
241 | | - Properties info = (Properties)properties.get(JdbcConnectionProperties.JDBC_CONNECTION_PROPERTIES); |
242 | | - info = (Properties)(info == null ? JdbcConnectionProperties.JDBC_CONNECTION_PROPERTIES.defaultValue() |
243 | | - : info.clone()); |
244 | | - info.setProperty("user", (String) properties.get(AdbaConnectionProperty.USER)); |
245 | | - info.setProperty("password", (String) properties.get(AdbaConnectionProperty.PASSWORD)); |
246 | | - String url = (String) properties.get(AdbaConnectionProperty.URL); |
247 | | - System.out.println("DriverManager.getConnection(\"" + url + "\", " + info +")"); //DEBUG |
248 | | - jdbcConnection = DriverManager.getConnection(url, info); |
249 | | - jdbcConnection.setAutoCommit(false); |
250 | | - setLifecycle(Connection.Lifecycle.OPEN); |
251 | | - return null; |
252 | | - } |
253 | | - catch (SQLException ex) { |
254 | | - throw new SqlException(ex.getMessage(), ex, ex.getSQLState(), ex.getErrorCode(), null, -1); |
255 | | - } |
256 | | - } |
257 | | - |
258 | | - private Void jdbcValidate(com.oracle.adbaoverjdbc.Operation<Void> op, |
259 | | - Validation depth) { |
260 | | - try { |
261 | | - switch (depth) { |
262 | | - case COMPLETE: |
263 | | - case SERVER: |
264 | | - int timeoutSeconds = (int) (op.getTimeoutMillis() / 1000L); |
265 | | - System.out.println("Connection.isValid(" + timeoutSeconds + ")"); //DEBUG |
266 | | - if (!jdbcConnection.isValid(timeoutSeconds)) { |
267 | | - throw new SqlException("validation failure", null, null, -1, null, -1); |
268 | | - } |
269 | | - break; |
270 | | - case NETWORK: |
271 | | - case SOCKET: |
272 | | - case LOCAL: |
273 | | - case NONE: |
274 | | - System.out.println("Connection.isClosed"); //DEBUG |
275 | | - if (jdbcConnection.isClosed()) { |
276 | | - throw new SqlException("validation failure", null, null, -1, null, -1); |
277 | | - } |
278 | | - } |
279 | | - return null; |
280 | | - } |
281 | | - catch (SQLException ex) { |
282 | | - throw new SqlException(ex.getMessage(), ex, ex.getSQLState(), ex.getErrorCode(), null, -1); |
283 | | - } |
284 | | - } |
285 | | - |
286 | | - |
287 | | - protected <T> T jdbcExecute(com.oracle.adbaoverjdbc.Operation<T> op, String sql) { |
288 | | - try (java.sql.Statement stmt = jdbcConnection.createStatement()) { |
289 | | - int timeoutSeconds = (int) (op.getTimeoutMillis() / 1000L); |
290 | | - if (timeoutSeconds < 0) stmt.setQueryTimeout(timeoutSeconds); |
291 | | - System.out.println("Statement.execute(\"" + sql + "\")"); //DEBUG |
292 | | - stmt.execute(sql); |
293 | | - } |
294 | | - catch (SQLException ex) { |
295 | | - throw new SqlException(ex.getMessage(), ex, ex.getSQLState(), ex.getErrorCode(), sql, -1); |
296 | | - } |
297 | | - return null; |
298 | | - } |
299 | | - |
300 | | - private Void jdbcClose(com.oracle.adbaoverjdbc.Operation<Void> op) { |
301 | | - try { |
302 | | - setLifecycle(connectionLifecycle.close()); |
303 | | - if (jdbcConnection != null) { |
304 | | - System.out.println("Connection.close"); //DEBUG |
305 | | - jdbcConnection.close(); |
306 | | - } |
307 | | - } |
308 | | - catch (SQLException ex) { |
309 | | - throw new SqlException(ex.getMessage(), ex, ex.getSQLState(), ex.getErrorCode(), null, -1); |
310 | | - } |
311 | | - finally { |
312 | | - closeImmediate(); |
313 | | - setLifecycle(connectionLifecycle.closed()); |
314 | | - } |
315 | | - return null; |
316 | | - } |
317 | | - |
318 | | - PreparedStatement prepareStatement(String sqlString) throws SQLException { |
319 | | - System.out.println("Connection.prepareStatement(\"" + sqlString + "\")"); //DEBUG |
320 | | - return jdbcConnection.prepareStatement(sqlString); |
321 | | - } |
322 | | - |
323 | | - TransactionOutcome jdbcEndTransaction(SimpleOperation<TransactionOutcome> op, Transaction trans) { |
324 | | - try { |
325 | | - if (trans.endWithCommit(this)) { |
326 | | - System.out.println("commit"); //DEBUG |
327 | | - jdbcConnection.commit(); |
328 | | - return TransactionOutcome.COMMIT; |
329 | | - } |
330 | | - else { |
331 | | - System.out.println("rollback"); //DEBUG |
332 | | - jdbcConnection.rollback(); |
333 | | - return TransactionOutcome.ROLLBACK; |
334 | | - } |
335 | | - } |
336 | | - catch (SQLException ex) { |
337 | | - throw new SqlException(ex.getMessage(), ex, ex.getSQLState(), ex.getErrorCode(), null, -1); |
338 | | - } |
339 | | - } |
340 | | - |
341 | | -} |
| 1 | +<html> |
| 2 | +<head><title> Oracle SSO Failure</title></head> |
| 3 | + <body bgcolor="white"> <font color="red"> |
| 4 | + <h1>Oracle SSO Failure - Unable to process request</h1> </font> Either the requested URL was not specified in terms of a fully-qualified host name or OHS single sign-on is incorrectly configured.<br> Please notify your administrator.<hr> </body> |
| 5 | +</html> |
0 commit comments