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.Prelude.sleep;
28  import static org.opencastproject.util.data.functions.Misc.chuck;
29  
30  import org.opencastproject.security.api.TrustedHttpClient;
31  import org.opencastproject.util.data.Either;
32  import org.opencastproject.util.data.Tuple;
33  
34  import org.apache.http.HttpEntityEnclosingRequest;
35  import org.apache.http.HttpResponse;
36  import org.apache.http.HttpStatus;
37  import org.apache.http.NameValuePair;
38  import org.apache.http.client.entity.UrlEncodedFormEntity;
39  import org.apache.http.client.methods.HttpGet;
40  import org.apache.http.client.methods.HttpHead;
41  import org.apache.http.client.methods.HttpPost;
42  import org.apache.http.message.BasicNameValuePair;
43  
44  import java.io.UnsupportedEncodingException;
45  import java.net.URI;
46  import java.net.URLEncoder;
47  import java.nio.charset.StandardCharsets;
48  import java.util.Arrays;
49  import java.util.List;
50  import java.util.stream.Collectors;
51  
52  /** Functions to support Apache httpcomponents and HTTP related operations in general. */
53  
54  /** Functions to support Apache httpcomponents. */
55  public final class HttpUtil {
56    private HttpUtil() {
57    }
58  
59    public static HttpPost post(NameValuePair... formParams) {
60      final HttpPost post = new HttpPost();
61      setFormParams(post, formParams);
62      return post;
63    }
64  
65    public static HttpPost post(String uri, NameValuePair... formParams) {
66      final HttpPost post = new HttpPost(uri);
67      setFormParams(post, formParams);
68      return post;
69    }
70  
71    public static HttpGet get(String path, Tuple<String, String>... queryParams) {
72      String queryString = Arrays.stream(queryParams)
73          .map(a -> {
74            try {
75              return a.getA() + "=" + URLEncoder.encode(a.getB(), StandardCharsets.UTF_8.toString());
76            } catch (UnsupportedEncodingException e) {
77              return chuck(e);
78            }
79          })
80          .collect(Collectors.joining("&"));
81  
82      String url = path + (queryString.isEmpty() ? "" : "?" + queryString);
83      return new HttpGet(url);
84    }
85  
86    private static void setFormParams(HttpEntityEnclosingRequest r, NameValuePair[] formParams) {
87      final List<NameValuePair> params = list(formParams);
88      try {
89        r.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
90      } catch (UnsupportedEncodingException e) {
91        chuck(e);
92      }
93    }
94  
95    public static NameValuePair param(String name, String value) {
96      return new BasicNameValuePair(name, value);
97    }
98  
99    public static boolean isOk(HttpResponse res) {
100     return res.getStatusLine().getStatusCode() == HttpStatus.SC_OK;
101   }
102 
103   /**
104    * Wait for a certain status of a resource.
105    *
106    * @return either an exception or the status code of the last http response
107    */
108   public static Either<Exception, Integer> waitForResource(final TrustedHttpClient http, final URI resourceUri,
109           final int expectedStatus, final long timeout, final long pollingInterval) {
110     long now = 0L;
111     while (true) {
112       final HttpHead head = new HttpHead(resourceUri);
113       HttpResponse response = null;
114       final int status;
115       try {
116         try {
117           response = http.execute(head);
118           status = response.getStatusLine().getStatusCode();
119         } finally {
120           http.close(response);
121         }
122         if (status == expectedStatus || now >= timeout) {
123           return right(status);
124         } else {
125           if (!sleep(pollingInterval)) {
126             return left(new Exception("Interrupted"));
127           } else {
128             now = now + pollingInterval;
129           }
130         }
131       } catch (Exception e) {
132         return left(e);
133       }
134     }
135   }
136 }