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.cxfbc;
018
019 import java.io.ByteArrayOutputStream;
020 import java.io.IOException;
021 import java.io.InputStream;
022 import java.util.ArrayList;
023 import java.util.List;
024
025 import javax.jbi.messaging.ExchangeStatus;
026 import javax.jbi.messaging.Fault;
027 import javax.jbi.messaging.InOptionalOut;
028 import javax.jbi.messaging.InOut;
029 import javax.jbi.messaging.MessageExchange;
030 import javax.jbi.messaging.MessagingException;
031 import javax.jbi.messaging.NormalizedMessage;
032 import javax.xml.transform.Source;
033
034 import org.apache.cxf.binding.soap.SoapMessage;
035 import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
036 import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
037 import org.apache.cxf.helpers.IOUtils;
038 import org.apache.cxf.interceptor.AttachmentInInterceptor;
039 import org.apache.cxf.interceptor.Interceptor;
040 import org.apache.cxf.interceptor.StaxInInterceptor;
041 import org.apache.cxf.io.CachedOutputStream;
042 import org.apache.cxf.message.Attachment;
043 import org.apache.cxf.message.Message;
044 import org.apache.cxf.phase.PhaseChainCache;
045 import org.apache.cxf.phase.PhaseInterceptorChain;
046 import org.apache.cxf.phase.PhaseManager;
047 import org.apache.cxf.service.model.BindingOperationInfo;
048 import org.apache.cxf.transport.MessageObserver;
049 import org.apache.servicemix.JbiConstants;
050 import org.apache.servicemix.cxfbc.interceptors.JbiInWsdl1Interceptor;
051
052
053
054 public class CxfBcProviderMessageObserver implements MessageObserver {
055 ByteArrayOutputStream response = new ByteArrayOutputStream();
056
057 boolean written;
058
059 String contentType;
060
061 private CxfBcProvider providerEndpoint;
062
063 public CxfBcProviderMessageObserver(CxfBcProvider providerEndpoint) {
064 this.providerEndpoint = providerEndpoint;
065 }
066
067 public ByteArrayOutputStream getResponseStream() throws Exception {
068 synchronized (this) {
069 if (!written) {
070 wait(1000000000);
071 }
072 }
073 return response;
074 }
075
076 public String getResponseContentType() {
077 return contentType;
078 }
079
080 public void onMessage(Message message) {
081 try {
082 MessageExchange messageExchange = message.getExchange().get(MessageExchange.class);
083 if (messageExchange == null) {
084 // probably, that's a WS-RM Response; use the messageObserver defined in exchange
085 MessageObserver messageObserver = message.getExchange().get(MessageObserver.class);
086 if (messageObserver != null) {
087 messageObserver.onMessage(message);
088 return;
089 }
090
091
092 }
093 if (messageExchange != null && messageExchange.getStatus() != ExchangeStatus.ACTIVE) {
094 return;
095 }
096
097 contentType = (String) message.get(Message.CONTENT_TYPE);
098 SoapMessage soapMessage =
099 (SoapMessage) this.providerEndpoint.getCxfEndpoint().getBinding().createMessage(message);
100
101
102 soapMessage
103 .put(org.apache.cxf.message.Message.REQUESTOR_ROLE, true);
104
105 // create Interceptor chain
106
107 PhaseChainCache inboundChainCache = new PhaseChainCache();
108 PhaseManager pm = providerEndpoint.getBus().getExtension(
109 PhaseManager.class);
110 List<Interceptor> inList = new ArrayList<Interceptor>();
111 inList.add(new ReadHeadersInterceptor(this.providerEndpoint.getBus()));
112 inList.add(new MustUnderstandInterceptor());
113 inList.add(new StaxInInterceptor());
114 inList.add(new JbiInWsdl1Interceptor(this.providerEndpoint.isUseJBIWrapper(),
115 this.providerEndpoint.isUseSOAPEnvelope()));
116 inList.add(new AttachmentInInterceptor());
117 PhaseInterceptorChain inChain = inboundChainCache.get(pm
118 .getInPhases(), inList);
119 inChain.add(providerEndpoint.getInInterceptors());
120 inChain.add(providerEndpoint.getInFaultInterceptors());
121 inChain.add(this.providerEndpoint.getInInterceptors());
122 inChain.add(this.providerEndpoint.getInFaultInterceptors());
123 soapMessage.setInterceptorChain(inChain);
124 inChain.doIntercept(soapMessage);
125 closeConnectionStream(soapMessage);
126 if (soapMessage.getContent(Source.class) == null) {
127 return;
128 }
129
130 messageExchange = soapMessage.getExchange().get(MessageExchange.class);
131 setMessageStatus(soapMessage, soapMessage.getExchange().get(BindingOperationInfo.class),
132 messageExchange);
133
134 boolean txSync = messageExchange.getStatus() == ExchangeStatus.ACTIVE
135 && messageExchange.isTransacted()
136 && Boolean.TRUE.equals(messageExchange
137 .getProperty(JbiConstants.SEND_SYNC));
138 if (txSync) {
139 providerEndpoint.getContext().getDeliveryChannel().sendSync(
140 messageExchange);
141 } else {
142 providerEndpoint.getContext().getDeliveryChannel().send(
143 messageExchange);
144 }
145
146 } catch (Exception e) {
147 e.printStackTrace();
148 } finally {
149 synchronized (this) {
150 written = true;
151 notifyAll();
152 }
153 }
154 }
155
156 private void closeConnectionStream(SoapMessage soapMessage) throws IOException {
157 InputStream is = soapMessage.getContent(InputStream.class);
158 if (is != null) {
159 CachedOutputStream bos = new CachedOutputStream();
160 IOUtils.copy(is, bos);
161
162 bos.flush();
163 is.close();
164
165 soapMessage.setContent(InputStream.class, bos.getInputStream());
166
167 bos.close();
168 }
169
170 }
171
172 private void setMessageStatus(SoapMessage soapMessage, BindingOperationInfo boi, MessageExchange messageExchange)
173 throws MessagingException {
174 if (boi.getOperationInfo().isOneWay()) {
175 messageExchange.setStatus(ExchangeStatus.DONE);
176 } else if (soapMessage.get("jbiFault") != null
177 && soapMessage.get("jbiFault").equals(true)) {
178 Fault fault = messageExchange.createFault();
179 fault.setContent(soapMessage.getContent(Source.class));
180 messageExchange.setFault(fault);
181 if (soapMessage.get("faultstring") != null) {
182 messageExchange.setProperty("faultstring", soapMessage.get("faultstring"));
183 }
184 if (soapMessage.get("faultcode") != null) {
185 messageExchange.setProperty("faultcode", soapMessage.get("faultcode"));
186 }
187 if (soapMessage.get("hasdetail") != null) {
188 messageExchange.setProperty("hasdetail", soapMessage.get("hasdetail"));
189 }
190 } else if (messageExchange instanceof InOut) {
191 NormalizedMessage msg = messageExchange.createMessage();
192 msg.setContent(soapMessage.getContent(Source.class));
193 toNMSAttachments(msg, soapMessage);
194 messageExchange.setMessage(msg, "out");
195 } else if (messageExchange instanceof InOptionalOut) {
196 if (soapMessage.getContent(Source.class) != null) {
197 NormalizedMessage msg = messageExchange.createMessage();
198 msg.setContent(soapMessage.getContent(Source.class));
199 toNMSAttachments(msg, soapMessage);
200 messageExchange.setMessage(msg, "out");
201 } else {
202 messageExchange.setStatus(ExchangeStatus.DONE);
203 }
204 } else {
205 messageExchange.setStatus(ExchangeStatus.DONE);
206
207 }
208 }
209
210 private void toNMSAttachments(NormalizedMessage normalizedMessage,
211 Message soapMessage) throws MessagingException {
212 if (soapMessage.getAttachments() != null) {
213 for (Attachment att : soapMessage.getAttachments()) {
214 normalizedMessage.addAttachment(att.getId(), att
215 .getDataHandler());
216 }
217 }
218 }
219
220 }