View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.transport.http;
8   
9   import org.mule.DefaultMuleEvent;
10  import org.mule.DefaultMuleMessage;
11  import org.mule.MessageExchangePattern;
12  import org.mule.api.MuleContext;
13  import org.mule.api.MuleEvent;
14  import org.mule.api.MuleMessage;
15  import org.mule.api.MuleSession;
16  import org.mule.api.construct.FlowConstruct;
17  import org.mule.api.endpoint.EndpointBuilder;
18  import org.mule.api.endpoint.InboundEndpoint;
19  import org.mule.api.endpoint.OutboundEndpoint;
20  import org.mule.api.lifecycle.CreateException;
21  import org.mule.api.processor.MessageProcessor;
22  import org.mule.api.transport.Connector;
23  import org.mule.endpoint.EndpointURIEndpointBuilder;
24  import org.mule.session.DefaultMuleSession;
25  import org.mule.transport.AbstractPollingMessageReceiver;
26  import org.mule.transport.http.i18n.HttpMessages;
27  import org.mule.util.MapUtils;
28  import org.mule.util.StringUtils;
29  
30  import java.util.Collections;
31  
32  /**
33   * Will poll an http URL and use the response as the input for a service request.
34   */
35  public class PollingHttpMessageReceiver extends AbstractPollingMessageReceiver
36  {
37      protected String etag = null;
38      private boolean checkEtag;
39      private boolean discardEmptyContent;
40      //The outbound endpoint to poll
41      private OutboundEndpoint outboundEndpoint;
42  
43      public PollingHttpMessageReceiver(Connector connector,
44                                        FlowConstruct flowConstruct,
45                                        final InboundEndpoint endpoint) throws CreateException
46      {
47  
48          super(connector, flowConstruct, endpoint);
49  
50          HttpPollingConnector pollingConnector;
51  
52          if (connector instanceof HttpPollingConnector)
53          {
54              pollingConnector = (HttpPollingConnector) connector;
55          }
56          else
57          {
58              throw new CreateException(HttpMessages.pollingReciverCannotbeUsed(), this);
59          }
60  
61          long pollingFrequency = MapUtils.getLongValue(endpoint.getProperties(), "pollingFrequency",
62                  pollingConnector.getPollingFrequency());
63          if (pollingFrequency > 0)
64          {
65              this.setFrequency(pollingFrequency);
66          }
67  
68          checkEtag = MapUtils.getBooleanValue(endpoint.getProperties(), "checkEtag", pollingConnector.isCheckEtag());
69          discardEmptyContent = MapUtils.getBooleanValue(endpoint.getProperties(), "discardEmptyContent", pollingConnector.isDiscardEmptyContent());
70      }
71  
72      @Override
73      protected void doDispose()
74      {
75          // nothing to do
76      }
77  
78      @Override
79      protected void doConnect() throws Exception
80      {
81          // nothing to do
82      }
83  
84      @Override
85      public void doDisconnect() throws Exception
86      {
87          // nothing to do
88      }
89  
90      @Override
91      public void poll() throws Exception
92      {
93          MuleContext muleContext = connector.getMuleContext();
94  
95          if (outboundEndpoint == null)
96          {
97              // We need to create an outbound endpoint to do the polled request using
98              // send() as thats the only way we can customize headers and use eTags
99              EndpointBuilder endpointBuilder = new EndpointURIEndpointBuilder(endpoint);
100             // Must not use inbound endpoint processors
101             endpointBuilder.setMessageProcessors(Collections.<MessageProcessor>emptyList());
102             endpointBuilder.setResponseMessageProcessors(Collections.<MessageProcessor>emptyList());
103             endpointBuilder.setMessageProcessors(Collections.<MessageProcessor>emptyList());
104             endpointBuilder.setResponseMessageProcessors(Collections.<MessageProcessor>emptyList());
105             endpointBuilder.setExchangePattern(MessageExchangePattern.REQUEST_RESPONSE);
106 
107             outboundEndpoint = muleContext.getEndpointFactory().getOutboundEndpoint(
108                     endpointBuilder);
109         }
110 
111         MuleMessage request = new DefaultMuleMessage(StringUtils.EMPTY, outboundEndpoint.getProperties(), muleContext);
112         if (etag != null && checkEtag)
113         {
114             request.setOutboundProperty(HttpConstants.HEADER_IF_NONE_MATCH, etag);
115         }
116         request.setOutboundProperty(HttpConnector.HTTP_METHOD_PROPERTY, "GET");
117 
118         MuleSession session = new DefaultMuleSession(flowConstruct, connector.getMuleContext());
119 
120 
121         MuleEvent event = new DefaultMuleEvent(request, outboundEndpoint, session);
122 
123         MuleEvent result = outboundEndpoint.process(event);
124         MuleMessage message = null;
125         if (result != null)
126         {
127             message = result.getMessage();
128         }
129 
130         final int contentLength = message.getOutboundProperty(HttpConstants.HEADER_CONTENT_LENGTH, -1);
131         if (contentLength == 0 && discardEmptyContent)
132         {
133             if (logger.isDebugEnabled())
134             {
135                 logger.debug("Received empty message and ignoring from: " + endpoint.getEndpointURI());
136             }
137             return;
138         }
139         int status = message.getOutboundProperty(HttpConnector.HTTP_STATUS_PROPERTY, 0);
140         etag = message.getOutboundProperty(HttpConstants.HEADER_ETAG);
141 
142         if ((status != HttpConstants.SC_NOT_MODIFIED || !checkEtag))
143         {
144             routeMessage(message);
145         }
146     }
147 }