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