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.model.rest;
018
019import java.util.ArrayList;
020import java.util.HashMap;
021import java.util.List;
022import java.util.Map;
023import javax.xml.bind.annotation.XmlAccessType;
024import javax.xml.bind.annotation.XmlAccessorType;
025import javax.xml.bind.annotation.XmlAttribute;
026import javax.xml.bind.annotation.XmlElement;
027import javax.xml.bind.annotation.XmlRootElement;
028
029import org.apache.camel.CamelContext;
030import org.apache.camel.spi.Metadata;
031import org.apache.camel.spi.RestConfiguration;
032import org.apache.camel.util.CamelContextHelper;
033
034/**
035 * To configure rest
036 */
037@Metadata(label = "rest")
038@XmlRootElement(name = "restConfiguration")
039@XmlAccessorType(XmlAccessType.FIELD)
040public class RestConfigurationDefinition {
041
042    @XmlAttribute
043    private String component;
044
045    @XmlAttribute @Metadata(label = "consumer", defaultValue = "swagger")
046    private String apiComponent;
047
048    @XmlAttribute @Metadata(label = "producer")
049    private String producerComponent;
050
051    @XmlAttribute
052    private String scheme;
053
054    @XmlAttribute
055    private String host;
056
057    @XmlAttribute
058    private String apiHost;
059
060    @XmlAttribute
061    private String port;
062
063    @XmlAttribute @Metadata(label = "producer")
064    private String producerApiDoc;
065
066    @XmlAttribute @Metadata(label = "consumer")
067    private String contextPath;
068
069    @XmlAttribute @Metadata(label = "consumer")
070    private String apiContextPath;
071
072    @XmlAttribute @Metadata(label = "consumer")
073    private String apiContextRouteId;
074
075    @XmlAttribute @Metadata(label = "consumer")
076    private String apiContextIdPattern;
077
078    @XmlAttribute @Metadata(label = "consumer")
079    private Boolean apiContextListing;
080
081    @XmlAttribute @Metadata(label = "consumer")
082    private Boolean apiVendorExtension;
083
084    @XmlAttribute @Metadata(label = "consumer")
085    private RestHostNameResolver hostNameResolver;
086
087    @XmlAttribute @Metadata(defaultValue = "off")
088    private RestBindingMode bindingMode;
089
090    @XmlAttribute
091    private Boolean skipBindingOnErrorCode;
092
093    @XmlAttribute
094    private Boolean clientRequestValidation;
095
096    @XmlAttribute @Metadata(label = "consumer")
097    private Boolean enableCORS;
098
099    @XmlAttribute
100    private String jsonDataFormat;
101
102    @XmlAttribute
103    private String xmlDataFormat;
104
105    @XmlElement(name = "componentProperty")
106    private List<RestPropertyDefinition> componentProperties = new ArrayList<>();
107
108    @XmlElement(name = "endpointProperty")
109    private List<RestPropertyDefinition> endpointProperties = new ArrayList<>();
110
111    @XmlElement(name = "consumerProperty") @Metadata(label = "consumer")
112    private List<RestPropertyDefinition> consumerProperties = new ArrayList<>();
113
114    @XmlElement(name = "dataFormatProperty")
115    private List<RestPropertyDefinition> dataFormatProperties = new ArrayList<>();
116
117    @XmlElement(name = "apiProperty") @Metadata(label = "consumer")
118    private List<RestPropertyDefinition> apiProperties = new ArrayList<>();
119
120    @XmlElement(name = "corsHeaders") @Metadata(label = "consumer")
121    private List<RestPropertyDefinition> corsHeaders = new ArrayList<>();
122
123    public String getComponent() {
124        return component;
125    }
126
127    /**
128     * The Camel Rest component to use for the REST transport (consumer), such as restlet, spark-rest.
129     * If no component has been explicit configured, then Camel will lookup if there is a Camel component
130     * that integrates with the Rest DSL, or if a org.apache.camel.spi.RestConsumerFactory is registered in the registry.
131     * If either one is found, then that is being used.
132     */
133    public void setComponent(String component) {
134        this.component = component;
135    }
136
137    public String getApiComponent() {
138        return apiComponent;
139    }
140
141    /**
142     * The name of the Camel component to use as the REST API (such as swagger)
143     */
144    public void setApiComponent(String apiComponent) {
145        this.apiComponent = apiComponent;
146    }
147
148    public String getProducerComponent() {
149        return producerComponent;
150    }
151
152    /**
153     * Sets the name of the Camel component to use as the REST producer
154     */
155    public void setProducerComponent(String producerComponent) {
156        this.producerComponent = producerComponent;
157    }
158
159    public String getScheme() {
160        return scheme;
161    }
162
163    /**
164     * The scheme to use for exposing the REST service. Usually http or https is supported.
165     * <p/>
166     * The default value is http
167     */
168    public void setScheme(String scheme) {
169        this.scheme = scheme;
170    }
171
172    public String getHost() {
173        return host;
174    }
175
176    /**
177     * The hostname to use for exposing the REST service.
178     */
179    public void setHost(String host) {
180        this.host = host;
181    }
182
183    public String getApiHost() {
184        return apiHost;
185    }
186
187    /**
188     * To use an specific hostname for the API documentation (eg swagger)
189     * <p/>
190     * This can be used to override the generated host with this configured hostname
191     */
192    public void setApiHost(String apiHost) {
193        this.apiHost = apiHost;
194    }
195
196    public String getPort() {
197        return port;
198    }
199
200    /**
201     * The port number to use for exposing the REST service.
202     * Notice if you use servlet component then the port number configured here does not apply,
203     * as the port number in use is the actual port number the servlet component is using.
204     * eg if using Apache Tomcat its the tomcat http port, if using Apache Karaf its the HTTP service in Karaf
205     * that uses port 8181 by default etc. Though in those situations setting the port number here,
206     * allows tooling and JMX to know the port number, so its recommended to set the port number
207     * to the number that the servlet engine uses.
208     */
209    public void setPort(String port) {
210        this.port = port;
211    }
212
213    public String getProducerApiDoc() {
214        return producerApiDoc;
215    }
216
217    /**
218     * Sets the location of the api document (swagger api) the REST producer will use
219     * to validate the REST uri and query parameters are valid accordingly to the api document.
220     * This requires adding camel-swagger-java to the classpath, and any miss configuration
221     * will let Camel fail on startup and report the error(s).
222     * <p/>
223     * The location of the api document is loaded from classpath by default, but you can use
224     * <tt>file:</tt> or <tt>http:</tt> to refer to resources to load from file or http url.
225     */
226    public void setProducerApiDoc(String producerApiDoc) {
227        this.producerApiDoc = producerApiDoc;
228    }
229
230    public String getContextPath() {
231        return contextPath;
232    }
233
234    /**
235     * Sets a leading context-path the REST services will be using.
236     * <p/>
237     * This can be used when using components such as <tt>camel-servlet</tt> where the deployed web application
238     * is deployed using a context-path. Or for components such as <tt>camel-jetty</tt> or <tt>camel-netty4-http</tt>
239     * that includes a HTTP server.
240     */
241    public void setContextPath(String contextPath) {
242        this.contextPath = contextPath;
243    }
244
245    public String getApiContextPath() {
246        return apiContextPath;
247    }
248
249    /**
250     * Sets a leading API context-path the REST API services will be using.
251     * <p/>
252     * This can be used when using components such as <tt>camel-servlet</tt> where the deployed web application
253     * is deployed using a context-path.
254     *
255     * @param contextPath the API context path
256     */
257    public void setApiContextPath(String contextPath) {
258        this.apiContextPath = contextPath;
259    }
260
261    public String getApiContextRouteId() {
262        return apiContextRouteId;
263    }
264
265    /**
266     * Sets the route id to use for the route that services the REST API.
267     * <p/>
268     * The route will by default use an auto assigned route id.
269     *
270     * @param apiContextRouteId  the route id
271     */
272    public void setApiContextRouteId(String apiContextRouteId) {
273        this.apiContextRouteId = apiContextRouteId;
274    }
275
276    public String getApiContextIdPattern() {
277        return apiContextIdPattern;
278    }
279
280    /**
281     * Sets an CamelContext id pattern to only allow Rest APIs from rest services within CamelContext's which name matches the pattern.
282     * <p/>
283     * The pattern <tt>#name#</tt> refers to the CamelContext name, to match on the current CamelContext only.
284     * For any other value, the pattern uses the rules from {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)}
285     *
286     * @param apiContextIdPattern  the pattern
287     */
288    public void setApiContextIdPattern(String apiContextIdPattern) {
289        this.apiContextIdPattern = apiContextIdPattern;
290    }
291
292    public Boolean getApiContextListing() {
293        return apiContextListing;
294    }
295
296    /**
297     * Sets whether listing of all available CamelContext's with REST services in the JVM is enabled. If enabled it allows to discover
298     * these contexts, if <tt>false</tt> then only the current CamelContext is in use.
299     */
300    public void setApiContextListing(Boolean apiContextListing) {
301        this.apiContextListing = apiContextListing;
302    }
303
304    public Boolean getApiVendorExtension() {
305        return apiVendorExtension;
306    }
307
308    /**
309     * Whether vendor extension is enabled in the Rest APIs. If enabled then Camel will include additional information
310     * as vendor extension (eg keys starting with x-) such as route ids, class names etc.
311     * Not all 3rd party API gateways and tools supports vendor-extensions when importing your API docs.
312     */
313    public void setApiVendorExtension(Boolean apiVendorExtension) {
314        this.apiVendorExtension = apiVendorExtension;
315    }
316
317    public RestHostNameResolver getHostNameResolver() {
318        return hostNameResolver;
319    }
320
321    /**
322     * If no hostname has been explicit configured, then this resolver is used to compute the hostname the REST service will be using.
323     */
324    public void setHostNameResolver(RestHostNameResolver hostNameResolver) {
325        this.hostNameResolver = hostNameResolver;
326    }
327
328    public RestBindingMode getBindingMode() {
329        return bindingMode;
330    }
331
332    /**
333     * Sets the binding mode to use.
334     * <p/>
335     * The default value is off
336     */
337    public void setBindingMode(RestBindingMode bindingMode) {
338        this.bindingMode = bindingMode;
339    }
340
341    public Boolean getSkipBindingOnErrorCode() {
342        return skipBindingOnErrorCode;
343    }
344
345    /**
346     * Whether to skip binding on output if there is a custom HTTP error code header.
347     * This allows to build custom error messages that do not bind to json / xml etc, as success messages otherwise will do.
348     */
349    public void setSkipBindingOnErrorCode(Boolean skipBindingOnErrorCode) {
350        this.skipBindingOnErrorCode = skipBindingOnErrorCode;
351    }
352
353    public Boolean getClientRequestValidation() {
354        return clientRequestValidation;
355    }
356
357    /**
358     * Whether to enable validation of the client request to check whether the Content-Type and Accept headers from
359     * the client is supported by the Rest-DSL configuration of its consumes/produces settings.
360     * <p/>
361     * This can be turned on, to enable this check. In case of validation error, then HTTP Status codes 415 or 406 is returned.
362     * <p/>
363     * The default value is false.
364     */
365    public void setClientRequestValidation(Boolean clientRequestValidation) {
366        this.clientRequestValidation = clientRequestValidation;
367    }
368
369    public Boolean getEnableCORS() {
370        return enableCORS;
371    }
372
373    /**
374     * Whether to enable CORS headers in the HTTP response.
375     * <p/>
376     * The default value is false.
377     */
378    public void setEnableCORS(Boolean enableCORS) {
379        this.enableCORS = enableCORS;
380    }
381
382    public String getJsonDataFormat() {
383        return jsonDataFormat;
384    }
385
386    /**
387     * Name of specific json data format to use.
388     * By default json-jackson will be used.
389     * Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance.
390     */
391    public void setJsonDataFormat(String jsonDataFormat) {
392        this.jsonDataFormat = jsonDataFormat;
393    }
394
395    public String getXmlDataFormat() {
396        return xmlDataFormat;
397    }
398
399    /**
400     * Name of specific XML data format to use.
401     * By default jaxb will be used.
402     * Important: This option is only for setting a custom name of the data format, not to refer to an existing data format instance.
403     */
404    public void setXmlDataFormat(String xmlDataFormat) {
405        this.xmlDataFormat = xmlDataFormat;
406    }
407
408    public List<RestPropertyDefinition> getComponentProperties() {
409        return componentProperties;
410    }
411
412    /**
413     * Allows to configure as many additional properties for the rest component in use.
414     */
415    public void setComponentProperties(List<RestPropertyDefinition> componentProperties) {
416        this.componentProperties = componentProperties;
417    }
418
419    public List<RestPropertyDefinition> getEndpointProperties() {
420        return endpointProperties;
421    }
422
423    /**
424     * Allows to configure as many additional properties for the rest endpoint in use.
425     */
426    public void setEndpointProperties(List<RestPropertyDefinition> endpointProperties) {
427        this.endpointProperties = endpointProperties;
428    }
429
430    public List<RestPropertyDefinition> getConsumerProperties() {
431        return consumerProperties;
432    }
433
434    /**
435     * Allows to configure as many additional properties for the rest consumer in use.
436     */
437    public void setConsumerProperties(List<RestPropertyDefinition> consumerProperties) {
438        this.consumerProperties = consumerProperties;
439    }
440
441    public List<RestPropertyDefinition> getDataFormatProperties() {
442        return dataFormatProperties;
443    }
444
445    /**
446     * Allows to configure as many additional properties for the data formats in use.
447     * For example set property prettyPrint to true to have json outputted in pretty mode.
448     * The properties can be prefixed to denote the option is only for either JSON or XML and for either the IN or the OUT.
449     * The prefixes are:
450     * <ul>
451     *     <li>json.in.</li>
452     *     <li>json.out.</li>
453     *     <li>xml.in.</li>
454     *     <li>xml.out.</li>
455     * </ul>
456     * For example a key with value "xml.out.mustBeJAXBElement" is only for the XML data format for the outgoing.
457     * A key without a prefix is a common key for all situations.
458     */
459    public void setDataFormatProperties(List<RestPropertyDefinition> dataFormatProperties) {
460        this.dataFormatProperties = dataFormatProperties;
461    }
462
463    public List<RestPropertyDefinition> getApiProperties() {
464        return apiProperties;
465    }
466
467    /**
468     * Allows to configure as many additional properties for the api documentation (swagger).
469     * For example set property api.title to my cool stuff
470     */
471    public void setApiProperties(List<RestPropertyDefinition> apiProperties) {
472        this.apiProperties = apiProperties;
473    }
474
475    public List<RestPropertyDefinition> getCorsHeaders() {
476        return corsHeaders;
477    }
478
479    /**
480     * Allows to configure custom CORS headers.
481     */
482    public void setCorsHeaders(List<RestPropertyDefinition> corsHeaders) {
483        this.corsHeaders = corsHeaders;
484    }
485
486    // Fluent API
487    //-------------------------------------------------------------------------
488
489    /**
490     * To use a specific Camel rest component (consumer)
491     */
492    public RestConfigurationDefinition component(String componentId) {
493        setComponent(componentId);
494        return this;
495    }
496
497    /**
498     * To use a specific Camel rest API component
499     */
500    public RestConfigurationDefinition apiComponent(String componentId) {
501        setApiComponent(componentId);
502        return this;
503    }
504
505    /**
506     * To use a specific Camel rest component (producer)
507     */
508    public RestConfigurationDefinition producerComponent(String componentId) {
509        setProducerComponent(componentId);
510        return this;
511    }
512
513    /**
514     * To use a specific scheme such as http/https
515     */
516    public RestConfigurationDefinition scheme(String scheme) {
517        setScheme(scheme);
518        return this;
519    }
520
521    /**
522     * To define the host to use, such as 0.0.0.0 or localhost
523     */
524    public RestConfigurationDefinition host(String host) {
525        setHost(host);
526        return this;
527    }
528
529    /**
530     * To define a specific host to use for API documentation (eg swagger) instead
531     * of using a generated API hostname that is relative to the REST service host.
532     */
533    public RestConfigurationDefinition apiHost(String host) {
534        setApiHost(host);
535        return this;
536    }
537
538    /**
539     * To specify the port number to use for the REST service
540     */
541    public RestConfigurationDefinition port(int port) {
542        setPort("" + port);
543        return this;
544    }
545
546    /**
547     * To specify the port number to use for the REST service
548     */
549    public RestConfigurationDefinition port(String port) {
550        setPort(port);
551        return this;
552    }
553
554    /**
555     * Sets the location of the api document (swagger api) the REST producer will use
556     * to validate the REST uri and query parameters are valid accordingly to the api document.
557     * This requires adding camel-swagger-java to the classpath, and any miss configuration
558     * will let Camel fail on startup and report the error(s).
559     * <p/>
560     * The location of the api document is loaded from classpath by default, but you can use
561     * <tt>file:</tt> or <tt>http:</tt> to refer to resources to load from file or http url.
562     */
563    public RestConfigurationDefinition producerApiDoc(String apiDoc) {
564        setProducerApiDoc(apiDoc);
565        return this;
566    }
567
568    /**
569     * Sets a leading context-path the REST services will be using.
570     * <p/>
571     * This can be used when using components such as <tt>camel-servlet</tt> where the deployed web application
572     * is deployed using a context-path. Or for components such as <tt>camel-jetty</tt> or <tt>camel-netty4-http</tt>
573     * that includes a HTTP server.
574     */
575    public RestConfigurationDefinition apiContextPath(String contextPath) {
576        setApiContextPath(contextPath);
577        return this;
578    }
579
580    /**
581     * Sets the route id to use for the route that services the REST API.
582     */
583    public RestConfigurationDefinition apiContextRouteId(String routeId) {
584        setApiContextRouteId(routeId);
585        return this;
586    }
587
588    /**
589     * Sets an CamelContext id pattern to only allow Rest APIs from rest services within CamelContext's which name matches the pattern.
590     * <p/>
591     * The pattern uses the rules from {@link org.apache.camel.util.EndpointHelper#matchPattern(String, String)}
592     */
593    public RestConfigurationDefinition apiContextIdPattern(String pattern) {
594        setApiContextIdPattern(pattern);
595        return this;
596    }
597
598    /**
599     * Sets whether listing of all available CamelContext's with REST services in the JVM is enabled. If enabled it allows to discover
600     * these contexts, if <tt>false</tt> then only the current CamelContext is in use.
601     */
602    public RestConfigurationDefinition apiContextListing(boolean listing) {
603        setApiContextListing(listing);
604        return this;
605    }
606
607    /**
608     * Whether vendor extension is enabled in the Rest APIs. If enabled then Camel will include additional information
609     * as vendor extension (eg keys starting with x-) such as route ids, class names etc.
610     * Some API tooling may not support vendor extensions and this option can then be turned off.
611     */
612    public RestConfigurationDefinition apiVendorExtension(boolean vendorExtension) {
613        setApiVendorExtension(vendorExtension);
614        return this;
615    }
616
617    /**
618     * Sets a leading context-path the REST services will be using.
619     * <p/>
620     * This can be used when using components such as <tt>camel-servlet</tt> where the deployed web application
621     * is deployed using a context-path.
622     */
623    public RestConfigurationDefinition contextPath(String contextPath) {
624        setContextPath(contextPath);
625        return this;
626    }
627
628    /**
629     * To specify the hostname resolver
630     */
631    public RestConfigurationDefinition hostNameResolver(RestHostNameResolver hostNameResolver) {
632        setHostNameResolver(hostNameResolver);
633        return this;
634    }
635
636    /**
637     * To specify the binding mode
638     */
639    public RestConfigurationDefinition bindingMode(RestBindingMode bindingMode) {
640        setBindingMode(bindingMode);
641        return this;
642    }
643
644    /**
645     * To specify whether to skip binding output if there is a custom HTTP error code
646     */
647    public RestConfigurationDefinition skipBindingOnErrorCode(boolean skipBindingOnErrorCode) {
648        setSkipBindingOnErrorCode(skipBindingOnErrorCode);
649        return this;
650    }
651
652    /**
653     * Whether to enable validation of the client request to check whether the Content-Type and Accept headers from
654     * the client is supported by the Rest-DSL configuration of its consumes/produces settings.
655     */
656    public RestConfigurationDefinition clientRequestValidation(boolean clientRequestValidation) {
657        setClientRequestValidation(clientRequestValidation);
658        return this;
659    }
660
661    /**
662     * To specify whether to enable CORS which means Camel will automatic include CORS in the HTTP headers in the response.
663     */
664    public RestConfigurationDefinition enableCORS(boolean enableCORS) {
665        setEnableCORS(enableCORS);
666        return this;
667    }
668
669    /**
670     * To use a specific json data format
671     * <p/>
672     * <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.
673     *
674     * @param name  name of the data format to {@link org.apache.camel.CamelContext#resolveDataFormat(java.lang.String) resolve}
675     */
676    public RestConfigurationDefinition jsonDataFormat(String name) {
677        setJsonDataFormat(name);
678        return this;
679    }
680
681    /**
682     * To use a specific XML data format
683     * <p/>
684     * <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.
685     *
686     * @param name  name of the data format to {@link org.apache.camel.CamelContext#resolveDataFormat(java.lang.String) resolve}
687     */
688    public RestConfigurationDefinition xmlDataFormat(String name) {
689        setXmlDataFormat(name);
690        return this;
691    }
692
693    /**
694     * For additional configuration options on component level
695     * <p/>
696     * The value can use <tt>#</tt> to refer to a bean to lookup in the registry.
697     */
698    public RestConfigurationDefinition componentProperty(String key, String value) {
699        RestPropertyDefinition prop = new RestPropertyDefinition();
700        prop.setKey(key);
701        prop.setValue(value);
702        getComponentProperties().add(prop);
703        return this;
704    }
705
706    /**
707     * For additional configuration options on endpoint level
708     * <p/>
709     * The value can use <tt>#</tt> to refer to a bean to lookup in the registry.
710     */
711    public RestConfigurationDefinition endpointProperty(String key, String value) {
712        RestPropertyDefinition prop = new RestPropertyDefinition();
713        prop.setKey(key);
714        prop.setValue(value);
715        getEndpointProperties().add(prop);
716        return this;
717    }
718
719    /**
720     * For additional configuration options on consumer level
721     * <p/>
722     * The value can use <tt>#</tt> to refer to a bean to lookup in the registry.
723     */
724    public RestConfigurationDefinition consumerProperty(String key, String value) {
725        RestPropertyDefinition prop = new RestPropertyDefinition();
726        prop.setKey(key);
727        prop.setValue(value);
728        getConsumerProperties().add(prop);
729        return this;
730    }
731
732    /**
733     * For additional configuration options on data format level
734     * <p/>
735     * The value can use <tt>#</tt> to refer to a bean to lookup in the registry.
736     */
737    public RestConfigurationDefinition dataFormatProperty(String key, String value) {
738        RestPropertyDefinition prop = new RestPropertyDefinition();
739        prop.setKey(key);
740        prop.setValue(value);
741        getDataFormatProperties().add(prop);
742        return this;
743    }
744
745    /**
746     * For configuring an api property, such as <tt>api.title</tt>, or <tt>api.version</tt>.
747     */
748    public RestConfigurationDefinition apiProperty(String key, String value) {
749        RestPropertyDefinition prop = new RestPropertyDefinition();
750        prop.setKey(key);
751        prop.setValue(value);
752        getApiProperties().add(prop);
753        return this;
754    }
755
756    /**
757     * For configuring CORS headers
758     */
759    public RestConfigurationDefinition corsHeaderProperty(String key, String value) {
760        RestPropertyDefinition prop = new RestPropertyDefinition();
761        prop.setKey(key);
762        prop.setValue(value);
763        getCorsHeaders().add(prop);
764        return this;
765    }
766
767    /**
768     * Shortcut for setting the {@code Access-Control-Allow-Credentials} header.
769     */
770    public RestConfigurationDefinition corsAllowCredentials(boolean corsAllowCredentials) {
771        return corsHeaderProperty("Access-Control-Allow-Credentials", String.valueOf(corsAllowCredentials));
772    }
773
774
775    // Implementation
776    //-------------------------------------------------------------------------
777
778    /**
779     * Creates a {@link org.apache.camel.spi.RestConfiguration} instance based on the definition
780     *
781     * @param context     the camel context
782     * @return the configuration
783     * @throws Exception is thrown if error creating the configuration
784     */
785    public RestConfiguration asRestConfiguration(CamelContext context) throws Exception {
786        RestConfiguration answer = new RestConfiguration();
787        if (component != null) {
788            answer.setComponent(CamelContextHelper.parseText(context, component));
789        }
790        if (apiComponent != null) {
791            answer.setApiComponent(CamelContextHelper.parseText(context, apiComponent));
792        }
793        if (producerComponent != null) {
794            answer.setProducerComponent(CamelContextHelper.parseText(context, producerComponent));
795        }
796        if (scheme != null) {
797            answer.setScheme(CamelContextHelper.parseText(context, scheme));
798        }
799        if (host != null) {
800            answer.setHost(CamelContextHelper.parseText(context, host));
801        }
802        if (apiHost != null) {
803            answer.setApiHost(CamelContextHelper.parseText(context, apiHost));
804        }
805        if (port != null) {
806            answer.setPort(CamelContextHelper.parseInteger(context, port));
807        }
808        if (producerApiDoc != null) {
809            answer.setProducerApiDoc(CamelContextHelper.parseText(context, producerApiDoc));
810        }
811        if (apiContextPath != null) {
812            answer.setApiContextPath(CamelContextHelper.parseText(context, apiContextPath));
813        }
814        if (apiContextRouteId != null) {
815            answer.setApiContextRouteId(CamelContextHelper.parseText(context, apiContextRouteId));
816        }
817        if (apiContextIdPattern != null) {
818            // special to allow #name# to refer to itself
819            if ("#name#".equals(apiComponent)) {
820                answer.setApiContextIdPattern(context.getName());
821            } else {
822                answer.setApiContextIdPattern(CamelContextHelper.parseText(context, apiContextIdPattern));
823            }
824        }
825        if (apiContextListing != null) {
826            answer.setApiContextListing(apiContextListing);
827        }
828        if (apiVendorExtension != null) {
829            answer.setApiVendorExtension(apiVendorExtension);
830        }
831        if (contextPath != null) {
832            answer.setContextPath(CamelContextHelper.parseText(context, contextPath));
833        }
834        if (hostNameResolver != null) {
835            answer.setRestHostNameResolver(hostNameResolver.name());
836        }
837        if (bindingMode != null) {
838            answer.setBindingMode(bindingMode.name());
839        }
840        if (skipBindingOnErrorCode != null) {
841            answer.setSkipBindingOnErrorCode(skipBindingOnErrorCode);
842        }
843        if (clientRequestValidation != null) {
844            answer.setClientRequestValidation(clientRequestValidation);
845        }
846        if (enableCORS != null) {
847            answer.setEnableCORS(enableCORS);
848        }
849        if (jsonDataFormat != null) {
850            answer.setJsonDataFormat(jsonDataFormat);
851        }
852        if (xmlDataFormat != null) {
853            answer.setXmlDataFormat(xmlDataFormat);
854        }
855        if (!componentProperties.isEmpty()) {
856            Map<String, Object> props = new HashMap<>();
857            for (RestPropertyDefinition prop : componentProperties) {
858                String key = prop.getKey();
859                String value = CamelContextHelper.parseText(context, prop.getValue());
860                props.put(key, value);
861            }
862            answer.setComponentProperties(props);
863        }
864        if (!endpointProperties.isEmpty()) {
865            Map<String, Object> props = new HashMap<>();
866            for (RestPropertyDefinition prop : endpointProperties) {
867                String key = prop.getKey();
868                String value = CamelContextHelper.parseText(context, prop.getValue());
869                props.put(key, value);
870            }
871            answer.setEndpointProperties(props);
872        }
873        if (!consumerProperties.isEmpty()) {
874            Map<String, Object> props = new HashMap<>();
875            for (RestPropertyDefinition prop : consumerProperties) {
876                String key = prop.getKey();
877                String value = CamelContextHelper.parseText(context, prop.getValue());
878                props.put(key, value);
879            }
880            answer.setConsumerProperties(props);
881        }
882        if (!dataFormatProperties.isEmpty()) {
883            Map<String, Object> props = new HashMap<>();
884            for (RestPropertyDefinition prop : dataFormatProperties) {
885                String key = prop.getKey();
886                String value = CamelContextHelper.parseText(context, prop.getValue());
887                props.put(key, value);
888            }
889            answer.setDataFormatProperties(props);
890        }
891        if (!apiProperties.isEmpty()) {
892            Map<String, Object> props = new HashMap<>();
893            for (RestPropertyDefinition prop : apiProperties) {
894                String key = prop.getKey();
895                String value = CamelContextHelper.parseText(context, prop.getValue());
896                props.put(key, value);
897            }
898            answer.setApiProperties(props);
899        }
900        if (!corsHeaders.isEmpty()) {
901            Map<String, String> props = new HashMap<>();
902            for (RestPropertyDefinition prop : corsHeaders) {
903                String key = prop.getKey();
904                String value = CamelContextHelper.parseText(context, prop.getValue());
905                props.put(key, value);
906            }
907            answer.setCorsHeaders(props);
908        }
909        return answer;
910    }
911
912}