View Javadoc

1   /*
2      Copyright 2007 Ramon Servadei
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 fulmine.distribution.channel;
17  
18  import fulmine.ILifeCycle;
19  import fulmine.context.IFrameworkContext;
20  import fulmine.distribution.IRetransmitter;
21  import fulmine.distribution.connection.IConnection;
22  import fulmine.event.subscription.ISubscriptionManager;
23  import fulmine.model.container.IContainer;
24  import fulmine.rpc.IRpcTransmissionManager;
25  
26  /**
27   * A channel is an abstraction of a 2-way communication link between 2
28   * {@link IFrameworkContext} instances. A channel is connected to another,
29   * single, peer channel in a remote context.
30   * <p>
31   * Each channel can subscribe for {@link IContainer} instances held in the peer
32   * channel's context. The subscription is received by the remote peer channel
33   * and handled. The remote peer channel then sends updates that occur to the
34   * subscribed container instances. The local channel receives these updates and
35   * applies them to the corresponding remote container instances in the local
36   * context. When the update is applied to the container, notifications occur so
37   * listeners can react to the changes (via the event distribution framework).
38   * <p>
39   * A channel can issue retransmission requests for individual remote containers
40   * or all currently subscribed remote containers.
41   * <p>
42   * A channel is dependent on an {@link IConnection}.
43   * <p>
44   * Channels exchange the following types of messages
45   * <ol>
46   * <li>A subscription message - sent by a channel that wants to receive data
47   * changes for specific containers. The containers are identified by the type
48   * and identity regular expression string in the message payload.
49   * <li>An unsubscribe message - sent by a channel that wants to cancel a
50   * subscription. The subscription is identified by the type and identity regular
51   * expression string in the message payload.
52   * <li>A data message - sent by a channel when a container changes that has been
53   * subscribed for by the remote peer channel. The message payload is the byte[]
54   * encapsulating the data changes for the container.
55   * <li>A retransmit container message - sent by a channel to request that the
56   * containers identified by the type and identity regular expression have their
57   * current complete state retransmitted.
58   * <li>A retransmit all message - sent by a channel to request retransmission of
59   * the current complete state of all currently subscribed containers.
60   * <li>A container created message - sent by a channel when a local container is
61   * created in the channel's context.
62   * <li>A container destroyed message - sent by a channel when a local container
63   * is destroyed in the channel's context.
64   * <li>A syn message - sent by a channel when it is started. The channel expects
65   * a syn_ack message from the peer channel. Until the syn_ack is received, the
66   * channel is not usable.
67   * <li>A syn_ack message - sent by a channel in response to receiving a syn
68   * message. This signals the remote peer channel that this channel is ready for
69   * communication and receiving subscriptions.
70   * <li>A destroy connection message - sent by a channel when it wants to close
71   * the connection; the peer channel will destroy its connection when it receives
72   * this message.
73   * <li>An invoke RPC message - sent from a channel by a context to invoke an RPC
74   * in the receiving context.
75   * </ol>
76   * When 2 channels connect, they must both synchronise readiness with each other
77   * using the syn-syn_ack sequence. Only when a channel receives the syn_ack from
78   * the other channel, can the channel be used. This applies to both channels
79   * participating in a link between 2 contexts.
80   * <p>
81   * The message format between channels in ABNF is:
82   * 
83   * <pre>
84   * message   = header &quot;:&quot; payload
85   * 
86   * header    = ALPHA ; used to identify the message type
87   * payload   = data / identity
88   * data      = 1*(OCTET)
89   * identity  = 1*(ALPHA / DIGIT) 0*(&quot;|&quot; (1*(ALPHA / DIGIT))) ; e1|e2|e3
90   * </pre>
91   * 
92   * @author Ramon Servadei
93   * 
94   */
95  public interface IChannel extends ISubscriptionManager, IRetransmitter,
96      IRpcTransmissionManager, ILifeCycle
97  {
98  
99      /** The delimiter for segments in the payload */
100     String DELIMITER = "|";
101 
102     /**
103      * The header for a subscribe message. This identifies that the message is
104      * subscribing for data changes from the container described in the message
105      * payload. The container identity is the last argument so it may contain
106      * "|" characters; the decode algorithm only needs to split on the first two
107      * occurrences of "|" to get the three arguments. The message structure in
108      * ABNF is:
109      * 
110      * <pre>
111      * subscribe-message = header &quot;:&quot; container
112      * 
113      * header           = &quot;su&quot;
114      * container        = type &quot;|&quot; domain &quot;|&quot; identity
115      * type             = DIGIT
116      * domain           = DIGIT
117      * identity-regex   = 1*(ALPHA / DIGIT)
118      * </pre>
119      */
120     String MSG_SUBSCRIBE = "su:";
121 
122     /**
123      * The header for a unsubscribe message. This identifies that the message is
124      * unsubscribing for data changes from the container described in the
125      * message payload. The container identity is the last argument so it may
126      * contain "|" characters; the decode algorithm only needs to split on the
127      * first two occurrences of "|" to get the three arguments. The message
128      * structure in ABNF is:
129      * 
130      * <pre>
131      * unsubscribe-message = header &quot;:&quot; container
132      * 
133      * header             = &quot;un&quot;
134      * container        = type &quot;|&quot; domain &quot;|&quot; identity
135      * type             = DIGIT
136      * domain           = DIGIT
137      * identity-regex     = 1*(ALPHA / DIGIT)
138      * </pre>
139      */
140     String MSG_UNSUBSCRIBE = "un:";
141 
142     /**
143      * The header for a data message. This identifies that the message payload
144      * is some data from a remote container. The message structure in ABNF is:
145      * 
146      * <pre>
147      * data-message = header &quot;:&quot; data
148      * 
149      * header       = &quot;da&quot;
150      * data         = 1*(OCTET)
151      * </pre>
152      */
153     String MSG_DATA = "da:";
154 
155     /**
156      * The header for a container destroyed message. This identifies the
157      * container type and identity of a destroyed container. The container
158      * identity is the last argument so it may contain "|" characters; the
159      * decode algorithm only needs to split on the first two occurrences of "|"
160      * to get the three arguments. The message structure in ABNF is:
161      * 
162      * <pre>
163      * container-destroyed = header &quot;:&quot; container
164      * 
165      * header           = &quot;cd&quot;
166      * container        = type &quot;|&quot; domain &quot;|&quot; identity
167      * type             = DIGIT
168      * domain           = DIGIT
169      * identity         = 1*(ALPHA / DIGIT)
170      * </pre>
171      */
172     String MSG_CONTAINER_DESTROYED = "cd:";
173 
174     /**
175      * The synchronise message. This has no header or body. This is sent by a
176      * channel to synchronise with the other one. The expected response is a
177      * {@link #MSG_SYN_ACK}. The channels cannot communicate until they are
178      * synchronised. The message structure in ABNF is:
179      * 
180      * <pre>
181      * synchronise-message = &quot;syn&quot;;
182      * </pre>
183      */
184     String MSG_SYN = "syn";
185 
186     /**
187      * The synchronise acknowledge message. This has no header or body. This is
188      * sent in response to a {@link #MSG_SYN} and confirms the connection
189      * between two channels - they are synchronised. The message structure in
190      * ABNF is:
191      * 
192      * <pre>
193      * synchronise-acknowledge-message = &quot;ack&quot;
194      * </pre>
195      */
196     String MSG_SYN_ACK = "ack";
197 
198     /**
199      * The retransmit message header. This is sent by a channel to request
200      * retransmission of the identified container. The container identity is the
201      * last argument so it may contain "|" characters; the decode algorithm only
202      * needs to split on the first two occurrences of "|" to get the three
203      * arguments. The message structure in ABNF is:
204      * 
205      * <pre>
206      * retransmit-message = header &quot;:&quot; container
207      * 
208      * header           = &quot;tx&quot;
209      * container        = type &quot;|&quot; domain &quot;|&quot; identity
210      * type             = DIGIT
211      * domain           = DIGIT
212      * identity-regex   = 1*(ALPHA / DIGIT)
213      * </pre>
214      */
215     String MSG_RETRANSMIT = "tx:";
216 
217     /**
218      * The retransmit all message header. This is sent by a channel to request
219      * retransmission of all containers that are subscribed to by the channel's
220      * context. The message structure in ABNF is:
221      * 
222      * <pre>
223      * retransmit-all-message = &quot;rtx&quot;
224      * </pre>
225      */
226     String MSG_RETRANSMIT_ALL = "rtx";
227 
228     /**
229      * The header for an 'invoke RPC' message. This includes the data necessary
230      * for the RPC to be invoked in the receiving context. The message structure
231      * in ABNF is:
232      * 
233      * <pre>
234      * invoke-rpc = header &quot;:&quot; data
235      * 
236      * header     = &quot;ir&quot; 
237      * data       = 1*(ALPHA / DIGIT) ; opaque byte array holding the RPC to invoke
238      * </pre>
239      */
240     String MSG_INVOKE_RPC = "ir:";
241 
242     /**
243      * The destroy connection message. This is sent by a remote channel to
244      * signal that the local channel should destroy its connection to the remote
245      * channel. The message structure in ABNF is:
246      * 
247      * <pre>
248      * destroy-channel-message = &quot;destroyconnection&quot;
249      * </pre>
250      */
251     String MSG_DESTROY_CONNECTION = "destroyconnection";
252 
253     /**
254      * Get the identity of the remote context this channel connects to
255      * 
256      * @return a string for the identity of the remote {@link IFrameworkContext}
257      */
258     String getRemoteContextIdentity();
259 
260     /**
261      * Get the channel's connection
262      * 
263      * @return the {@link IConnection} used by the channel
264      */
265     IConnection getConnection();
266 }