View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  
22  package org.opencastproject.util;
23  
24  import static org.opencastproject.util.data.Collections.list;
25  import static org.opencastproject.util.data.Either.left;
26  import static org.opencastproject.util.data.Either.right;
27  import static org.opencastproject.util.data.Monadics.mlist;
28  import static org.opencastproject.util.data.Prelude.sleep;
29  import static org.opencastproject.util.data.functions.Misc.chuck;
30  
31  import org.opencastproject.security.api.TrustedHttpClient;
32  import org.opencastproject.util.data.Either;
33  import org.opencastproject.util.data.Function;
34  import org.opencastproject.util.data.Tuple;
35  
36  import org.apache.http.HttpEntityEnclosingRequest;
37  import org.apache.http.HttpResponse;
38  import org.apache.http.HttpStatus;
39  import org.apache.http.NameValuePair;
40  import org.apache.http.client.entity.UrlEncodedFormEntity;
41  import org.apache.http.client.methods.HttpGet;
42  import org.apache.http.client.methods.HttpHead;
43  import org.apache.http.client.methods.HttpPost;
44  import org.apache.http.message.BasicNameValuePair;
45  
46  import java.io.UnsupportedEncodingException;
47  import java.net.URI;
48  import java.net.URLEncoder;
49  import java.util.List;
50  
51  /** Functions to support Apache httpcomponents and HTTP related operations in general. */
52  
53  /** Functions to support Apache httpcomponents. */
54  public final class HttpUtil {
55    private HttpUtil() {
56    }
57  
58    public static HttpPost post(NameValuePair... formParams) {
59      final HttpPost post = new HttpPost();
60      setFormParams(post, formParams);
61      return post;
62    }
63  
64    public static HttpPost post(String uri, NameValuePair... formParams) {
65      final HttpPost post = new HttpPost(uri);
66      setFormParams(post, formParams);
67      return post;
68    }
69  
70    public static HttpGet get(String path, Tuple<String, String>... queryParams) {
71      final String url = mlist(path, mlist(queryParams).map(new Function<Tuple<String, String>, String>() {
72        @Override
73        public String apply(Tuple<String, String> a) {
74          try {
75            return a.getA() + "=" + URLEncoder.encode(a.getB(), "UTF-8");
76          } catch (UnsupportedEncodingException e) {
77            return chuck(e);
78          }
79        }
80      }).mkString("&")).mkString("?");
81      return new HttpGet(url);
82    }
83  
84    private static void setFormParams(HttpEntityEnclosingRequest r, NameValuePair[] formParams) {
85      final List<NameValuePair> params = list(formParams);
86      try {
87        r.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
88      } catch (UnsupportedEncodingException e) {
89        chuck(e);
90      }
91    }
92  
93    public static NameValuePair param(String name, String value) {
94      return new BasicNameValuePair(name, value);
95    }
96  
97    public static final Function<HttpResponse, Integer> getStatusCode = new Function<HttpResponse, Integer>() {
98      @Override
99      public Integer apply(HttpResponse response) {
100       return response.getStatusLine().getStatusCode();
101     }
102   };
103 
104   public static boolean isOk(HttpResponse res) {
105     return res.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
106   }
107 
108   /**
109    * Wait for a certain status of a resource.
110    *
111    * @return either an exception or the status code of the last http response
112    */
113   public static Either<Exception, Integer> waitForResource(final TrustedHttpClient http, final URI resourceUri,
114           final int expectedStatus, final long timeout, final long pollingInterval) {
115     long now = 0L;
116     while (true) {
117       final HttpHead head = new HttpHead(resourceUri);
118       HttpResponse response = null;
119       final int status;
120       try {
121         try {
122           response = http.execute(head);
123           status = response.getStatusLine().getStatusCode();
124         } finally {
125           http.close(response);
126         }
127         if (status == expectedStatus || now >= timeout) {
128           return right(status);
129         } else {
130           if (!sleep(pollingInterval)) {
131             return left(new Exception("Interrupted"));
132           } else {
133             now = now + pollingInterval;
134           }
135         }
136       } catch (Exception e) {
137         return left(e);
138       }
139     }
140   }
141 }