001 002package io.vrap.rmf.base.client; 003 004import java.net.MalformedURLException; 005import java.net.URI; 006import java.net.URL; 007import java.nio.charset.StandardCharsets; 008import java.util.HashMap; 009import java.util.Map; 010import java.util.Optional; 011 012import org.apache.commons.lang3.builder.EqualsBuilder; 013import org.apache.commons.lang3.builder.HashCodeBuilder; 014import org.apache.commons.lang3.builder.ToStringBuilder; 015 016public class ApiHttpRequest extends Base implements ContextAware<ApiHttpRequest> { 017 018 private ApiHttpMethod method; 019 private URI uri; 020 private ApiHttpHeaders headers; 021 private byte[] body; 022 023 private Map<Object, Object> contextMap = new HashMap<>(); 024 025 public ApiHttpRequest() { 026 } 027 028 public ApiHttpRequest(final ApiHttpMethod method, final URI uri, final ApiHttpHeaders headers, final byte[] body, 029 final Map<Object, Object> contextMap) { 030 this.method = method; 031 this.uri = uri; 032 this.headers = headers; 033 this.body = body; 034 this.contextMap = contextMap; 035 } 036 037 public ApiHttpRequest(final ApiHttpMethod method, final URI uri, final ApiHttpHeaders headers, final byte[] body) { 038 this.method = method; 039 this.uri = uri; 040 this.headers = headers; 041 this.body = body; 042 } 043 044 public ApiHttpRequest(final ApiHttpRequest r) { 045 this.method = r.method; 046 this.uri = r.uri; 047 this.headers = r.headers; 048 this.body = r.body; 049 this.contextMap = r.contextMap; 050 } 051 052 public Map<Object, Object> getContextMap() { 053 return contextMap; 054 } 055 056 public ApiHttpRequest withContextMap(final Map<Object, Object> contextMap) { 057 final ApiHttpRequest request = copy(); 058 request.contextMap = new HashMap<>(contextMap); 059 060 return request; 061 } 062 063 @SuppressWarnings("unchecked") 064 public <T> T getContext(Class<T> key) { 065 return (T) contextMap.get(key); 066 } 067 068 public <T> ApiHttpRequest addContext(T value) { 069 final ApiHttpRequest request = copy(); 070 final Map<Object, Object> contextMap = new HashMap<>(request.contextMap); 071 contextMap.put(value.getClass(), value); 072 request.contextMap = contextMap; 073 074 return request; 075 } 076 077 public Object getContext(Object key) { 078 return contextMap.get(key); 079 } 080 081 public ApiHttpRequest addContext(Object key, Object value) { 082 final ApiHttpRequest request = copy(); 083 final Map<Object, Object> contextMap = new HashMap<>(request.contextMap); 084 contextMap.put(key, value); 085 request.contextMap = contextMap; 086 087 return request; 088 } 089 090 public ApiHttpMethod getMethod() { 091 return method; 092 } 093 094 public ApiHttpRequest withMethod(final ApiHttpMethod method) { 095 ApiHttpRequest request = copy(); 096 request.method = method; 097 098 return request; 099 } 100 101 public ApiHttpHeaders getHeaders() { 102 if (headers == null) { 103 this.headers = new ApiHttpHeaders(); 104 } 105 return headers; 106 } 107 108 public ApiHttpRequest addHeader(final String key, final String value) { 109 ApiHttpRequest request = copy(); 110 request.headers = getHeaders().addHeader(key, value); 111 112 return request; 113 } 114 115 public ApiHttpRequest withHeaders(final ApiHttpHeaders headers) { 116 ApiHttpRequest request = copy(); 117 request.headers = headers; 118 return request; 119 } 120 121 public ApiHttpRequest withHeader(final String key, final String value) { 122 ApiHttpRequest request = copy(); 123 request.headers = getHeaders().withHeader(key, value); 124 125 return request; 126 } 127 128 public ApiHttpRequest withoutHeader(final String key) { 129 ApiHttpRequest request = copy(); 130 request.headers = getHeaders().withoutHeader(key); 131 132 return request; 133 } 134 135 public byte[] getBody() { 136 return body; 137 } 138 139 public ApiHttpRequest withBody(final byte[] body) { 140 ApiHttpRequest request = copy(); 141 request.body = body; 142 return request; 143 } 144 145 public ApiHttpRequest withBody(final String body) { 146 ApiHttpRequest request = copy(); 147 if (body == null) { 148 request.body = null; 149 } 150 else { 151 request.body = body.getBytes(StandardCharsets.UTF_8); 152 } 153 154 return request; 155 } 156 157 public URI getUri() { 158 return uri; 159 } 160 161 public URL getUrl() { 162 try { 163 return uri.toURL(); 164 } 165 catch (MalformedURLException e) { 166 throw new IllegalStateException("Malformed URI", e); 167 } 168 } 169 170 public ApiHttpRequest withUri(final String uri) { 171 ApiHttpRequest request = copy(); 172 request.uri = URI.create(uri); 173 return request; 174 } 175 176 public ApiHttpRequest withUri(final URI uri) { 177 ApiHttpRequest request = copy(); 178 request.uri = uri; 179 180 return request; 181 } 182 183 public ApiHttpRequest resolve(final URI baseUri) { 184 return withUri(baseUri.resolve(this.uri)); 185 } 186 187 @Override 188 public String toString() { 189 return new ToStringBuilder(this).append("method", method) 190 .append("uri", "\"" + uri + "\"") 191 .append("headers", headers) 192 .append("textInterpretedBody", getSecuredBody()) 193 .toString(); 194 } 195 196 public String getSecuredBody() { 197 return Optional.ofNullable(body) 198 .map(b -> tryToFilter(new String(b, StandardCharsets.UTF_8))) 199 .orElse("empty body"); 200 } 201 202 static String tryToFilter(final String input) { 203 return input.replaceAll("(\"\\w*([Pp]ass|access_token|refresh_token)\\w*\"):\"[^\"]*\"", 204 "$1:\"**removed from output**\""); 205 } 206 207 private ApiHttpRequest copy() { 208 return new ApiHttpRequest(this); 209 } 210 211 @Override 212 public boolean equals(Object o) { 213 if (this == o) 214 return true; 215 216 if (o == null || getClass() != o.getClass()) 217 return false; 218 219 ApiHttpRequest request = (ApiHttpRequest) o; 220 221 return new EqualsBuilder().append(method, request.method) 222 .append(uri, request.uri) 223 .append(headers, request.headers) 224 .append(body, request.body) 225 .append(contextMap, request.contextMap) 226 .isEquals(); 227 } 228 229 @Override 230 public int hashCode() { 231 return new HashCodeBuilder(17, 37).append(method) 232 .append(uri) 233 .append(headers) 234 .append(body) 235 .append(contextMap) 236 .toHashCode(); 237 } 238}