001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.xbean.kernel;
018
019 import java.util.List;
020
021 /**
022 * This iterface defines the API for managing and monitoring service life-cycle. A kernel can be constructed with the
023 * following code:
024 * <p><blockquote><pre>
025 * Kernel kernel = KernelFactory.newInstance().createKernel(name);
026 * </pre></blockquote>
027 * Services can be registered, unregistered, started and
028 * stopped. The lifecycle model is loosly based on the J2ee Management Specification (JSR 77). All lifecycle
029 * transitions are broadcasted via a ServiceMonitor.
030 * <p/>
031 * Each kernel must have a name that is unique with in the KernelFactory (there should only be one KernelFactory per
032 * VM but class loader tricks can result in several KernelFactory)
033 * <p/>
034 * This class is loosely based on the J2ee management MEJB and JMX MBeanServer interfaces.
035 *
036 * @author Dain Sundstrom
037 * @version $Id$
038 * @since 2.0
039 */
040 public interface Kernel {
041 /**
042 * Destroys this kernel. This method causes all services to be stopped and unregistered.
043 */
044 void destroy();
045
046 /**
047 * Waits for the kernel to be destroyed.
048 */
049 void waitForDestruction();
050
051 /**
052 * Gets the running status of the kernel. Services can not be registered or started on a stopped kernel.
053 *
054 * @return true if the kernel is running; false otherwise
055 */
056 boolean isRunning();
057
058 /**
059 * Gets the unique name of this kernel within the KernelFactory.
060 *
061 * @return the unique name of this kernel
062 */
063 String getKernelName();
064
065 /**
066 * Registers a service with this kernel. If the service is restartable, it will enter the server in the
067 * STOPPED state. If a service is not restartable, the kernel will assure that all
068 * dependencies are satisfied and service will enter the kernel in the RUNNING state. If a
069 * dependency for a non-restartable service is not immediately satisfiable, this method will throw a
070 * ServiceRegistrationException.
071 *
072 * @param serviceName the unique name of the service in the kernel
073 * @param serviceFactory the factory used to create the service
074 * @throws ServiceAlreadyExistsException if service is already registered with the specified name
075 * @throws ServiceRegistrationException if the service is not restartable and an error occured while starting the service
076 */
077 void registerService(ServiceName serviceName, ServiceFactory serviceFactory) throws ServiceAlreadyExistsException, ServiceRegistrationException;
078
079 /**
080 * Unregisters a service from this kernel. The kernel will attempt to stop the service using the
081 * SYNCHRONOUS stop strategy, but if it can not stop the service a
082 * ServiceRegistrationException will be thrown containing an UnsatisfiedConditionsException.
083 *
084 * @param serviceName the unique name of the service in the kernel
085 * @throws ServiceNotFoundException if there is no service registered under the specified name
086 * @throws ServiceRegistrationException if the service could not be stopped
087 */
088 void unregisterService(ServiceName serviceName) throws ServiceNotFoundException, ServiceRegistrationException;
089
090 /**
091 * Unregisters a service from this kernel. The kernel will attempt to stop the service using the specified stop
092 * strategy, but if it can not stop the service a ServiceRegistrationException will be thrown containing
093 * either an UnsatisfiedConditionsException or a IllegalServiceStateException.
094 *
095 * @param serviceName the unique name of the service in the kernel
096 * @param stopStrategy the strategy that determines how unsatisfied conditions are handled
097 * @throws ServiceNotFoundException if there is no service registered under the specified name
098 * @throws ServiceRegistrationException if the service could not be stopped
099 */
100 void unregisterService(ServiceName serviceName, StopStrategy stopStrategy) throws ServiceNotFoundException, ServiceRegistrationException;
101
102 /**
103 * Determines if there is a service registered under the specified name.
104 *
105 * @param serviceName the unique name of the service
106 * @return true if there is a service registered with the specified name; false otherwise
107 */
108 boolean isRegistered(ServiceName serviceName);
109
110 /**
111 * Gets the ServiceState of the specified service. If the service is not restartable, this method will
112 * always return RUNNING.
113 *
114 * @param serviceName the unique name of the service in the kernel
115 * @return the curren ServiceState of the service
116 * @throws ServiceNotFoundException if there is no service registered under the specified name
117 */
118 ServiceState getServiceState(ServiceName serviceName) throws ServiceNotFoundException;
119
120 /**
121 * Gets the time the specified service entered the RUNNING state since the epoch
122 * (January 1, 1970, 00:00:00) in milliseconds. If the service is in the STOPPED or
123 * STARTING states, this method will return 0.
124 *
125 * @param serviceName the unique name of the service in the kernel
126 * @return the time the service started in milliseconds since January 1, 1970, 00:00:00
127 * @throws ServiceNotFoundException if there is no service registered under the specified name
128 */
129 long getServiceStartTime(ServiceName serviceName) throws ServiceNotFoundException;
130
131 /**
132 * Immediately starts the service using the SYNCHRONOUS start strategy. Any exception throw
133 * from service constuction is throw directly from this method. If a start condition can not be immediately
134 * satisfied, a UnsatisfiedConditionsException will be thrown. If a service already in the
135 * RUNNING state, or is not restartable, this method is a noop. If the service
136 * is in the STOPPING state an IllegalServiceStateException will be thrown. If the
137 * service is disabled, this method will throw an IllegalServiceStateException.
138 * <p/>
139 * This method has no effect on as service that is not restartable.
140 *
141 * @param serviceName the unique name of the service to start
142 * @throws ServiceNotFoundException if there is no service registered under the specified name
143 * @throws IllegalServiceStateException if the service is restartable and is in the STOPPING state or if the
144 * service is disabled
145 * @throws UnsatisfiedConditionsException if some of the start conditions can not be immediately satisfied
146 * @throws Exception if service construction threw an Exception
147 */
148 void startService(ServiceName serviceName) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception;
149
150 /**
151 * Immediately starts the service using the specified start strategy.
152 * <p/>
153 * The start strategy determines how any exception thrown from service constuction is handled including throwing
154 * the exception directly from this method.
155 * <p/>
156 * The start strategy determines what to do if a start condition can not be immediately satisfied. Possibilities
157 * include throwing an UnsatisfiedConditionsException, blocking, leaving the service in the
158 * RUNNING state, or unregistering the service.
159 * <p/>
160 * If a service already in the RUNNING state, or is not restartable, this method is a noop.
161 * If the service is in the STOPPING state an IllegalServiceStateException will be
162 * thrown. If the service is disabled, this method will throw an IllegalServiceStateException.
163 * <p/>
164 * This method has no effect on as service that is not restartable.
165 *
166 * @param serviceName the unique name of the service to start
167 * @param startStrategy the strategy that determines how unsatisfied conditions and construction exceptions are handled
168 * @throws ServiceNotFoundException if there is no service registered under the specified name
169 * @throws IllegalServiceStateException if the service is restartable and is in the STOPPING state or if the
170 * service is disabled
171 * @throws UnsatisfiedConditionsException if some of the start conditions can not be immediately satisfied
172 * @throws Exception if service construction threw an Exception
173 */
174 void startService(ServiceName serviceName, StartStrategy startStrategy) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception;
175
176 /**
177 * Immediately starts the service, and if the start ultimately completes successfully, all services owned by the
178 * specified service, all services that are owned by those services, and so on, will be started using the
179 * startServiceRecursive(ServiceName) method.
180 *
181 * @param serviceName the unique name of the service to start recursively
182 * @throws ServiceNotFoundException if there is no service registered under the specified name
183 * @throws IllegalServiceStateException if the service is restartable and is in the STOPPING state or if the
184 * service is disabled
185 * @throws UnsatisfiedConditionsException if some of the start conditions can not be immediately satisfied
186 * @throws Exception if service construction threw an Exception
187 */
188 void startServiceRecursive(ServiceName serviceName) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception;
189
190 /**
191 * Immediately starts the service, and if the start ultimately completes successfully, all services owned by the
192 * specified service, all services that are owned by those services, and so on, will be started using the
193 * startServiceRecursive(ServiceName, StartStrategy) method.
194 *
195 * @param serviceName the unique name of the service to start recursively
196 * @param startStrategy the strategy that determines how unsatisfied conditions and construction exceptions are handled
197 * @throws ServiceNotFoundException if there is no service registered under the specified name
198 * @throws IllegalServiceStateException if the service is restartable and is in the STOPPING state or if the
199 * service is disabled
200 * @throws UnsatisfiedConditionsException if some of the start conditions can not be immediately satisfied
201 * @throws Exception if service construction threw an Exception
202 */
203 void startServiceRecursive(ServiceName serviceName, StartStrategy startStrategy) throws ServiceNotFoundException, IllegalServiceStateException, UnsatisfiedConditionsException, Exception;
204
205 /**
206 * Immediately stops the service using the SYNCHRONOUS stop strategy. If a stop condition can
207 * not be immediately satisfied, an UnsatisfiedConditionsException will be thrown. If a service already in
208 * the STOPPED state, this method is a noop.
209 * <p/>
210 * If the service is not restartable, this method only attempts to satify the stop conditions. This is useful for
211 * stopping all dependent services of a non-restartable service before unregistering the service.
212 *
213 * @param serviceName the unique name of the service to stop
214 * @throws ServiceNotFoundException if there is no service registered under the specified name
215 */
216 void stopService(ServiceName serviceName) throws ServiceNotFoundException, UnsatisfiedConditionsException;
217
218 /**
219 * Immediately stops the service using the specified stop strategy. If a stop condition can not be immediately
220 * satisfied, an UnsatisfiedConditionsException will be thrown. If a service already in the
221 * STOPPED state, this method is a noop.
222 * <p/>
223 * If the service is not restartable, this method only attempts to satify the stop conditions. This is useful for
224 * stopping all dependent services of a non-restartable service before unregistering the service.
225 *
226 * @param serviceName the unique name of the service to stop
227 * @param stopStrategy the strategy that determines how unsatisfied conditions are handled
228 * @throws ServiceNotFoundException if there is no service registered under the specified name
229 */
230 void stopService(ServiceName serviceName, StopStrategy stopStrategy) throws ServiceNotFoundException, UnsatisfiedConditionsException;
231
232 /**
233 * Determines if the service can be instantiated in a kernel. A disabled restartable service can not be
234 * started. This method is equivalent to:
235 * <p><blockquote><pre>
236 * kernel.getServiceFactory(serviceName).isEnabled();
237 * </pre></blockquote>
238 * <p/>
239 *
240 * @param serviceName the unique name of the service
241 * @return true if the service factory is enabled; false otherwise
242 * @throws ServiceNotFoundException if there is no service registered under the specified name
243 */
244 boolean isServiceEnabled(ServiceName serviceName) throws ServiceNotFoundException;
245
246 /**
247 * Sets the enabled status of a service. A disabled restartable service can not be started. This state has
248 * no effect on a service that is already started, but if a running service is disabled, it can not be restarted.
249 * This method is equivalent to:
250 * <p><blockquote><pre>
251 * kernel.getServiceFactory(serviceName).setEnabled(enabled);
252 * </pre></blockquote>
253 * <p/>
254 *
255 * @param serviceName the unique name of the service
256 * @param enabled the new enabled state of this factory
257 * @throws ServiceNotFoundException if there is no service registered under the specified name
258 */
259 void setServiceEnabled(ServiceName serviceName, boolean enabled) throws ServiceNotFoundException;
260
261 /**
262 * Gets the service registered under the specified name. If the service is not in the RUNNING,
263 * or STARTING state this method will throw an IllegalArgumentException.
264 *
265 * @param serviceName the unique name of the service
266 * @return the service associated with the specified name
267 * @throws ServiceNotFoundException if there is no service registered under the specified name
268 * @throws IllegalArgumentException if the service is not in the RUNNING, or STARTING state
269 */
270 Object getService(ServiceName serviceName) throws ServiceNotFoundException, IllegalArgumentException;
271
272 /**
273 * Gets the first running service registered with the kernel that is an instance of the specified type. If no
274 * running services are instances of the specified type, null is returned.
275 *
276 * @param type the of the desired service
277 * @return the first registered service that is an instance of the specified type and is running
278 */
279 Object getService(Class type);
280
281 /**
282 * Gets the all of running service registered with the kernel that are an instances of the specified type. If no
283 * running services are instances of the specified type, an empty list is returned
284 *
285 * @param type the of the desired service
286 * @return the registered services that are instances of the specified type and are running
287 */
288 List getServices(Class type);
289
290 /**
291 * Gets the service factory registered under the specified name.
292 *
293 * @param serviceName the unique name of the service
294 * @return the service factory associated with the specified name
295 * @throws ServiceNotFoundException if there is no service registered under the specified name
296 */
297 ServiceFactory getServiceFactory(ServiceName serviceName) throws ServiceNotFoundException;
298
299 /**
300 * Gets the first service factory registered with the kernel that creates an instance of the specified type.
301 * If no service factories create an instance of the specified type, null is returned.
302 *
303 * @param type the of the desired service
304 * @return the first service factory registered with the kernel that creates an instance of the specified type
305 */
306 ServiceFactory getServiceFactory(Class type);
307
308 /**
309 * Gets the all of the service factories registered with the kernel that create an instances of the specified type.
310 * If no service factories create an instance of the specified type, an empty list is returned.
311 *
312 * @param type the of the desired service
313 * @return the registered services that are instances of the specified type and are running
314 */
315 List getServiceFactories(Class type);
316
317 /**
318 * Gets the class loader associated with the specifed service.
319 *
320 * @param serviceName the unique name of the service
321 * @return the class loader associated with the specified name
322 * @throws ServiceNotFoundException if there is no service registered under the specified name
323 */
324 ClassLoader getClassLoaderFor(ServiceName serviceName) throws ServiceNotFoundException;
325
326 /**
327 * Adds a kernel monitor.
328 *
329 * @param kernelMonitor the kernel monitor to add
330 */
331 void addKernelMonitor(KernelMonitor kernelMonitor);
332
333 /**
334 * Removes a kernel monitor.
335 *
336 * @param kernelMonitor the kernel monitor to remove
337 */
338 void removeKernelMonitor(KernelMonitor kernelMonitor);
339
340 /**
341 * Adds a service monitor for all services registered with the kernel. This method is equivalent to:
342 * <p><blockquote><pre>
343 * addServiceMonitor(serviceMonitor, null);
344 * </pre></blockquote>
345 * <p/>
346 * Note: the order in which service monitors are notified is not specified.
347 *
348 * @param serviceMonitor the service monitor to add
349 */
350 void addServiceMonitor(ServiceMonitor serviceMonitor);
351
352 /**
353 * Adds a service monitor for a specific service.
354 * <p/>
355 * Note: the order in which service monitors are notified is not specified.
356 *
357 * @param serviceMonitor the service monitor to add
358 * @param serviceName the unique name of the service to monitor or null to monitor all services
359 */
360 void addServiceMonitor(ServiceMonitor serviceMonitor, ServiceName serviceName);
361
362 /**
363 * Removes a service monitor.
364 *
365 * @param serviceMonitor the service monitor to remove
366 */
367 void removeServiceMonitor(ServiceMonitor serviceMonitor);
368 }