Package com.sequenceiq.cloudbreak.service.stack.connector.aws

Source Code of com.sequenceiq.cloudbreak.service.stack.connector.aws.AwsMetadataSetup

package com.sequenceiq.cloudbreak.service.stack.connector.aws;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.amazonaws.services.autoscaling.AmazonAutoScalingClient;
import com.amazonaws.services.cloudformation.AmazonCloudFormationClient;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Reservation;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import com.sequenceiq.cloudbreak.conf.ReactorConfig;
import com.sequenceiq.cloudbreak.domain.AwsCredential;
import com.sequenceiq.cloudbreak.domain.AwsTemplate;
import com.sequenceiq.cloudbreak.domain.CloudPlatform;
import com.sequenceiq.cloudbreak.domain.InstanceMetaData;
import com.sequenceiq.cloudbreak.domain.Resource;
import com.sequenceiq.cloudbreak.domain.Stack;
import com.sequenceiq.cloudbreak.logger.MDCBuilder;
import com.sequenceiq.cloudbreak.service.stack.connector.MetadataSetup;
import com.sequenceiq.cloudbreak.service.stack.event.MetadataSetupComplete;
import com.sequenceiq.cloudbreak.service.stack.event.MetadataUpdateComplete;
import com.sequenceiq.cloudbreak.service.stack.flow.CoreInstanceMetaData;

import reactor.core.Reactor;
import reactor.event.Event;

@Component
public class AwsMetadataSetup implements MetadataSetup {

    private static final Logger LOGGER = LoggerFactory.getLogger(AwsMetadataSetup.class);

    private static final int POLLING_INTERVAL = 5000;

    @Autowired
    private AwsStackUtil awsStackUtil;

    @Autowired
    private Reactor reactor;

    @Autowired
    private CloudFormationStackUtil cfStackUtil;

    @Override
    public void setupMetadata(Stack stack) {
        MDCBuilder.buildMdcContext(stack);

        Set<CoreInstanceMetaData> coreInstanceMetadata = new HashSet<>();

        AwsTemplate awsTemplate = (AwsTemplate) stack.getTemplate();
        AwsCredential awsCredential = (AwsCredential) stack.getCredential();

        AmazonCloudFormationClient amazonCFClient = awsStackUtil.createCloudFormationClient(awsTemplate.getRegion(), awsCredential);
        AmazonAutoScalingClient amazonASClient = awsStackUtil.createAutoScalingClient(awsTemplate.getRegion(), awsCredential);
        AmazonEC2Client amazonEC2Client = awsStackUtil.createEC2Client(awsTemplate.getRegion(), awsCredential);

        List<String> instanceIds = cfStackUtil.getInstanceIds(stack, amazonASClient, amazonCFClient);
        // If spot priced instances are used, CloudFormation signals completion
        // when the spot requests are made but the instances are not running
        // yet, so we will have to wait until the spot requests are fulfilled
        // (there are as many instances in the ASG as needed)
        if (awsTemplate.getSpotPrice() != null) {
            while (instanceIds.size() < stack.getNodeCount()) {
                LOGGER.info("Spot requests for stack '{}' are not fulfilled yet. Trying to reach instances in the next polling interval.", stack.getId());
                awsStackUtil.sleep(stack, POLLING_INTERVAL);
                instanceIds = cfStackUtil.getInstanceIds(stack, amazonASClient, amazonCFClient);
            }
        }

        DescribeInstancesRequest instancesRequest = new DescribeInstancesRequest().withInstanceIds(instanceIds);
        DescribeInstancesResult instancesResult = amazonEC2Client.describeInstances(instancesRequest);
        for (Reservation reservation : instancesResult.getReservations()) {
            for (com.amazonaws.services.ec2.model.Instance instance : reservation.getInstances()) {
                coreInstanceMetadata.add(new CoreInstanceMetaData(
                        instance.getInstanceId(),
                        instance.getPrivateIpAddress(),
                        instance.getPublicDnsName(),
                        instance.getBlockDeviceMappings().size() - 1,
                        instance.getPrivateDnsName()
                        ));
            }
        }

        LOGGER.info("Publishing {} event [StackId: '{}']", ReactorConfig.METADATA_SETUP_COMPLETE_EVENT, stack.getId());
        reactor.notify(ReactorConfig.METADATA_SETUP_COMPLETE_EVENT,
                Event.wrap(new MetadataSetupComplete(CloudPlatform.AWS, stack.getId(), coreInstanceMetadata)));
    }

    @Override
    public void addNewNodesToMetadata(Stack stack, Set<Resource> resourceList) {
        MDCBuilder.buildMdcContext(stack);
        Set<CoreInstanceMetaData> coreInstanceMetadata = new HashSet<>();
        LOGGER.info("Adding new instances to metadata: [stack: '{}']", stack.getId());
        AmazonEC2Client amazonEC2Client = awsStackUtil.createEC2Client(
                ((AwsTemplate) stack.getTemplate()).getRegion(),
                (AwsCredential) stack.getCredential());
        List<String> instanceIds = cfStackUtil.getInstanceIds(stack);
        DescribeInstancesRequest instancesRequest = new DescribeInstancesRequest().withInstanceIds(instanceIds);
        DescribeInstancesResult instancesResult = amazonEC2Client.describeInstances(instancesRequest);
        for (Reservation reservation : instancesResult.getReservations()) {
            for (final com.amazonaws.services.ec2.model.Instance instance : reservation.getInstances()) {
                boolean metadataExists = FluentIterable.from(stack.getInstanceMetaData()).anyMatch(new Predicate<InstanceMetaData>() {
                    @Override
                    public boolean apply(InstanceMetaData input) {
                        return input.getInstanceId().equals(instance.getInstanceId());
                    }
                });
                if (!metadataExists) {
                    coreInstanceMetadata.add(new CoreInstanceMetaData(
                            instance.getInstanceId(),
                            instance.getPrivateIpAddress(),
                            instance.getPublicDnsName(),
                            instance.getBlockDeviceMappings().size() - 1,
                            instance.getPrivateDnsName()
                            ));
                    LOGGER.info("New instance added to metadata: [stack: '{}', instanceId: '{}']", stack.getId(), instance.getInstanceId());
                }
            }
        }
        LOGGER.info("Publishing {} event [StackId: '{}']", ReactorConfig.METADATA_UPDATE_COMPLETE_EVENT, stack.getId());
        reactor.notify(ReactorConfig.METADATA_UPDATE_COMPLETE_EVENT,
                Event.wrap(new MetadataUpdateComplete(CloudPlatform.AWS, stack.getId(), coreInstanceMetadata)));
    }

    @Override
    public CloudPlatform getCloudPlatform() {
        return CloudPlatform.AWS;
    }

}
TOP

Related Classes of com.sequenceiq.cloudbreak.service.stack.connector.aws.AwsMetadataSetup

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.