View Javadoc

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 }