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.common.utils.IOUtils.*;
20  import static org.junit.jupiter.api.Assertions.*;
21  
22  import java.io.*;
23  import java.util.concurrent.*;
24  
25  import org.apache.http.*;
26  import org.apache.juneau.*;
27  import org.apache.juneau.http.annotation.*;
28  import org.apache.juneau.rest.annotation.*;
29  import org.apache.juneau.rest.config.*;
30  import org.apache.juneau.rest.mock.*;
31  import org.junit.jupiter.api.*;
32  
33  class Remote_RemoteOpAnnotation_Test extends TestBase {
34  
35  	//-----------------------------------------------------------------------------------------------------------------
36  	// Inferred methods/paths
37  	//-----------------------------------------------------------------------------------------------------------------
38  
39  	@Rest
40  	public static class A {
41  		@RestOp
42  		public String get() {
43  			return "foo";
44  		}
45  		@RestOp
46  		public String x1() {
47  			return "bar";
48  		}
49  		@RestOp
50  		public String postX2() {
51  			return "baz";
52  		}
53  		@RestOp(path="/doFoo")
54  		public String doFoo() {
55  			return "qux";
56  		}
57  	}
58  
59  	@Remote
60  	public interface A1 {
61  		String doGet();
62  		String doGET();
63  		String doFoo();
64  		String getX1();
65  		String postX2();
66  	}
67  
68  	@Test void a01_inferredMethodsAndPaths() {
69  		var t = remote(A.class,A1.class);
70  		assertEquals("foo",t.doGet());
71  		assertEquals("foo",t.doGET());
72  		assertEquals("qux",t.doFoo());
73  		assertEquals("bar",t.getX1());
74  		assertEquals("baz",t.postX2());
75  	}
76  
77  	@Remote
78  	public interface A2 {
79  		Future<String> doGet();
80  		Future<String> doGET();
81  		Future<String> doFoo();
82  		Future<String> getX1();
83  		Future<String> postX2();
84  	}
85  
86  	@Test void a02_inferredMethodsAndPaths_futures() throws Exception {
87  		var t = remote(A.class,A2.class);
88  		assertEquals("foo",t.doGet().get());
89  		assertEquals("foo",t.doGET().get());
90  		assertEquals("qux",t.doFoo().get());
91  		assertEquals("bar",t.getX1().get());
92  		assertEquals("baz",t.postX2().get());
93  	}
94  
95  	@Remote
96  	public interface A3 {
97  		CompletableFuture<String> doGet();
98  		CompletableFuture<String> doGET();
99  		CompletableFuture<String> doFoo();
100 		CompletableFuture<String> getX1();
101 		CompletableFuture<String> postX2();
102 	}
103 
104 	@Test void a03_inferredMethodsAndPaths_completableFutures() throws Exception {
105 		var t = remote(A.class,A3.class);
106 		assertEquals("foo",t.doGet().get());
107 		assertEquals("foo",t.doGET().get());
108 		assertEquals("qux",t.doFoo().get());
109 		assertEquals("bar",t.getX1().get());
110 		assertEquals("baz",t.postX2().get());
111 	}
112 
113 	//-----------------------------------------------------------------------------------------------------------------
114 	// Return types
115 	//-----------------------------------------------------------------------------------------------------------------
116 
117 	@Rest
118 	public static class B {
119 		@RestOp(path="/*")
120 		public String get() {
121 			return "foo";
122 		}
123 	}
124 
125 	@Remote
126 	public interface B1 {
127 		void x1();
128 		String x2();
129 		HttpResponse x3();
130 		Reader x4();
131 		InputStream x5();
132 		Future<Void> x6();
133 		Future<String> x7();
134 		Future<HttpResponse> x8();
135 		Future<Reader> x9();
136 		Future<InputStream> x10();
137 		CompletableFuture<Void> x11();
138 		CompletableFuture<String> x12();
139 		CompletableFuture<HttpResponse> x13();
140 		CompletableFuture<Reader> x14();
141 		CompletableFuture<InputStream> x15();
142 	}
143 
144 	@Test void b01_returnTypes() throws Exception {
145 		var x = remote(B.class,B1.class);
146 		x.x1();
147 		assertEquals("foo",x.x2());
148 		assertEquals("foo",read(x.x3().getEntity().getContent()));
149 		assertEquals("foo",read(x.x4()));
150 		assertEquals("foo",read(x.x5()));
151 		x.x6().get();
152 		assertEquals("foo",x.x7().get());
153 		assertEquals("foo",read(x.x8().get().getEntity().getContent()));
154 		assertEquals("foo",read(x.x9().get()));
155 		assertEquals("foo",read(x.x10().get()));
156 		x.x11().get();
157 		assertEquals("foo",x.x12().get());
158 		assertEquals("foo",read(x.x13().get().getEntity().getContent()));
159 		assertEquals("foo",read(x.x14().get()));
160 		assertEquals("foo",read(x.x15().get()));
161 	}
162 
163 	//-----------------------------------------------------------------------------------------------------------------
164 	// Return types, JSON
165 	//-----------------------------------------------------------------------------------------------------------------
166 
167 	@Rest
168 	public static class C implements BasicJson5Config {
169 		@RestOp(path="/*")
170 		public String post(@Content String body) {
171 			return body;
172 		}
173 	}
174 
175 	@Remote
176 	public interface C1 {
177 		String postX1(@Content String foo);
178 		HttpResponse postX2(@Content String foo);
179 		Reader postX3(@Content String foo);
180 		InputStream postX4(@Content String foo);
181 		Future<String> postX5(@Content String foo);
182 		Future<HttpResponse> postX6(@Content String foo);
183 		Future<Reader> postX7(@Content String foo);
184 		Future<InputStream> postX8(@Content String foo);
185 		CompletableFuture<String> postX9(@Content String foo);
186 		CompletableFuture<HttpResponse> postX10(@Content String foo);
187 		CompletableFuture<Reader> postX11(@Content String foo);
188 		CompletableFuture<InputStream> postX12(@Content String foo);
189 	}
190 
191 	@Test void c01_returnTypes_json() throws Exception {
192 		var x = MockRestClient.buildJson(C.class).getRemote(C1.class);
193 		assertEquals("foo",x.postX1("foo"));
194 		assertEquals("'foo'",read(x.postX2("foo").getEntity().getContent()));
195 		assertEquals("'foo'",read(x.postX3("foo")));
196 		assertEquals("'foo'",read(x.postX4("foo")));
197 		assertEquals("foo",x.postX5("foo").get());
198 		assertEquals("'foo'",read(x.postX6("foo").get().getEntity().getContent()));
199 		assertEquals("'foo'",read(x.postX7("foo").get()));
200 		assertEquals("'foo'",read(x.postX8("foo").get()));
201 		assertEquals("foo",x.postX9("foo").get());
202 		assertEquals("'foo'",read(x.postX10("foo").get().getEntity().getContent()));
203 		assertEquals("'foo'",read(x.postX11("foo").get()));
204 		assertEquals("'foo'",read(x.postX12("foo").get()));
205 	}
206 
207 	//-----------------------------------------------------------------------------------------------------------------
208 	// Return types, part serialization
209 	//-----------------------------------------------------------------------------------------------------------------
210 
211 	@Rest
212 	public static class D implements BasicOpenApiConfig {
213 		@RestPost(path="/*") @Response
214 		public String x1(@Content String body) {
215 			return body;
216 		}
217 	}
218 
219 	@Remote
220 	public interface D1 {
221 		String postX1(@Content String foo);
222 		HttpResponse postX2(@Content String foo);
223 		Reader postX3(@Content String foo);
224 		InputStream postX4(@Content String foo);
225 		Future<String> postX5(@Content String foo);
226 		Future<HttpResponse> postX6(@Content String foo);
227 		Future<Reader> postX7(@Content String foo);
228 		Future<InputStream> postX8(@Content String foo);
229 		CompletableFuture<String> postX9(@Content String foo);
230 		CompletableFuture<HttpResponse> postX10(@Content String foo);
231 		CompletableFuture<Reader> postX11(@Content String foo);
232 		CompletableFuture<InputStream> postX12(@Content String foo);
233 	}
234 
235 	@Test void d01_returnTypes_partSerialization() throws Exception {
236 		var x = MockRestClient.create(D.class).openApi().build().getRemote(D1.class);
237 		assertEquals("foo",x.postX1("foo"));
238 		assertEquals("foo",read(x.postX2("foo").getEntity().getContent()));
239 		assertEquals("foo",read(x.postX3("foo")));
240 		assertEquals("foo",read(x.postX4("foo")));
241 		assertEquals("foo",x.postX5("foo").get());
242 		assertEquals("foo",read(x.postX6("foo").get().getEntity().getContent()));
243 		assertEquals("foo",read(x.postX7("foo").get()));
244 		assertEquals("foo",read(x.postX8("foo").get()));
245 		assertEquals("foo",x.postX9("foo").get());
246 		assertEquals("foo",read(x.postX10("foo").get().getEntity().getContent()));
247 		assertEquals("foo",read(x.postX11("foo").get()));
248 		assertEquals("foo",read(x.postX12("foo").get()));
249 	}
250 
251 	//------------------------------------------------------------------------------------------------------------------
252 	// Helper methods.
253 	//------------------------------------------------------------------------------------------------------------------
254 
255 	private static <T> T remote(Class<?> rest, Class<T> t) {
256 		return MockRestClient.build(rest).getRemote(t);
257 	}
258 }