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 }