1 package org.kuali.rice.ksb.api.bus;
2
3 import java.util.List;
4 import java.util.Map;
5
6 import javax.xml.namespace.QName;
7
8 /**
9 * The {@code ServiceBus} is the primary api that client applications use to interact with the Kuali
10 * Service Bus. It provides capabilities to retrieve services endpoints for use when needing to
11 * invoke a service. It also provides a mechanism by which a client application can publish it's own
12 * services to the bus.
13 *
14 * <p>
15 * The service bus may be backed by a service registry which can be used to locate services which
16 * other applications have published to the service registry. The service bus will synchronize it's
17 * known state with the of the registry, either through explicit invocations of the
18 * {@link #synchronize()} method or on a periodic basis (the details of which are up to the
19 * implementation).
20 *
21 * <p>
22 * Note that the {@code ServiceBus} manages two primary collections of {@link Endpoint} classes.
23 * Those that have been published by this application (referred to as "local" endpoints) and those
24 * which have been published by other applications (referred to as "remote" endpoints).
25 *
26 * @see Endpoint
27 * @see ServiceConfiguration
28 * @see ServiceDefinition
29 *
30 * @author Kuali Rice Team (rice.collab@kuali.org)
31 *
32 */
33 public interface ServiceBus {
34
35 /**
36 * Returns the instance ID which identifies this client application to the service bus. The
37 * instance ID should be unique for each client of the service bus and will never be blank or
38 * null.
39 *
40 * @return the instance ID for the application in which this service bus client is resident
41 */
42 String getInstanceId();
43
44 /**
45 * Returns an unmodifiable list of accessible endpoints that are available to the service bus
46 * with the given service name. This method will only return endpoints that the service bus
47 * believes are online, endpoints which are offline will not be included. In certain cases a
48 * specific service endpoint will be available both as a local and remote service. In these
49 * cases, the list returned from this method will preferentially include the local service. It
50 * will *not* include both the local and remote endpoint to the same service. This is important
51 * as this method may be used to get endpoints for broadcasting service calls to all endpoints
52 * with a given name. In these cases, it is not desirable to invoke the same endpoint twice.
53 *
54 * @return a list of the remote endpoints that are available for the given service name, this
55 * list will never be null but may be empty if there are no remote endpoints for the
56 * given service name
57 * @throws IllegalArgumentException if serviceName is null
58 */
59 List<Endpoint> getEndpoints(QName serviceName);
60
61 /**
62 * Returns an unmodifiable list of remotely accessible endpoints that are available in the
63 * service registry with the given service name. This method will only return endpoints that the
64 * service bus believes are online, endpoints which are offline will not be included.
65 *
66 * <p>
67 * If the service bus client has also deployed a service with this name, a remoted endpoint to
68 * this service will likely also be included in this list assuming that endpoint has already
69 * been synchronized with the registry.
70 *
71 * <p>
72 * In most cases, it is preferable to use {@link #getEndpoints(QName)} instead of this method.
73 * Because it will preferably return a local endpoint reference for a given service endpoint if
74 * one is available.
75 *
76 * @return a list of all endpoints that are available for the given service name, this list will
77 * never be null but may be empty if there are no endpoints for the given service name
78 * @throws IllegalArgumentException if serviceName is null
79 */
80 List<Endpoint> getRemoteEndpoints(QName serviceName);
81
82 /**
83 * Returns the endpoint for the service with the given name that was published by this service
84 * bus client. If this client has not published any such service, then this method will return
85 * null.
86 *
87 * @param serviceName the name of the service represented by the local endpoint
88 * @return the local endpoint for the given service name which was deployed by this client, or
89 * null if no such service has been published
90 * @throws IllegalArgumentException if serviceName is null
91 */
92 Endpoint getLocalEndpoint(QName serviceName);
93
94 /**
95 * Returns an unmodifiable list of all services that have been published by this service bus
96 * client.
97 *
98 * @return a map with the local service name as the key and the local endpoint as the value
99 * which contains all local services published by this service bus client. This map may
100 * be empty if this client has published no services, but it should never be null.
101 */
102 Map<QName, Endpoint> getLocalEndpoints();
103
104 /**
105 * Returns an unmodifiable list of all available and online endpoints of which the service bus
106 * is aware, including both local and remote endpoints.
107 *
108 * @return all available endpoints, this list may be empty if no endpoints exist but will never
109 * be null
110 */
111 List<Endpoint> getAllEndpoints();
112
113 /**
114 * Returns an available endpoint for the service with the given name. If the service with the
115 * given name is published locally, preference will be given to the locally deployed version of
116 * the service.
117 *
118 * <p>
119 * Based on the nature of this method, if there is more than one endpoint available for the
120 * given name, multiple invocations of this method with the same service name may return
121 * different {@link Endpoint} instances each time.
122 *
123 * @param serviceName the name of the service for which to locate an available endpoint
124 * @return an available endpoint for the service with the given name, or null if none is
125 * available
126 * @throws IllegalArgumentException if serviceName is null
127 */
128 Endpoint getEndpoint(QName serviceName);
129
130 /**
131 * Returns an available endpoint for the service with the given name which is hosted by the
132 * application with the given application id. This operation functions the same as
133 * {@link #getEndpoint(QName)} with the exception that it will only consider endpoints with the
134 * given application id.
135 *
136 * <p>
137 * Invoking this method with a null or blank value for {@code applicationId} is equivalent to
138 * invoking {@link #getEndpoint(QName)}.
139 *
140 * @param serviceName the name of the service for which to locate an available endpoint
141 * @param applicationId the id of the application for which to locate an available endpoint for
142 * the given service name
143 * @return an available endpoint for the service with the given name and application id, or null
144 * if none is available
145 * @throws IllegalArgumentException if serviceName is null
146 */
147 Endpoint getEndpoint(QName serviceName, String applicationId);
148
149 /**
150 * Returns the endpoint matching the given service configuration, if one exists. In the case of
151 * services published by this service bus client, this method will preferably return the local
152 * endpoints in place of a remote endpoint to the same service.
153 *
154 * @param serviceConfiguration the service configuration by which to lookup up the endpoint
155 * @return the endpoint who's service configuration matches the given configuration, or null if
156 * no such match could be determined
157 * @throws IllegalArgumentException if the given serviceConfiguration is null
158 */
159 Endpoint getConfiguredEndpoint(ServiceConfiguration serviceConfiguration);
160
161 /**
162 * Returns a proxy to the service with the given name. This proxy should have built-in support
163 * for fail-over and load balancing capabilities. This means it is safe for client applications
164 * to cache a reference to this service proxy.
165 *
166 * <p>
167 * This proxy should additionally be thread-safe.
168 *
169 * <p>
170 * This method is equivalent to invoking {@link #getEndpoint(QName).getService()}.
171 *
172 * @param serviceName the name of the service for which to locate an available proxy
173 * @return an available proxy for the service with the given name, or null if none is available
174 * @throws IllegalArgumentException if serviceName is null
175 */
176 Object getService(QName serviceName);
177
178 /**
179 * Returns a proxy to the service with the given name which is hosted by the application with
180 * the given application id. This operation functions the same as {@link #getService(QName)}
181 * with the exception that it will only consider endpoints with the given application id.
182 *
183 * <p>
184 * Invoking this method with a null or blank value for {@code applicationId} is equivalent to
185 * invoking {@link #getService(QName)}. This method is also equivalent to invoking
186 * {@link #getEndpoint(QName, String).getService()}.
187 *
188 * @param serviceName the name of the service for which to locate an available proxy
189 * @param applicationId the id of the application for which to locate an available proxy for the
190 * given service name
191 * @return an available proxy for the service with the given name, or null if none is available
192 * @throws IllegalArgumentException if serviceName is null
193 */
194 Object getService(QName serviceName, String applicationId);
195
196 /**
197 * Publish a service with the given ServiceDefinition to the service bus. This effectively
198 * updates the service registry and provides an endpoint for other applications to invoke. If
199 * this application has already published a service under this name, it will be updated instead
200 * to reflect the new ServiceDefinition.
201 *
202 * <p>
203 * The method also provides the ability for the service bus to immediately synchronize with the
204 * service registry after registering the service if {@code synchronize} is set to {@code true}.
205 *
206 * @see #synchronize()
207 *
208 * @param serviceDefinition the definition of the service to publish, must not be null
209 * @param synchronize indicates whether or not this service bus client should immediately
210 * synchronize it's changes with the registry after registering the service.
211 * @return the service configuration for the published service
212 * @throws IllegalArgumentException if serviceDefinition is null
213 */
214 ServiceConfiguration publishService(ServiceDefinition serviceDefinition, boolean synchronize);
215
216 /**
217 * Functions as per {@link #publishService(ServiceDefinition, boolean)} but allows for multiple
218 * services to be published to the bus in a single operation. If the given list of service
219 * definitions is empty then this method will do nothing (including skipping synchronization
220 * with the registry if that was requested).
221 *
222 * @see #publishService(ServiceDefinition, boolean)
223 * @see #synchronize()
224 *
225 * @param serviceDefinitions the list of definition for the services to publish, must not be
226 * null
227 * @param synchronize indicates whether or not this service bus client should immediately
228 * synchronize it's changes with the registry after registering the services.
229 * @return the list of service configurations for the published services in the same order as
230 * the list of service definitions
231 * @throws IllegalArgumentException if serviceDefinitions is null
232 */
233 List<ServiceConfiguration> publishServices(List<ServiceDefinition> serviceDefinitions, boolean synchronize);
234
235 /**
236 * Removes the service from the service bus and the service registry with the given service
237 * name. Client applications should only be able to remove services that they themselves have
238 * published.
239 *
240 * <p>
241 * This method also provides the ability for the service bus to immediately synchronize with the
242 * service registry after removing the service if {@code synchronize} is set to {@code true}. If
243 * the service is not located and successfully removed, however, the sychronization will not
244 * run.
245 *
246 * @see #synchronize()
247 *
248 * @param serviceName the name of the service to remove
249 * @param synchronize indicates whether or not this service bus client should immediately
250 * synchronize after removing the service
251 * @return true if the service was removed, false otherwise
252 * @throws IllegalArgumentException if the given serviceName is null
253 */
254 boolean removeService(QName serviceName, boolean synchronize);
255
256 /**
257 * Functions as per {@link #removeService(QName, boolean)} but allows for multiple services to
258 * be removed from the bus in a single operation. If the given list of service names is empty
259 * then this method will do nothing (including skipping synchronization with the registry if
260 * that was requested).
261 *
262 * <p>
263 * If the list returned from the method contains only false responses (meaning that no services
264 * were removed) this method will skip synchronization even if it is requested.
265 *
266 * @see #removeService(QName, boolean)
267 * @see #synchronize()
268 *
269 * @param serviceNames the list of names for the services to remove, must not be null
270 * @param synchronize indicates whether or not this service bus client should immediately
271 * synchronize it's changes with the registry after removing the services.
272 * @return a list of Booleans indicating which of the service removals were successful. This
273 * list will be in the same order as the list of service configurations that were passed
274 * in.
275 * @throws IllegalArgumentException if serviceNames is null
276 */
277 List<Boolean> removeServices(List<QName> serviceNames, boolean synchronize);
278
279 /**
280 * Synchronizes the current client's service bus with the central service registry. This is done
281 * automatically on a periodic basic, but can be invoked manually through this method. This
282 * method should both register any outstanding service publications to the registry, as well as
283 * detect any changes in remote services that have been published/removed by other applications
284 * in the registry and update local service bus state accordingly.
285 */
286 void synchronize();
287
288 }