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.wsn.component;
018    
019    import java.net.URL;
020    import java.util.ArrayList;
021    import java.util.HashMap;
022    import java.util.List;
023    import java.util.Map;
024    import java.util.Properties;
025    
026    import javax.jbi.servicedesc.ServiceEndpoint;
027    import javax.jms.ConnectionFactory;
028    import javax.naming.Context;
029    import javax.naming.InitialContext;
030    import javax.naming.NamingException;
031    import javax.wsdl.Definition;
032    import javax.wsdl.factory.WSDLFactory;
033    import javax.wsdl.xml.WSDLReader;
034    import javax.xml.namespace.QName;
035    
036    import org.w3c.dom.Document;
037    
038    import com.ibm.wsdl.Constants;
039    
040    import org.apache.servicemix.common.BaseServiceUnitManager;
041    import org.apache.servicemix.common.DefaultComponent;
042    import org.apache.servicemix.common.Deployer;
043    import org.apache.servicemix.common.Endpoint;
044    import org.apache.servicemix.common.EndpointSupport;
045    import org.apache.servicemix.common.ServiceUnit;
046    import org.apache.servicemix.common.tools.wsdl.WSDLFlattener;
047    import org.apache.servicemix.wsn.EndpointManager;
048    import org.apache.servicemix.wsn.EndpointRegistrationException;
049    import org.apache.servicemix.wsn.jbi.JbiNotificationBroker;
050    import org.apache.servicemix.wsn.jms.JmsCreatePullPoint;
051    import org.springframework.core.io.Resource;
052    
053    public class WSNComponent extends DefaultComponent {
054    
055        private WSDLFlattener flattener;
056    
057        private Map<QName, Document> descriptions;
058    
059        private JbiNotificationBroker notificationBroker;
060    
061        private JmsCreatePullPoint createPullPoint;
062    
063        private WSNConfiguration configuration;
064    
065        private ConnectionFactory connectionFactory;
066    
067        private Resource[] resources;
068    
069        private Object[] requests;
070    
071        private List<Endpoint> endpoints;
072    
073        private WSNDeployer deployer;
074    
075        public WSNComponent() {
076            configuration = new WSNConfiguration();
077            serviceUnit = new ServiceUnit();
078            serviceUnit.setComponent(component);
079        }
080    
081        public JbiNotificationBroker getNotificationBroker() {
082            return notificationBroker;
083        }
084    
085        public JmsCreatePullPoint getCreatePullPoint() {
086            return createPullPoint;
087        }
088    
089        protected Object getExtensionMBean() throws Exception {
090            return configuration;
091        }
092    
093        @Override
094        public BaseServiceUnitManager createServiceUnitManager() {
095            deployer = new WSNDeployer(this);
096            return new BaseServiceUnitManager(this, new Deployer[] {deployer });
097        }
098    
099        public ConnectionFactory getConnectionFactory() {
100            return this.connectionFactory;
101        }
102    
103        public void setConnectionFactory(ConnectionFactory connectionFactory) {
104            this.connectionFactory = connectionFactory;
105        }
106    
107        protected List getConfiguredEndpoints() {
108            return endpoints;
109        }
110    
111        protected Class[] getEndpointClasses() {
112            return new Class[] {
113                WSNEndpoint.class,
114                WSNDeployer.WSNPublisherEndpoint.class,
115                WSNDeployer.WSNPullPointEndpoint.class,
116                WSNDeployer.WSNSubscriptionEndpoint.class,
117            };
118        }
119    
120        /**
121         * @return Returns the endpoints.
122         */
123        public Resource[] getResources() {
124            return resources;
125        }
126    
127        /**
128         * @param resources The resources to set.
129         */
130        public void setResources(Resource[] resources) {
131            this.resources = resources;
132        }
133    
134        /**
135         * @return Returns the requests.
136         */
137        public Object[] getRequests() {
138            return requests;
139        }
140    
141        /**
142         * @param requests The requests to set.
143         */
144        public void setRequests(Object[] requests) {
145            this.requests = requests;
146        }
147    
148        @Override
149        protected void doInit() throws Exception {
150            configuration.setRootDir(context.getWorkspaceRoot());
151            configuration.load();
152            // Notification Broker
153            notificationBroker = new JbiNotificationBroker(configuration.getBrokerName());
154            notificationBroker.setManager(new WSNEndpointManager());
155            if (connectionFactory == null) {
156                connectionFactory = lookupConnectionFactory();
157            }
158            notificationBroker.setConnectionFactory(connectionFactory);
159            notificationBroker.init();
160            // Create PullPoint
161            createPullPoint = new JmsCreatePullPoint(configuration.getBrokerName());
162            createPullPoint.setManager(new WSNEndpointManager());
163            if (connectionFactory == null) {
164                connectionFactory = lookupConnectionFactory();
165            }
166            createPullPoint.setConnectionFactory(connectionFactory);
167            createPullPoint.init();
168            // Create endpoints
169            endpoints = new ArrayList<Endpoint>();
170            if (resources != null) {
171                for (int i = 0; i < resources.length; i++) {
172                    Endpoint ep = deployer.createEndpoint(resources[i].getURL());
173                    endpoints.add(ep);
174                }
175            }
176            if (requests != null) {
177                for (int i = 0; i < requests.length; i++) {
178                    Endpoint ep = deployer.createEndpoint(requests[i]);
179                    endpoints.add(ep);
180                }
181            }
182            super.doInit();
183        }
184    
185        @Override
186        protected void doShutDown() throws Exception {
187            notificationBroker.destroy();
188            createPullPoint.destroy();
189            super.doShutDown();
190        }
191    
192        /*
193         * (non-Javadoc)
194         * 
195         * @see org.apache.servicemix.common.BaseComponent#getServiceDescription(javax.jbi.servicedesc.ServiceEndpoint)
196         */
197        @Override
198        public Document getServiceDescription(ServiceEndpoint endpoint) {
199            if (logger.isDebugEnabled()) {
200                logger.debug("Querying service description for " + endpoint);
201            }
202            String key = EndpointSupport.getKey(endpoint);
203            Endpoint ep = this.registry.getEndpoint(key);
204            if (ep != null) {
205                QName interfaceName = ep.getInterfaceName();
206                if (interfaceName == null) {
207                    if (logger.isDebugEnabled()) {
208                        logger.debug("Could not retrieve description for endpoint " + key + " (no interface defined)");
209                    }
210                    return null;
211                }
212                return getDescription(interfaceName);
213            } else {
214                if (logger.isDebugEnabled()) {
215                    logger.debug("No endpoint found for " + key);
216                }
217                return null;
218            }
219        }
220    
221        private synchronized Document getDescription(QName interfaceName) {
222            try {
223                if (descriptions == null) {
224                    descriptions = new HashMap<QName, Document>();
225                }
226                Document doc = descriptions.get(interfaceName);
227                if (doc == null) {
228                    if (flattener == null) {
229                        URL resource = getClass().getClassLoader().getResource("org/apache/servicemix/wsn/wsn.wsdl");
230                        WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
231                        reader.setFeature(Constants.FEATURE_VERBOSE, false);
232                        Definition definition = reader.readWSDL(null, resource.toString());
233                        flattener = new WSDLFlattener(definition);
234                    }
235                    Definition flatDef = flattener.getDefinition(interfaceName);
236                    doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(flatDef);
237                    descriptions.put(interfaceName, doc);
238                }
239                return doc;
240            } catch (Exception e) {
241                if (logger.isDebugEnabled()) {
242                    logger.debug("Error retrieving endpoint description", e);
243                }
244                return null;
245            }
246        }
247    
248        protected ConnectionFactory lookupConnectionFactory() throws NamingException {
249            Properties props = new Properties();
250            if (configuration.getInitialContextFactory() != null && configuration.getJndiProviderURL() != null) {
251                props.put(Context.INITIAL_CONTEXT_FACTORY, configuration.getInitialContextFactory());
252                props.put(Context.PROVIDER_URL, configuration.getJndiProviderURL());
253            }
254            InitialContext ctx = new InitialContext(props);
255            return (ConnectionFactory) ctx.lookup(configuration.getJndiConnectionFactoryName());
256        }
257    
258        public class WSNEndpointManager implements EndpointManager {
259    
260            public Object register(String address, Object service) throws EndpointRegistrationException {
261                try {
262                    WSNEndpoint endpoint = new WSNEndpoint(address, service);
263                    WSNComponent.this.addEndpoint(endpoint);
264                    return endpoint;
265                } catch (Exception e) {
266                    throw new EndpointRegistrationException("Unable to activate endpoint", e);
267                }
268            }
269    
270            public void unregister(Object endpoint) throws EndpointRegistrationException {
271                try {
272                    WSNComponent.this.removeEndpoint((Endpoint) endpoint);
273                } catch (Exception e) {
274                    throw new EndpointRegistrationException("Unable to activate endpoint", e);
275                }
276            }
277    
278        }
279    
280    }