Java tutorial
package com.kixeye.chassis.bootstrap.aws; /* * #%L * Chassis Bootstrap * %% * Copyright (C) 2014 KIXEYE, Inc * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import com.amazonaws.regions.Regions; import com.amazonaws.services.ec2.AmazonEC2; import com.amazonaws.services.ec2.AmazonEC2Client; import com.amazonaws.services.ec2.model.Region; import com.amazonaws.services.ec2.model.Tag; import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancing; import com.amazonaws.services.elasticloadbalancing.AmazonElasticLoadBalancingClient; import com.amazonaws.services.elasticloadbalancing.model.ListenerDescription; import com.amazonaws.services.elasticloadbalancing.model.LoadBalancerDescription; import com.amazonaws.util.EC2MetadataUtils; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; import com.kixeye.chassis.bootstrap.BootstrapException; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; /** * Instance context that the server is running in. * * @author dturner@kixeye.com */ public class ServerInstanceContext { private static final Logger LOGGER = LoggerFactory.getLogger(ServerInstanceContext.class); private String environment; private String exhibitorHost; private int exhibitorPort; private String userData; private String instanceId; private String availabilityZone; private String region; private String privateIp; private String publicIp; private String appName; private String version; private AmazonElasticLoadBalancing amazonElasticLoadBalancing; private AmazonEC2 amazonEC2; private Ec2MetadataClient ec2MetadataClient; private ServerInstanceContext() { amazonElasticLoadBalancing = new AmazonElasticLoadBalancingClient(); amazonEC2 = new AmazonEC2Client(); ec2MetadataClient = new Ec2MetadataClient() { @Override public String getAvailabilityZone() { return EC2MetadataUtils.getAvailabilityZone(); } @Override public String getInstanceId() { return EC2MetadataUtils.getInstanceId(); } @Override public String getUserData() { return EC2MetadataUtils.getUserData(); } @Override public String getPrivateIpAddress() { return EC2MetadataUtils.getPrivateIpAddress(); } @Override public String getPublicIpAddress() { for (EC2MetadataUtils.NetworkInterface net : EC2MetadataUtils.getNetworkInterfaces()) { List<String> ips = net.getPublicIPv4s(); if (ips != null && ips.size() > 0) { return ips.get(0); } } return null; } }; init(); } public ServerInstanceContext(Ec2MetadataClient ec2MetadataClient, AmazonEC2 amazonEC2, AmazonElasticLoadBalancing amazonElasticLoadBalancing) { this.ec2MetadataClient = ec2MetadataClient; this.amazonEC2 = amazonEC2; this.amazonElasticLoadBalancing = amazonElasticLoadBalancing; init(); } private void init() { initInstanceMetadata(); initUserData(); initEnvironment(); initExhibitor(); } private void initInstanceMetadata() { LOGGER.info("Initializing instance meta-data..."); this.instanceId = ec2MetadataClient.getInstanceId(); if (this.instanceId == null) { throw new BootstrapException( "Unable to get instance-id from AwsUtils. Either the application is not running in AWS, or AWS is having issues."); } this.privateIp = ec2MetadataClient.getPrivateIpAddress(); this.publicIp = ec2MetadataClient.getPublicIpAddress(); this.availabilityZone = ec2MetadataClient.getAvailabilityZone(); this.region = findRegion(); initAmazonClients(); this.appName = AwsUtils.getInstanceName(this.instanceId, amazonEC2); LOGGER.info("Initialed instance meta-data with: instance-id:{}, az:{}, region:{}, appName:{}", this.instanceId, this.availabilityZone, this.region, this.appName); } private void initAmazonClients() { amazonEC2.setRegion(com.amazonaws.regions.Region.getRegion(Regions.fromName(this.region))); amazonElasticLoadBalancing.setRegion(com.amazonaws.regions.Region.getRegion(Regions.fromName(this.region))); } private String findRegion() { for (Region region : amazonEC2.describeRegions().getRegions()) { if (this.availabilityZone.startsWith(region.getRegionName())) { return region.getRegionName(); } } throw new BootstrapException("Unable to determine region"); } public String getEnvironment() { return environment; } public String getExhibitorHost() { return exhibitorHost; } public String getUserData() { return userData; } private void initExhibitor() { LOGGER.info("Initializing exhibitor info..."); List<LoadBalancerDescription> loadBalancers = AwsUtils.findLoadBalancers(amazonElasticLoadBalancing, new ZookeeperElbFilter(environment)); if (loadBalancers.size() == 0) { LOGGER.info("No Zookeeper ELBs for environment " + environment); return; } else if (loadBalancers.size() != 1) { throw new BootstrapException("Found multiple Zookeeper ELBs for environment " + environment); } LoadBalancerDescription loadBalancer = loadBalancers.get(0); ListenerDescription exhibitorListenerDescription = getExhibitorListenerDescription(loadBalancer); this.exhibitorHost = loadBalancer.getDNSName(); this.exhibitorPort = exhibitorListenerDescription.getListener().getLoadBalancerPort(); LOGGER.info("Initialized exhibitor info with: exhibitorHost: {}, exhibitorPort: {}", exhibitorHost, exhibitorPort); } private ListenerDescription getExhibitorListenerDescription(LoadBalancerDescription loadBalancer) { for (ListenerDescription listenerDescription : loadBalancer.getListenerDescriptions()) { if (listenerDescription.getListener().getProtocol().toLowerCase().equals("http")) { return listenerDescription; } } throw new BootstrapException( "Unable to find any listeners which supports http on ELB " + loadBalancer.getLoadBalancerName()); } private void initUserData() { LOGGER.info("Initializing user-data..."); this.userData = ec2MetadataClient.getUserData(); LOGGER.info("Initialized user-data with: user-data:{}", userData); } private void initEnvironment() { LOGGER.info("Initializing environment..."); try { this.environment = UserData.parse(userData).getEnvironment(); } catch (BootstrapException e) { // If we can't determine the environment from the user-data, that's fine. // It can be passed in with the -e command-line param } LOGGER.info("Initialized environment as: environment:{}", environment); } public static ServerInstanceContext initialize() { try { return new ServerInstanceContext(); } catch (Exception e) { LOGGER.warn("Caught exception initializing AWS Instance Context.", e); return null; } } public void setAppName(String appName) { this.appName = appName; } public void setVersion(String version) { this.version = version; } public void shutdown() { try { amazonEC2.shutdown(); } catch (Exception e) { LOGGER.warn("Failed to shutdown amazonEC2", e); } try { amazonElasticLoadBalancing.shutdown(); } catch (Exception e) { LOGGER.warn("Failed to shutdown amazonElasticLoadBalancing", e); } } public String getRegion() { return region; } public String getInstanceId() { return instanceId; } public String getAvailabilityZone() { return availabilityZone; } public String getVersion() { return version; } public String getAppName() { return appName; } public int getExhibitorPort() { return exhibitorPort; } public String getPrivateIp() { return privateIp; } public String getPublicIp() { return publicIp; } }