From 55bd2dd8213f34d5f5daff84d74b7501fac25cbf Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 14 Oct 2014 17:03:46 +0100 Subject: [PATCH] Make Eureka into a CF service broker --- .../configuration/CatalogLeaseManager.java | 56 ++++++++++++++++++- .../ServiceBrokerAutoConfiguration.java | 45 --------------- 2 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/springframework/cloud/cloudfoundry/broker/configuration/CatalogLeaseManager.java b/src/main/java/org/springframework/cloud/cloudfoundry/broker/configuration/CatalogLeaseManager.java index 0ff3d29..6071f03 100644 --- a/src/main/java/org/springframework/cloud/cloudfoundry/broker/configuration/CatalogLeaseManager.java +++ b/src/main/java/org/springframework/cloud/cloudfoundry/broker/configuration/CatalogLeaseManager.java @@ -21,21 +21,31 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.cloudfoundry.community.servicebroker.model.Catalog; import org.cloudfoundry.community.servicebroker.model.ServiceDefinition; import org.cloudfoundry.community.servicebroker.service.BeanCatalogService; import org.cloudfoundry.community.servicebroker.service.CatalogService; import org.springframework.cloud.cloudfoundry.broker.FreeServiceDefinitionFactory; +import org.springframework.cloud.netflix.eureka.advice.LeaseManagerLite; +import org.springframework.cloud.netflix.eureka.event.EurekaInstanceCanceledEvent; +import org.springframework.cloud.netflix.eureka.event.EurekaInstanceRegisteredEvent; +import org.springframework.cloud.netflix.eureka.event.EurekaInstanceRenewedEvent; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.event.SmartApplicationListener; import com.netflix.appinfo.InstanceInfo; import com.netflix.appinfo.InstanceInfo.ActionType; -import com.netflix.eureka.lease.LeaseManager; +import com.netflix.eureka.lease.Lease; /** * @author Dave Syer * */ -public class CatalogLeaseManager implements LeaseManager, CatalogService { +public class CatalogLeaseManager implements CatalogService, LeaseManagerLite, SmartApplicationListener { + + private static Log logger = LogFactory.getLog(CatalogLeaseManager.class); private Map definitions = new HashMap(); @@ -55,9 +65,49 @@ public class CatalogLeaseManager implements LeaseManager, CatalogS return new BeanCatalogService(getCatalog()).getServiceDefinition(serviceId); } + @Override + public boolean supportsEventType(Class eventType) { + return EurekaInstanceRegisteredEvent.class.isAssignableFrom(eventType) + || EurekaInstanceCanceledEvent.class.isAssignableFrom(eventType) + || EurekaInstanceRenewedEvent.class.isAssignableFrom(eventType); + } + + @Override + public int getOrder() { + return 0; + } + + @Override + public boolean supportsSourceType(Class sourceType) { + return true; + } + + @Override + public void onApplicationEvent(ApplicationEvent event) { + if (event instanceof EurekaInstanceRegisteredEvent) { + EurekaInstanceRegisteredEvent registered = (EurekaInstanceRegisteredEvent) event; + register(registered.getInstanceInfo(), registered.isReplication()); + } + else if (event instanceof EurekaInstanceCanceledEvent) { + EurekaInstanceCanceledEvent canceled = (EurekaInstanceCanceledEvent) event; + cancel(canceled.getAppName(), canceled.getServerId(), canceled.isReplication()); + } + else if (event instanceof EurekaInstanceRenewedEvent) { + EurekaInstanceRenewedEvent renewed = (EurekaInstanceRenewedEvent) event; + renew(renewed.getAppName(), renewed.getServerId(), renewed.isReplication()); + } + } + + @Override + public void register(InstanceInfo info, boolean isReplication) { + register(info, Lease.DEFAULT_DURATION_IN_SECS, isReplication); + } + @Override public void register(InstanceInfo info, int leaseDuration, boolean isReplication) { + logger.info("Registration request for: " + info.getAppName()); if (!definitions.containsKey(info.getAppName())) { + logger.info("Registering: " + info.getAppName()); ServiceDefinition definition = getServiceDefinition(info); definitions.put(info.getAppName(), definition); values.add(definition); @@ -68,6 +118,7 @@ public class CatalogLeaseManager implements LeaseManager, CatalogS public boolean cancel(String appName, String id, boolean isReplication) { ServiceDefinition definition = definitions.remove(appName); if (definition != null) { + logger.info("Cancelling: " + appName); values.remove(definition); } return true; @@ -76,6 +127,7 @@ public class CatalogLeaseManager implements LeaseManager, CatalogS @Override public boolean renew(String appName, String id, boolean isReplication) { if (definitions.containsKey(appName)) { + logger.info("Renewing: " + appName); definitions.get(appName).getMetadata() .put("timestamp", System.currentTimeMillis()); } diff --git a/src/main/java/org/springframework/cloud/cloudfoundry/broker/configuration/ServiceBrokerAutoConfiguration.java b/src/main/java/org/springframework/cloud/cloudfoundry/broker/configuration/ServiceBrokerAutoConfiguration.java index faf492b..82bea7e 100644 --- a/src/main/java/org/springframework/cloud/cloudfoundry/broker/configuration/ServiceBrokerAutoConfiguration.java +++ b/src/main/java/org/springframework/cloud/cloudfoundry/broker/configuration/ServiceBrokerAutoConfiguration.java @@ -15,8 +15,6 @@ */ package org.springframework.cloud.cloudfoundry.broker.configuration; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; @@ -27,7 +25,6 @@ import org.cloudfoundry.community.servicebroker.service.BeanCatalogService; import org.cloudfoundry.community.servicebroker.service.CatalogService; import org.cloudfoundry.community.servicebroker.service.ServiceInstanceBindingService; import org.cloudfoundry.community.servicebroker.service.ServiceInstanceService; -import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfigureAfter; @@ -44,21 +41,15 @@ import org.springframework.cloud.cloudfoundry.broker.simple.SimpleServiceInstanc import org.springframework.cloud.cloudfoundry.broker.simple.SimpleServiceInstanceRepository; import org.springframework.cloud.cloudfoundry.broker.simple.SimpleServiceInstanceService; import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration; -import org.springframework.cloud.netflix.eureka.advice.PiggybackMethodInterceptor; -import org.springframework.cloud.netflix.eureka.event.EurekaRegistryAvailableEvent; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.stereotype.Component; -import org.springframework.util.ReflectionUtils; import com.netflix.appinfo.EurekaInstanceConfig; import com.netflix.appinfo.InstanceInfo; import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider; -import com.netflix.eureka.PeerAwareInstanceRegistry; import com.netflix.eureka.lease.LeaseManager; /** @@ -157,42 +148,6 @@ public class ServiceBrokerAutoConfiguration { } - @Configuration - @ConditionalOnClass(PeerAwareInstanceRegistry.class) - @ConditionalOnBean(EurekaInstanceConfig.class) - protected static class Initializer implements - ApplicationListener { - - @Autowired - private ApplicationContext applicationContext; - - @Autowired - private CatalogLeaseManager leaseManager; - - @Override - public void onApplicationEvent(EurekaRegistryAvailableEvent event) { - ProxyFactory factory = new ProxyFactory( - PeerAwareInstanceRegistry.getInstance()); - factory.addAdvice(new PiggybackMethodInterceptor(leaseManager, - LeaseManager.class)); - factory.setProxyTargetClass(true); - Field field = ReflectionUtils.findField(PeerAwareInstanceRegistry.class, - "instance"); - try { - // Awful ugly hack to work around lack of DI in eureka - field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); - ReflectionUtils.setField(field, null, factory.getProxy()); - } - catch (Exception e) { - throw new IllegalStateException("Cannot modify instance registry", e); - } - } - - } - @Bean @ConditionalOnMissingBean(ServiceInstanceService.class) public SimpleServiceInstanceService serviceInstanceService(