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