1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport.http.construct;
12
13 import org.mule.MessageExchangePattern;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleException;
16 import org.mule.api.MuleMessage;
17 import org.mule.api.construct.FlowConstructInvalidException;
18 import org.mule.api.endpoint.InboundEndpoint;
19 import org.mule.api.endpoint.OutboundEndpoint;
20 import org.mule.api.processor.InterceptingMessageProcessor;
21 import org.mule.api.processor.MessageProcessor;
22 import org.mule.api.processor.MessageProcessorChainBuilder;
23 import org.mule.api.source.MessageSource;
24 import org.mule.api.transport.PropertyScope;
25 import org.mule.config.i18n.MessageFactory;
26 import org.mule.construct.AbstractConfigurationPattern;
27 import org.mule.endpoint.DynamicOutboundEndpoint;
28 import org.mule.endpoint.DynamicURIOutboundEndpoint;
29 import org.mule.endpoint.EndpointURIEndpointBuilder;
30 import org.mule.pattern.core.support.CopyInboundToOutboundPropertiesTransformerCallback;
31 import org.mule.processor.ResponseMessageProcessorAdapter;
32 import org.mule.transformer.TransformerTemplate;
33 import org.mule.transformer.TransformerTemplate.TransformerCallback;
34 import org.mule.transformer.simple.MessagePropertiesTransformer;
35 import org.mule.util.ObjectUtils;
36 import org.mule.util.StringUtils;
37
38 import java.util.List;
39
40
41
42
43 public class HttpProxy extends AbstractConfigurationPattern
44 {
45 private final OutboundEndpoint outboundEndpoint;
46
47 private final InterceptingMessageProcessor cachingMessageProcessor;
48
49 public HttpProxy(final String name,
50 final MuleContext muleContext,
51 final MessageSource messageSource,
52 final OutboundEndpoint outboundEndpoint,
53 final List<MessageProcessor> transformers,
54 final List<MessageProcessor> responseTransformers,
55 final InterceptingMessageProcessor cachingMessageProcessor) throws MuleException
56 {
57 super(name, muleContext, transformers, responseTransformers);
58
59 if (messageSource == null)
60 {
61 throw new FlowConstructInvalidException(
62 MessageFactory.createStaticMessage("messageSource can't be null on: " + this.toString()),
63 this);
64 }
65
66 super.setMessageSource(messageSource);
67
68 if (outboundEndpoint == null)
69 {
70 throw new FlowConstructInvalidException(
71 MessageFactory.createStaticMessage("outboundEndpoint can't be null on: " + this.toString()),
72 this);
73 }
74
75 this.outboundEndpoint = outboundEndpoint;
76 this.cachingMessageProcessor = cachingMessageProcessor;
77 }
78
79 @Override
80 protected void configureMessageProcessorsBeforeTransformation(final MessageProcessorChainBuilder builder)
81 {
82 configureContentLengthRemover(this, builder);
83 }
84
85 @Override
86 protected void configureMessageProcessorsAfterTransformation(final MessageProcessorChainBuilder builder)
87 throws MuleException
88 {
89
90 final TransformerTemplate copyInboundToOutboundPropertiesTransformer = new TransformerTemplate(
91 new CopyInboundToOutboundPropertiesTransformerCallback());
92 builder.chain(copyInboundToOutboundPropertiesTransformer);
93 builder.chain(new ResponseMessageProcessorAdapter(copyInboundToOutboundPropertiesTransformer));
94
95 if (cachingMessageProcessor != null)
96 {
97 builder.chain(cachingMessageProcessor);
98 }
99
100 if (outboundEndpoint instanceof DynamicURIOutboundEndpoint)
101 {
102
103 builder.chain(outboundEndpoint);
104 }
105 else
106 {
107
108 builder.chain(new TransformerTemplate(new TransformerCallback()
109 {
110 public Object doTransform(final MuleMessage message) throws Exception
111 {
112 final String pathExtension = StringUtils.substringAfter(
113 (String) message.getInboundProperty("http.request"),
114 (String) message.getInboundProperty("http.context.path"));
115
116 message.setInvocationProperty("http.path.extension",
117 StringUtils.defaultString(pathExtension));
118 return message;
119 }
120 }));
121
122 logger.error("Endpoint: " + outboundEndpoint);
123 final DynamicOutboundEndpoint dynamicOutboundEndpoint;
124
125 if (outboundEndpoint instanceof DynamicOutboundEndpoint)
126 {
127 dynamicOutboundEndpoint = (DynamicOutboundEndpoint) outboundEndpoint;
128 }
129 else
130 {
131 final String uriTemplate = outboundEndpoint.getEndpointURI().getUri().toString()
132 + "#[variable:http.path.extension]";
133
134 dynamicOutboundEndpoint = new DynamicOutboundEndpoint(
135 new EndpointURIEndpointBuilder(outboundEndpoint), uriTemplate);
136 }
137
138 builder.chain(dynamicOutboundEndpoint);
139 }
140 }
141
142 public static void configureContentLengthRemover(final AbstractConfigurationPattern configurationPattern,
143 final MessageProcessorChainBuilder builder)
144 {
145
146
147 if ((configurationPattern.hasTransformers()) || (configurationPattern.hasResponseTransformers()))
148 {
149 final MessagePropertiesTransformer contentLengthHeaderRemover = newContentLengthHeaderRemover();
150 if (configurationPattern.hasTransformers())
151 {
152 builder.chain(contentLengthHeaderRemover);
153 }
154 if (configurationPattern.hasResponseTransformers())
155 {
156 builder.chain(new ResponseMessageProcessorAdapter(contentLengthHeaderRemover));
157 }
158 }
159 }
160
161 private static MessagePropertiesTransformer newContentLengthHeaderRemover()
162 {
163 final MessagePropertiesTransformer contentLengthHeaderRemover = new MessagePropertiesTransformer();
164 contentLengthHeaderRemover.setScope(PropertyScope.INBOUND);
165 contentLengthHeaderRemover.setDeleteProperties("(?i)content-length");
166 return contentLengthHeaderRemover;
167 }
168
169 @Override
170 protected void validateConstruct() throws FlowConstructInvalidException
171 {
172 super.validateConstruct();
173
174 if (messageSource instanceof InboundEndpoint)
175 {
176 final InboundEndpoint inboundEndpoint = (InboundEndpoint) messageSource;
177
178 if (!inboundEndpoint.getExchangePattern().equals(MessageExchangePattern.REQUEST_RESPONSE))
179 {
180 throw new FlowConstructInvalidException(
181 MessageFactory.createStaticMessage("HttpProxy only works with a request-response inbound endpoint."),
182 this);
183 }
184 }
185
186 if (!outboundEndpoint.getExchangePattern().equals(MessageExchangePattern.REQUEST_RESPONSE))
187 {
188 throw new FlowConstructInvalidException(
189 MessageFactory.createStaticMessage("HttpProxy only works with a request-response outbound endpoint."),
190 this);
191 }
192 }
193
194 @Override
195 public String toString()
196 {
197 return ObjectUtils.toString(this);
198 }
199
200 @Override
201 public String getConstructType()
202 {
203 return "HTTP-Proxy";
204 }
205 }