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 boolean useXForwardHeaders = true;
047    private String apiHost;
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    /**
163     * WWhether to use X-Forward headers to set host etc. for Swagger.
164     * <p/>
165     * This option is default <tt>true</tt>.
166     */
167    public boolean isUseXForwardHeaders() {
168        return useXForwardHeaders;
169    }
170
171    /**
172     * WWhether to use X-Forward headers to set host etc. for Swagger.
173     * <p/>
174     * This option is default <tt>true</tt>.
175     * 
176     * @param useXForwardHeaders whether to use X-Forward headers
177     */
178    public void setUseXForwardHeaders(boolean useXForwardHeaders) {
179        this.useXForwardHeaders = useXForwardHeaders;
180    }
181
182    public String getApiHost() {
183        return apiHost;
184    }
185
186    /**
187     * To use an specific hostname for the API documentation (eg swagger)
188     * <p/>
189     * This can be used to override the generated host with this configured hostname
190     */
191    public void setApiHost(String apiHost) {
192        this.apiHost = apiHost;
193    }
194
195    /**
196     * Gets the scheme to use by the REST consumer
197     *
198     * @return the scheme, or <tt>null</tt> to use default scheme
199     */
200    public String getScheme() {
201        return scheme;
202    }
203
204    /**
205     * Sets the scheme to use by the REST consumer
206     *
207     * @param scheme the scheme
208     */
209    public void setScheme(String scheme) {
210        this.scheme = scheme;
211    }
212
213    /**
214     * Gets the port to use by the REST consumer
215     *
216     * @return the port, or <tt>0</tt> or <tt>-1</tt> to use default port
217     */
218    public int getPort() {
219        return port;
220    }
221
222    /**
223     * Sets the port to use by the REST consumer
224     *
225     * @param port the port number
226     */
227    public void setPort(int port) {
228        this.port = port;
229    }
230
231    /**
232     * Gets the configured context-path
233     *
234     * @return the context path, or <tt>null</tt> if none configured.
235     */
236    public String getContextPath() {
237        return contextPath;
238    }
239
240    /**
241     * Sets a leading context-path the REST services will be using.
242     * <p/>
243     * This can be used when using components such as <tt>camel-servlet</tt> where the deployed web application
244     * is deployed using a context-path. Or for components such as <tt>camel-jetty</tt> or <tt>camel-netty4-http</tt>
245     * that includes a HTTP server.
246     *
247     * @param contextPath the context path
248     */
249    public void setContextPath(String contextPath) {
250        this.contextPath = contextPath;
251    }
252
253    public String getApiContextPath() {
254        return apiContextPath;
255    }
256
257    /**
258     * Sets a leading API context-path the REST API services will be using.
259     * <p/>
260     * This can be used when using components such as <tt>camel-servlet</tt> where the deployed web application
261     * is deployed using a context-path.
262     *
263     * @param contextPath the API context path
264     */
265    public void setApiContextPath(String contextPath) {
266        this.apiContextPath = contextPath;
267    }
268
269    public String getApiContextRouteId() {
270        return apiContextRouteId;
271    }
272
273    /**
274     * Sets the route id to use for the route that services the REST API.
275     * <p/>
276     * The route will by default use an auto assigned route id.
277     *
278     * @param apiContextRouteId  the route id
279     */
280    public void setApiContextRouteId(String apiContextRouteId) {
281        this.apiContextRouteId = apiContextRouteId;
282    }
283
284    public String getApiContextIdPattern() {
285        return apiContextIdPattern;
286    }
287
288    /**
289     * Optional CamelContext id pattern to only allow Rest APIs from rest services within CamelContext's which name matches the pattern.
290     * <p/>
291     * The pattern <tt>#name#</tt> refers to the CamelContext name, to match on the current CamelContext only.
292     * For any other value, the pattern uses the rules from {@link org.apache.camel.support.EndpointHelper#matchPattern(String, String)}
293     *
294     * @param apiContextIdPattern  the pattern
295     */
296    public void setApiContextIdPattern(String apiContextIdPattern) {
297        this.apiContextIdPattern = apiContextIdPattern;
298    }
299
300    public boolean isApiContextListing() {
301        return apiContextListing;
302    }
303
304    /**
305     * Sets whether listing of all available CamelContext's with REST services in the JVM is enabled. If enabled it allows to discover
306     * these contexts, if <tt>false</tt> then only the current CamelContext is in use.
307     */
308    public void setApiContextListing(boolean apiContextListing) {
309        this.apiContextListing = apiContextListing;
310    }
311
312    public boolean isApiVendorExtension() {
313        return apiVendorExtension;
314    }
315
316    /**
317     * Whether vendor extension is enabled in the Rest APIs. If enabled then Camel will include additional information
318     * as vendor extension (eg keys starting with x-) such as route ids, class names etc.
319     * Not all 3rd party API gateways and tools supports vendor-extensions when importing your API docs.
320     */
321    public void setApiVendorExtension(boolean apiVendorExtension) {
322        this.apiVendorExtension = apiVendorExtension;
323    }
324
325    /**
326     * Gets the resolver to use for resolving hostname
327     *
328     * @return the resolver
329     */
330    public RestHostNameResolver getHostNameResolver() {
331        return hostNameResolver;
332    }
333
334    /**
335     * Sets the resolver to use for resolving hostname
336     *
337     * @param hostNameResolver the resolver
338     */
339    public void setHostNameResolver(RestHostNameResolver hostNameResolver) {
340        this.hostNameResolver = hostNameResolver;
341    }
342
343    /**
344     * Sets the resolver to use for resolving hostname
345     *
346     * @param hostNameResolver the resolver
347     */
348    public void setHostNameResolver(String hostNameResolver) {
349        this.hostNameResolver = RestHostNameResolver.valueOf(hostNameResolver);
350    }
351
352    /**
353     * Gets the binding mode used by the REST consumer
354     *
355     * @return the binding mode
356     */
357    public RestBindingMode getBindingMode() {
358        return bindingMode;
359    }
360
361    /**
362     * Sets the binding mode to be used by the REST consumer
363     *
364     * @param bindingMode the binding mode
365     */
366    public void setBindingMode(RestBindingMode bindingMode) {
367        this.bindingMode = bindingMode;
368    }
369
370    /**
371     * Sets the binding mode to be used by the REST consumer
372     *
373     * @param bindingMode the binding mode
374     */
375    public void setBindingMode(String bindingMode) {
376        this.bindingMode = RestBindingMode.valueOf(bindingMode);
377    }
378
379    /**
380     * Whether to skip binding output if there is a custom HTTP error code, and instead use the response body as-is.
381     * <p/>
382     * This option is default <tt>true</tt>.
383     *
384     * @return whether to skip binding on error code
385     */
386    public boolean isSkipBindingOnErrorCode() {
387        return skipBindingOnErrorCode;
388    }
389
390    /**
391     * Whether to skip binding output if there is a custom HTTP error code, and instead use the response body as-is.
392     * <p/>
393     * This option is default <tt>true</tt>.
394     *
395     * @param skipBindingOnErrorCode whether to skip binding on error code
396     */
397    public void setSkipBindingOnErrorCode(boolean skipBindingOnErrorCode) {
398        this.skipBindingOnErrorCode = skipBindingOnErrorCode;
399    }
400
401    public boolean isClientRequestValidation() {
402        return clientRequestValidation;
403    }
404
405    /**
406     * Whether to enable validation of the client request to check whether the Content-Type and Accept headers from
407     * the client is supported by the Rest-DSL configuration of its consumes/produces settings.
408     * <p/>
409     * This can be turned on, to enable this check. In case of validation error, then HTTP Status codes 415 or 406 is returned.
410     * <p/>
411     * The default value is false.
412     */
413    public void setClientRequestValidation(boolean clientRequestValidation) {
414        this.clientRequestValidation = clientRequestValidation;
415    }
416
417    /**
418     * To specify whether to enable CORS which means Camel will automatic include CORS in the HTTP headers in the response.
419     * <p/>
420     * This option is default <tt>false</tt>
421     *
422     * @return whether CORS is enabled or not
423     */
424    public boolean isEnableCORS() {
425        return enableCORS;
426    }
427
428    /**
429     * To specify whether to enable CORS which means Camel will automatic include CORS in the HTTP headers in the response.
430     * <p/>
431     * This option is default <tt>false</tt>
432     *
433     * @param enableCORS <tt>true</tt> to enable CORS
434     */
435    public void setEnableCORS(boolean enableCORS) {
436        this.enableCORS = enableCORS;
437    }
438
439    /**
440     * Gets the name of the json data format.
441     * <p/>
442     * <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.
443     *
444     * @return the name, or <tt>null</tt> to use default
445     */
446    public String getJsonDataFormat() {
447        return jsonDataFormat;
448    }
449
450    /**
451     * Sets a custom json data format to be used
452     * <p/>
453     * <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.
454     *
455     * @param name name of the data format
456     */
457    public void setJsonDataFormat(String name) {
458        this.jsonDataFormat = name;
459    }
460
461    /**
462     * Gets the name of the xml data format.
463     * <p/>
464     * <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.
465     *
466     * @return the name, or <tt>null</tt> to use default
467     */
468    public String getXmlDataFormat() {
469        return xmlDataFormat;
470    }
471
472    /**
473     * Sets a custom xml data format to be used.
474     * <p/>
475     * <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.
476     *
477     * @param name name of the data format
478     */
479    public void setXmlDataFormat(String name) {
480        this.xmlDataFormat = name;
481    }
482
483    /**
484     * Gets additional options on component level
485     *
486     * @return additional options
487     */
488    public Map<String, Object> getComponentProperties() {
489        return componentProperties;
490    }
491
492    /**
493     * Sets additional options on component level
494     *
495     * @param componentProperties the options
496     */
497    public void setComponentProperties(Map<String, Object> componentProperties) {
498        this.componentProperties = componentProperties;
499    }
500
501    /**
502     * Gets additional options on endpoint level
503     *
504     * @return additional options
505     */
506    public Map<String, Object> getEndpointProperties() {
507        return endpointProperties;
508    }
509
510    /**
511     * Sets additional options on endpoint level
512     *
513     * @param endpointProperties the options
514     */
515    public void setEndpointProperties(Map<String, Object> endpointProperties) {
516        this.endpointProperties = endpointProperties;
517    }
518
519    /**
520     * Gets additional options on consumer level
521     *
522     * @return additional options
523     */
524    public Map<String, Object> getConsumerProperties() {
525        return consumerProperties;
526    }
527
528    /**
529     * Sets additional options on consumer level
530     *
531     * @param consumerProperties the options
532     */
533    public void setConsumerProperties(Map<String, Object> consumerProperties) {
534        this.consumerProperties = consumerProperties;
535    }
536
537    /**
538     * Gets additional options on data format level
539     *
540     * @return additional options
541     */
542    public Map<String, Object> getDataFormatProperties() {
543        return dataFormatProperties;
544    }
545
546    /**
547     * Sets additional options on data format level
548     *
549     * @param dataFormatProperties the options
550     */
551    public void setDataFormatProperties(Map<String, Object> dataFormatProperties) {
552        this.dataFormatProperties = dataFormatProperties;
553    }
554
555    public Map<String, Object> getApiProperties() {
556        return apiProperties;
557    }
558
559    /**
560     * Sets additional options on api level
561     *
562     * @param apiProperties the options
563     */
564    public void setApiProperties(Map<String, Object> apiProperties) {
565        this.apiProperties = apiProperties;
566    }
567
568    /**
569     * Gets the CORS headers to use if CORS has been enabled.
570     *
571     * @return the CORS headers
572     */
573    public Map<String, String> getCorsHeaders() {
574        return corsHeaders;
575    }
576
577    /**
578     * Sets the CORS headers to use if CORS has been enabled.
579     *
580     * @param corsHeaders the CORS headers
581     */
582    public void setCorsHeaders(Map<String, String> corsHeaders) {
583        this.corsHeaders = corsHeaders;
584    }
585}