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