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.spring;
018    
019    import java.io.StringWriter;
020    
021    import javax.jbi.JBIException;
022    import javax.jbi.messaging.ExchangeStatus;
023    import javax.jbi.messaging.MessageExchange;
024    import javax.jbi.messaging.MessagingException;
025    import javax.jbi.messaging.NormalizedMessage;
026    import javax.xml.bind.JAXBContext;
027    import javax.xml.transform.Source;
028    
029    import org.w3c.dom.Element;
030    
031    import org.apache.commons.logging.Log;
032    import org.apache.commons.logging.LogFactory;
033    import org.apache.servicemix.MessageExchangeListener;
034    import org.apache.servicemix.components.util.ComponentSupport;
035    import org.apache.servicemix.jbi.jaxp.SourceTransformer;
036    import org.apache.servicemix.jbi.jaxp.StringSource;
037    import org.apache.servicemix.wsn.client.AbstractWSAClient;
038    import org.apache.servicemix.wsn.client.NotificationBroker;
039    import org.oasis_open.docs.wsn.b_2.Subscribe;
040    import org.oasis_open.docs.wsn.b_2.SubscribeResponse;
041    import org.oasis_open.docs.wsn.b_2.Unsubscribe;
042    import org.oasis_open.docs.wsn.b_2.UnsubscribeResponse;
043    
044    /**
045     * 
046     * @author gnodet
047     * @version $Revision: 376451 $
048     * @org.apache.xbean.XBean element="publisher"
049     */
050    public class PublisherComponent extends ComponentSupport implements MessageExchangeListener {
051    
052        private static final Log LOG = LogFactory.getLog(PublisherComponent.class);
053    
054        private NotificationBroker wsnBroker;
055    
056        private String topic;
057    
058        private boolean demand;
059    
060        private String subscriptionEndpoint = "subscription";
061    
062        private Subscribe subscription;
063    
064        /**
065         * @return Returns the demand.
066         */
067        public boolean getDemand() {
068            return demand;
069        }
070    
071        /**
072         * @param demand The demand to set.
073         */
074        public void setDemand(boolean demand) {
075            this.demand = demand;
076        }
077    
078        /**
079         * @return Returns the topic.
080         */
081        public String getTopic() {
082            return topic;
083        }
084    
085        /**
086         * @param topic The topic to set.
087         */
088        public void setTopic(String topic) {
089            this.topic = topic;
090        }
091    
092        /**
093         * @return Returns the subscription.
094         */
095        public Subscribe getSubscription() {
096            return subscription;
097        }
098    
099        /* (non-Javadoc)
100         * @see org.apache.servicemix.jbi.management.BaseLifeCycle#init()
101         */
102        public void init() throws JBIException {
103            super.init();
104            getContext().activateEndpoint(getService(), subscriptionEndpoint);
105        }
106    
107        /* (non-Javadoc)
108         * @see javax.jbi.management.LifeCycleMBean#start()
109         */
110        public void start() throws JBIException {
111            new Thread() {
112                public void run() {
113                    try {
114                        wsnBroker = new NotificationBroker(getContext());
115                        String wsaAddress = getService().getNamespaceURI() + "/" + getService().getLocalPart() + "/"
116                                + subscriptionEndpoint;
117                        wsnBroker.registerPublisher(AbstractWSAClient.createWSA(wsaAddress), topic, demand);
118                    } catch (Exception e) {
119                        LOG.error("Could not create wsn client", e);
120                    }
121                }
122            } .start();
123        }
124    
125        /* (non-Javadoc)
126         * @see javax.jbi.management.LifeCycleMBean#shutDown()
127         */
128        public void shutDown() throws JBIException {
129            super.shutDown();
130        }
131    
132        /* (non-Javadoc)
133         * @see org.apache.servicemix.MessageExchangeListener#onMessageExchange(javax.jbi.messaging.MessageExchange)
134         */
135        public void onMessageExchange(MessageExchange exchange) throws MessagingException {
136            if (exchange.getStatus() != ExchangeStatus.ACTIVE) {
137                return;
138            }
139            // This is a notification from the WSN broker
140            if (exchange.getEndpoint().getEndpointName().equals(subscriptionEndpoint)) {
141                try {
142                    JAXBContext jaxbContext = JAXBContext.newInstance(Subscribe.class);
143                    Source src = exchange.getMessage("in").getContent();
144                    Object input = jaxbContext.createUnmarshaller().unmarshal(src);
145                    if (input instanceof Subscribe) {
146                        subscription = (Subscribe) input;
147                        SubscribeResponse response = new SubscribeResponse();
148                        String wsaAddress = getService().getNamespaceURI() + "/" + getService().getLocalPart() + "/"
149                                + subscriptionEndpoint;
150                        response.setSubscriptionReference(AbstractWSAClient.createWSA(wsaAddress));
151                        StringWriter writer = new StringWriter();
152                        jaxbContext.createMarshaller().marshal(response, writer);
153                        NormalizedMessage out = exchange.createMessage();
154                        out.setContent(new StringSource(writer.toString()));
155                        exchange.setMessage(out, "out");
156                        send(exchange);
157                    } else if (input instanceof Unsubscribe) {
158                        subscription = null;
159                        UnsubscribeResponse response = new UnsubscribeResponse();
160                        StringWriter writer = new StringWriter();
161                        jaxbContext.createMarshaller().marshal(response, writer);
162                        NormalizedMessage out = exchange.createMessage();
163                        out.setContent(new StringSource(writer.toString()));
164                        exchange.setMessage(out, "out");
165                        send(exchange);
166                    } else {
167                        throw new Exception("Unkown request");
168                    }
169                } catch (Exception e) {
170                    fail(exchange, e);
171                }
172                // This is a notification to publish
173            } else {
174                try {
175                    if (!demand || subscription != null) {
176                        Element elem = new SourceTransformer().toDOMElement(exchange.getMessage("in"));
177                        wsnBroker.notify(topic, elem);
178                        done(exchange);
179                    } else {
180                        LOG.info("Ingore notification as the publisher is no subscribers");
181                    }
182                } catch (Exception e) {
183                    fail(exchange, e);
184                }
185            }
186        }
187    
188    }