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