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.wsdl.xml.WSDLLocator;
035 import javax.xml.namespace.QName;
036
037 import org.w3c.dom.Document;
038
039 import com.ibm.wsdl.Constants;
040
041 import org.apache.servicemix.common.BaseServiceUnitManager;
042 import org.apache.servicemix.common.DefaultComponent;
043 import org.apache.servicemix.common.Deployer;
044 import org.apache.servicemix.common.Endpoint;
045 import org.apache.servicemix.common.EndpointSupport;
046 import org.apache.servicemix.common.ServiceUnit;
047 import org.apache.servicemix.common.DefaultServiceUnit;
048 import org.apache.servicemix.common.tools.wsdl.WSDLFlattener;
049 import org.apache.servicemix.wsn.EndpointManager;
050 import org.apache.servicemix.wsn.EndpointRegistrationException;
051 import org.apache.servicemix.wsn.jbi.JbiNotificationBroker;
052 import org.apache.servicemix.wsn.jms.JmsCreatePullPoint;
053 import org.springframework.core.io.Resource;
054 import org.xml.sax.InputSource;
055
056 public class WSNComponent extends DefaultComponent {
057
058 private WSDLFlattener flattener;
059
060 private Map<QName, Document> descriptions;
061
062 private JbiNotificationBroker notificationBroker;
063
064 private JmsCreatePullPoint createPullPoint;
065
066 private WSNConfiguration configuration;
067
068 private ConnectionFactory connectionFactory;
069
070 private Resource[] resources;
071
072 private Object[] requests;
073
074 private List<Endpoint> endpoints;
075
076 private WSNDeployer deployer;
077
078 public WSNComponent() {
079 configuration = new WSNConfiguration();
080 serviceUnit = new DefaultServiceUnit(this);
081 }
082
083 public JbiNotificationBroker getNotificationBroker() {
084 return notificationBroker;
085 }
086
087 public JmsCreatePullPoint getCreatePullPoint() {
088 return createPullPoint;
089 }
090
091 protected Object getExtensionMBean() throws Exception {
092 return configuration;
093 }
094
095 @Override
096 public BaseServiceUnitManager createServiceUnitManager() {
097 deployer = new WSNDeployer(this);
098 return new BaseServiceUnitManager(this, new Deployer[] {deployer });
099 }
100
101 public ConnectionFactory getConnectionFactory() {
102 return this.connectionFactory;
103 }
104
105 public void setConnectionFactory(ConnectionFactory connectionFactory) {
106 this.connectionFactory = connectionFactory;
107 }
108
109 protected List getConfiguredEndpoints() {
110 return endpoints;
111 }
112
113 protected Class[] getEndpointClasses() {
114 return new Class[] {
115 WSNEndpoint.class,
116 WSNDeployableEndpoint.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 final 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 // Do not let wsdl4j read imports, as it uses the URL getContent() which fails because wsdl
233 // is not a known extension in OSGi
234 Definition definition = reader.readWSDL(new WSDLLocator() {
235 private String last = null;
236 public InputSource getBaseInputSource() {
237 return new InputSource(resource.toString());
238 }
239 public InputSource getImportInputSource(String parentLocation, String importLocation) {
240 int idx = parentLocation.lastIndexOf('/');
241 last = parentLocation.substring(0, idx + 1) + importLocation;
242 return new InputSource(last);
243 }
244 public String getBaseURI() {
245 return resource.toString();
246 }
247 public String getLatestImportURI() {
248 return last;
249 }
250 public void close() {
251 }
252 });
253 flattener = new WSDLFlattener(definition);
254 }
255 Definition flatDef = flattener.getDefinition(interfaceName);
256 doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(flatDef);
257 descriptions.put(interfaceName, doc);
258 }
259 return doc;
260 } catch (Exception e) {
261 if (logger.isDebugEnabled()) {
262 logger.debug("Error retrieving endpoint description", e);
263 }
264 return null;
265 }
266 }
267
268 protected ConnectionFactory lookupConnectionFactory() throws NamingException {
269 Properties props = new Properties();
270 if (configuration.getInitialContextFactory() != null && configuration.getJndiProviderURL() != null) {
271 props.put(Context.INITIAL_CONTEXT_FACTORY, configuration.getInitialContextFactory());
272 props.put(Context.PROVIDER_URL, configuration.getJndiProviderURL());
273 }
274 InitialContext ctx = new InitialContext(props);
275 return (ConnectionFactory) ctx.lookup(configuration.getJndiConnectionFactoryName());
276 }
277
278 public class WSNEndpointManager implements EndpointManager {
279
280 public Object register(String address, Object service) throws EndpointRegistrationException {
281 try {
282 WSNEndpoint endpoint = new WSNEndpoint(address, service);
283 WSNComponent.this.addEndpoint(endpoint);
284 return endpoint;
285 } catch (Exception e) {
286 throw new EndpointRegistrationException("Unable to activate endpoint", e);
287 }
288 }
289
290 public void unregister(final Object endpoint) throws EndpointRegistrationException {
291 WSNComponent.this.getExecutor().execute(new Runnable() {
292 public void run() {
293 try {
294 Endpoint ep = (Endpoint) endpoint;
295 WSNComponent.this.removeEndpoint(ep);
296 } catch (Exception e) {
297 logger.error("Unable to deactivate endpoint", e);
298 }
299 }
300 });
301 }
302
303 }
304
305 }