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 }