1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package io.wcm.caravan.io.http.request;
21
22 import static com.google.common.base.Preconditions.checkNotNull;
23
24 import java.nio.charset.Charset;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.apache.commons.lang3.StringUtils;
32 import org.apache.http.client.methods.HttpGet;
33 import org.osgi.annotation.versioning.ProviderType;
34
35 import com.damnhandy.uri.template.UriTemplate;
36 import com.google.common.base.Charsets;
37 import com.google.common.base.Strings;
38 import com.google.common.collect.ArrayListMultimap;
39 import com.google.common.collect.ImmutableList;
40 import com.google.common.collect.Lists;
41 import com.google.common.collect.Maps;
42 import com.google.common.collect.Multimap;
43 import com.google.common.collect.Sets;
44
45 import io.wcm.caravan.io.http.impl.CaravanHttpHelper;
46
47
48
49
50 @ProviderType
51 public final class CaravanHttpRequestBuilder {
52
53 private final String serviceId;
54 private String method = HttpGet.METHOD_NAME;
55 private StringBuilder path = new StringBuilder();
56 private Set<String> queryNames = Sets.newHashSet();
57 private Map<String, Object> values = Maps.newHashMap();
58 private final Multimap<String, String> headers = ArrayListMultimap.create();
59 private Charset charset;
60 private byte[] body;
61 private String bodyTemplate;
62
63
64
65
66 public CaravanHttpRequestBuilder() {
67 serviceId = null;
68 }
69
70
71
72
73 public CaravanHttpRequestBuilder(String serviceId) {
74 this.serviceId = serviceId;
75 }
76
77
78
79
80
81 public CaravanHttpRequestBuilder correlationId(String correlationId) {
82 if (correlationId != null) {
83 header(CaravanHttpRequest.CORRELATION_ID_HEADER_NAME, ImmutableList.of(correlationId));
84 }
85 return this;
86 }
87
88
89
90
91
92
93 public CaravanHttpRequestBuilder method(String newMethod) {
94 this.method = checkNotNull(newMethod, "method");
95 return this;
96 }
97
98
99
100
101
102
103
104
105 public CaravanHttpRequestBuilder header(String name, String value) {
106 headers.put(name, value);
107 return this;
108 }
109
110
111
112
113
114
115
116
117 public CaravanHttpRequestBuilder header(String name, Collection<String> headerValues) {
118 headers.putAll(name, headerValues);
119 return this;
120 }
121
122
123
124
125
126
127 public CaravanHttpRequestBuilder append(String urlFragment) {
128 this.path.append(urlFragment);
129 return this;
130 }
131
132
133
134
135
136
137 public CaravanHttpRequestBuilder query(String name) {
138 queryNames.add(name);
139 return this;
140 }
141
142
143
144
145
146
147
148
149 public CaravanHttpRequestBuilder query(String name, Object value) {
150 return query(name).value(name, value);
151 }
152
153
154
155
156
157
158
159 public CaravanHttpRequestBuilder value(String name, Object value) {
160 values.put(name, value);
161 return this;
162 }
163
164
165
166
167
168
169
170 public CaravanHttpRequestBuilder body(String template) {
171 body = null;
172 charset = Charsets.UTF_8;
173 bodyTemplate = template;
174 return this;
175 }
176
177
178
179
180
181
182
183
184 public CaravanHttpRequestBuilder body(byte[] newBody, Charset newCharset) {
185 body = newBody;
186 charset = newCharset;
187 bodyTemplate = null;
188 return this;
189 }
190
191
192
193
194
195 public CaravanHttpRequest build() {
196 return build(Collections.emptyMap());
197 }
198
199
200
201
202
203
204 public CaravanHttpRequest build(Map<String, Object> parameters) {
205 String expandedUrl = getExpandedUrl(parameters);
206 Multimap<String, String> expandedHeaders = getExpandedHeaders(parameters);
207 byte[] expandedBody = getExpandedBody(parameters);
208 return new CaravanHttpRequest(serviceId, method, expandedUrl, expandedHeaders, expandedBody, charset);
209 }
210
211 private String getExpandedUrl(Map<String, Object> parameters) {
212
213 Map<String, Object> mergedParams = Maps.newHashMap(parameters);
214 mergedParams.putAll(values);
215 List<String> sortedQueryNames = Lists.newArrayList(queryNames);
216 Collections.sort(sortedQueryNames);
217 String operator = path.indexOf("?") == -1 ? "?" : "&";
218 String query = queryNames.isEmpty() ? "" : ('{' + operator + StringUtils.join(queryNames, ',') + '}');
219 return UriTemplate.fromTemplate(path + query).expand(mergedParams);
220
221 }
222
223 private Multimap<String, String> getExpandedHeaders(Map<String, Object> parameters) {
224 Multimap<String, String> expandedHeaders = ArrayListMultimap.create();
225 headers.entries().forEach(entry -> {
226 String template = entry.getValue();
227 String expanded = UriTemplate.expand(template, parameters);
228 if (!Strings.isNullOrEmpty(expanded)) {
229 expandedHeaders.put(entry.getKey(), expanded);
230 }
231 });
232 return expandedHeaders;
233 }
234
235 private byte[] getExpandedBody(Map<String, Object> parameters) {
236 if (bodyTemplate == null) {
237 return body;
238 }
239 return CaravanHttpHelper.urlDecode(UriTemplate.expand(bodyTemplate, parameters)).getBytes(Charsets.UTF_8);
240 }
241
242 }