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.client;
018    
019    import java.util.concurrent.atomic.AtomicBoolean;
020    
021    import javax.jbi.JBIException;
022    
023    import org.apache.servicemix.id.IdGenerator;
024    import org.apache.servicemix.jbi.container.ActivationSpec;
025    import org.apache.servicemix.jbi.container.JBIContainer;
026    import org.apache.servicemix.jbi.nmr.flow.jms.JMSFlow;
027    
028    /**
029     * Provides remote access to ServiceMix JBI Containers running on the JMS NMR Flow
030     * The RemoteServiceMixClient creates an enbedded JBIContainer and set the 
031     * flow to use JMSFlow @see org.apache.servicemix.jbi.nmr.flow.jms.JMSFlow
032     * 
033     * @version $Revision: 564374 $
034     */
035    public class RemoteServiceMixClient extends DefaultServiceMixClient {
036    
037        private JBIContainer container;
038        private ActivationSpec activationSpec;
039        private String uri;
040        private JMSFlow jmsFlow;
041        private AtomicBoolean initialized = new AtomicBoolean(false);
042        private AtomicBoolean started = new AtomicBoolean(false);
043    
044        /**
045         * Create a RemoteServiceMixClient - setting the default
046         * transport for the JMSFlow to be peer:// 
047         * 
048         */
049        public RemoteServiceMixClient() {
050            this("peer://org.apache.servicemix?persistent=false");
051        }
052    
053        /**
054         * Create a RemoteServiceMixClient
055         * @param uri 
056         * 
057         */
058        public RemoteServiceMixClient(String uri) {
059            this(uri, new ActivationSpec());
060        }
061    
062        /**
063         * Create a RemoteServiceMixClient
064         * @param uri 
065         * @param activationSpec 
066         */
067        public RemoteServiceMixClient(String uri, ActivationSpec activationSpec) {
068            container = new JBIContainer();
069            container.setEmbedded(true);
070            container.setUseMBeanServer(false);
071            container.setName(new IdGenerator().generateSanitizedId());
072            this.uri = uri;
073            this.activationSpec = activationSpec;
074    
075        }
076    
077        /**
078         * init initializes the embedded JBIContainer
079         * 
080         * @throws JBIException
081         */
082        public void init() throws JBIException {
083            if (initialized.compareAndSet(false, true)) {
084                jmsFlow = new JMSFlow();
085                jmsFlow.setJmsURL(uri);
086                container.setFlow(jmsFlow);
087                container.setEmbedded(true);
088                container.setUseMBeanServer(false);
089                container.setCreateMBeanServer(false);
090                container.setMonitorDeploymentDirectory(false);
091                container.setMonitorInstallationDirectory(false);
092                container.init();
093                activationSpec.setComponent(this);
094                container.activateComponent(activationSpec);
095            }
096        }
097    
098        /**
099         * Start the item.
100         * 
101         * @exception javax.jbi.JBIException
102         *                if the item fails to start.
103         */
104        public void start() throws JBIException {
105            start(Long.MAX_VALUE);
106        }
107        
108        public void start(long timeout) throws JBIException {
109            init();
110            if (started.compareAndSet(false, true)) {
111                container.start();
112                if (timeout > 0) {
113                    // Wait for cluster to be connected
114                    // This is very ugly but we have no way yet to be notified
115                    // of cluster events.
116                    long start = System.currentTimeMillis();
117                    while (jmsFlow.numberInNetwork() == 0
118                               && System.currentTimeMillis() - start < timeout) {
119                        try {
120                            Thread.sleep(50);
121                        } catch (InterruptedException e) {
122                            throw new JBIException(e);
123                        }
124                    }
125                    if (jmsFlow.numberInNetwork() == 0) {
126                        throw new JBIException("Timeout while connecting to remote JBI container");
127                    }
128                }
129                super.start();
130            }
131        }
132    
133        /**
134         * Stop the item. This suspends current messaging activities.
135         * 
136         * @exception javax.jbi.JBIException
137         *                if the item fails to stop.
138         */
139        public void stop() throws JBIException {
140            super.stop();
141        }
142    
143        /**
144         * Shut down the item. The releases resources, preparatory to uninstallation.
145         * 
146         * @exception javax.jbi.JBIException
147         *                if the item fails to shut down.
148         */
149        public void shutDown() throws JBIException {
150            super.shutDown();
151            container.shutDown();
152        }
153        
154        public String getContainerName() {
155            return container.getName();
156        }
157        
158        public void setContainerName(String name) {
159            container.setName(name);
160        }
161        
162        public void close() throws JBIException {
163            shutDown();
164        }
165    
166    }