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.servicemix.geronimo;
018    
019    import java.io.File;
020    import java.util.Collection;
021    
022    import javax.jbi.JBIException;
023    import javax.transaction.TransactionManager;
024    
025    import org.apache.commons.logging.Log;
026    import org.apache.commons.logging.LogFactory;
027    import org.apache.geronimo.gbean.GBeanInfo;
028    import org.apache.geronimo.gbean.GBeanInfoBuilder;
029    import org.apache.geronimo.gbean.GBeanLifecycle;
030    import org.apache.geronimo.kernel.Kernel;
031    import org.apache.servicemix.jbi.container.ComponentEnvironment;
032    import org.apache.servicemix.jbi.container.JBIContainer;
033    import org.apache.servicemix.jbi.container.ServiceAssemblyEnvironment;
034    import org.apache.servicemix.jbi.framework.ComponentContextImpl;
035    import org.apache.servicemix.jbi.framework.ComponentMBeanImpl;
036    import org.apache.servicemix.jbi.framework.ComponentNameSpace;
037    import org.apache.servicemix.jbi.framework.ServiceAssemblyLifeCycle;
038    
039    public class ServiceMixGBean implements GBeanLifecycle, Container {
040    
041        private Log log = LogFactory.getLog(getClass().getName());
042        
043        private JBIContainer container;
044        private String name;
045        private String directory;
046        private TransactionManager transactionManager;
047        private Kernel kernel;
048        private Collection jndiResources;
049    
050        public static final GBeanInfo GBEAN_INFO;
051    
052        static {
053            GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("ServiceMix JBI Container", ServiceMixGBean.class, "JBIContainer");
054            infoFactory.addInterface(Container.class);
055            infoFactory.addAttribute("name", String.class, true);
056            infoFactory.addAttribute("directory", String.class, true);
057            infoFactory.addReference("transactionManager", TransactionManager.class);
058            infoFactory.addAttribute("kernel", Kernel.class, false);
059            infoFactory.setConstructor(new String[]{"name", "directory", "transactionManager", "kernel"});
060            GBEAN_INFO = infoFactory.getBeanInfo();
061        }
062    
063        public static GBeanInfo getGBeanInfo() {
064            return GBEAN_INFO;
065        }
066    
067        public ServiceMixGBean(String name, 
068                                               String directory, 
069                                               TransactionManager transactionManager, 
070                                               Kernel kernel) {
071            this.name = name;
072            this.directory = directory;
073            this.transactionManager = transactionManager;
074            this.kernel = kernel;
075            if (log.isDebugEnabled()) {
076                log.debug("ServiceMixGBean created");
077            }
078            /*
079            // Print available jndi resources
080            Set patterns = new HashSet();
081            this.jndiResources = kernel.listGBeans(patterns);
082            for (Iterator it = jndiResources.iterator(); it.hasNext();) {
083                    ObjectName name = (ObjectName) it.next();
084                    log.info("Resource name: " + name);
085                    log.info("Resource inst: " + kernel.)
086            }
087            */
088        }
089        
090        /**
091         * Starts the GBean.  This informs the GBean that it is about to transition to the running state.
092         *
093         * @throws Exception if the target failed to start; this will cause a transition to the failed state
094         */
095        public void doStart() throws Exception {
096            if (log.isDebugEnabled()) {
097                log.debug("ServiceMixGBean doStart");
098            }
099            ClassLoader old = Thread.currentThread().getContextClassLoader();
100            Thread.currentThread().setContextClassLoader(ServiceMixGBean.class.getClassLoader());
101            try {
102                if (container == null) {
103                    container = createContainer();
104                    container.init();
105                    container.start();
106                }
107            } finally {
108                Thread.currentThread().setContextClassLoader(old);
109            }
110        }
111    
112        /**
113         * Stops the target.  This informs the GBean that it is about to transition to the stopped state.
114         *
115         * @throws Exception if the target failed to stop; this will cause a transition to the failed state
116         */
117        public void doStop() throws Exception {
118            if (log.isDebugEnabled()) {
119                log.debug("ServiceMixGBean doStop");
120            }
121            try {
122                if (container != null) {
123                    container.shutDown();
124                }
125            } finally {
126                container = null;
127            }
128        }
129    
130        /**
131         * Fails the GBean.  This informs the GBean that it is about to transition to the failed state.
132         */
133        public void doFail() {
134            if (log.isDebugEnabled()) {
135                log.debug("ServiceMixGBean doFail");
136            }
137            try {
138                if (container != null) {
139                    try {
140                        container.shutDown();
141                    }
142                    catch (JBIException e) {
143                        log.info("Caught while closing due to failure: " + e, e);
144                    }
145                }
146            } finally {
147                container = null;
148            }
149        }
150    
151        private JBIContainer createContainer() {
152            JBIContainer container = new JBIContainer();
153            container.setName(name);
154            container.setRootDir(directory);
155            container.setTransactionManager(transactionManager);
156            container.setMonitorInstallationDirectory(false);
157            container.setMonitorDeploymentDirectory(false);
158            return container;
159        }
160        
161        public void register(Component component) throws Exception {
162            ComponentNameSpace cns = new ComponentNameSpace(container.getName(), component.getName());
163            ComponentContextImpl context = new ComponentContextImpl(container, cns);
164            ComponentEnvironment env = new ComponentEnvironment();
165            env.setComponentRoot(new File(component.getRootDir()));
166            env.setInstallRoot(new File(component.getInstallDir()));
167            env.setWorkspaceRoot(new File(component.getWorkDir()));
168            context.setEnvironment(env);
169            
170            container.activateComponent(null,
171                                                                    component.getComponent(),
172                                                                    component.getDescription(),
173                                                                    context,
174                                                                    component.getType().equals("binding-component"),
175                                                                    component.getType().equals("service-engine"),
176                                        null);
177            ComponentMBeanImpl cmb = container.getComponent(component.getName());
178            File stateFile = cmb.getContext().getEnvironment().getStateFile();
179            if (stateFile.isFile()) {
180                    cmb.setInitialRunningState();
181            } else {
182                    cmb.start();
183            }
184        }
185    
186        public void unregister(Component component) throws Exception {
187            container.deactivateComponent(component.getName());
188        }
189        
190        public void register(ServiceAssembly assembly) throws Exception {
191            File rootDir = new File(assembly.getRootDir());
192            ServiceAssemblyEnvironment env = new ServiceAssemblyEnvironment();
193            env.setRootDir(rootDir);
194            env.setInstallDir(new File(rootDir, "install"));
195            env.setSusDir(new File(rootDir, "sus"));
196            env.setStateFile(new File(rootDir, "state.xml"));
197            ServiceAssemblyLifeCycle salc = container.getRegistry().registerServiceAssembly(assembly.getDescriptor().getServiceAssembly(), env);
198            if (env.getStateFile().isFile()) {
199                    salc.restore();
200            } else {
201                    salc.start();
202            }
203        }
204        
205        public void unregister(ServiceAssembly assembly) throws Exception {
206            ServiceAssemblyLifeCycle salc = container.getRegistry().getServiceAssembly(assembly.getName());
207            salc.shutDown(false);
208            container.getRegistry().unregisterServiceAssembly(assembly.getName());
209        }
210    
211    }