View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.hc.core5.testing.framework;
28  
29  import java.util.Map;
30  
31  /**
32   *
33   * <p>This adapter expects a request to be made up of POJOs such as Maps and Lists.  In Groovy
34   * the request could be expressed like this:</p>
35   *
36   * <pre>
37   *
38   * def request = [
39   *                   path    : "a/path",
40   *                   method  : "GET",
41   *                   query   : [
42   *                                parm1 : "1",
43   *                                parm2 : "2",
44   *                             ]
45   *                   headers : [
46   *                                header1 : "stuff",
47   *                                header2 : "more_stuff",
48   *                             ]
49   *                   contentType : "application/json",
50   *                   body        : '{"location" : "home" }',
51   *                ]
52   * </pre>
53   *
54   * <p>The adapter will translate this request into calls specific to a particular HTTP client.</p>
55   *
56   * <p>The response is then returned with POJOs with this structure:</p>
57   *
58   * <pre>
59   *
60   * def response = [
61   *                    status      : 200,
62   *                    headers     : [
63   *                                      header1 : "response_stuff",
64   *                                  ]
65   *                    contentType : "application/json",
66   *                    body        : '{"location" : "work" }',
67   *                ]
68   * </pre>
69   * @since 5.0
70   */
71  public abstract class ClientPOJOAdapter {
72      public static final String BODY = "body";
73      public static final String CONTENT_TYPE = "contentType";
74      public static final String HEADERS = "headers";
75      public static final String METHOD = "method";
76      public static final String NAME = "name";
77      public static final String PATH = "path";
78      public static final String PROTOCOL_VERSION = "protocolVersion";
79      public static final String QUERY = "query";
80      public static final String REQUEST = "request";
81      public static final String RESPONSE = "response";
82      public static final String STATUS = "status";
83      public static final String TIMEOUT = "timeout";
84  
85      /**
86       * Name of the HTTP Client that this adapter uses.
87       *
88       * @return name of the HTTP Client.
89       */
90      public abstract String getClientName();
91  
92      /**
93       * Execute an HTTP request.
94       *
95       * @param defaultURI   the URI used by default.  The path in the request is
96       *                     usually appended to it.
97       * @param request      the request as specified above.
98       *
99       * @return the response to the request as specified above.
100      *
101      * @throws Exception in case of a problem
102      */
103     public abstract Map<String, Object> execute(String defaultURI, Map<String, Object> request) throws Exception;
104 
105     /**
106      * <p>Check if a request is supported.</p>
107      *
108      * <p>Usually called directly by a testing framework.  If an HTTP client does not support
109      * a particular request, a non-null reason should be returned.  Otherwise, if
110      * the request is supported, return null.</p>
111      *
112      * <p>If this method is overridden, then the execute method should probably call
113      * assertRequestSupported() at the beginning.</p>
114      *
115      * @param request the request as specified above.
116      *
117      * @return null if the request is supported;  Otherwise, return a reason.
118      */
119     public String checkRequestSupport(final Map<String, Object> request) {
120         return null;
121     }
122 
123     /**
124      * <p>Assert that the request is supported</p>
125      *
126      * <p>Usually called by the execute method.  Throws an exception if the request
127      * is not supported.</p>
128      *
129      * @param request the request as specified above.
130      * @throws Exception if the request is not supported.
131      */
132     public void assertRequestSupported(final Map<String, Object> request) throws Exception {
133         final String reason = checkRequestSupport(request);
134         if (reason != null) {
135             throw new Exception(reason);
136         }
137     }
138 
139     /**
140      * <p>Modify the request.</p>
141      *
142      * <p>In a testing context, a testing framework can call this method to allow
143      * the adapter to change the request.  The request is then given to a
144      * special request handler of the in-process HttpServer which will later check
145      * an actual HTTP request against what is expected.</p>
146      *
147      * <p>In a production context, this is called by the execute method (if at all).</p>
148      *
149      * @param request the request as specified above.
150      * @return the same request or a modification of it.
151      */
152     public Map<String, Object> modifyRequest(final Map<String, Object> request) {
153         return request;
154     }
155 }