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 ":" 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*("|" (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 ":" container 112 * 113 * header = "su" 114 * container = type "|" domain "|" 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 ":" container 132 * 133 * header = "un" 134 * container = type "|" domain "|" 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 ":" data 148 * 149 * header = "da" 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 ":" container 164 * 165 * header = "cd" 166 * container = type "|" domain "|" 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 = "syn"; 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 = "ack" 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 ":" container 207 * 208 * header = "tx" 209 * container = type "|" domain "|" 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 = "rtx" 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 ":" data 235 * 236 * header = "ir" 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 = "destroyconnection" 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 }