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.camel.spi;
018
019import java.util.Map;
020
021/**
022 * Configuration use by {@link org.apache.camel.spi.RestConsumerFactory} and {@link org.apache.camel.spi.RestApiConsumerFactory}
023 * for Camel components to support the Camel {@link org.apache.camel.model.rest.RestDefinition rest} DSL.
024 */
025public class RestConfiguration {
026
027    public static final String CORS_ACCESS_CONTROL_ALLOW_ORIGIN = "*";
028    public static final String CORS_ACCESS_CONTROL_ALLOW_METHODS = "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH";
029    public static final String CORS_ACCESS_CONTROL_MAX_AGE = "3600";
030    public static final String CORS_ACCESS_CONTROL_ALLOW_HEADERS = "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers";
031
032    public enum RestBindingMode {
033        auto, off, json, xml, json_xml
034    }
035
036    public enum RestHostNameResolver {
037        allLocalIp, localIp, localHostName
038    }
039
040    private String component;
041    private String apiComponent;
042    private String producerComponent;
043    private String producerApiDoc;
044    private String scheme;
045    private String host;
046    private String apiHost;
047    private boolean useXForwardHeaders = true;
048    private int port;
049    private String contextPath;
050    private String apiContextPath;
051    private String apiContextRouteId;
052    private String apiContextIdPattern;
053    private boolean apiContextListing;
054    private boolean apiVendorExtension;
055    private RestHostNameResolver hostNameResolver = RestHostNameResolver.allLocalIp;
056    private RestBindingMode bindingMode = RestBindingMode.off;
057    private boolean skipBindingOnErrorCode = true;
058    private boolean clientRequestValidation;
059    private boolean enableCORS;
060    private String jsonDataFormat;
061    private String xmlDataFormat;
062    private Map<String, Object> componentProperties;
063    private Map<String, Object> endpointProperties;
064    private Map<String, Object> consumerProperties;
065    private Map<String, Object> dataFormatProperties;
066    private Map<String, Object> apiProperties;
067    private Map<String, String> corsHeaders;
068
069    /**
070     * Gets the name of the Camel component to use as the REST consumer
071     *
072     * @return the component name, or <tt>null</tt> to let Camel search the {@link Registry} to find suitable implementation
073     */
074    public String getComponent() {
075        return component;
076    }
077
078    /**
079     * Sets the name of the Camel component to use as the REST consumer
080     *
081     * @param componentName the name of the component (such as restlet, spark-rest, etc.)
082     */
083    public void setComponent(String componentName) {
084        this.component = componentName;
085    }
086
087    /**
088     * Gets the name of the Camel component to use as the REST API (such as swagger)
089     *
090     * @return the component name, or <tt>null</tt> to let Camel use the default name <tt>swagger</tt>
091     */
092    public String getApiComponent() {
093        return apiComponent;
094    }
095
096    /**
097     * Sets the name of the Camel component to use as the REST API (such as swagger)
098     *
099     * @param apiComponent the name of the component (such as swagger)
100     */
101    public void setApiComponent(String apiComponent) {
102        this.apiComponent = apiComponent;
103    }
104
105    /**
106     * Gets the name of the Camel component to use as the REST producer
107     *
108     * @return the component name, or <tt>null</tt> to let Camel search the {@link Registry} to find suitable implementation
109     */
110    public String getProducerComponent() {
111        return producerComponent;
112    }
113
114    /**
115     * Sets the name of the Camel component to use as the REST producer
116     *
117     * @param componentName the name of the component (such as restlet, jetty, etc.)
118     */
119    public void setProducerComponent(String componentName) {
120        this.producerComponent = componentName;
121    }
122
123    /**
124     * Gets the location of the api document (swagger api) the REST producer will use
125     * to validate the REST uri and query parameters are valid accordingly to the api document.
126     */
127    public String getProducerApiDoc() {
128        return producerApiDoc;
129    }
130
131    /**
132     * Sets the location of the api document (swagger api) the REST producer will use
133     * to validate the REST uri and query parameters are valid accordingly to the api document.
134     * This requires adding camel-swagger-java to the classpath, and any miss configuration
135     * will let Camel fail on startup and report the error(s).
136     * <p/>
137     * The location of the api document is loaded from classpath by default, but you can use
138     * <tt>file:</tt> or <tt>http:</tt> to refer to resources to load from file or http url.
139     */
140    public void setProducerApiDoc(String producerApiDoc) {
141        this.producerApiDoc = producerApiDoc;
142    }
143
144    /**
145     * Gets the hostname to use by the REST consumer
146     *
147     * @return the hostname, or <tt>null</tt> to use default hostname
148     */
149    public String getHost() {
150        return host;
151    }
152
153    /**
154     * Sets the hostname to use by the REST consumer
155     *
156     * @param host the hostname
157     */
158    public void setHost(String host) {
159        this.host = host;
160    }
161
162    public String getApiHost() {
163        return apiHost;
164    }
165
166    /**
167     * To use an specific hostname for the API documentation (eg swagger)
168     * <p/>
169     * This can be used to override the generated host with this configured hostname
170     */
171    public void setApiHost(String apiHost) {
172        this.apiHost = apiHost;
173    }
174
175    /**
176     * Gets the scheme to use by the REST consumer
177     *
178     * @return the scheme, or <tt>null</tt> to use default scheme
179     */
180    public String getScheme() {
181        return scheme;
182    }
183
184    /**
185     * Sets the scheme to use by the REST consumer
186     *
187     * @param scheme the scheme
188     */
189    public void setScheme(String scheme) {
190        this.scheme = scheme;
191    }
192
193    /**
194     * Gets the port to use by the REST consumer
195     *
196     * @return the port, or <tt>0</tt> or <tt>-1</tt> to use default port
197     */
198    public int getPort() {
199        return port;
200    }
201
202    /**
203     * Sets the port to use by the REST consumer
204     *
205     * @param port the port number
206     */
207    public void setPort(int port) {
208        this.port = port;
209    }
210
211    /**
212     * Gets the configured context-path
213     *
214     * @return the context path, or <tt>null</tt> if none configured.
215     */
216    public String getContextPath() {
217        return contextPath;
218    }
219
220    /**
221     * Sets a leading context-path the REST services will be using.
222     * <p/>
223     * This can be used when using components such as <tt>camel-servlet</tt> where the deployed web application
224     * is deployed using a context-path. Or for components such as <tt>camel-jetty</tt> or <tt>camel-netty4-http</tt>
225     * that includes a HTTP server.
226     *
227     * @param contextPath the context path
228     */
229    public void setContextPath(String contextPath) {
230        this.contextPath = contextPath;
231    }
232
233    public String getApiContextPath() {
234        return apiContextPath;
235    }
236
237    /**
238     * Sets a leading API context-path the REST API services will be using.
239     * <p/>
240     * This can be used when using components such as <tt>camel-servlet</tt> where the deployed web application
241     * is deployed using a context-path.
242     *
243     * @param contextPath the API context path
244     */
245    public void setApiContextPath(String contextPath) {
246        this.apiContextPath = contextPath;
247    }
248
249    public String getApiContextRouteId() {
250        return apiContextRouteId;
251    }
252
253    /**
254     * Sets the route id to use for the route that services the REST API.
255     * <p/>
256     * The route will by default use an auto assigned route id.
257     *
258     * @param apiContextRouteId  the route id
259     */
260    public void setApiContextRouteId(String apiContextRouteId) {
261        this.apiContextRouteId = apiContextRouteId;
262    }
263
264    public String getApiContextIdPattern() {
265        return apiContextIdPattern;
266    }
267
268    /**
269     * Optional CamelContext id pattern to only allow Rest APIs from rest services within CamelContext's which name matches the pattern.
270     * <p/>
271     * The pattern <tt>#name#</tt> refers to the CamelContext name, to match on the current CamelContext only.
272     * For any other value, the pattern uses the rules from {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)}
273     *
274     * @param apiContextIdPattern  the pattern
275     */
276    public void setApiContextIdPattern(String apiContextIdPattern) {
277        this.apiContextIdPattern = apiContextIdPattern;
278    }
279
280    public boolean isApiContextListing() {
281        return apiContextListing;
282    }
283
284    /**
285     * Sets whether listing of all available CamelContext's with REST services in the JVM is enabled. If enabled it allows to discover
286     * these contexts, if <tt>false</tt> then only the current CamelContext is in use.
287     */
288    public void setApiContextListing(boolean apiContextListing) {
289        this.apiContextListing = apiContextListing;
290    }
291
292    public boolean isApiVendorExtension() {
293        return apiVendorExtension;
294    }
295
296    /**
297     * Whether vendor extension is enabled in the Rest APIs. If enabled then Camel will include additional information
298     * as vendor extension (eg keys starting with x-) such as route ids, class names etc.
299     * Not all 3rd party API gateways and tools supports vendor-extensions when importing your API docs.
300     */
301    public void setApiVendorExtension(boolean apiVendorExtension) {
302        this.apiVendorExtension = apiVendorExtension;
303    }
304
305    /**
306     * Gets the resolver to use for resolving hostname
307     *
308     * @return the resolver
309     * @deprecated use getHostNameResolver
310     */
311    @Deprecated
312    public RestHostNameResolver getRestHostNameResolver() {
313        return getHostNameResolver();
314    }
315
316    /**
317     * Sets the resolver to use for resolving hostname
318     *
319     * @param restHostNameResolver the resolver
320     * @deprecated use setHostNameResolver
321     */
322    @Deprecated
323    public void setRestHostNameResolver(RestHostNameResolver restHostNameResolver) {
324        setHostNameResolver(restHostNameResolver);
325    }
326
327    /**
328     * Sets the resolver to use for resolving hostname
329     *
330     * @param restHostNameResolver the resolver
331     * @deprecated use setHostNameResolver
332     */
333    @Deprecated
334    public void setRestHostNameResolver(String restHostNameResolver) {
335        settHostNameResolver(restHostNameResolver);
336    }
337
338    /**
339     * Gets the resolver to use for resolving hostname
340     *
341     * @return the resolver
342     */
343    public RestHostNameResolver getHostNameResolver() {
344        return hostNameResolver;
345    }
346
347    /**
348     * Sets the resolver to use for resolving hostname
349     *
350     * @param hostNameResolver the resolver
351     */
352    public void setHostNameResolver(RestHostNameResolver hostNameResolver) {
353        this.hostNameResolver = hostNameResolver;
354    }
355
356    /**
357     * Sets the resolver to use for resolving hostname
358     *
359     * @param hostNameResolver the resolver
360     */
361    public void settHostNameResolver(String hostNameResolver) {
362        this.hostNameResolver = RestHostNameResolver.valueOf(hostNameResolver);
363    }
364
365    /**
366     * Gets the binding mode used by the REST consumer
367     *
368     * @return the binding mode
369     */
370    public RestBindingMode getBindingMode() {
371        return bindingMode;
372    }
373
374    /**
375     * Sets the binding mode to be used by the REST consumer
376     *
377     * @param bindingMode the binding mode
378     */
379    public void setBindingMode(RestBindingMode bindingMode) {
380        this.bindingMode = bindingMode;
381    }
382
383    /**
384     * Sets the binding mode to be used by the REST consumer
385     *
386     * @param bindingMode the binding mode
387     */
388    public void setBindingMode(String bindingMode) {
389        this.bindingMode = RestBindingMode.valueOf(bindingMode);
390    }
391
392    /**
393     * Whether to skip binding output if there is a custom HTTP error code, and instead use the response body as-is.
394     * <p/>
395     * This option is default <tt>true</tt>.
396     *
397     * @return whether to skip binding on error code
398     */
399    public boolean isSkipBindingOnErrorCode() {
400        return skipBindingOnErrorCode;
401    }
402
403    /**
404     * Whether to skip binding output if there is a custom HTTP error code, and instead use the response body as-is.
405     * <p/>
406     * This option is default <tt>true</tt>.
407     *
408     * @param skipBindingOnErrorCode whether to skip binding on error code
409     */
410    public void setSkipBindingOnErrorCode(boolean skipBindingOnErrorCode) {
411        this.skipBindingOnErrorCode = skipBindingOnErrorCode;
412    }
413
414    public boolean isClientRequestValidation() {
415        return clientRequestValidation;
416    }
417
418    /**
419     * Whether to enable validation of the client request to check whether the Content-Type and Accept headers from
420     * the client is supported by the Rest-DSL configuration of its consumes/produces settings.
421     * <p/>
422     * This can be turned on, to enable this check. In case of validation error, then HTTP Status codes 415 or 406 is returned.
423     * <p/>
424     * The default value is false.
425     */
426    public void setClientRequestValidation(boolean clientRequestValidation) {
427        this.clientRequestValidation = clientRequestValidation;
428    }
429
430    /**
431     * To specify whether to enable CORS which means Camel will automatic include CORS in the HTTP headers in the response.
432     * <p/>
433     * This option is default <tt>false</tt>
434     *
435     * @return whether CORS is enabled or not
436     */
437    public boolean isEnableCORS() {
438        return enableCORS;
439    }
440
441    /**
442     * To specify whether to enable CORS which means Camel will automatic include CORS in the HTTP headers in the response.
443     * <p/>
444     * This option is default <tt>false</tt>
445     *
446     * @param enableCORS <tt>true</tt> to enable CORS
447     */
448    public void setEnableCORS(boolean enableCORS) {
449        this.enableCORS = enableCORS;
450    }
451
452    /**
453     * Gets the name of the json data format.
454     * <p/>
455     * <b>Important:</b> This option is only for setting a custom name of the data format, not to refer to an existing data format instance.
456     *
457     * @return the name, or <tt>null</tt> to use default
458     */
459    public String getJsonDataFormat() {
460        return jsonDataFormat;
461    }
462
463    /**
464     * Sets a custom json data format to be used
465     * <p/>
466     * <b>Important:</b> This option is only for setting a custom name of the data format, not to refer to an existing data format instance.
467     *
468     * @param name name of the data format
469     */
470    public void setJsonDataFormat(String name) {
471        this.jsonDataFormat = name;
472    }
473
474    /**
475     * Gets the name of the xml data format.
476     * <p/>
477     * <b>Important:</b> This option is only for setting a custom name of the data format, not to refer to an existing data format instance.
478     *
479     * @return the name, or <tt>null</tt> to use default
480     */
481    public String getXmlDataFormat() {
482        return xmlDataFormat;
483    }
484
485    /**
486     * Sets a custom xml data format to be used.
487     * <p/>
488     * <b>Important:</b> This option is only for setting a custom name of the data format, not to refer to an existing data format instance.
489     *
490     * @param name name of the data format
491     */
492    public void setXmlDataFormat(String name) {
493        this.xmlDataFormat = name;
494    }
495
496    /**
497     * Gets additional options on component level
498     *
499     * @return additional options
500     */
501    public Map<String, Object> getComponentProperties() {
502        return componentProperties;
503    }
504
505    /**
506     * Sets additional options on component level
507     *
508     * @param componentProperties the options
509     */
510    public void setComponentProperties(Map<String, Object> componentProperties) {
511        this.componentProperties = componentProperties;
512    }
513
514    /**
515     * Gets additional options on endpoint level
516     *
517     * @return additional options
518     */
519    public Map<String, Object> getEndpointProperties() {
520        return endpointProperties;
521    }
522
523    /**
524     * Sets additional options on endpoint level
525     *
526     * @param endpointProperties the options
527     */
528    public void setEndpointProperties(Map<String, Object> endpointProperties) {
529        this.endpointProperties = endpointProperties;
530    }
531
532    /**
533     * Gets additional options on consumer level
534     *
535     * @return additional options
536     */
537    public Map<String, Object> getConsumerProperties() {
538        return consumerProperties;
539    }
540
541    /**
542     * Sets additional options on consumer level
543     *
544     * @param consumerProperties the options
545     */
546    public void setConsumerProperties(Map<String, Object> consumerProperties) {
547        this.consumerProperties = consumerProperties;
548    }
549
550    /**
551     * Gets additional options on data format level
552     *
553     * @return additional options
554     */
555    public Map<String, Object> getDataFormatProperties() {
556        return dataFormatProperties;
557    }
558
559    /**
560     * Sets additional options on data format level
561     *
562     * @param dataFormatProperties the options
563     */
564    public void setDataFormatProperties(Map<String, Object> dataFormatProperties) {
565        this.dataFormatProperties = dataFormatProperties;
566    }
567
568    public Map<String, Object> getApiProperties() {
569        return apiProperties;
570    }
571
572    /**
573     * Sets additional options on api level
574     *
575     * @param apiProperties the options
576     */
577    public void setApiProperties(Map<String, Object> apiProperties) {
578        this.apiProperties = apiProperties;
579    }
580
581    /**
582     * Gets the CORS headers to use if CORS has been enabled.
583     *
584     * @return the CORS headers
585     */
586    public Map<String, String> getCorsHeaders() {
587        return corsHeaders;
588    }
589
590    /**
591     * Sets the CORS headers to use if CORS has been enabled.
592     *
593     * @param corsHeaders the CORS headers
594     */
595    public void setCorsHeaders(Map<String, String> corsHeaders) {
596        this.corsHeaders = corsHeaders;
597    }
598
599    /**
600     * Whether to use X-FOWARD headers to set host etc. for Swagger.
601     * <p/>
602     * This option is default <tt>true</tt>.
603     *
604     * @return whether to use X-FOWARD headers
605     */
606    public boolean isUseXForwardHeaders() {
607        return useXForwardHeaders;
608    }
609
610    /**
611     * WWhether to use X-FOWARD headers to set host etc. for Swagger.
612     * <p/>
613     * This option is default <tt>true</tt>.
614     *
615     * @param useXForwardHeaders whether to use X-FOWARD headers
616     */
617    public void setUseXForwardHeaders(boolean useXForwardHeaders) {
618        this.useXForwardHeaders = useXForwardHeaders;
619    }
620}