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 */ 017 package org.apache.camel.model.loadbalancer; 018 019 import java.util.List; 020 021 import javax.xml.bind.annotation.XmlAccessType; 022 import javax.xml.bind.annotation.XmlAccessorType; 023 import javax.xml.bind.annotation.XmlTransient; 024 import javax.xml.bind.annotation.XmlType; 025 026 import org.apache.camel.AsyncCallback; 027 import org.apache.camel.Exchange; 028 import org.apache.camel.Processor; 029 import org.apache.camel.model.IdentifiedType; 030 import org.apache.camel.processor.loadbalancer.LoadBalancer; 031 import org.apache.camel.spi.RouteContext; 032 import org.apache.camel.util.IntrospectionSupport; 033 import org.apache.camel.util.ObjectHelper; 034 import static org.apache.camel.util.ObjectHelper.notNull; 035 036 /** 037 * Represents an XML <loadBalance/> element 038 */ 039 @XmlType(name = "loadBalancerType") 040 @XmlAccessorType(XmlAccessType.FIELD) 041 public class LoadBalancerType extends IdentifiedType implements LoadBalancer { 042 043 @XmlTransient 044 private LoadBalancer loadBalancer; 045 @XmlTransient 046 private String loadBalancerTypeName; 047 048 public LoadBalancerType() { 049 } 050 051 public LoadBalancerType(LoadBalancer loadBalancer) { 052 this.loadBalancer = loadBalancer; 053 } 054 055 protected LoadBalancerType(String loadBalancerTypeName) { 056 this.loadBalancerTypeName = loadBalancerTypeName; 057 } 058 059 public static LoadBalancer getLoadBalancer(RouteContext routeContext, LoadBalancerType type, String ref) { 060 if (type == null) { 061 notNull(ref, "ref or LoadBalancerType"); 062 LoadBalancer loadBalancer = routeContext.lookup(ref, LoadBalancer.class); 063 if (loadBalancer instanceof LoadBalancerType) { 064 type = (LoadBalancerType) loadBalancer; 065 } else { 066 return loadBalancer; 067 } 068 } 069 return type.getLoadBalancer(routeContext); 070 } 071 072 073 /** 074 * Sets a named property on the data format instance using introspection 075 */ 076 protected void setProperty(Object bean, String name, Object value) { 077 try { 078 IntrospectionSupport.setProperty(bean, name, value); 079 } catch (Exception e) { 080 throw new IllegalArgumentException("Failed to set property " + name + " on " + bean 081 + ". Reason: " + e, e); 082 } 083 } 084 085 /** 086 * Allows derived classes to customize the load balancer 087 */ 088 protected void configureLoadBalancer(LoadBalancer loadBalancer) { 089 } 090 091 public LoadBalancer getLoadBalancer(RouteContext routeContext) { 092 if (loadBalancer == null) { 093 loadBalancer = createLoadBalancer(routeContext); 094 ObjectHelper.notNull(loadBalancer, "loadBalancer"); 095 configureLoadBalancer(loadBalancer); 096 } 097 return loadBalancer; 098 } 099 100 /** 101 * Factory method to create the load balancer instance 102 */ 103 protected LoadBalancer createLoadBalancer(RouteContext routeContext) { 104 if (loadBalancerTypeName != null) { 105 Class type = ObjectHelper.loadClass(loadBalancerTypeName, getClass().getClassLoader()); 106 if (type == null) { 107 throw new IllegalArgumentException("The class " + loadBalancerTypeName + " is not on the classpath! Cannot use the loadBalancer " + this); 108 } 109 return (LoadBalancer) ObjectHelper.newInstance(type); 110 } 111 return null; 112 } 113 114 115 public void addProcessor(Processor processor) { 116 ObjectHelper.notNull(loadBalancer, "loadBalancer"); 117 loadBalancer.addProcessor(processor); 118 } 119 120 public List<Processor> getProcessors() { 121 ObjectHelper.notNull(loadBalancer, "loadBalancer"); 122 return loadBalancer.getProcessors(); 123 } 124 125 public void removeProcessor(Processor processor) { 126 ObjectHelper.notNull(loadBalancer, "loadBalancer"); 127 loadBalancer.removeProcessor(processor); 128 } 129 130 public void process(Exchange exchange) throws Exception { 131 ObjectHelper.notNull(loadBalancer, "loadBalancer"); 132 loadBalancer.process(exchange); 133 } 134 135 public boolean process(Exchange exchange, final AsyncCallback callback) { 136 ObjectHelper.notNull(loadBalancer, "loadBalancer"); 137 138 return loadBalancer.process(exchange, new AsyncCallback() { 139 public void done(boolean doneSynchronously) { 140 // Only handle the async case... 141 if (doneSynchronously) { 142 return; 143 } else { 144 callback.done(doneSynchronously); 145 } 146 } 147 }); 148 149 } 150 151 }