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.blueprint; 018 019import java.util.Set; 020import javax.xml.bind.annotation.XmlAccessType; 021import javax.xml.bind.annotation.XmlAccessorType; 022import javax.xml.bind.annotation.XmlAttribute; 023import javax.xml.bind.annotation.XmlRootElement; 024import javax.xml.bind.annotation.XmlTransient; 025 026import org.apache.aries.blueprint.services.ExtendedBlueprintContainer; 027import org.apache.camel.CamelContext; 028import org.apache.camel.Endpoint; 029import org.apache.camel.FailedToCreateProducerException; 030import org.apache.camel.Producer; 031import org.apache.camel.component.bean.ProxyHelper; 032import org.apache.camel.core.xml.AbstractCamelFactoryBean; 033import org.apache.camel.util.ServiceHelper; 034 035/** 036 * A factory to create a Proxy to a a Camel Pojo Endpoint. 037 */ 038@XmlRootElement(name = "proxy") 039@XmlAccessorType(XmlAccessType.FIELD) 040public class CamelProxyFactoryBean extends AbstractCamelFactoryBean<Object> { 041 042 @XmlAttribute 043 private String serviceUrl; 044 @XmlAttribute 045 private String serviceRef; 046 @XmlAttribute 047 private String serviceInterface; 048 @XmlAttribute 049 private Boolean binding; 050 @XmlTransient 051 private Endpoint endpoint; 052 @XmlTransient 053 private Object serviceProxy; 054 @XmlTransient 055 private Producer producer; 056 @XmlTransient 057 private ExtendedBlueprintContainer blueprintContainer; 058 059 public Object getObject() { 060 return serviceProxy; 061 } 062 063 public Class<Object> getObjectType() { 064 return Object.class; 065 } 066 067 protected CamelContext getCamelContextWithId(String camelContextId) { 068 if (blueprintContainer != null) { 069 return (CamelContext) blueprintContainer.getComponentInstance(camelContextId); 070 } 071 return null; 072 } 073 074 @Override 075 protected CamelContext discoverDefaultCamelContext() { 076 if (blueprintContainer != null) { 077 Set<String> ids = BlueprintCamelContextLookupHelper.lookupBlueprintCamelContext(blueprintContainer); 078 if (ids.size() == 1) { 079 // there is only 1 id for a BlueprintCamelContext so fallback and use this 080 return getCamelContextWithId(ids.iterator().next()); 081 } 082 } 083 return null; 084 } 085 086 public void afterPropertiesSet() throws Exception { 087 if (endpoint == null) { 088 getCamelContext(); 089 if (getServiceUrl() == null && getServiceRef() == null) { 090 throw new IllegalArgumentException("serviceUrl or serviceRef must be specified."); 091 } 092 if (getServiceInterface() == null) { 093 throw new IllegalArgumentException("serviceInterface must be specified."); 094 } 095 096 // lookup endpoint or we have the url for it 097 if (getServiceRef() != null) { 098 endpoint = getCamelContext().getRegistry().lookupByNameAndType(getServiceRef(), Endpoint.class); 099 } else { 100 endpoint = getCamelContext().getEndpoint(getServiceUrl()); 101 } 102 103 if (endpoint == null) { 104 throw new IllegalArgumentException("Could not resolve endpoint: " + getServiceUrl()); 105 } 106 } 107 108 // binding is enabled by default 109 boolean bind = getBinding() != null ? getBinding() : true; 110 111 try { 112 // need to start endpoint before we create producer 113 ServiceHelper.startService(endpoint); 114 producer = endpoint.createProducer(); 115 // add and start producer 116 getCamelContext().addService(producer, true, true); 117 Class<?> clazz = blueprintContainer.loadClass(getServiceInterface()); 118 serviceProxy = ProxyHelper.createProxy(endpoint, bind, producer, clazz); 119 } catch (Exception e) { 120 throw new FailedToCreateProducerException(endpoint, e); 121 } 122 } 123 124 public void destroy() throws Exception { 125 // we let CamelContext manage the lifecycle of the producer and shut it down when Camel stops 126 } 127 128 public String getServiceUrl() { 129 return serviceUrl; 130 } 131 132 public void setServiceUrl(String serviceUrl) { 133 this.serviceUrl = serviceUrl; 134 } 135 136 public String getServiceRef() { 137 return serviceRef; 138 } 139 140 public void setServiceRef(String serviceRef) { 141 this.serviceRef = serviceRef; 142 } 143 144 public Boolean getBinding() { 145 return binding; 146 } 147 148 public void setBinding(Boolean binding) { 149 this.binding = binding; 150 } 151 152 public String getServiceInterface() { 153 return serviceInterface; 154 } 155 156 public void setServiceInterface(String serviceInterface) { 157 this.serviceInterface = serviceInterface; 158 } 159 160 public Endpoint getEndpoint() { 161 return endpoint; 162 } 163 164 public void setEndpoint(Endpoint endpoint) { 165 this.endpoint = endpoint; 166 } 167 168 public Producer getProducer() { 169 return producer; 170 } 171 172 public void setProducer(Producer producer) { 173 this.producer = producer; 174 } 175 176 public ExtendedBlueprintContainer getBlueprintContainer() { 177 return blueprintContainer; 178 } 179 180 public void setBlueprintContainer(ExtendedBlueprintContainer blueprintContainer) { 181 this.blueprintContainer = blueprintContainer; 182 } 183 184}