View Javadoc
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 &lt;= n &lt;= 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 }