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.List; 021 022import javax.xml.bind.annotation.XmlAccessType; 023import javax.xml.bind.annotation.XmlAccessorType; 024import javax.xml.bind.annotation.XmlAttribute; 025import javax.xml.bind.annotation.XmlElement; 026import javax.xml.bind.annotation.XmlElementRef; 027import javax.xml.bind.annotation.XmlElements; 028import javax.xml.bind.annotation.XmlRootElement; 029import javax.xml.bind.annotation.XmlTransient; 030 031import org.apache.camel.model.OptionalIdentifiedDefinition; 032import org.apache.camel.model.RouteDefinition; 033import org.apache.camel.model.ToDefinition; 034import org.apache.camel.model.ToDynamicDefinition; 035import org.apache.camel.spi.Metadata; 036 037/** 038 * Rest command 039 */ 040@Metadata(label = "rest") 041@XmlRootElement(name = "verb") 042@XmlAccessorType(XmlAccessType.FIELD) 043public class VerbDefinition extends OptionalIdentifiedDefinition<VerbDefinition> { 044 045 @XmlAttribute 046 private String method; 047 048 @XmlElementRef 049 private List<RestOperationParamDefinition> params = new ArrayList<>(); 050 051 @XmlElementRef 052 private List<RestOperationResponseMsgDefinition> responseMsgs = new ArrayList<>(); 053 054 @XmlElementRef 055 private List<SecurityDefinition> security = new ArrayList<>(); 056 057 @XmlAttribute 058 private String uri; 059 060 @XmlAttribute 061 private String consumes; 062 063 @XmlAttribute 064 private String produces; 065 066 @XmlAttribute 067 @Metadata(defaultValue = "auto") 068 private RestBindingMode bindingMode; 069 070 @XmlAttribute 071 private Boolean skipBindingOnErrorCode; 072 073 @XmlAttribute 074 private Boolean clientRequestValidation; 075 076 @XmlAttribute 077 private Boolean enableCORS; 078 079 @XmlAttribute 080 private String type; 081 082 @XmlAttribute 083 private String outType; 084 085 // used by XML DSL to either select a <to>, <toD>, or <route> 086 // so we need to use the common type OptionalIdentifiedDefinition 087 // must select one of them, and hence why they are all set to required = 088 // true, but the XSD is set to only allow one of the element 089 @XmlElements({@XmlElement(required = true, name = "to", type = ToDefinition.class), @XmlElement(required = true, name = "toD", type = ToDynamicDefinition.class), 090 @XmlElement(required = true, name = "route", type = RouteDefinition.class)}) 091 private OptionalIdentifiedDefinition<?> toOrRoute; 092 093 // the Java DSL uses the to or route definition directory 094 @XmlTransient 095 private ToDefinition to; 096 @XmlTransient 097 private ToDynamicDefinition toD; 098 @XmlTransient 099 private RouteDefinition route; 100 @XmlTransient 101 private RestDefinition rest; 102 @XmlAttribute 103 private String routeId; 104 @XmlAttribute 105 private Boolean apiDocs; 106 107 @XmlTransient 108 private Boolean usedForGeneratingNodeId = Boolean.FALSE; 109 110 @Override 111 public String getShortName() { 112 return "verb"; 113 } 114 115 @Override 116 public String getLabel() { 117 if (method != null) { 118 return method; 119 } else { 120 return "verb"; 121 } 122 } 123 124 public List<RestOperationParamDefinition> getParams() { 125 return params; 126 } 127 128 /** 129 * To specify the REST operation parameters using Swagger. 130 */ 131 public void setParams(List<RestOperationParamDefinition> params) { 132 this.params = params; 133 } 134 135 public List<RestOperationResponseMsgDefinition> getResponseMsgs() { 136 return responseMsgs; 137 } 138 139 /** 140 * Sets swagger operation response messages. 141 */ 142 public void setResponseMsgs(List<RestOperationResponseMsgDefinition> responseMsgs) { 143 this.responseMsgs = responseMsgs; 144 } 145 146 public List<SecurityDefinition> getSecurity() { 147 return security; 148 } 149 150 /** 151 * Sets the swagger security settings for this verb. 152 */ 153 public void setSecurity(List<SecurityDefinition> security) { 154 this.security = security; 155 } 156 157 public String getMethod() { 158 return method; 159 } 160 161 /** 162 * The HTTP verb such as GET, POST, DELETE, etc. 163 */ 164 public void setMethod(String method) { 165 this.method = method; 166 } 167 168 public String getUri() { 169 return uri; 170 } 171 172 /** 173 * Uri template of this REST service such as /{id}. 174 */ 175 public void setUri(String uri) { 176 this.uri = uri; 177 } 178 179 public String getConsumes() { 180 return consumes; 181 } 182 183 /** 184 * To define the content type what the REST service consumes (accept as 185 * input), such as application/xml or application/json. This option will 186 * override what may be configured on a parent level 187 */ 188 public void setConsumes(String consumes) { 189 this.consumes = consumes; 190 } 191 192 public String getProduces() { 193 return produces; 194 } 195 196 /** 197 * To define the content type what the REST service produces (uses for 198 * output), such as application/xml or application/json This option will 199 * override what may be configured on a parent level 200 */ 201 public void setProduces(String produces) { 202 this.produces = produces; 203 } 204 205 public RestBindingMode getBindingMode() { 206 return bindingMode; 207 } 208 209 /** 210 * Sets the binding mode to use. This option will override what may be 211 * configured on a parent level 212 * <p/> 213 * The default value is auto 214 */ 215 public void setBindingMode(RestBindingMode bindingMode) { 216 this.bindingMode = bindingMode; 217 } 218 219 public Boolean getSkipBindingOnErrorCode() { 220 return skipBindingOnErrorCode; 221 } 222 223 /** 224 * Whether to skip binding on output if there is a custom HTTP error code 225 * header. This allows to build custom error messages that do not bind to 226 * json / xml etc, as success messages otherwise will do. This option will 227 * override what may be configured on a parent level 228 */ 229 public void setSkipBindingOnErrorCode(Boolean skipBindingOnErrorCode) { 230 this.skipBindingOnErrorCode = skipBindingOnErrorCode; 231 } 232 233 public Boolean getClientRequestValidation() { 234 return clientRequestValidation; 235 } 236 237 /** 238 * Whether to enable validation of the client request to check whether the 239 * Content-Type and Accept headers from the client is supported by the 240 * Rest-DSL configuration of its consumes/produces settings. 241 * <p/> 242 * This can be turned on, to enable this check. In case of validation error, 243 * then HTTP Status codes 415 or 406 is returned. 244 * <p/> 245 * The default value is false. 246 */ 247 public void setClientRequestValidation(Boolean clientRequestValidation) { 248 this.clientRequestValidation = clientRequestValidation; 249 } 250 251 public Boolean getEnableCORS() { 252 return enableCORS; 253 } 254 255 /** 256 * Whether to enable CORS headers in the HTTP response. This option will 257 * override what may be configured on a parent level 258 * <p/> 259 * The default value is false. 260 */ 261 public void setEnableCORS(Boolean enableCORS) { 262 this.enableCORS = enableCORS; 263 } 264 265 public String getType() { 266 return type; 267 } 268 269 /** 270 * Sets the class name to use for binding from input to POJO for the 271 * incoming data This option will override what may be configured on a 272 * parent level. 273 * <p/> 274 * The canonical name of the class of the input data. Append a [] to the end 275 * of the canonical name if you want the input to be an array type. 276 */ 277 public void setType(String type) { 278 this.type = type; 279 } 280 281 public String getOutType() { 282 return outType; 283 } 284 285 /** 286 * Sets the class name to use for binding from POJO to output for the 287 * outgoing data This option will override what may be configured on a 288 * parent level 289 * <p/> 290 * The canonical name of the class of the input data. Append a [] to the end 291 * of the canonical name if you want the input to be an array type. 292 */ 293 public void setOutType(String outType) { 294 this.outType = outType; 295 } 296 297 public String getRouteId() { 298 return routeId; 299 } 300 301 /** 302 * The route id this rest-dsl is using (read-only) 303 */ 304 public void setRouteId(String routeId) { 305 this.routeId = routeId; 306 } 307 308 public Boolean getApiDocs() { 309 return apiDocs; 310 } 311 312 /** 313 * Whether to include or exclude the VerbDefinition in API documentation. 314 * <p/> 315 * The default value is true. 316 */ 317 public void setApiDocs(Boolean apiDocs) { 318 this.apiDocs = apiDocs; 319 } 320 321 public RestDefinition getRest() { 322 return rest; 323 } 324 325 public void setRest(RestDefinition rest) { 326 this.rest = rest; 327 } 328 329 public RouteDefinition getRoute() { 330 if (route != null) { 331 return route; 332 } else if (toOrRoute instanceof RouteDefinition) { 333 return (RouteDefinition)toOrRoute; 334 } else { 335 return null; 336 } 337 } 338 339 public void setRoute(RouteDefinition route) { 340 this.route = route; 341 this.toOrRoute = route; 342 } 343 344 public ToDefinition getTo() { 345 if (to != null) { 346 return to; 347 } else if (toOrRoute instanceof ToDefinition) { 348 return (ToDefinition)toOrRoute; 349 } else { 350 return null; 351 } 352 } 353 354 public ToDynamicDefinition getToD() { 355 if (toD != null) { 356 return toD; 357 } else if (toOrRoute instanceof ToDynamicDefinition) { 358 return (ToDynamicDefinition)toOrRoute; 359 } else { 360 return null; 361 } 362 } 363 364 public void setTo(ToDefinition to) { 365 this.to = to; 366 this.toD = null; 367 this.toOrRoute = to; 368 } 369 370 public void setToD(ToDynamicDefinition to) { 371 this.to = null; 372 this.toD = to; 373 this.toOrRoute = to; 374 } 375 376 public OptionalIdentifiedDefinition<?> getToOrRoute() { 377 return toOrRoute; 378 } 379 380 /** 381 * To route from this REST service to a Camel endpoint, or an inlined route 382 */ 383 public void setToOrRoute(OptionalIdentifiedDefinition<?> toOrRoute) { 384 this.toOrRoute = toOrRoute; 385 } 386 387 // Fluent API 388 // ------------------------------------------------------------------------- 389 390 public RestDefinition get() { 391 return rest.get(); 392 } 393 394 public RestDefinition get(String uri) { 395 return rest.get(uri); 396 } 397 398 public RestDefinition post() { 399 return rest.post(); 400 } 401 402 public RestDefinition post(String uri) { 403 return rest.post(uri); 404 } 405 406 public RestDefinition put() { 407 return rest.put(); 408 } 409 410 public RestDefinition put(String uri) { 411 return rest.put(uri); 412 } 413 414 public RestDefinition delete() { 415 return rest.delete(); 416 } 417 418 public RestDefinition delete(String uri) { 419 return rest.delete(uri); 420 } 421 422 public RestDefinition head() { 423 return rest.head(); 424 } 425 426 public RestDefinition head(String uri) { 427 return rest.head(uri); 428 } 429 430 public RestDefinition verb(String verb) { 431 return rest.verb(verb); 432 } 433 434 public RestDefinition verb(String verb, String uri) { 435 return rest.verb(verb, uri); 436 } 437 438 public String asVerb() { 439 // we do not want the jaxb model to repeat itself, by outputting <get 440 // method="get"> 441 // so we infer the verb from the instance type 442 if (this instanceof GetVerbDefinition) { 443 return "get"; 444 } else if (this instanceof PostVerbDefinition) { 445 return "post"; 446 } else if (this instanceof PutVerbDefinition) { 447 return "put"; 448 } else if (this instanceof PatchVerbDefinition) { 449 return "patch"; 450 } else if (this instanceof DeleteVerbDefinition) { 451 return "delete"; 452 } else if (this instanceof HeadVerbDefinition) { 453 return "head"; 454 } else { 455 return method; 456 } 457 } 458 459 public Boolean getUsedForGeneratingNodeId() { 460 return usedForGeneratingNodeId; 461 } 462 463 public void setUsedForGeneratingNodeId(Boolean usedForGeneratingNodeId) { 464 this.usedForGeneratingNodeId = usedForGeneratingNodeId; 465 } 466}