View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.http.remote;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.commons.utils.CollectionUtils.*;
21  import static org.apache.juneau.commons.utils.IoUtils.*;
22  import static org.apache.juneau.http.HttpParts.*;
23  import static org.junit.jupiter.api.Assertions.*;
24  
25  import java.io.*;
26  import java.util.*;
27  
28  import org.apache.http.*;
29  import org.apache.http.entity.*;
30  import org.apache.juneau.*;
31  import org.apache.juneau.http.annotation.*;
32  import org.apache.juneau.http.annotation.Header;
33  import org.apache.juneau.http.part.*;
34  import org.apache.juneau.json.*;
35  import org.apache.juneau.marshaller.*;
36  import org.apache.juneau.rest.annotation.*;
37  import org.apache.juneau.rest.config.*;
38  import org.apache.juneau.rest.mock.*;
39  import org.junit.jupiter.api.*;
40  
41  /**
42   * Tests the @Body annotation.
43   */
44  class Remote_ContentAnnotation_Test extends TestBase {
45  
46  	//------------------------------------------------------------------------------------------------------------------
47  	// Helpers
48  	//------------------------------------------------------------------------------------------------------------------
49  
50  	public static class Bean {
51  		public int f;
52  
53  		public static Bean create() {
54  			var b = new Bean();
55  			b.f = 1;
56  			return b;
57  		}
58  
59  		@Override
60  		public String toString() {
61  			return Json5.of(this);
62  		}
63  	}
64  
65  	//-----------------------------------------------------------------------------------------------------------------
66  	// Basic tests - JSON
67  	//-----------------------------------------------------------------------------------------------------------------
68  
69  	@Rest(parsers=JsonParser.class)
70  	public static class A {
71  		@RestPost
72  		public String x1(@Content int b, @Header("Content-Type") String ct) {
73  			assertEquals("application/json",ct);
74  			return String.valueOf(b);
75  		}
76  
77  		@RestPost
78  		public String x2(@Content float b, @Header("Content-Type") String ct) {
79  			assertEquals("application/json",ct);
80  			return String.valueOf(b);
81  		}
82  
83  		@RestPost
84  		public String x3(@Content Bean b, @Header("Content-Type") String ct) {
85  			assertEquals("application/json",ct);
86  			return Json5Serializer.DEFAULT.toString(b);
87  		}
88  
89  		@RestPost
90  		public String x4(@Content Bean[] b, @Header("Content-Type") String ct) {
91  			assertEquals("application/json",ct);
92  			return Json5Serializer.DEFAULT.toString(b);
93  		}
94  
95  		@RestPost
96  		public String x5(@Content List<Bean> b, @Header("Content-Type") String ct) {
97  			assertEquals("application/json",ct);
98  			return Json5Serializer.DEFAULT.toString(b);
99  		}
100 
101 		@RestPost
102 		public String x6(@Content Map<String,Bean> b, @Header("Content-Type") String ct) {
103 			assertEquals("application/json",ct);
104 			return Json5Serializer.DEFAULT.toString(b);
105 		}
106 
107 		@RestPost
108 		public String x7(@Content Reader b, @Header("Content-Type") String ct) throws Exception {
109 			assertEquals("text/plain",ct);
110 			return read(b);
111 		}
112 
113 		@RestPost
114 		public String x8(@Content InputStream b, @Header("Content-Type") String ct) throws Exception {
115 			assertEquals("application/octet-stream",ct);
116 			return read(b);
117 		}
118 
119 		@RestPost
120 		public String x9(@Content Reader b, @Header("Content-Type") String ct) throws Exception {
121 			assertTrue(ct.startsWith("text/plain"));
122 			return read(b);
123 		}
124 
125 		@RestPost
126 		public String x10(@Content Reader b, @Header("Content-Type") String ct) throws IOException {
127 			assertEquals("application/x-www-form-urlencoded",ct);
128 			return read(b);
129 		}
130 	}
131 
132 	@Remote
133 	public interface A1 {
134 		String postX1(@Content int b);
135 		String postX2(@Content float b);
136 		String postX3(@Content Bean b);
137 		String postX4(@Content Bean[] b);
138 		String postX5(@Content List<Bean> b);
139 		String postX6(@Content Map<String,Bean> b);
140 		String postX7(@Content Reader b);
141 		String postX8(@Content InputStream b);
142 		String postX9(@Content HttpEntity b);
143 		String postX10(@Content PartList b);
144 	}
145 
146 	@Test void a01_objectTypes_json() throws Exception {
147 		var x = MockRestClient.create(A.class).serializer(JsonSerializer.class).build().getRemote(A1.class);
148 		assertEquals("1",x.postX1(1));
149 		assertEquals("1.0",x.postX2(1f));
150 		assertEquals("{f:1}",x.postX3(Bean.create()));
151 		assertEquals("[{f:1}]",x.postX4(a(Bean.create())));
152 		assertEquals("[{f:1}]",x.postX5(l(Bean.create())));
153 		assertEquals("{k1:{f:1}}",x.postX6(map("k1",Bean.create())));
154 		assertEquals("xxx",x.postX7(reader("xxx")));
155 		assertEquals("xxx",x.postX8(inputStream("xxx")));
156 		assertEquals("xxx",x.postX9(new StringEntity("xxx")));
157 		assertEquals("foo=bar",x.postX10(partList("foo","bar")));
158 	}
159 
160 	//-----------------------------------------------------------------------------------------------------------------
161 	// Basic tests - OpenAPI
162 	//-----------------------------------------------------------------------------------------------------------------
163 
164 	@Rest
165 	public static class B implements BasicOpenApiConfig {
166 		@RestPost
167 		public Object x1(@Content int b, @Header("Content-Type") String ct) {
168 			assertEquals("text/openapi",ct);
169 			return b;
170 		}
171 
172 		@RestPost
173 		public Object x2(@Content float b, @Header("Content-Type") String ct) {
174 			assertEquals("text/openapi",ct);
175 			return b;
176 		}
177 
178 		@RestPost
179 		public String x3(@Content Bean b, @Header("Content-Type") String ct) {
180 			assertEquals("text/openapi",ct);
181 			return Json5.of(b);
182 		}
183 
184 		@RestPost
185 		public Object x4(@Content Bean[] b, @Header("Content-Type") String ct) {
186 			assertEquals("text/openapi",ct);
187 			return Json5.of(b);
188 		}
189 
190 		@RestPost
191 		public Object x5(@Content List<Bean> b, @Header("Content-Type") String ct) {
192 			assertEquals("text/openapi",ct);
193 			return Json5.of(b);
194 		}
195 
196 		@RestPost
197 		public Object x6(@Content Map<String,Bean> b, @Header("Content-Type") String ct) {
198 			assertEquals("text/openapi",ct);
199 			return Json5.of(b);
200 		}
201 
202 		@RestPost
203 		public Object x7(@Content Reader b, @Header("Content-Type") String ct) {
204 			assertEquals("text/plain",ct);
205 			return b;
206 		}
207 
208 		@RestPost
209 		public Object x8(@Content InputStream b, @Header("Content-Type") String ct) {
210 			assertEquals("application/octet-stream",ct);
211 			return b;
212 		}
213 
214 		@RestPost
215 		public Object x9(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
216 			assertEquals("text/plain",ct);
217 			return b;
218 		}
219 
220 		@RestPost
221 		public Object x10(@Content Reader b, @Header("Content-Type") String ct) {
222 			assertEquals("application/x-www-form-urlencoded",ct);
223 			return b;
224 		}
225 	}
226 	@Remote
227 	public interface B1 {
228 		String postX1(@Content int b);
229 		String postX2(@Content float b);
230 		String postX3(@Content Bean b);
231 		String postX4(@Content Bean[] b);
232 		String postX5(@Content List<Bean> b);
233 		String postX6(@Content Map<String,Bean> b);
234 		String postX7(@Content Reader b);
235 		String postX8(@Content InputStream b);
236 		String postX9(@Content HttpEntity b);
237 		String postX10(@Content PartList b);
238 	}
239 
240 	@Test void b01_objectTypes_openApi() throws Exception {
241 		var x = MockRestClient.create(B.class).openApi().contentType(null).build().getRemote(B1.class);
242 		assertEquals("1",x.postX1(1));
243 		assertEquals("1.0",x.postX2(1f));
244 		assertEquals("{f:1}",x.postX3(Bean.create()));
245 		assertEquals("[{f:1}]",x.postX4(a(Bean.create())));
246 		assertEquals("[{f:1}]",x.postX5(l(Bean.create())));
247 		assertEquals("{k1:{f:1}}",x.postX6(map("k1",Bean.create())));
248 		assertEquals("xxx",x.postX7(reader("xxx")));
249 		assertEquals("xxx",x.postX8(inputStream("xxx")));
250 		assertEquals("xxx",x.postX9(new StringEntity("xxx",org.apache.http.entity.ContentType.create("text/plain"))));
251 		assertEquals("foo=bar",x.postX10(partList("foo","bar")));
252 	}
253 
254 	//-----------------------------------------------------------------------------------------------------------------
255 	// Basic tests - OpenAPI, overridden Content-Type
256 	//-----------------------------------------------------------------------------------------------------------------
257 
258 	@Rest
259 	public static class C {
260 		@RestPost
261 		public Reader x1(@Content Reader b, @Header("Content-Type") String ct) {
262 			assertEquals("text/foo",ct);
263 			return b;
264 		}
265 		@RestPost
266 		public Reader x2(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
267 			assertEquals("text/foo",ct);
268 			return b;
269 		}
270 		@RestPost
271 		public Reader x3(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
272 			assertEquals("text/foo",ct);
273 			return b;
274 		}
275 		@RestPost
276 		public Reader x5(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
277 			assertEquals("text/foo",ct);
278 			return b;
279 		}
280 		@RestPost
281 		public Reader x6(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
282 			assertEquals("text/foo",ct);
283 			return b;
284 		}
285 		@RestPost
286 		public Reader x7(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
287 			assertEquals("text/foo",ct);
288 			return b;
289 		}
290 		@RestPost
291 		public Reader x8(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
292 			assertEquals("text/foo",ct);
293 			return b;
294 		}
295 		@RestPost
296 		public Reader x9(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
297 			assertEquals("text/foo",ct);
298 			return b;
299 		}
300 		@RestPost
301 		public Reader x10(@Content Reader b, @Header("Content-Type") String ct) {  // NOSONAR
302 			assertEquals("text/foo",ct);
303 			return b;
304 		}
305 	}
306 	@Remote
307 	public interface C1 {
308 		String postX1(@Content int b);
309 		String postX2(@Content float b);
310 		String postX3(@Content Bean b);
311 		String postX4(@Content Bean[] b);
312 		String postX5(@Content List<Bean> b);
313 		String postX6(@Content Map<String,Bean> b);
314 		String postX7(@Content Reader b);
315 		String postX8(@Content InputStream b);
316 		String postX9(@Content HttpEntity b);
317 		String postX10(@Content PartList b);
318 	}
319 
320 	@Test void c01_openApi_overriddenContentType() throws Exception {
321 		var x = MockRestClient.create(C.class).parser(JsonParser.class).contentType("text/foo").build().getRemote(C1.class);
322 		assertEquals("1",x.postX1(1));
323 		assertEquals("1.0",x.postX2(1f));
324 		assertEquals("{f:1}",x.postX3(Bean.create()));
325 		assertEquals("[{f:1}]",x.postX5(l(Bean.create())));
326 		assertEquals("{k1={f:1}}",x.postX6(map("k1",Bean.create())));
327 		assertEquals("xxx",x.postX7(reader("xxx")));
328 		assertEquals("xxx",x.postX8(inputStream("xxx")));
329 		assertEquals("xxx",x.postX9(new StringEntity("xxx",org.apache.http.entity.ContentType.create("text/plain"))));
330 		assertEquals("foo=bar",x.postX10(partList("foo","bar")));
331 	}
332 }