View Javadoc

1   /*
2    * $Id: PollingHttpMessageReceiver.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.providers.http;
12  
13  import org.mule.config.i18n.CoreMessages;
14  import org.mule.impl.MuleMessage;
15  import org.mule.providers.AbstractPollingMessageReceiver;
16  import org.mule.umo.UMOComponent;
17  import org.mule.umo.UMOMessage;
18  import org.mule.umo.endpoint.UMOEndpoint;
19  import org.mule.umo.lifecycle.InitialisationException;
20  import org.mule.umo.provider.UMOConnector;
21  import org.mule.umo.provider.UMOMessageAdapter;
22  import org.mule.util.Base64;
23  import org.mule.util.MapUtils;
24  
25  import java.io.InputStream;
26  import java.net.HttpURLConnection;
27  import java.net.MalformedURLException;
28  import java.net.URL;
29  import java.util.HashMap;
30  import java.util.Iterator;
31  import java.util.List;
32  import java.util.Map;
33  
34  import org.apache.commons.io.output.ByteArrayOutputStream;
35  
36  /**
37   * Will poll an http URL and use the response as the input for a service request.
38   */
39  public class PollingHttpMessageReceiver extends AbstractPollingMessageReceiver
40  {
41      private URL pollUrl;
42  
43      private static final int DEFAULT_BUFFER_SIZE = 1024 * 32;
44  
45      public PollingHttpMessageReceiver(UMOConnector connector,
46                                        UMOComponent component,
47                                        final UMOEndpoint endpoint) throws InitialisationException
48      {
49          super(connector, component, endpoint);
50  
51          long pollingFrequency = MapUtils.getLongValue(endpoint.getProperties(), "pollingFrequency",
52              -1);
53          if (pollingFrequency > 0)
54          {
55              this.setFrequency(pollingFrequency);
56          }
57  
58          try
59          {
60              pollUrl = new URL(endpoint.getEndpointURI().getAddress());
61          }
62          catch (MalformedURLException e)
63          {
64              throw new InitialisationException(
65                  CoreMessages.valueIsInvalidFor(endpoint.getEndpointURI().getAddress(), "uri"), 
66                  e, this);
67          }
68      }
69  
70      protected void doDispose()
71      {
72          // template method
73      }
74  
75      protected void doConnect() throws Exception
76      {
77          URL url;
78          String connectUrl = (String)endpoint.getProperties().get("connectUrl");
79          if (connectUrl == null)
80          {
81              url = pollUrl;
82          }
83          else
84          {
85              url = new URL(connectUrl);
86          }
87          logger.debug("Using url to connect: " + pollUrl.toString());
88          HttpURLConnection connection = (HttpURLConnection)url.openConnection();
89          connection.disconnect();
90      }
91  
92      public void doDisconnect() throws Exception
93      {
94          // nothing to do
95      }
96  
97      public void poll() throws Exception
98      {
99          HttpURLConnection connection = (HttpURLConnection)pollUrl.openConnection();
100         String authentication = endpoint.getEndpointURI().getUserInfo();
101         if (authentication != null)
102         {
103             connection.setRequestProperty("Authorization", "Basic "
104                                                            + Base64.encodeBytes(authentication
105                                                                .getBytes()));
106         }
107 
108         int len;
109         int bytesWritten = 0;
110 
111         int contentLength = connection.getContentLength();
112         boolean contentLengthNotSet = false;
113         if (contentLength < 0)
114         {
115             contentLength = DEFAULT_BUFFER_SIZE;
116             contentLengthNotSet = true;
117         }
118 
119         // TODO this is pretty dangerous for big payloads
120         byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
121         ByteArrayOutputStream baos = new ByteArrayOutputStream(contentLength);
122         InputStream is = connection.getInputStream();
123 
124         // Ensure we read all bytes, http connections may be slow
125         // to send all bytes in consistent stream. I've only seen
126         // this when using Axis...
127         while (bytesWritten != contentLength)
128         {
129             len = is.read(buffer);
130             if (len != -1)
131             {
132                 baos.write(buffer, 0, len);
133                 bytesWritten += len;
134             }
135             else
136             {
137                 if (contentLengthNotSet)
138                 {
139                     contentLength = bytesWritten;
140                 }
141             }
142         }
143         buffer = baos.toByteArray();
144         baos.close();
145 
146         // Truncate repetitive headers
147         Map respHeaders = new HashMap();
148         Iterator it = connection.getHeaderFields().entrySet().iterator();
149         while (it.hasNext())
150         {
151             Map.Entry msgHeader = (Map.Entry)it.next();
152             Object key = msgHeader.getKey();
153             Object value = msgHeader.getValue();
154             if (key != null && value != null)
155             {
156                 respHeaders.put(key, ((List)value).get(0));
157             }
158         }
159 
160         UMOMessageAdapter adapter = connector.getMessageAdapter(new Object[]{buffer, respHeaders});
161 
162         connection.disconnect();
163         UMOMessage message = new MuleMessage(adapter);
164         routeMessage(message, endpoint.isSynchronous());
165     }
166 }