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.Fault;
022 import javax.jbi.messaging.InOnly;
023 import javax.jbi.messaging.MessageExchange;
024 import javax.jbi.messaging.MessagingException;
025 import javax.jbi.messaging.NormalizedMessage;
026 import javax.xml.transform.Source;
027
028 import org.apache.commons.logging.Log;
029 import org.apache.commons.logging.LogFactory;
030 import org.apache.servicemix.common.EndpointSupport;
031 import org.apache.servicemix.common.JbiConstants;
032 import org.apache.servicemix.common.util.MessageUtil;
033 import org.apache.servicemix.common.util.URIResolver;
034 import org.apache.servicemix.drools.DroolsComponent;
035 import org.apache.servicemix.drools.DroolsEndpoint;
036 import org.apache.servicemix.jbi.jaxp.SourceTransformer;
037 import org.apache.servicemix.jbi.jaxp.StringSource;
038 import org.drools.FactHandle;
039 import org.drools.WorkingMemory;
040
041 /**
042 * A helper class for use inside a rule to forward a message to an endpoint
043 *
044 * @version $Revision: 426415 $
045 */
046 public class JbiHelper {
047
048 private DroolsEndpoint endpoint;
049 private Exchange exchange;
050 private WorkingMemory memory;
051 private FactHandle exchangeFactHandle;
052 private boolean exchangeHandled = false;
053
054 public JbiHelper(DroolsEndpoint endpoint, MessageExchange exchange, WorkingMemory memory) {
055 this.endpoint = endpoint;
056 this.exchange = new Exchange(exchange, endpoint.getNamespaceContext());
057 this.memory = memory;
058 this.exchangeFactHandle = this.memory.insert(this.exchange);
059 }
060
061 public DroolsEndpoint getEndpoint() {
062 return endpoint;
063 }
064
065 public ComponentContext getContext() {
066 return endpoint.getContext();
067 }
068
069 public DeliveryChannel getChannel() throws MessagingException {
070 return getContext().getDeliveryChannel();
071 }
072
073 public Exchange getExchange() {
074 return exchange;
075 }
076
077 public Log getLogger() {
078 return LogFactory.getLog(memory.getRuleBase().getPackages()[0].getName());
079 }
080
081 /**
082 * Forwards the inbound message to the given target
083 *
084 * @param uri
085 */
086 public void route(String uri) throws MessagingException {
087 Source src = null;
088 routeTo(src, uri);
089 }
090
091 /**
092 * @see #routeTo(Source, String)
093 */
094 public void routeTo(String content, String uri) throws MessagingException {
095 if (content == null) {
096 routeTo(this.exchange.getInternalExchange().getMessage("in").getContent(), uri);
097 } else {
098 routeTo(new StringSource(content), uri);
099 }
100 }
101
102 /**
103 * Send a message to the uri
104 *
105 * @param content the message content
106 * @param uri the target endpoint's uri
107 * @throws MessagingException
108 */
109 public void routeTo(Source content, String uri) throws MessagingException {
110 MessageExchange me = this.exchange.getInternalExchange();
111
112 NormalizedMessage in = null;
113 if (content == null) {
114 in = me.getMessage("in");
115 } else {
116 in = me.createMessage();
117 in.setContent(content);
118 }
119 MessageExchange newMe = getChannel().createExchangeFactory().createExchange(me.getPattern());
120 URIResolver.configureExchange(newMe, getContext(), uri);
121 MessageUtil.transferToIn(in, newMe);
122 // Set the sender endpoint property
123 String key = EndpointSupport.getKey(endpoint);
124 newMe.setProperty(JbiConstants.SENDER_ENDPOINT, key);
125 newMe.setProperty(JbiConstants.CORRELATION_ID, DroolsEndpoint.getCorrelationId(this.exchange.getInternalExchange()));
126 newMe.setProperty(DroolsComponent.DROOLS_CORRELATION_ID, me.getExchangeId());
127 getChannel().send(newMe);
128 }
129
130 /**
131 * @see #routeToDefault(Source)
132 */
133 public void routeToDefault(String content) throws MessagingException {
134 routeTo(content, endpoint.getDefaultRouteURI());
135 }
136
137 /**
138 * Send this content to the default routing URI ({@link DroolsEndpoint#getDefaultRouteURI()} specified on the endpoint
139 *
140 * @param content the message body
141 * @throws MessagingException
142 */
143 public void routeToDefault(Source content) throws MessagingException {
144 routeTo(content, endpoint.getDefaultRouteURI());
145 }
146
147 /**
148 * @see #fault(Source)
149 */
150 public void fault(String content) throws Exception {
151 MessageExchange me = this.exchange.getInternalExchange();
152 if (me instanceof InOnly) {
153 me.setError(new Exception(content));
154 getChannel().send(me);
155 } else {
156 Fault fault = me.createFault();
157 fault.setContent(new StringSource(content));
158 me.setFault(fault);
159 getChannel().send(me);
160 }
161 exchangeHandled = true;
162 }
163
164 /**
165 * Send a JBI Error message (for InOnly) or JBI Fault message (for the other MEPs)
166 *
167 * @param content the error content
168 * @throws Exception
169 */
170 public void fault(Source content) throws Exception {
171 MessageExchange me = this.exchange.getInternalExchange();
172 if (me instanceof InOnly) {
173 me.setError(new Exception(new SourceTransformer().toString(content)));
174 getChannel().send(me);
175 } else {
176 Fault fault = me.createFault();
177 fault.setContent(content);
178 me.setFault(fault);
179 getChannel().send(me);
180 }
181 exchangeHandled = true;
182 }
183
184 /**
185 * @see #answer(Source)
186 */
187 public void answer(String content) throws Exception {
188 answer(new StringSource(content));
189 }
190
191 /**
192 * Answer the exchange with the given response content
193 *
194 * @param content the response
195 * @throws Exception
196 */
197 public void answer(Source content) throws Exception {
198 MessageExchange me = this.exchange.getInternalExchange();
199 NormalizedMessage out = me.createMessage();
200 out.setContent(content);
201 me.setMessage(out, "out");
202 getChannel().send(me);
203 exchangeHandled = true;
204 update();
205 }
206
207 /**
208 * Update the {@link MessageExchange} information in the rule engine's {@link WorkingMemory}
209 */
210 public void update() {
211 this.memory.update(this.exchangeFactHandle, this.exchange);
212 }
213
214 /**
215 * Has the MessageExchange been handled by the drools endpoint?
216 *
217 * @return
218 */
219 public boolean isExchangeHandled() {
220 return exchangeHandled;
221 }
222
223 }