001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.http.remote;
018
019import static java.lang.annotation.ElementType.*;
020import static java.lang.annotation.RetentionPolicy.*;
021
022import java.lang.annotation.*;
023
024/**
025 * Identifies a proxy against a REST interface.
026 *
027 * <h5 class='section'>See Also:</h5><ul>
028 *    <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/RestProxies">REST Proxies</a>
029 * </ul>
030 */
031@Documented
032@Target({ TYPE })
033@Retention(RUNTIME)
034@Inherited
035public @interface Remote {
036
037   /**
038    * Default request header list.
039    *
040    * <p>
041    * Specifies a supplier of headers to set on all requests. The value is interpreted by the active REST client:
042    * the classic Apache-HttpClient transport accepts subclasses of
043    * <c>org.apache.juneau.http.classic.header.HeaderList</c>; other transports may ignore the value.
044    *
045    * <h5 class='section'>Notes:</h5><ul>
046    *    <li class='note'>
047    *       Supplier class must provide a public no-arg constructor.
048    *    <li class='note'>
049    *       Default <c>Void.class</c> means no default header list is supplied.
050    * </ul>
051    *
052    * @return The annotation value.
053    */
054   Class<?> headerList() default Void.class;
055
056   /**
057    * Default request headers.
058    *
059    * <p>
060    * Specifies headers to set on all requests.
061    *
062    * <h5 class='section'>Notes:</h5><ul>
063    *    <li class='note'>
064    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/DefaultVarResolver">VarResolver.DEFAULT</a>
065    *       (e.g. <js>"$P{mySystemProperty}"</js>).
066    * </ul>
067    *
068    * @return The annotation value.
069    */
070   String[] headers() default {};
071
072   /**
073    * Default request query parameters.
074    *
075    * <p>
076    * Specifies always-applied constant query parameters emitted on <i>every</i> request the proxy makes &mdash; no
077    * corresponding method parameter is required.  Each entry uses the <js>"name=value"</js> form (the first
078    * <js>'='</js> separates name from value), mirroring the URL-query convention and the {@link #headers()}
079    * <js>"Name: value"</js> precedent.
080    *
081    * <p>
082    * A caller-supplied parameter value for the same name still composes with the constant (the constant is not
083    * suppressed).  A method-level constant of the same name (see {@code @RemoteOp(queryData=...)} and the verb
084    * annotations) takes precedence over the interface-level value declared here.
085    *
086    * <h5 class='section'>Notes:</h5><ul>
087    *    <li class='note'>
088    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/DefaultVarResolver">VarResolver.DEFAULT</a>
089    *       (e.g. <js>"$S{mySystemProperty}"</js>).
090    *    <li class='note'>
091    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
092    *       (<c>RestClient.getRemote(...)</c>).
093    * </ul>
094    *
095    * @return The annotation value.
096    */
097   String[] queryData() default {};
098
099   /**
100    * Default request form-data parameters.
101    *
102    * <p>
103    * Specifies always-applied constant form-data fields emitted on <i>every</i> request the proxy makes &mdash; no
104    * corresponding method parameter is required.  Each entry uses the <js>"name=value"</js> form (the first
105    * <js>'='</js> separates name from value), mirroring the form-encoded convention and the {@link #headers()}
106    * <js>"Name: value"</js> precedent.
107    *
108    * <p>
109    * A caller-supplied parameter value for the same name still composes with the constant (the constant is not
110    * suppressed).  A method-level constant of the same name (see {@code @RemoteOp(formData=...)} and the verb
111    * annotations) takes precedence over the interface-level value declared here.
112    *
113    * <h5 class='section'>Notes:</h5><ul>
114    *    <li class='note'>
115    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/DefaultVarResolver">VarResolver.DEFAULT</a>
116    *       (e.g. <js>"$S{mySystemProperty}"</js>).
117    *    <li class='note'>
118    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
119    *       (<c>RestClient.getRemote(...)</c>).
120    * </ul>
121    *
122    * @return The annotation value.
123    */
124   String[] formData() default {};
125
126   /**
127    * REST service path.
128    *
129    * <ul class='values'>
130    *    <li>An absolute URL.
131    *    <li>A relative URL interpreted as relative to the root URL defined on the <c>RestClient</c>
132    *    <li>No path interpreted as the class name (e.g. <js>"http://localhost/root-url/org.foo.MyInterface"</js>)
133    * </ul>
134    *
135    * <h5 class='section'>Notes:</h5><ul>
136    *    <li class='note'>
137    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/DefaultVarResolver">VarResolver.DEFAULT</a>
138    *       (e.g. <js>"$P{mySystemProperty}"</js>).
139    * </ul>
140    *
141    * @return The annotation value.
142    */
143   String path() default "";
144
145   /**
146    * Alias for {@link #path()}.
147    *
148    * <p>
149    * Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/DefaultVarResolver">VarResolver.DEFAULT</a>
150    * (e.g. <js>"$P{mySystemProperty}"</js>).
151    * </p>
152    *
153    * @return The annotation value.
154    */
155   String value() default "";
156
157   /**
158    * Base/host override applied to every request the proxy makes.
159    *
160    * <p>
161    * Replaces only the authority+root portion of the request URL &mdash; in effect, an annotation-declared substitute
162    * for the client's root URL &mdash; while <i>preserving</i> the interface base path, the method path, and any
163    * <c>{var}</c> templating.  For example, with <c>baseUrl=<js>"http://other-host"</js></c>, an interface path of
164    * <js>"/api"</js> and a method path of <js>"/users/{id}"</js>, the effective URL is
165    * <js>"http://other-host/api/users/{id}"</js>.
166    *
167    * <p>
168    * Precedence (most-specific first): an {@link org.apache.juneau.http.Url @Url} parameter, then a method-level
169    * {@code baseUrl} (see {@code @RemoteOp(baseUrl=...)} and the verb annotations), then this interface-level value,
170    * then the client root URL.
171    *
172    * <h5 class='section'>Notes:</h5><ul>
173    *    <li class='note'>
174    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/DefaultVarResolver">VarResolver.DEFAULT</a>
175    *       (e.g. <js>"$S{mySystemProperty}"</js>).
176    *    <li class='note'>
177    *       Only <c>http</c>/<c>https</c> schemes are permitted when the override yields an absolute URL; other schemes
178    *       are rejected (SSRF guardrail).
179    *    <li class='note'>
180    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
181    *       (<c>RestClient.getRemote(...)</c>), with the same http/https-only scheme guard on both.
182    * </ul>
183    *
184    * @return The annotation value.
185    */
186   String baseUrl() default "";
187
188   /**
189    * Interface-level default request body format (and {@code Content-Type} header) for all methods.
190    *
191    * <p>
192    * Names a media type (e.g. <js>"application/xml"</js>) used as the default for every method on this interface.  The
193    * next-generation engine selects the matching registered request serializer from the client's serializer set so the
194    * request body bytes are actually written in that format, and sets the {@code Content-Type} header to this media
195    * type &mdash; cleanly replacing the serializer's default content type (exactly one {@code Content-Type} header is
196    * sent).  If no registered serializer matches, the client's default serializer is used but this media type is still
197    * sent as the label (supporting vendor media types).
198    *
199    * <p>
200    * A method-level {@link RemoteOp#contentType()} (or verb-annotation equivalent) overrides this default.
201    *
202    * <h5 class='section'>Notes:</h5><ul>
203    *    <li class='note'>
204    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
205    *       (<c>RestClient.getRemote(...)</c>).
206    * </ul>
207    *
208    * @return The annotation value.
209    */
210   String contentType() default "";
211
212   /**
213    * Interface-level default {@code Accept} header (and response parser fallback) for all methods.
214    *
215    * <p>
216    * Names a media type (e.g. <js>"application/xml"</js>) sent as the default {@code Accept} header for every method on
217    * this interface.  Response parsing remains driven by the <i>response</i> {@code Content-Type}; this media type is
218    * the fallback parser only when the response is unlabeled or its {@code Content-Type} matches no registered parser.
219    *
220    * <p>
221    * A method-level {@link RemoteOp#accept()} (or verb-annotation equivalent) overrides this default.
222    *
223    * <h5 class='section'>Notes:</h5><ul>
224    *    <li class='note'>
225    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
226    *       (<c>RestClient.getRemote(...)</c>).
227    * </ul>
228    *
229    * @return The annotation value.
230    */
231   String accept() default "";
232
233   /**
234    * Specifies the client version of this interface.
235    *
236    * <p>
237    * Used to populate the <js>"Client-Version"</js> header that identifies what version of client this is
238    * so that the server side can handle older versions accordingly.
239    *
240    * <p>
241    * The format of this is a string of the format <c>#[.#[.#[...]]</c> (e.g. <js>"1.2.3"</js>).
242    *
243    * <p>
244    * The server side then uses an OSGi-version matching pattern to identify which methods to call:
245    * <p class='bjava'>
246    *    <jc>// Call this method if Client-Version is at least 2.0.
247    *    // Note that this also matches 2.0.1.</jc>
248    *    <ja>@RestGet</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>)
249    *    <jk>public</jk> Object method1()  {...}
250    *
251    *    <jc>// Call this method if Client-Version is at least 1.1, but less than 2.0.</jc>
252    *    <ja>@RestGet</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>)
253    *    <jk>public</jk> Object method2()  {...}
254    *
255    *    <jc>// Call this method if Client-Version is less than 1.1.</jc>
256    *    <ja>@RestGet</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"[0,1.1)"</js>)
257    *    <jk>public</jk> Object method3()  {...}
258    * </p>
259    *
260    * <h5 class='section'>Notes:</h5><ul>
261    *    <li class='note'>
262    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/DefaultVarResolver">VarResolver.DEFAULT</a>
263    *       (e.g. <js>"$P{mySystemProperty}"</js>).
264    * </ul>
265    *
266    * @return The annotation value.
267    */
268   String version() default "";
269
270   /**
271    * Specifies the client version header name.
272    *
273    * <p>
274    * The default value is <js>"Client-Version"</js>.
275    *
276    * <h5 class='section'>Notes:</h5><ul>
277    *    <li class='note'>
278    *       Supports <a class="doclink" href="https://juneau.apache.org/docs/topics/DefaultVarResolver">VarResolver.DEFAULT</a>
279    *       (e.g. <js>"$P{mySystemProperty}"</js>).
280    * </ul>
281    *
282    * @return The annotation value.
283    */
284   String versionHeader() default "";
285
286   /**
287    * Default lifecycle interceptors applied to every request the proxy makes.
288    *
289    * <p>
290    * Each class must implement the next-generation <c>RestCallInterceptor</c> SPI and provide a public no-arg
291    * constructor.  Interface-level interceptors run <i>after</i> the builder-configured interceptors and <i>before</i>
292    * any method-level ({@code @RemoteOp/@RemoteGet/...(interceptors=...)}) interceptors; the three sets are unioned in
293    * the order builder &rarr; interface &rarr; method (method-level runs closest to the call).
294    *
295    * <h5 class='section'>Notes:</h5><ul>
296    *    <li class='note'>
297    *       The member type is {@code Class<?>[]} (not {@code Class<? extends RestCallInterceptor>[]}) because
298    *       <c>RestCallInterceptor</c> lives in the {@code juneau-rest-client} module, which this annotation's module
299    *       must not depend on; each element is resolved to a <c>RestCallInterceptor</c> at proxy-build time.
300    *    <li class='note'>
301    *       Honored by the next-generation engine (<c>RestClient.remote(...)</c>) only; the classic engine currently
302    *       ignores this attribute.
303    * </ul>
304    *
305    * @return The annotation value.
306    */
307   Class<?>[] interceptors() default {};
308
309   /**
310    * Default per-call response/read timeout applied to every request the proxy makes.
311    *
312    * <p>
313    * Expressed as a duration string (e.g. <js>"30s"</js>, <js>"1500ms"</js>, <js>"1m"</js>) parsed by Juneau's
314    * duration parser.  A method-level {@code timeout} ({@code @RemoteOp/@RemoteGet/...}) overrides this default.
315    * Connect timeouts remain a client-level setting (not configurable per call).
316    *
317    * <h5 class='section'>Notes:</h5><ul>
318    *    <li class='note'>
319    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
320    *       (<c>RestClient.getRemote(...)</c>).
321    * </ul>
322    *
323    * @return The annotation value.
324    */
325   String timeout() default "";
326
327   /**
328    * Default maximum number of automatic retry attempts applied to every request the proxy makes.
329    *
330    * <p>
331    * A value of {@code 0} (the default) disables retries.  A positive method-level {@code retries} overrides this
332    * default.  See {@code @RemoteOp(retries=...)} for the retry trigger statuses and the (hard) safety gating rules.
333    *
334    * <h5 class='section'>Notes:</h5><ul>
335    *    <li class='note'>
336    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
337    *       (<c>RestClient.getRemote(...)</c>).
338    * </ul>
339    *
340    * @return The annotation value.
341    */
342   int retries() default 0;
343
344   /**
345    * Opts non-idempotent verbs (<c>POST</c>/<c>PATCH</c>) into automatic retries for every method on the proxy.
346    *
347    * <p>
348    * Has no effect unless {@link #retries()} (or a method-level {@code retries}) is positive.  Even when enabled, a
349    * request with a non-repeatable body is never retried.  The effective value is the logical OR of this default and
350    * the method-level value.
351    *
352    * <h5 class='section'>Notes:</h5><ul>
353    *    <li class='note'>
354    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
355    *       (<c>RestClient.getRemote(...)</c>).
356    * </ul>
357    *
358    * @return The annotation value.
359    */
360   boolean retryNonIdempotent() default false;
361
362   /**
363    * Default for throwing a generic exception on an error response, applied to every method on the proxy.
364    *
365    * <p>
366    * When <jk>true</jk> and the response status is an error ({@code >=400}) and no typed exception from the method's
367    * {@code throws} clause matched, a generic exception is thrown.  The effective value is the logical OR of this
368    * default and the method-level value.  See {@code @RemoteOp(throwOnError=...)}.
369    *
370    * <h5 class='section'>Notes:</h5><ul>
371    *    <li class='note'>
372    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
373    *       (<c>RestClient.getRemote(...)</c>).
374    * </ul>
375    *
376    * @return The annotation value.
377    */
378   boolean throwOnError() default false;
379
380   /**
381    * Opts this interface's absolute {@code @Remote}/{@code @Url}/{@code baseUrl()} targets out of the default
382    * deny-private SSRF guardrail, applied to every method on the proxy.
383    *
384    * <p>
385    * By default, an absolute <c>http</c>/<c>https</c> URL supplied via {@link #baseUrl()}, an {@code @Url}
386    * parameter, or an already-absolute {@link #path()}/{@link #value()} is rejected &mdash; both at pre-check time
387    * and at connect time via resolved-address pinning, re-checked on every followed redirect &mdash; when it targets
388    * a loopback, RFC1918/link-local, IPv6 unique-local, or cloud-metadata address.  Setting this to <jk>true</jk>
389    * disables that check for local-dev/intranet targets that are intentionally private.
390    *
391    * <p>
392    * The effective value is the logical OR of this annotation value, the {@code RestClient} builder's
393    * {@code allowPrivateUrls(...)} setting, and the <js>"RestClient.allowPrivateUrls"</js> system property: any one
394    * of the three opting in is sufficient.
395    *
396    * <h5 class='section'>Notes:</h5><ul>
397    *    <li class='note'>
398    *       Honored by both the next-generation engine (<c>RestClient.remote(...)</c>) and the classic engine
399    *       (<c>RestClient.getRemote(...)</c>).
400    *    <li class='note'>
401    *       Does not affect the http/https-only scheme guard, which always applies.
402    * </ul>
403    *
404    * @return The annotation value.
405    */
406   boolean allowPrivateUrls() default false;
407}