Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial version

  • Loading branch information...
commit 7324ed426d437e77647f78b683b9305f1d55e799 0 parents
David Phillips authored
17 .gitignore
... ... @@ -0,0 +1,17 @@
  1 +*.iml
  2 +*.ipr
  3 +*.iws
  4 +target/
  5 +/var
  6 +pom.xml.versionsBackup
  7 +test-output/
  8 +/atlassian-ide-plugin.xml
  9 +.idea
  10 +.DS_Store
  11 +.classpath
  12 +.settings
  13 +.project
  14 +temp-testng-customsuite.xml
  15 +test-output
  16 +.externalToolBuilders
  17 +*~
1  README.txt
... ... @@ -0,0 +1 @@
  1 +Automatically update AWS Elastic Load Balancers (ELB) from Discovery
2  etc/config.properties
... ... @@ -0,0 +1,2 @@
  1 +node.environment=testing
  2 +discovery.uri=http://localhost:8411
2  etc/log.properties
... ... @@ -0,0 +1,2 @@
  1 +com.proofpoint=DEBUG
  2 +com.amazonaws.request=WARN
13 license-header.txt
... ... @@ -0,0 +1,13 @@
  1 +Copyright 2011 Proofpoint, Inc.
  2 +
  3 +Licensed under the Apache License, Version 2.0 (the "License");
  4 +you may not use this file except in compliance with the License.
  5 +You may obtain a copy of the License at
  6 +
  7 + http://www.apache.org/licenses/LICENSE-2.0
  8 +
  9 +Unless required by applicable law or agreed to in writing, software
  10 +distributed under the License is distributed on an "AS IS" BASIS,
  11 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 +See the License for the specific language governing permissions and
  13 +limitations under the License.
165 pom.xml
... ... @@ -0,0 +1,165 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4 + <modelVersion>4.0.0</modelVersion>
  5 + <parent>
  6 + <groupId>com.proofpoint.platform</groupId>
  7 + <artifactId>rest-server-base</artifactId>
  8 + <version>0.46</version>
  9 + </parent>
  10 +
  11 + <properties>
  12 + <main-class>com.proofpoint.discovery.elb.Main</main-class>
  13 + </properties>
  14 +
  15 + <groupId>com.proofpoint.discovery</groupId>
  16 + <artifactId>elb</artifactId>
  17 + <version>1.0-SNAPSHOT</version>
  18 +
  19 + <dependencies>
  20 + <dependency>
  21 + <groupId>com.amazonaws</groupId>
  22 + <artifactId>aws-java-sdk</artifactId>
  23 + <version>1.2.7</version>
  24 + </dependency>
  25 +
  26 + <dependency>
  27 + <groupId>com.google.code.findbugs</groupId>
  28 + <artifactId>jsr305</artifactId>
  29 + <version>1.3.9</version>
  30 + </dependency>
  31 +
  32 + <dependency>
  33 + <groupId>javax.inject</groupId>
  34 + <artifactId>javax.inject</artifactId>
  35 + <version>1</version>
  36 + </dependency>
  37 +
  38 + <dependency>
  39 + <groupId>javax.validation</groupId>
  40 + <artifactId>validation-api</artifactId>
  41 + </dependency>
  42 +
  43 + <dependency>
  44 + <groupId>com.google.guava</groupId>
  45 + <artifactId>guava</artifactId>
  46 + </dependency>
  47 +
  48 + <dependency>
  49 + <groupId>org.weakref</groupId>
  50 + <artifactId>jmxutils</artifactId>
  51 + </dependency>
  52 +
  53 + <dependency>
  54 + <groupId>com.google.inject</groupId>
  55 + <artifactId>guice</artifactId>
  56 + </dependency>
  57 +
  58 + <dependency>
  59 + <groupId>com.proofpoint.platform</groupId>
  60 + <artifactId>bootstrap</artifactId>
  61 + </dependency>
  62 +
  63 + <dependency>
  64 + <groupId>com.proofpoint.platform</groupId>
  65 + <artifactId>configuration</artifactId>
  66 + </dependency>
  67 +
  68 + <dependency>
  69 + <groupId>com.proofpoint.platform</groupId>
  70 + <artifactId>discovery-experimental</artifactId>
  71 + </dependency>
  72 +
  73 + <dependency>
  74 + <groupId>com.proofpoint.platform</groupId>
  75 + <artifactId>log</artifactId>
  76 + </dependency>
  77 +
  78 + <dependency>
  79 + <groupId>com.proofpoint.platform</groupId>
  80 + <artifactId>http-server</artifactId>
  81 + </dependency>
  82 +
  83 + <dependency>
  84 + <groupId>com.proofpoint.platform</groupId>
  85 + <artifactId>jaxrs</artifactId>
  86 + </dependency>
  87 +
  88 + <dependency>
  89 + <groupId>com.proofpoint.platform</groupId>
  90 + <artifactId>json</artifactId>
  91 + </dependency>
  92 +
  93 + <dependency>
  94 + <groupId>com.proofpoint.platform</groupId>
  95 + <artifactId>jmx</artifactId>
  96 + </dependency>
  97 +
  98 + <dependency>
  99 + <groupId>com.proofpoint.platform</groupId>
  100 + <artifactId>node</artifactId>
  101 + </dependency>
  102 +
  103 + <dependency>
  104 + <groupId>com.proofpoint.platform</groupId>
  105 + <artifactId>units</artifactId>
  106 + </dependency>
  107 +
  108 + <dependency>
  109 + <groupId>com.proofpoint.platform</groupId>
  110 + <artifactId>experimental</artifactId>
  111 + </dependency>
  112 +
  113 + <!-- for packaging -->
  114 + <dependency>
  115 + <groupId>com.proofpoint.platform</groupId>
  116 + <artifactId>launcher</artifactId>
  117 + <classifier>bin</classifier>
  118 + <type>tar.gz</type>
  119 + </dependency>
  120 +
  121 + <!-- for testing -->
  122 + <dependency>
  123 + <groupId>org.testng</groupId>
  124 + <artifactId>testng</artifactId>
  125 + <scope>test</scope>
  126 + </dependency>
  127 + </dependencies>
  128 +
  129 + <build>
  130 + <plugins>
  131 + <!--
  132 + Do a license check by running: mvn license:check
  133 + Update the license by running: mvn license:format
  134 + -->
  135 + <plugin>
  136 + <groupId>com.mycila.maven-license-plugin</groupId>
  137 + <artifactId>maven-license-plugin</artifactId>
  138 + <configuration>
  139 + <header>license-header.txt</header>
  140 + <strictCheck>true</strictCheck>
  141 + <mapping>
  142 + <java>SLASHSTAR_STYLE</java>
  143 + </mapping>
  144 + <useDefaultExcludes>true</useDefaultExcludes>
  145 + <excludes>
  146 + <exclude>**/README.txt</exclude>
  147 + <exclude>**/config.properties</exclude>
  148 + <exclude>**/log.properties</exclude>
  149 + <exclude>**/logback-test.xml</exclude>
  150 + <exclude>**/.gitignore</exclude>
  151 + <exclude>var/**</exclude>
  152 + </excludes>
  153 + </configuration>
  154 + <executions>
  155 + <execution>
  156 + <phase>test</phase>
  157 + <goals>
  158 + <goal>check</goal>
  159 + </goals>
  160 + </execution>
  161 + </executions>
  162 + </plugin>
  163 + </plugins>
  164 + </build>
  165 +</project>
116 src/main/java/com/proofpoint/discovery/elb/Ec2Location.java
... ... @@ -0,0 +1,116 @@
  1 +/*
  2 + * Copyright 2011 Proofpoint, Inc.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.proofpoint.discovery.elb;
  17 +
  18 +import com.google.common.base.Joiner;
  19 +import com.google.common.base.Objects;
  20 +import com.google.common.base.Splitter;
  21 +import com.google.common.collect.ImmutableList;
  22 +
  23 +import javax.annotation.concurrent.Immutable;
  24 +import java.util.List;
  25 +
  26 +import static com.google.common.base.Objects.equal;
  27 +import static com.google.common.base.Preconditions.checkNotNull;
  28 +
  29 +/**
  30 + * EC2 Galaxy location: {@code ec2/region/zone/instance/slot}
  31 + */
  32 +@Immutable
  33 +@SuppressWarnings("UnusedDeclaration")
  34 +public class Ec2Location
  35 +{
  36 + private final String region;
  37 + private final String availabilityZone;
  38 + private final String instanceId;
  39 + private final String slot;
  40 +
  41 + public Ec2Location(String region, String availabilityZone, String instanceId, String slot)
  42 + {
  43 + this.region = checkNotNull(region, "region is null");
  44 + this.availabilityZone = checkNotNull(availabilityZone, "availabilityZone is null");
  45 + this.instanceId = checkNotNull(instanceId, "instanceId is null");
  46 + this.slot = checkNotNull(slot, "slot is null");
  47 + }
  48 +
  49 + public String getRegion()
  50 + {
  51 + return region;
  52 + }
  53 +
  54 + public String getAvailabilityZone()
  55 + {
  56 + return availabilityZone;
  57 + }
  58 +
  59 + public String getInstanceId()
  60 + {
  61 + return instanceId;
  62 + }
  63 +
  64 + public String getSlot()
  65 + {
  66 + return slot;
  67 + }
  68 +
  69 + @Override
  70 + public boolean equals(Object o)
  71 + {
  72 + if (this == o) {
  73 + return true;
  74 + }
  75 + if (!(o instanceof Ec2Location)) {
  76 + return false;
  77 + }
  78 + Ec2Location x = (Ec2Location) o;
  79 + return equal(region, x.region) &&
  80 + equal(availabilityZone, x.availabilityZone) &&
  81 + equal(instanceId, x.instanceId) &&
  82 + equal(slot, x.slot);
  83 + }
  84 +
  85 + @Override
  86 + public int hashCode()
  87 + {
  88 + return Objects.hashCode(region, availabilityZone, instanceId, slot);
  89 + }
  90 +
  91 + @Override
  92 + public String toString()
  93 + {
  94 + return Joiner.on('/').join("ec2", region, availabilityZone, instanceId, slot);
  95 + }
  96 +
  97 + /**
  98 + * Parse an EC2 location string into an {@link Ec2Location}.
  99 + *
  100 + * @param location the location string
  101 + * @return the parsed location
  102 + * @throws IllegalArgumentException if the location string is invalid
  103 + */
  104 + public static Ec2Location valueOf(String location)
  105 + throws IllegalArgumentException
  106 + {
  107 + List<String> parts = ImmutableList.copyOf(Splitter.on('/').split(location).iterator());
  108 + if (parts.size() != 5) {
  109 + throw new IllegalArgumentException("wrong number of parts");
  110 + }
  111 + if (!parts.get(0).equals("ec2")) {
  112 + throw new IllegalArgumentException("not an EC2 location");
  113 + }
  114 + return new Ec2Location(parts.get(1), parts.get(2), parts.get(3), parts.get(4));
  115 + }
  116 +}
241 src/main/java/com/proofpoint/discovery/elb/ElasticLoadBalancerUpdater.java
... ... @@ -0,0 +1,241 @@
  1 +/*
  2 + * Copyright 2011 Proofpoint, Inc.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.proofpoint.discovery.elb;
  17 +
  18 +import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancing;
  19 +import com.amazonaws.services.elasticloadbalancing.model.DeregisterInstancesFromLoadBalancerRequest;
  20 +import com.amazonaws.services.elasticloadbalancing.model.Instance;
  21 +import com.amazonaws.services.elasticloadbalancing.model.Listener;
  22 +import com.amazonaws.services.elasticloadbalancing.model.ListenerDescription;
  23 +import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription;
  24 +import com.amazonaws.services.elasticloadbalancing.model.RegisterInstancesWithLoadBalancerRequest;
  25 +import com.google.common.base.Function;
  26 +import com.google.common.base.Splitter;
  27 +import com.google.common.util.concurrent.ThreadFactoryBuilder;
  28 +import com.proofpoint.discovery.client.DiscoveryClient;
  29 +import com.proofpoint.discovery.client.ServiceDescriptor;
  30 +import com.proofpoint.discovery.client.ServiceDescriptors;
  31 +import com.proofpoint.log.Logger;
  32 +import com.proofpoint.node.NodeInfo;
  33 +import com.proofpoint.units.Duration;
  34 +
  35 +import javax.annotation.PostConstruct;
  36 +import javax.annotation.PreDestroy;
  37 +import javax.annotation.concurrent.Immutable;
  38 +import javax.inject.Inject;
  39 +import java.io.IOException;
  40 +import java.net.URI;
  41 +import java.util.Collection;
  42 +import java.util.List;
  43 +import java.util.Map;
  44 +import java.util.Set;
  45 +import java.util.concurrent.Executors;
  46 +import java.util.concurrent.ScheduledExecutorService;
  47 +import java.util.concurrent.TimeUnit;
  48 +
  49 +import static com.google.common.base.Preconditions.checkNotNull;
  50 +import static com.google.common.collect.ImmutableList.copyOf;
  51 +import static com.google.common.collect.Iterables.transform;
  52 +import static com.google.common.collect.Sets.difference;
  53 +import static com.google.common.collect.Sets.newHashSet;
  54 +
  55 +@Immutable
  56 +public class ElasticLoadBalancerUpdater
  57 +{
  58 + private static final Logger log = Logger.get(ElasticLoadBalancerUpdater.class);
  59 +
  60 + private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(
  61 + new ThreadFactoryBuilder().setNameFormat("ElasticLoadBalancerUpdater-%s").build());
  62 +
  63 + private final AmazonElasticLoadBalancing elbClient;
  64 + private final NodeInfo nodeInfo;
  65 + private final DiscoveryClient discoveryClient;
  66 + private final Duration updateInterval;
  67 +
  68 + @Inject
  69 + public ElasticLoadBalancerUpdater(AmazonElasticLoadBalancing elbClient, NodeInfo nodeInfo, DiscoveryClient discoveryClient, ServerConfig config)
  70 + {
  71 + this.elbClient = checkNotNull(elbClient, "elbClient is null");
  72 + this.nodeInfo = checkNotNull(nodeInfo, "nodeInfo is null");
  73 + this.discoveryClient = checkNotNull(discoveryClient, "discoveryClient is null");
  74 + checkNotNull(config, "config is null");
  75 + updateInterval = config.getUpdateInterval();
  76 + }
  77 +
  78 + @PostConstruct
  79 + public void start()
  80 + {
  81 + Runnable updater = new Runnable()
  82 + {
  83 + @Override
  84 + public void run()
  85 + {
  86 + try {
  87 + update();
  88 + }
  89 + catch (Exception e) {
  90 + log.error(e, "update failed");
  91 + }
  92 + }
  93 + };
  94 + executor.scheduleAtFixedRate(updater, 0, (long) updateInterval.toMillis(), TimeUnit.MILLISECONDS);
  95 + }
  96 +
  97 + @PreDestroy
  98 + public void destroy()
  99 + throws IOException
  100 + {
  101 + executor.shutdown();
  102 + }
  103 +
  104 + public void update()
  105 + throws Exception
  106 + {
  107 + for (LoadBalancerDescription loadBalancer : elbClient.describeLoadBalancers().getLoadBalancerDescriptions()) {
  108 + // split ELB name into parts
  109 + String elbName = loadBalancer.getLoadBalancerName();
  110 + List<String> parts = copyOf(Splitter.on('-').split(elbName).iterator());
  111 + if (parts.size() != 3) {
  112 + log.debug("ignoring load balancer: %s", elbName);
  113 + continue;
  114 + }
  115 + String environment = parts.get(0);
  116 + String type = parts.get(1);
  117 + String pool = parts.get(2);
  118 + log.debug("found load balancer: %s", elbName);
  119 +
  120 + // check against environment
  121 + if (!environment.equals(nodeInfo.getEnvironment())) {
  122 + continue;
  123 + }
  124 +
  125 + // look for services in discovery
  126 + ServiceDescriptors services = discoveryClient.getServices(type, pool).get(1, TimeUnit.SECONDS);
  127 +
  128 + // map services to instances
  129 + Set<String> instances = newHashSet();
  130 + for (ServiceDescriptor descriptor : services.getServiceDescriptors()) {
  131 + String instanceId = extractEc2InstanceId(descriptor.getLocation());
  132 + if (instanceId == null) {
  133 + log.warn("invalid EC2 location: %s", descriptor.getLocation());
  134 + continue;
  135 + }
  136 +
  137 + // verify load balancer listeners against the service announcement
  138 + boolean valid = true;
  139 + for (Listener listener : transform(loadBalancer.getListenerDescriptions(), GET_LISTENER)) {
  140 + if (!serviceExistsForListener(listener, descriptor.getProperties())) {
  141 + valid = false;
  142 + log.warn("load balancer %s listener %s does not match service %s", elbName, listener, descriptor);
  143 + }
  144 + }
  145 + if (valid) {
  146 + instances.add(instanceId);
  147 + }
  148 + }
  149 +
  150 + // get registered instances
  151 + Set<String> registeredInstances = newHashSet(transform(loadBalancer.getInstances(), GET_INSTANCE_ID));
  152 +
  153 + // add new instances to load balancer
  154 + Collection<String> addInstances = difference(instances, registeredInstances);
  155 + if (!addInstances.isEmpty()) {
  156 + registerInstances(elbName, addInstances);
  157 + }
  158 +
  159 + // remove missing instances from load balancer
  160 + Collection<String> removeInstances = difference(registeredInstances, instances);
  161 + if (!removeInstances.isEmpty()) {
  162 + deregisterInstances(elbName, removeInstances);
  163 + }
  164 + }
  165 + }
  166 +
  167 + private static boolean serviceExistsForListener(Listener listener, Map<String, String> properties)
  168 + {
  169 + // TODO: use instanceProtocol when supported by AWS library
  170 + String protocol = listener.getProtocol().toLowerCase();
  171 + if ((!protocol.equals("http")) && (!protocol.equals("https"))) {
  172 + return false;
  173 + }
  174 + URI uri = extractUri(properties.get(protocol));
  175 + return (uri != null) && (uri.getPort() == listener.getInstancePort());
  176 + }
  177 +
  178 + private void registerInstances(String elbName, Collection<String> instanceIds)
  179 + {
  180 + List<Instance> instances = copyOf(transform(instanceIds, NEW_INSTANCE));
  181 + log.debug("adding instances to load balancer: %s: %s", elbName, instanceIds);
  182 + elbClient.registerInstancesWithLoadBalancer(new RegisterInstancesWithLoadBalancerRequest(elbName, instances));
  183 + log.info("added instances to load balancer: %s: %s", elbName, instanceIds);
  184 + }
  185 +
  186 + private void deregisterInstances(String elbName, Collection<String> instanceIds)
  187 + {
  188 + List<Instance> instances = copyOf(transform(instanceIds, NEW_INSTANCE));
  189 + log.debug("removing instances from load balancer: %s: %s", elbName, instanceIds);
  190 + elbClient.deregisterInstancesFromLoadBalancer(new DeregisterInstancesFromLoadBalancerRequest(elbName, instances));
  191 + log.info("removed instances from load balancer: %s: %s", elbName, instanceIds);
  192 + }
  193 +
  194 + private static String extractEc2InstanceId(String location)
  195 + {
  196 + try {
  197 + return Ec2Location.valueOf(location).getInstanceId();
  198 + }
  199 + catch (IllegalArgumentException e) {
  200 + return null;
  201 + }
  202 + }
  203 +
  204 + private static URI extractUri(String uri)
  205 + {
  206 + try {
  207 + return new URI(uri);
  208 + }
  209 + catch (Exception e) {
  210 + return null;
  211 + }
  212 + }
  213 +
  214 + private static Function<ListenerDescription, Listener> GET_LISTENER = new Function<ListenerDescription, Listener>()
  215 + {
  216 + @Override
  217 + public Listener apply(ListenerDescription input)
  218 + {
  219 + return input.getListener();
  220 + }
  221 + };
  222 +
  223 + private static Function<Instance, String> GET_INSTANCE_ID = new Function<Instance, String>()
  224 + {
  225 + @Override
  226 + public String apply(Instance input)
  227 + {
  228 + return input.getInstanceId();
  229 + }
  230 + };
  231 +
  232 + private static Function<String, Instance> NEW_INSTANCE = new Function<String, Instance>()
  233 + {
  234 +
  235 + @Override
  236 + public Instance apply(String input)
  237 + {
  238 + return new Instance(input);
  239 + }
  240 + };
  241 +}
49 src/main/java/com/proofpoint/discovery/elb/Main.java
... ... @@ -0,0 +1,49 @@
  1 +/*
  2 + * Copyright 2011 Proofpoint, Inc.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.proofpoint.discovery.elb;
  17 +
  18 +import com.google.inject.Injector;
  19 +import com.proofpoint.bootstrap.Bootstrap;
  20 +import com.proofpoint.discovery.client.Announcer;
  21 +import com.proofpoint.discovery.client.DiscoveryModule;
  22 +import com.proofpoint.experimental.jmx.JmxHttpModule;
  23 +import com.proofpoint.http.server.HttpServerModule;
  24 +import com.proofpoint.jaxrs.JaxrsModule;
  25 +import com.proofpoint.jmx.JmxModule;
  26 +import com.proofpoint.json.JsonModule;
  27 +import com.proofpoint.node.NodeModule;
  28 +import org.weakref.jmx.guice.MBeanModule;
  29 +
  30 +public class Main
  31 +{
  32 + public static void main(String[] args)
  33 + throws Exception
  34 + {
  35 + Bootstrap app = new Bootstrap(
  36 + new NodeModule(),
  37 + new DiscoveryModule(),
  38 + new HttpServerModule(),
  39 + new JsonModule(),
  40 + new JaxrsModule(),
  41 + new MBeanModule(),
  42 + new JmxModule(),
  43 + new JmxHttpModule(),
  44 + new MainModule());
  45 +
  46 + Injector injector = app.strictConfig().initialize();
  47 + injector.getInstance(Announcer.class).start();
  48 + }
  49 +}
53 src/main/java/com/proofpoint/discovery/elb/MainModule.java
... ... @@ -0,0 +1,53 @@
  1 +/*
  2 + * Copyright 2011 Proofpoint, Inc.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.proofpoint.discovery.elb;
  17 +
  18 +import com.amazonaws.auth.AWSCredentials;
  19 +import com.amazonaws.auth.BasicAWSCredentials;
  20 +import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancing;
  21 +import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient;
  22 +import com.google.inject.Binder;
  23 +import com.google.inject.Module;
  24 +import com.google.inject.Provides;
  25 +import com.google.inject.Scopes;
  26 +
  27 +import static com.proofpoint.configuration.ConfigurationModule.bindConfig;
  28 +
  29 +public class MainModule
  30 + implements Module
  31 +{
  32 + public void configure(Binder binder)
  33 + {
  34 + binder.requireExplicitBindings();
  35 + binder.disableCircularProxies();
  36 +
  37 + binder.bind(ElasticLoadBalancerUpdater.class).in(Scopes.SINGLETON);
  38 +
  39 + bindConfig(binder).to(ServerConfig.class);
  40 + }
  41 +
  42 + @Provides
  43 + private AmazonElasticLoadBalancing provideAmazonElasticLoadBalancing(AWSCredentials awsCredentials)
  44 + {
  45 + return new AmazonElasticLoadBalancingClient(awsCredentials);
  46 + }
  47 +
  48 + @Provides
  49 + private AWSCredentials provideAwsCredentials(ServerConfig config)
  50 + {
  51 + return new BasicAWSCredentials(config.getAwsAccessKey(), config.getAwsSecretKey());
  52 + }
  53 +}
74 src/main/java/com/proofpoint/discovery/elb/ServerConfig.java
... ... @@ -0,0 +1,74 @@
  1 +/*
  2 + * Copyright 2011 Proofpoint, Inc.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.proofpoint.discovery.elb;
  17 +
  18 +import com.proofpoint.configuration.Config;
  19 +import com.proofpoint.configuration.ConfigDescription;
  20 +import com.proofpoint.units.Duration;
  21 +import com.proofpoint.units.MinDuration;
  22 +
  23 +import javax.validation.constraints.NotNull;
  24 +import java.util.concurrent.TimeUnit;
  25 +
  26 +public class ServerConfig
  27 +{
  28 + private Duration updateInterval = new Duration(30, TimeUnit.SECONDS);
  29 + private String awsAccessKey;
  30 + private String awsSecretKey;
  31 +
  32 + @Config("elb.update-interval")
  33 + @ConfigDescription("time between updates")
  34 + public ServerConfig setUpdateInterval(Duration updateInterval)
  35 + {
  36 + this.updateInterval = updateInterval;
  37 + return this;
  38 + }
  39 +
  40 + @NotNull
  41 + @MinDuration("1s")
  42 + public Duration getUpdateInterval()
  43 + {
  44 + return updateInterval;
  45 + }
  46 +
  47 + @Config("elb.aws-access-key")
  48 + @ConfigDescription("AWS access key")
  49 + public ServerConfig setAwsAccessKey(String awsAccessKey)
  50 + {
  51 + this.awsAccessKey = awsAccessKey;
  52 + return this;
  53 + }
  54 +
  55 + @NotNull
  56 + public String getAwsAccessKey()
  57 + {
  58 + return awsAccessKey;
  59 + }
  60 +
  61 + @Config("elb.aws-secret-key")
  62 + @ConfigDescription("AWS secret key")
  63 + public ServerConfig setAwsSecretKey(String awsSecretKey)
  64 + {
  65 + this.awsSecretKey = awsSecretKey;
  66 + return this;
  67 + }
  68 +
  69 + @NotNull
  70 + public String getAwsSecretKey()
  71 + {
  72 + return awsSecretKey;
  73 + }
  74 +}
60 src/test/java/com/proofpoint/discovery/elb/TestServer.java
... ... @@ -0,0 +1,60 @@
  1 +/*
  2 + * Copyright 2011 Proofpoint, Inc.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.proofpoint.discovery.elb;
  17 +
  18 +import com.google.common.collect.ImmutableMap;
  19 +import com.google.inject.Guice;
  20 +import com.google.inject.Injector;
  21 +import com.proofpoint.configuration.ConfigurationFactory;
  22 +import com.proofpoint.configuration.ConfigurationModule;
  23 +import com.proofpoint.discovery.client.testing.TestingDiscoveryModule;
  24 +import com.proofpoint.http.server.testing.TestingHttpServerModule;
  25 +import com.proofpoint.jaxrs.JaxrsModule;
  26 +import com.proofpoint.json.JsonModule;
  27 +import com.proofpoint.node.testing.TestingNodeModule;
  28 +import org.testng.Assert;
  29 +import org.testng.annotations.BeforeMethod;
  30 +import org.testng.annotations.Test;
  31 +
  32 +public class TestServer
  33 +{
  34 + @BeforeMethod
  35 + public void setup()
  36 + throws Exception
  37 + {
  38 + ImmutableMap<String, String> config = ImmutableMap.<String, String>builder()
  39 + .put("elb.aws-access-key", "fake-aws-access-key")
  40 + .put("elb.aws-secret-key", "fake-aws-secret-key")
  41 + .build();
  42 +
  43 + Injector injector = Guice.createInjector(
  44 + new TestingNodeModule(),
  45 + new TestingDiscoveryModule(),
  46 + new TestingHttpServerModule(),
  47 + new JsonModule(),
  48 + new JaxrsModule(),
  49 + new MainModule(),
  50 + new ConfigurationModule(new ConfigurationFactory(config)));
  51 +
  52 + injector.getInstance(ElasticLoadBalancerUpdater.class);
  53 + }
  54 +
  55 + @Test
  56 + public void testSuccess()
  57 + {
  58 + Assert.assertTrue(true);
  59 + }
  60 +}
54 src/test/java/com/proofpoint/discovery/elb/TestServerConfig.java
... ... @@ -0,0 +1,54 @@
  1 +/*
  2 + * Copyright 2011 Proofpoint, Inc.
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package com.proofpoint.discovery.elb;
  17 +
  18 +import com.google.common.collect.ImmutableMap;
  19 +import com.proofpoint.configuration.testing.ConfigAssertions;
  20 +import com.proofpoint.units.Duration;
  21 +import org.testng.annotations.Test;
  22 +
  23 +import java.util.Map;
  24 +import java.util.concurrent.TimeUnit;
  25 +
  26 +public class TestServerConfig
  27 +{
  28 + @Test
  29 + public void testDefaults()
  30 + {
  31 + ConfigAssertions.assertRecordedDefaults(ConfigAssertions.recordDefaults(ServerConfig.class)
  32 + .setUpdateInterval(new Duration(30, TimeUnit.SECONDS))
  33 + .setAwsAccessKey(null)
  34 + .setAwsSecretKey(null)
  35 + );
  36 + }
  37 +
  38 + @Test
  39 + public void testExplicitPropertyMappings()
  40 + {
  41 + Map<String, String> properties = new ImmutableMap.Builder<String, String>()
  42 + .put("elb.update-interval", "2s")
  43 + .put("elb.aws-access-key", "my-access-key")
  44 + .put("elb.aws-secret-key", "my-secret-key")
  45 + .build();
  46 +
  47 + ServerConfig expected = new ServerConfig()
  48 + .setUpdateInterval(new Duration(2, TimeUnit.SECONDS))
  49 + .setAwsAccessKey("my-access-key")
  50 + .setAwsSecretKey("my-secret-key");
  51 +
  52 + ConfigAssertions.assertFullMapping(properties, expected);
  53 + }
  54 +}
11 src/test/resources/logback-test.xml
... ... @@ -0,0 +1,11 @@
  1 +<configuration>
  2 + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  3 + <encoder>
  4 + <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
  5 + </encoder>
  6 + </appender>
  7 +
  8 + <root level="INFO">
  9 + <appender-ref ref="STDOUT"/>
  10 + </root>
  11 +</configuration>

0 comments on commit 7324ed4

Please sign in to comment.
Something went wrong with that request. Please try again.