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.drools.model;
018
019 import javax.jbi.component.ComponentContext;
020 import javax.jbi.messaging.DeliveryChannel;
021 import javax.jbi.messaging.ExchangeStatus;
022 import javax.jbi.messaging.Fault;
023 import javax.jbi.messaging.InOnly;
024 import javax.jbi.messaging.MessageExchange;
025 import javax.jbi.messaging.MessagingException;
026 import javax.jbi.messaging.NormalizedMessage;
027 import javax.jbi.messaging.RobustInOnly;
028 import javax.xml.transform.Source;
029
030 import org.apache.commons.logging.Log;
031 import org.apache.commons.logging.LogFactory;
032 import org.apache.servicemix.JbiConstants;
033 import org.apache.servicemix.client.ServiceMixClient;
034 import org.apache.servicemix.client.ServiceMixClientFacade;
035 import org.apache.servicemix.common.EndpointSupport;
036 import org.apache.servicemix.drools.DroolsComponent;
037 import org.apache.servicemix.drools.DroolsEndpoint;
038 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
039 import org.apache.servicemix.jbi.jaxp.StringSource;
040 import org.apache.servicemix.jbi.resolver.URIResolver;
041 import org.apache.servicemix.jbi.util.MessageUtil;
042 import org.drools.FactHandle;
043 import org.drools.WorkingMemory;
044 import org.drools.event.ActivationCreatedEvent;
045 import org.drools.event.DefaultAgendaEventListener;
046
047 /**
048 * A helper class for use inside a rule to forward a message to an endpoint
049 *
050 * @version $Revision: 426415 $
051 */
052 public class JbiHelper extends DefaultAgendaEventListener {
053
054 private DroolsEndpoint endpoint;
055 private Exchange exchange;
056 private WorkingMemory memory;
057 private FactHandle exchangeFactHandle;
058 private int rulesFired;
059 private boolean exchangeHandled;
060
061 public JbiHelper(DroolsEndpoint endpoint, MessageExchange exchange, WorkingMemory memory) {
062 this.endpoint = endpoint;
063 this.exchange = new Exchange(exchange, endpoint.getNamespaceContext());
064 this.memory = memory;
065
066 this.memory.addEventListener(this);
067 this.exchangeFactHandle = this.memory.assertObject(this.exchange);
068
069
070 }
071
072 public DroolsEndpoint getEndpoint() {
073 return endpoint;
074 }
075
076 public ComponentContext getContext() {
077 return endpoint.getContext();
078 }
079
080 public DeliveryChannel getChannel() throws MessagingException {
081 return getContext().getDeliveryChannel();
082 }
083
084 public ServiceMixClient getClient() {
085 return new ServiceMixClientFacade(getContext());
086 }
087
088 public Exchange getExchange() {
089 return exchange;
090 }
091
092 public Log getLogger() {
093 return LogFactory.getLog(memory.getRuleBase().getPackages()[0].getName());
094 }
095
096 /**
097 * Forwards the inbound message to the given
098 *
099 * @param uri
100 * @param localPart
101 */
102 /*
103 * public void forward(String uri) throws MessagingException { if (exchange
104 * instanceof InOnly || exchange instanceof RobustInOnly) { MessageExchange
105 * me =
106 * getChannel().createExchangeFactory().createExchange(exchange.getPattern
107 * ()); URIResolver.configureExchange(me, getContext(), uri);
108 * MessageUtil.transferToIn(in, me); getChannel().sendSync(me); } else {
109 * throw new
110 * MessagingException("Only InOnly and RobustInOnly exchanges can be forwarded"
111 * ); } }
112 */
113 public void route(String uri) throws MessagingException {
114 routeTo(null, uri);
115 }
116
117 public void routeTo(String content, String uri) throws MessagingException {
118 MessageExchange me = this.exchange.getInternalExchange();
119 NormalizedMessage in = null;
120 if (content == null) {
121 in = me.getMessage("in");
122 } else {
123 in = me.createMessage();
124 in.setContent(new StringSource(content));
125 }
126 MessageExchange newMe = getChannel().createExchangeFactory().createExchange(me.getPattern());
127 URIResolver.configureExchange(newMe, getContext(), uri);
128 MessageUtil.transferToIn(in, newMe);
129 // Set the sender endpoint property
130 String key = EndpointSupport.getKey(endpoint);
131 newMe.setProperty(JbiConstants.SENDER_ENDPOINT, key);
132 newMe.setProperty(JbiConstants.CORRELATION_ID, DroolsEndpoint.getCorrelationId(this.exchange.getInternalExchange()));
133 newMe.setProperty(DroolsComponent.DROOLS_CORRELATION_ID, me.getExchangeId());
134 getChannel().send(newMe);
135 }
136
137 public void routeToDefault(String content) throws MessagingException {
138 routeTo(content, endpoint.getDefaultRouteURI());
139 }
140
141 /**
142 * This method allows for an asynchronous send().
143 * It has no error handling support or support for InOut/InOptionalOut MEPs.
144 *
145 * @param content
146 * @param uri
147 * @throws MessagingException
148 */
149 @Deprecated
150 public void sendTo(String content, String uri) throws MessagingException {
151
152 MessageExchange me = this.exchange.getInternalExchange();
153
154 if ((me instanceof InOnly) || (me instanceof RobustInOnly)) {
155 NormalizedMessage in = null;
156 if (content == null) {
157 in = me.getMessage("in");
158 } else {
159 in = me.createMessage();
160 in.setContent(new StringSource(content));
161 }
162 MessageExchange newMe = getChannel().createExchangeFactory().createExchange(me.getPattern());
163 URIResolver.configureExchange(newMe, getContext(), uri);
164 MessageUtil.transferToIn(in, newMe);
165
166 // If i am in route method could send back the done
167 me.setStatus(ExchangeStatus.DONE);
168 getChannel().send(me);
169
170 // And send forward the new me
171 getChannel().send(newMe);
172 update();
173 } else {
174 throw new IllegalStateException("sendTo() method should be used for InOnly or RobustInOnly");
175 }
176
177 }
178
179 public void fault(String content) throws Exception {
180 fault(new StringSource(content));
181 }
182 /**
183 * Send a JBI Error message (for InOnly) or JBI Fault message (for the other MEPs)
184 *
185 * @param content the error content
186 * @throws Exception
187 */
188 public void fault(Source content) throws Exception {
189 MessageExchange me = this.exchange.getInternalExchange();
190 if (me instanceof InOnly) {
191 me.setError(new Exception(new SourceTransformer().toString(content)));
192 getChannel().send(me);
193 } else {
194 Fault fault = me.createFault();
195 fault.setContent(content);
196 me.setFault(fault);
197 getChannel().send(me);
198 }
199 exchangeHandled = true;
200 }
201
202 public void answer(String content) throws Exception {
203 answer(new StringSource(content));
204 }
205
206 /**
207 * Answer the exchange with the given response content
208 *
209 * @param content the response
210 * @throws Exception
211 */
212 public void answer(Source content) throws Exception {
213 MessageExchange me = this.exchange.getInternalExchange();
214 NormalizedMessage out = me.createMessage();
215 out.setContent(content);
216 me.setMessage(out, "out");
217 getChannel().sendSync(me);
218 exchangeHandled = true;
219 update();
220 }
221
222 public void update() {
223 this.memory.modifyObject(this.exchangeFactHandle, this.exchange);
224 }
225
226 /**
227 * Get the number of rules that were fired
228 *
229 * @return the number of rules
230 */
231 public int getRulesFired() {
232 return rulesFired;
233 }
234
235 /**
236 * Has the MessageExchange been handled by the drools endpoint?
237 *
238 * @return
239 */
240
241 public boolean isExchangeHandled() {
242 return exchangeHandled;
243 }
244
245
246 // event handler callbacks
247 @Override
248 public void activationCreated(ActivationCreatedEvent event) {
249 rulesFired++;
250 }
251
252 }