1 package com.ericsson.research.trap.spi;
2
3 /*
4 * ##_BEGIN_LICENSE_##
5 * Transport Abstraction Package (trap)
6 * ----------
7 * Copyright (C) 2014 Ericsson AB
8 * ----------
9 * Redistribution and use in source and binary forms, with or without modification,
10 * are permitted provided that the following conditions are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright notice, this
13 * list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of the Ericsson AB nor the names of its contributors
20 * may be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32 * OF THE POSSIBILITY OF SUCH DAMAGE.
33 * ##_END_LICENSE_##
34 */
35
36
37
38 import java.util.Collection;
39 import java.util.Map;
40
41 import com.ericsson.research.trap.TrapException;
42 import com.ericsson.research.trap.TrapKeepalivePolicy;
43 import com.ericsson.research.trap.auth.TrapAuthentication;
44 import com.ericsson.research.trap.auth.TrapContextKeys;
45 import com.ericsson.research.trap.spi.TrapMessage.Format;
46 import com.ericsson.research.trap.utils.Callback;
47 import com.ericsson.research.trap.utils.SSLUtil.SSLMaterial;
48
49 /**
50 * Defines the methods available for interacting with the various Trap transports.
51 * <p>
52 * Applications should not need to spend too much effort in configuring the specifics of the Trap transports. At most,
53 * applications should suffice with using the enable/disable functionality, and leave Trap to manage the rest.
54 *
55 * @author Vladimir Katardjiev
56 */
57 public interface TrapTransport
58 {
59
60 /**
61 * The package to search for transports
62 */
63 public static final String TRAP_TRANSPORT_PACKAGE = "com.ericsson.research.trap.spi.transports";
64
65 /**
66 * Option to enable a transport. Set to true/false to enable/disable respectively.
67 */
68 public static final String OPTION_ENABLED = "enabled";
69
70 /**
71 * The transport priority is a numeric value that determines the order in which Trap should prefer transports. Lower
72 * values are preferred.
73 */
74 public static final String OPTION_PRIORITY = "priority";
75
76 /**
77 * Sets a string that will be used as a prefix to logger calls. Use this to redirect Trap logger traffic into
78 * specific logging parent contexts.
79 */
80 public static final String OPTION_LOGGERPREFIX = "loggerprefix";
81
82 /**
83 * Option string to configure the transport to warn about (server) transports that have not been configured to
84 * listen to a specific IP number.
85 */
86 public static final String OPTION_WARN_ADDRESS = "warnAddressConfiguration";
87
88 /**
89 * Uses <b>insecure, untrusted</b> default certificates. Set to <i>true</i> to enable. This enables TLS on
90 * transports that support it (http, socket, ws), but uses an invalid and insecure certificate.
91 */
92 public static final String CERT_USE_INSECURE_TEST = "certInsecureDefault";
93
94 /**
95 * Corresponding flag to {@link #CERT_USE_INSECURE_TEST} to tell client transports to ignore invalid server
96 * certificates.
97 */
98 public static final String CERT_IGNORE_INVALID = "certIgnoreInvalid";
99
100 /**
101 * The type of the certificate keystore. Usually "jks" or "pkcs12".
102 */
103 public static final String CERT_KEYSTORE_TYPE = "certKeystoreType";
104
105 /**
106 * The name (in case of a .jar embedded resource) or path to the file containing the keystore material. The keystore
107 * is used for the server (or client, where applicable) certificate.
108 */
109 public static final String CERT_KEYSTORE_NAME = "certKeystoreName";
110
111 /**
112 * The password/passphrase used for the keystore file.
113 */
114 public static final String CERT_KEYSTORE_PASS = "certKeystorePass";
115
116 /**
117 * The type of the certificate truststore. Usually {@link SSLMaterial#JKS_TYPE} or {@link SSLMaterial#PKCS12_TYPE}.
118 */
119 public static final String CERT_TRUSTSTORE_TYPE = "certTruststoreType";
120
121 /**
122 * The name (in case of a .jar embedded resource) or path to the file containing the keystore material. The
123 * truststore should contain any and all root certificates that the transport should accept. May be null, in which
124 * case the system-wide defaults are used.
125 */
126 public static final String CERT_TRUSTSTORE_NAME = "certTruststoreName";
127
128 /**
129 * The password/passphrase used for the truststore file.
130 */
131 public static final String CERT_TRUSTSTORE_PASS = "certTruststorePass";
132
133 /**
134 * Checks whether the given Trap transport is enabled (i.e. it will react to any calls other than configuration).
135 *
136 * @return <i>true</i> if the transport is enabled, <i>false</i> otherwise.
137 */
138 public boolean isEnabled();
139
140 /**
141 * Enables this transport. Does not imply that this transport should connect; {@link #connect()} must be called
142 * separately for that to happen.
143 */
144 public void enable();
145
146 /**
147 * Disables this transport, preventing it from participating in the transport abstraction. Unlike {@link #enable()},
148 * disable <b>does imply the transport must close</b> and refuse to carry other messages. Disable may not fail.
149 */
150 public void disable();
151
152 /**
153 * Checks if this transport is currently connected to the other end. Does not imply whether or not it is possible
154 * for this transport to connect.
155 *
156 * @return <i>true</i> if this transport object represents an active connection to the other end, <i>false</i>
157 * otherwise.
158 */
159 public boolean isConnected();
160
161 /**
162 * Signals to this transport that it should attempt to connect to the remote endpoint. The transport may attempt to
163 * connect synchronously, asynchronously or not at all according to its own configuration.
164 * <p>
165 * Not all transport instances are able to open an outgoing connection (e.g. server instances) and, as such, some
166 * instances may throw an exception when calling this method. If the transport does not support outgoing
167 * connections, it must throw an exception immediately.
168 *
169 * @throws TrapException
170 * If this transport does not support outgoing connections.
171 */
172 public void connect() throws TrapException;
173
174 /**
175 * Signals to this transport that it must disconnect. The transport must immediately take all measures to close the
176 * connection, must clean up as much as it can, and may not throw any exceptions while doing so.
177 * <p>
178 * May NOT block.
179 */
180 public void disconnect();
181
182 /**
183 * Fetches this transport's priority, which is used in the comparable implementation to sort transports, if needed.
184 * Currently unused.
185 *
186 * @return The transport's priority
187 */
188 public int getTransportPriority();
189
190 /**
191 * Sets this transport's priority. This is a relative priority that determines the order-of-preference between
192 * transports.
193 *
194 * @param priority
195 * The new priority. May be positive or negative.
196 */
197 public void setTransportPriority(int priority);
198
199 /**
200 * Gets this transport's name. The transport name is used for, among other things, log outputs and configuration
201 * settings, must be alphanumeric and contain no spaces.
202 *
203 * @return The transport's name.
204 */
205 public String getTransportName();
206
207 /**
208 * Configures a specific transport setting (key/value)
209 *
210 * @param configurationKey
211 * A string key representing the configuration parameter.
212 * @param configurationValue
213 * The new value of the configuration parameter.
214 * @throws TrapException
215 * If the configuration is invalid, or could not be executed.
216 */
217 public void configure(String configurationKey, String configurationValue);
218
219 /**
220 * Configures a specific transport setting (key/value) using integer values.
221 *
222 * @param configurationKey
223 * A string key representing the configuration parameter.
224 * @param configurationValue
225 * The new value of the configuration parameter.
226 * @throws TrapException
227 * If the configuration is invalid, or could not be executed.
228 */
229 public void configure(String configurationKey, int configurationValue) throws TrapException;
230
231 /**
232 * Sets the Transport's configuration object. This configuration object is shared with the parent.
233 *
234 * @param configuration
235 * The new configuration object.
236 */
237 public void setConfiguration(TrapConfiguration configuration);
238
239 /**
240 * Returns a configuration string representing this transport's configuration.
241 *
242 * @return A String representation of the configuration of this TrapTransport.
243 */
244 public String getConfiguration();
245
246 /**
247 * Sets the listener of this transport. The delegate will be notified of this transport's state changes, as well as
248 * incoming messages.
249 *
250 * @param delegate
251 * The new delegate to the transport, which will receive all transport delegate calls.
252 * @param context
253 * An arbitrary object that will be passed along with all calls to the delegate.
254 */
255 public void setTransportDelegate(TrapTransportDelegate delegate, Object context);
256
257 /**
258 * Set an authentication instance for this transport, to be used for authenticating any messages that need
259 * authentication.
260 *
261 * @param authentication
262 * An instance ot TrapAuthentication capable of performing all authentication-related tasks.
263 * @throws TrapException
264 * If the transport and Authentication instances are not mutually compatible. This transport should then
265 * be discarded.
266 */
267 public void setAuthentication(TrapAuthentication authentication) throws TrapException;
268
269 /**
270 * Queries if this transport can perform a connection, i.e. if it can act as a client transport.
271 *
272 * @return <i>true</i> if this transport can perform an outgoing connection, <i>false</i> otherwise.
273 */
274 public boolean canConnect();
275
276 /**
277 * Queries if this transport can accept incoming connections, i.e. if it can act as a server.
278 *
279 * @return <i>true</i> if this transport can receive incoming connections, <i>false</i> otherwise.
280 */
281 public boolean canListen();
282
283 /**
284 * Attempts to send a message with this transport. If the transport cannot send this message, in full, right now, it
285 * MUST throw an exception. The transport MUST NOT buffer messages if the <i>expectMore</i> flag is false. The
286 * transport MAY buffer messages if <i>expectMore</i> is <i>true</i> but this is not required.
287 *
288 * @param message
289 * The message to send.
290 * @param expectMore
291 * A flag signifying to the transport that more messages will be sent in a short timespan (less than
292 * 1ms). Some transports may wish to buffer these messages before sending to optimise performance.
293 * @throws TrapException
294 * If an error occurred during the sending of the message(s). The exception MUST contain the message(s)
295 * that failed sending. If it contains more than one message, the order must be in the same order that
296 * send() was called.
297 */
298 public void send(TrapMessage message, boolean expectMore) throws TrapTransportException;
299
300 /**
301 * Asks if the transport is available for sending. Effectively checks the transport's state for available, but this
302 * way is faster.
303 *
304 * @return <i>true</i> if the transport can be used to send a message, <i>false</i> otherwise.
305 */
306 public boolean isAvailable();
307
308 /**
309 * Fetches the transport's current state
310 *
311 * @return The transport's current state.
312 */
313 public TrapTransportState getState();
314
315 /**
316 * Fetches the last known liveness timestamp of the transport. This is the last time it received a message from the
317 * other end.
318 *
319 * @return The timestamp of the last message received from the remote side.
320 */
321 public long lastAlive();
322
323 /**
324 * Attempts to verify if the transport is alive, or has been alive within a certain number of milliseconds.
325 * Effectively, this can be used to trigger a keepalive check of the transport if used with a <i>within</i>
326 * parameter of 0 and a <i>check</i> parameter of true.
327 * <p>
328 * This function has a two-part purpose. The first is for the upper layer to be able to check the last known
329 * liveness of the transport, to reduce the discovery time of a dead connection. The second is to trigger a check
330 * for a dead transport, when the application needs to know that it has active connectivity.
331 * <p>
332 * Note that in normal operation, the transport itself will report when it has disconnected; the upper layer does
333 * not need to concern itself with this detail unless it specifically needs to know that it has connectivity right
334 * now.
335 *
336 * @param within
337 * Within how many milliseconds the last activity of the transport should have occurred before the
338 * transport should question whether it is alive.
339 * @param check
340 * Whether the transport should attempt to check for liveness, or simply return false if the last known
341 * activity of the transport is not later than within.
342 * @param timeout
343 * If check is true, how many milliseconds at most the liveness check should take before returning false
344 * anyway. The application can use this value if it has a time constraint on it.
345 * @return <i>true</i> if the connection is currently alive (including if this function successfully re-established
346 * the connection), <i>false</i> otherwise.
347 */
348 public Callback<Boolean> isAlive(long within, boolean check, long timeout);
349
350 /**
351 * Initialises the transport, making it able to connect again. This is, in effect, reconstructing the object, but
352 * does not need to use reflection. This method MUST properly clean up the old connection(s) and state(s) if
353 * applicable, and make the object like new again. It may and should keep its existing configuration, however.
354 */
355 public void init();
356
357 /**
358 * Retreives the current value of <i>keepaliveInterval</i>. See {@link #setKeepaliveInterval(int)} for information
359 * about what the different values mean.
360 *
361 * @return The number of seconds between keepalives.
362 */
363 public int getKeepaliveInterval();
364
365 /**
366 * Sets a new keepalive interval for the trap endpoint. The keepalive interval has one of three possible meanings:
367 * <ul>
368 * <li>A value of {@link TrapKeepalivePolicy#DISABLED} will disable the keepalives.
369 * <li>A value of {@link TrapKeepalivePolicy#DEFAULT} will cause each transport to use its internal estimate of what
370 * a good keepalive is.
371 * <li>A value of 1 <= n <= 999999 will specify the number of seconds between keepalive messages.
372 * </ul>
373 * Any change on the TrapEndpoint level will affect all transports associated with this endpoint, overwriting any
374 * individual configuration the transports may have had. The inverse does not apply.
375 * <p>
376 * See <a href= "http://www.cf.ericsson.net/confluence/display/warp/Trap+Keepalives">the Trap Keepalive
377 * documentation</a> for details on the keepalives.
378 *
379 * @param newInterval
380 * The new keepalive interval or policy.
381 */
382 public void setKeepaliveInterval(int newInterval);
383
384 /**
385 * Retrieves the currently-in-use keepalive predictor. See {@link TrapKeepalivePredictor} for details.
386 *
387 * @return the currently-in-use predictor.
388 */
389 public TrapKeepalivePredictor getKeepalivePredictor();
390
391 /**
392 * Assigns a new predictor. See {@link TrapKeepalivePredictor}. Before assigning a predictor to a transport, ensure
393 * the predictor supports the transport. Some transports, e.g. http, do not support or require keepalive prediction
394 * and thus disable it.
395 *
396 * @param newPredictor
397 * the new predictor.
398 */
399 public void setKeepalivePredictor(TrapKeepalivePredictor newPredictor);
400
401 /**
402 * Alias to set the expiry of the currently configured predictor.
403 *
404 * @see TrapKeepalivePredictor#setKeepaliveExpiry(long)
405 * @param newExpiry
406 * The new keepalive expiry.
407 */
408 public void setKeepaliveExpiry(long newExpiry);
409
410 /**
411 * Queries whether this transport is configured for a particular role. This method can be used to ask a transport if
412 * it is capable of performing the requisite task (Listen for a Server transport, or connect for a client transport)
413 * if called upon.
414 * <p>
415 * This method is strict and, i.e. if a transport is asked both client=true and server=true it must only return true
416 * if it can act as both client and server AND the configuration is appropriate.
417 * <p>
418 * The method is mainly intended for introspection.
419 *
420 * @param client
421 * Whether the transport's configuration as a client is necessary.
422 * @param server
423 * Whether the transport's configuration as a server is necessary.
424 * @return <i>true</i> if the client can act as, and is configured for, the roles asked. <i>false</i> otherwise.
425 */
426 public boolean isConfigured(boolean client, boolean server);
427
428 /**
429 * Forces the transport to enter an ERROR state, closing the transport ungracefully. This is generally invoked when
430 * a transport
431 */
432 public void forceError();
433
434 /**
435 * Sets the message format for this transport. This method is intended for Endpoint use, as configuring transports
436 * to have a different format than their respective endpoints can have unintended consequences.
437 *
438 * @param format
439 * The new message format to use.
440 */
441 public abstract void setFormat(Format format);
442
443 /**
444 * Accesses the current format for this transport.
445 *
446 * @return The current message format.
447 */
448 public abstract Format getFormat();
449
450 /**
451 * Sends a transport-specific message, bypassing the regular message queue. This method can only be used on
452 * unordered messages that must arrive on the other side out-of-order. Ping/pong, notifications, etc, should use
453 * this method. Notably, regularly scheduled CLOSE and END must not use sendTransportSpecific, as they must remain
454 * in the message buffer in order to allow all messages to transfer.
455 *
456 * @param message
457 * The message to send.
458 */
459 public void sendTransportSpecific(TrapMessage message);
460
461 /**
462 * Queries whether this transport is capable of transporting TrapObjectMessages. These transports are essentially a
463 * short circuit around much of Trap's functionality, and will thus skip the message queue.
464 *
465 * @return <i>true</i> if this is an object/loopback transport, <i>false</i> otherwise.
466 */
467 public abstract boolean isObjectTransport();
468
469 /**
470 * Flushes the transport buffers. Any buffered messages should be sent.
471 */
472 public abstract void flushTransport();
473
474 /**
475 * Fetches the associated callback context object.
476 */
477 public abstract Object getContext();
478
479 /**
480 * Receives a transported message, sent from the other side using
481 * {@link TrapTransportDelegate#ttNeedTransport(TrapMessage, TrapTransport, Object)}
482 *
483 * @since 1.2
484 */
485 public abstract void receiveTransportedMessage(TrapMessage msg);
486
487 /**
488 * Fetches the authentication keys available; the keys are string options that specify which context data is
489 * available. Some common keys are specified in {@link TrapContextKeys}, and may differ from transport to transport.
490 * This context can be used to identify and authenticate a remote endpoint.
491 *
492 * @return A collection with all the keys that the transport can provide values for.
493 */
494 public Collection<String> getAuthenticationKeys();
495
496 /**
497 * Fetches all available authentication context keys and values. This may be computationally intensive, and is a
498 * synchronous operation. If not all values are necessary, consider {@link #getAuthenticationContext(Collection)}
499 *
500 * @return A map containing all the current keys and values. Note that values may change over time; that change will
501 * not be represented here.
502 */
503 public Map<String, Object> getAuthenticationContext();
504
505 /**
506 * Fetches the available authentication context values for the specified keys. Only values with the corresponding
507 * keys will be returned. If a key cannot be mapped to a value, the key will not be represented in the returned map.
508 *
509 * @param authenticationKeys
510 * The keys which to fetch.
511 * @return A map containing the subset of <i>authenticationKeys</i> that could be mapped to a value.
512 */
513 public Map<String, Object> getAuthenticationContext(Collection<String> authenticationKeys);
514
515 }