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.io.File;
020    import java.io.FilenameFilter;
021    import java.net.MalformedURLException;
022    import java.net.URL;
023    import java.util.ArrayList;
024    import java.util.Iterator;
025    import java.util.List;
026    
027    import javax.jbi.management.DeploymentException;
028    import javax.jbi.management.LifeCycleMBean;
029    import javax.jbi.messaging.MessageExchange.Role;
030    import javax.xml.bind.JAXBContext;
031    import javax.xml.bind.JAXBException;
032    import javax.xml.namespace.QName;
033    
034    import org.apache.activemq.util.IdGenerator;
035    import org.apache.servicemix.common.AbstractDeployer;
036    import org.apache.servicemix.common.BaseComponent;
037    import org.apache.servicemix.common.Deployer;
038    import org.apache.servicemix.common.Endpoint;
039    import org.apache.servicemix.common.ExchangeProcessor;
040    import org.apache.servicemix.common.ServiceUnit;
041    import org.apache.servicemix.wsn.EndpointManager;
042    import org.apache.servicemix.wsn.EndpointRegistrationException;
043    import org.apache.servicemix.wsn.jaxws.NotificationBroker;
044    import org.apache.servicemix.wsn.jbi.JbiNotificationBroker;
045    import org.apache.servicemix.wsn.jms.JmsCreatePullPoint;
046    import org.oasis_open.docs.wsn.b_2.CreatePullPoint;
047    import org.oasis_open.docs.wsn.b_2.CreatePullPointResponse;
048    import org.oasis_open.docs.wsn.b_2.Subscribe;
049    import org.oasis_open.docs.wsn.b_2.SubscribeResponse;
050    import org.oasis_open.docs.wsn.br_2.RegisterPublisher;
051    import org.oasis_open.docs.wsn.br_2.RegisterPublisherResponse;
052    
053    public class WSNDeployer extends AbstractDeployer implements Deployer {
054    
055        protected FilenameFilter filter;
056    
057        protected JAXBContext context;
058    
059        public WSNDeployer(BaseComponent component) {
060            super(component);
061            filter = new XmlFilter();
062            try {
063                context = WSNEndpoint.createJAXBContext(NotificationBroker.class);
064            } catch (JAXBException e) {
065                throw new RuntimeException("Could not create jaxb context", e);
066            }
067        }
068    
069        public boolean canDeploy(String serviceUnitName, String serviceUnitRootPath) {
070            File[] xmls = new File(serviceUnitRootPath).listFiles(filter);
071            return xmls != null && xmls.length > 0;
072        }
073    
074        public ServiceUnit deploy(String serviceUnitName, String serviceUnitRootPath) throws DeploymentException {
075            File[] xmls = new File(serviceUnitRootPath).listFiles(filter);
076            if (xmls == null || xmls.length == 0) {
077                throw failure("deploy", "No wsdl found", null);
078            }
079            WSNServiceUnit su = new WSNServiceUnit();
080            su.setComponent(component);
081            su.setName(serviceUnitName);
082            su.setRootPath(serviceUnitRootPath);
083            for (int i = 0; i < xmls.length; i++) {
084                Endpoint ep;
085                URL url;
086                try {
087                    url = xmls[i].toURL();
088                } catch (MalformedURLException e) {
089                    // TODO Auto-generated catch block
090                    throw new DeploymentException("Error deploying xml file", e);
091                }
092                ep = createEndpoint(url);
093                ep.setServiceUnit(su);
094                validate(ep);
095                su.addEndpoint(ep);
096            }
097            if (su.getEndpoints().size() == 0) {
098                throw failure("deploy", "Invalid wsdl: no endpoints found", null);
099            }
100            return su;
101        }
102    
103        public Endpoint createEndpoint(URL url) throws DeploymentException {
104            Object request = null;
105            try {
106                request = context.createUnmarshaller().unmarshal(url);
107            } catch (JAXBException e) {
108                throw failure("deploy", "Invalid xml", e);
109            }
110            return createEndpoint(request);
111        }
112    
113        public Endpoint createEndpoint(Object request) throws DeploymentException {
114            if (request instanceof Subscribe) {
115                return new WSNSubscriptionEndpoint((Subscribe) request);
116            } else if (request instanceof CreatePullPoint) {
117                return new WSNPullPointEndpoint((CreatePullPoint) request);
118            } else if (request instanceof RegisterPublisher) {
119                return new WSNPublisherEndpoint((RegisterPublisher) request);
120            } else {
121                throw failure("deploy", "Unsupported request " + request.getClass().getName(), null);
122            }
123        }
124    
125        public class WSNSubscriptionEndpoint extends Endpoint implements EndpointManager {
126    
127            private Subscribe request;
128    
129            private SubscribeResponse response;
130    
131            public WSNSubscriptionEndpoint(Subscribe request) throws DeploymentException {
132                this.service = new QName("http://servicemix.org/wsnotification", "Subscription");
133                this.endpoint = new IdGenerator().generateSanitizedId();
134                this.request = request;
135            }
136    
137            @Override
138            public Role getRole() {
139                return Role.CONSUMER;
140            }
141    
142            @Override
143            public void activate() throws Exception {
144                JbiNotificationBroker broker = ((WSNLifeCycle) serviceUnit.getComponent().getLifeCycle())
145                        .getNotificationBroker();
146                response = broker.handleSubscribe(request, this);
147            }
148    
149            @Override
150            public void deactivate() throws Exception {
151                JbiNotificationBroker broker = ((WSNLifeCycle) serviceUnit.getComponent().getLifeCycle())
152                        .getNotificationBroker();
153                broker.unsubscribe(response.getSubscriptionReference().getAddress().getValue());
154            }
155    
156            @Override
157            public ExchangeProcessor getProcessor() {
158                return null;
159            }
160    
161            public Object register(String address, Object service) throws EndpointRegistrationException {
162                return null;
163            }
164    
165            public void unregister(Object endpoint) throws EndpointRegistrationException {
166            }
167    
168        }
169    
170        public class WSNPullPointEndpoint extends Endpoint implements EndpointManager {
171    
172            private CreatePullPoint request;
173    
174            private CreatePullPointResponse response;
175    
176            public WSNPullPointEndpoint(CreatePullPoint request) throws DeploymentException {
177                this.service = new QName("http://servicemix.org/wsnotification", "Subscription");
178                this.endpoint = new IdGenerator().generateSanitizedId();
179                this.request = request;
180            }
181    
182            @Override
183            public Role getRole() {
184                return Role.PROVIDER;
185            }
186    
187            @Override
188            public void activate() throws Exception {
189                JmsCreatePullPoint createPullPoint = ((WSNLifeCycle) serviceUnit.getComponent().getLifeCycle())
190                        .getCreatePullPoint();
191                response = createPullPoint.createPullPoint(request);
192            }
193    
194            @Override
195            public void deactivate() throws Exception {
196                JmsCreatePullPoint createPullPoint = ((WSNLifeCycle) serviceUnit.getComponent().getLifeCycle())
197                        .getCreatePullPoint();
198                createPullPoint.destroyPullPoint(response.getPullPoint().getAddress().getValue());
199            }
200    
201            @Override
202            public ExchangeProcessor getProcessor() {
203                return null;
204            }
205    
206            public Object register(String address, Object service) throws EndpointRegistrationException {
207                return null;
208            }
209    
210            public void unregister(Object endpoint) throws EndpointRegistrationException {
211            }
212    
213        }
214    
215        public static class WSNPublisherEndpoint extends Endpoint implements EndpointManager {
216    
217            private RegisterPublisher request;
218    
219            private RegisterPublisherResponse response;
220    
221            public WSNPublisherEndpoint(RegisterPublisher request) {
222                this.service = new QName("http://servicemix.org/wsnotification", "Publisher");
223                this.endpoint = new IdGenerator().generateSanitizedId();
224                this.request = request;
225            }
226    
227            @Override
228            public Role getRole() {
229                return Role.CONSUMER;
230            }
231    
232            @Override
233            public void activate() throws Exception {
234                JbiNotificationBroker broker = ((WSNLifeCycle) serviceUnit.getComponent().getLifeCycle())
235                        .getNotificationBroker();
236                response = broker.handleRegisterPublisher(request, this);
237            }
238    
239            @Override
240            public void deactivate() throws Exception {
241                JbiNotificationBroker broker = ((WSNLifeCycle) serviceUnit.getComponent().getLifeCycle())
242                        .getNotificationBroker();
243                broker.unsubscribe(response.getPublisherRegistrationReference().getAddress().getValue());
244            }
245    
246            @Override
247            public ExchangeProcessor getProcessor() {
248                return null;
249            }
250    
251            public Object register(String address, Object service) throws EndpointRegistrationException {
252                return null;
253            }
254    
255            public void unregister(Object endpoint) throws EndpointRegistrationException {
256            }
257    
258        }
259    
260        public static class WSNServiceUnit extends ServiceUnit {
261            public void start() throws Exception {
262                List<Endpoint> activated = new ArrayList<Endpoint>();
263                try {
264                    for (Iterator iter = getEndpoints().iterator(); iter.hasNext();) {
265                        Endpoint endpoint = (Endpoint) iter.next();
266                        if (endpoint instanceof WSNPullPointEndpoint) {
267                            endpoint.activate();
268                            activated.add(endpoint);
269                        }
270                    }
271                    for (Iterator iter = getEndpoints().iterator(); iter.hasNext();) {
272                        Endpoint endpoint = (Endpoint) iter.next();
273                        if (endpoint instanceof WSNSubscriptionEndpoint) {
274                            endpoint.activate();
275                            activated.add(endpoint);
276                        }
277                    }
278                    this.status = LifeCycleMBean.STARTED;
279                } catch (Exception e) {
280                    // Deactivate activated endpoints
281                    for (Endpoint endpoint : activated) {
282                        try {
283                            endpoint.deactivate();
284                        } catch (Exception e2) {
285                            // do nothing
286                        }
287                    }
288                    throw e;
289                }
290            }
291        }
292    
293        public static class XmlFilter implements FilenameFilter {
294    
295            public boolean accept(File dir, String name) {
296                return name.endsWith(".xml");
297            }
298    
299        }
300    
301    }