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.support; 018 019import org.apache.camel.Exchange; 020import org.apache.camel.model.remote.ServiceCallDefinition; 021import org.apache.camel.util.ObjectHelper; 022import org.slf4j.Logger; 023import org.slf4j.LoggerFactory; 024 025/** 026 * Support class for custom implementations of {@link ServiceCallDefinition ServiceCall EIP} components. 027 * <p/> 028 * Below are some examples how to call a service and what Camel endpoint URI is constructed based on the input: 029 * <pre> 030 serviceCall("myService") -> http://hostname:port 031 serviceCall("myService/foo") -> http://hostname:port/foo 032 serviceCall("http:myService/foo") -> http:hostname:port/foo 033 serviceCall("myService", "http:myService.host:myService.port/foo") -> http:hostname:port/foo 034 serviceCall("myService", "netty4:tcp:myService?connectTimeout=1000") -> netty:tcp:hostname:port?connectTimeout=1000 035 * </pre> 036 */ 037public abstract class ServiceCallExpressionSupport extends ExpressionAdapter { 038 039 private static final Logger LOG = LoggerFactory.getLogger(ServiceCallExpressionSupport.class); 040 041 private final String name; 042 private final String scheme; 043 private final String contextPath; 044 private final String uri; 045 046 public ServiceCallExpressionSupport(String name, String scheme, String contextPath, String uri) { 047 this.name = name; 048 this.scheme = scheme; 049 this.contextPath = contextPath; 050 this.uri = uri; 051 } 052 053 public abstract String getIp(Exchange exchange) throws Exception; 054 055 public abstract int getPort(Exchange exchange) throws Exception; 056 057 @Override 058 public Object evaluate(Exchange exchange) { 059 try { 060 String ip = getIp(exchange); 061 int port = getPort(exchange); 062 return buildCamelEndpointUri(ip, port, name, uri, contextPath, scheme); 063 } catch (Exception e) { 064 throw ObjectHelper.wrapRuntimeCamelException(e); 065 } 066 } 067 068 protected static String buildCamelEndpointUri(String ip, int port, String name, String uri, String contextPath, String scheme) { 069 // build basic uri if none provided 070 String answer = uri; 071 if (answer == null) { 072 if (scheme == null) { 073 // use http/https by default if no scheme has been configured 074 if (port == 443) { 075 scheme = "https"; 076 } else { 077 scheme = "http"; 078 } 079 } 080 answer = scheme + "://" + ip + ":" + port; 081 if (contextPath != null) { 082 answer += "" + contextPath; 083 } 084 } else { 085 // we have existing uri, then replace the serviceName with ip:port 086 if (answer.contains(name + ".host")) { 087 answer = answer.replaceFirst(name + "\\.host", ip); 088 } 089 if (answer.contains(name + ".port")) { 090 answer = answer.replaceFirst(name + "\\.port", "" + port); 091 } 092 if (answer.contains(name)) { 093 answer = answer.replaceFirst(name, ip + ":" + port); 094 } 095 } 096 097 LOG.debug("Camel endpoint uri: {} for calling service: {} on server {}:{}", answer, name, ip, port); 098 return answer; 099 } 100 101}