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    }