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.component.rest; 018 019import java.util.Map; 020import java.util.Set; 021 022import org.apache.camel.Component; 023import org.apache.camel.Consumer; 024import org.apache.camel.NoSuchBeanException; 025import org.apache.camel.Processor; 026import org.apache.camel.Producer; 027import org.apache.camel.impl.DefaultEndpoint; 028import org.apache.camel.spi.RestConfiguration; 029import org.apache.camel.spi.RestConsumerFactory; 030import org.apache.camel.spi.UriEndpoint; 031import org.apache.camel.spi.UriParam; 032import org.apache.camel.util.HostUtils; 033import org.apache.camel.util.ObjectHelper; 034 035@UriEndpoint(scheme = "rest") 036public class RestEndpoint extends DefaultEndpoint { 037 038 @UriParam 039 private String method; 040 @UriParam 041 private String path; 042 @UriParam 043 private String uriTemplate; 044 @UriParam 045 private String consumes; 046 @UriParam 047 private String produces; 048 @UriParam 049 private String componentName; 050 @UriParam 051 private String inType; 052 @UriParam 053 private String outType; 054 @UriParam 055 private String routeId; 056 @UriParam 057 private String description; 058 059 private Map<String, Object> parameters; 060 061 public RestEndpoint(String endpointUri, RestComponent component) { 062 super(endpointUri, component); 063 } 064 065 @Override 066 public RestComponent getComponent() { 067 return (RestComponent) super.getComponent(); 068 } 069 070 public String getMethod() { 071 return method; 072 } 073 074 public void setMethod(String method) { 075 this.method = method; 076 } 077 078 public String getPath() { 079 return path; 080 } 081 082 public void setPath(String path) { 083 this.path = path; 084 } 085 086 public String getUriTemplate() { 087 return uriTemplate; 088 } 089 090 public void setUriTemplate(String uriTemplate) { 091 this.uriTemplate = uriTemplate; 092 } 093 094 public String getConsumes() { 095 return consumes; 096 } 097 098 public void setConsumes(String consumes) { 099 this.consumes = consumes; 100 } 101 102 public String getProduces() { 103 return produces; 104 } 105 106 public void setProduces(String produces) { 107 this.produces = produces; 108 } 109 110 public String getComponentName() { 111 return componentName; 112 } 113 114 public void setComponentName(String componentName) { 115 this.componentName = componentName; 116 } 117 118 public String getInType() { 119 return inType; 120 } 121 122 public void setInType(String inType) { 123 this.inType = inType; 124 } 125 126 public String getOutType() { 127 return outType; 128 } 129 130 public void setOutType(String outType) { 131 this.outType = outType; 132 } 133 134 public String getRouteId() { 135 return routeId; 136 } 137 138 public void setRouteId(String routeId) { 139 this.routeId = routeId; 140 } 141 142 public String getDescription() { 143 return description; 144 } 145 146 public void setDescription(String description) { 147 this.description = description; 148 } 149 150 public Map<String, Object> getParameters() { 151 return parameters; 152 } 153 154 public void setParameters(Map<String, Object> parameters) { 155 this.parameters = parameters; 156 } 157 158 @Override 159 public Producer createProducer() throws Exception { 160 throw new UnsupportedOperationException("Producer not supported"); 161 } 162 163 @Override 164 public Consumer createConsumer(Processor processor) throws Exception { 165 RestConsumerFactory factory = null; 166 167 if (getComponentName() != null) { 168 Object comp = getCamelContext().getRegistry().lookupByName(getComponentName()); 169 if (comp != null && comp instanceof RestConsumerFactory) { 170 factory = (RestConsumerFactory) comp; 171 } else { 172 comp = getCamelContext().getComponent(getComponentName()); 173 if (comp != null && comp instanceof RestConsumerFactory) { 174 factory = (RestConsumerFactory) comp; 175 } 176 } 177 178 if (factory == null) { 179 if (comp != null) { 180 throw new IllegalArgumentException("Component " + getComponentName() + " is not a RestConsumerFactory"); 181 } else { 182 throw new NoSuchBeanException(getComponentName(), RestConsumerFactory.class.getName()); 183 } 184 } 185 } 186 187 // try all components 188 if (factory == null) { 189 for (String name : getCamelContext().getComponentNames()) { 190 Component comp = getCamelContext().getComponent(name); 191 if (comp != null && comp instanceof RestConsumerFactory) { 192 factory = (RestConsumerFactory) comp; 193 break; 194 } 195 } 196 } 197 198 // lookup in registry 199 if (factory == null) { 200 Set<RestConsumerFactory> factories = getCamelContext().getRegistry().findByType(RestConsumerFactory.class); 201 if (factories != null && factories.size() == 1) { 202 factory = factories.iterator().next(); 203 } 204 } 205 206 if (factory != null) { 207 Consumer consumer = factory.createConsumer(getCamelContext(), processor, getMethod(), getPath(), getUriTemplate(), getConsumes(), getProduces(), getParameters()); 208 configureConsumer(consumer); 209 210 // if no explicit port/host configured, then use port from rest configuration 211 String scheme = "http"; 212 String host = ""; 213 int port = 80; 214 215 RestConfiguration config = getCamelContext().getRestConfiguration(); 216 if (config.getScheme() != null) { 217 scheme = config.getScheme(); 218 } 219 if (config.getHost() != null) { 220 host = config.getHost(); 221 } 222 int num = config.getPort(); 223 if (num > 0) { 224 port = num; 225 } 226 227 // if no explicit hostname set then resolve the hostname 228 if (ObjectHelper.isEmpty(host)) { 229 if (config.getRestHostNameResolver() == RestConfiguration.RestHostNameResolver.localHostName) { 230 host = HostUtils.getLocalHostName(); 231 } else if (config.getRestHostNameResolver() == RestConfiguration.RestHostNameResolver.localIp) { 232 host = HostUtils.getLocalIp(); 233 } 234 } 235 236 237 // calculate the url to the rest service 238 String path = getPath(); 239 if (!path.startsWith("/")) { 240 path = "/" + path; 241 } 242 243 // there may be an optional context path configured to help Camel calculate the correct urls for the REST services 244 // this may be needed when using camel-serlvet where we cannot get the actual context-path or port number of the servlet engine 245 // during init of the servlet 246 String contextPath = config.getContextPath(); 247 if (contextPath != null) { 248 if (!contextPath.startsWith("/")) { 249 path = "/" + contextPath + path; 250 } else { 251 path = contextPath + path; 252 } 253 } 254 255 String baseUrl = scheme + "://" + host + (port != 80 ? ":" + port : "") + path; 256 257 String url = baseUrl; 258 if (uriTemplate != null) { 259 // make sure to avoid double slashes 260 if (uriTemplate.startsWith("/")) { 261 url = url + uriTemplate; 262 } else { 263 url = url + "/" + uriTemplate; 264 } 265 } 266 267 // add to rest registry so we can keep track of them, we will remove from the registry when the consumer is removed 268 // the rest registry will automatic keep track when the consumer is removed, 269 // and un-register the REST service from the registry 270 getCamelContext().getRestRegistry().addRestService(consumer, url, baseUrl, getPath(), getUriTemplate(), getMethod(), 271 getConsumes(), getProduces(), getInType(), getOutType(), getRouteId(), getDescription()); 272 return consumer; 273 } else { 274 throw new IllegalStateException("Cannot find RestConsumerFactory in Registry or as a Component to use"); 275 } 276 } 277 278 @Override 279 public boolean isSingleton() { 280 return true; 281 } 282 283 @Override 284 public boolean isLenientProperties() { 285 return true; 286 } 287}