All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vmware.photon.controller.model.adapters.awsadapter.enumeration.AWSMissingResourcesEnumerationService Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2015-2016 VMware, Inc. All Rights Reserved.
 *
 * 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.
 */

package com.vmware.photon.controller.model.adapters.awsadapter.enumeration;

import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import com.vmware.photon.controller.model.adapters.awsadapter.AWSConstants;
import com.vmware.photon.controller.model.adapters.awsadapter.AWSUriPaths;
import com.vmware.photon.controller.model.resources.ComputeDescriptionService;
import com.vmware.photon.controller.model.resources.ComputeDescriptionService.ComputeDescription;
import com.vmware.photon.controller.model.resources.ComputeService;
import com.vmware.photon.controller.model.resources.ComputeService.ComputeState;
import com.vmware.photon.controller.model.resources.ComputeService.ComputeStateWithDescription;
import com.vmware.photon.controller.model.tasks.EndpointAllocationTaskService;
import com.vmware.xenon.common.Operation;
import com.vmware.xenon.common.OperationJoin.JoinedCompletionHandler;
import com.vmware.xenon.common.OperationSequence;
import com.vmware.xenon.common.ServiceHost.ServiceNotFoundException;
import com.vmware.xenon.common.StatelessService;
import com.vmware.xenon.common.UriUtils;
import com.vmware.xenon.common.Utils;

public class AWSMissingResourcesEnumerationService extends StatelessService {

    public static final String SELF_LINK = AWSUriPaths.AWS_MISSING_RESOURCES_SERVICE;

    public static class Request {
        public ComputeStateWithDescription primaryAccountCompute;
        public Collection missingLinkedAccountIds;
    }

    public class AwsMissingResourcesEnumContext {
        protected AwsMissingResourcesEnumStages stage;
        protected Request request;
        protected Operation requestOp;

        public AwsMissingResourcesEnumContext() {
            this.stage = AwsMissingResourcesEnumStages.CREATE_LINKED_COMPUTES;
        }
    }

    public enum AwsMissingResourcesEnumStages {
        CREATE_LINKED_COMPUTES
    }

    @Override
    public void handlePost(Operation op) {
        if (!op.hasBody()) {
            op.fail(new IllegalArgumentException("body is required"));
            return;
        }
        Object obj = op.getBody(Request.class);
        Request request = Utils.fromJson(obj,
                Request.class);
        AwsMissingResourcesEnumContext context = new AwsMissingResourcesEnumContext();
        context.request = request;
        context.requestOp = op;
        handleRequest(context);
    }

    protected void handleRequest(AwsMissingResourcesEnumContext context) {
        switch (context.stage) {
        case CREATE_LINKED_COMPUTES:
            createLinkedComputeStates(context);
            break;

        default:
            logSevere("Unknown stage while creating the missing linked account compute states");
            break;
        }
    }

    /**
     *  creates new linked account endpoint states of a primary account
     * @param context
     *
     */

    private void createLinkedComputeStates(AwsMissingResourcesEnumContext context) {
        AtomicInteger completionCounter = new AtomicInteger(context.request.missingLinkedAccountIds
                .size());
        AtomicBoolean isSuccessful = new AtomicBoolean(true);
        context.request.missingLinkedAccountIds.forEach(linkedAccountId -> {
            ComputeDescription computeDescription = populateComputeDescription(context,
                    linkedAccountId);
            ComputeState computeState = populateComputeState(context, linkedAccountId);
            computeState.descriptionLink = computeDescription.documentSelfLink;
            Operation csOp = Operation.createPost(this, ComputeService.FACTORY_LINK)
                    .setBody(computeState);
            Operation cdOp = Operation.createPost(this, ComputeDescriptionService.FACTORY_LINK)
                    .setBody(computeDescription);

            JoinedCompletionHandler completionHandler = (ops, exs) -> {
                if (exs != null && !exs.isEmpty()) {
                    logWarning(() -> String.format("Error creating missing resources for"
                            + " account with ID %s.", linkedAccountId));
                    isSuccessful.set(false);
                } else {
                    logInfo(() -> String.format("Created missing resources for account " +
                            "with ID %s.", linkedAccountId));
                }
                if (completionCounter.decrementAndGet() == 0) {
                    if (isSuccessful.get()) {
                        context.requestOp.complete();
                    } else {
                        context.requestOp.fail(new Exception("Failed to create missing resources " +
                                "for atleast one linked account."));
                    }
                }
            };

            Operation.createGet(this, computeDescription.documentSelfLink)
                    .setReferer(this.getUri())
                    .setCompletion((o, e) -> {
                        if (e != null && (e instanceof ServiceNotFoundException
                                || o.getStatusCode() == Operation.STATUS_CODE_NOT_FOUND)) {
                            OperationSequence.create(cdOp).next(csOp)
                                    .setCompletion(completionHandler)
                                    .sendWith(this);
                        } else {
                            OperationSequence.create(csOp).setCompletion(completionHandler)
                                    .sendWith(this);
                        }
                    }).sendWith(this);
        });
    }

    /**
     *  creates a compute description for the identified linked accounts
     * @return
     */
    private ComputeDescription populateComputeDescription(AwsMissingResourcesEnumContext context,
            String linkedAccountId) {
        ComputeDescription cd = new ComputeDescription();
        ComputeStateWithDescription primaryAccountCompute = context.request.primaryAccountCompute;
        cd.regionId = primaryAccountCompute.regionId;
        cd.environmentName = primaryAccountCompute.environmentName;
        cd.tenantLinks = primaryAccountCompute.tenantLinks;
        cd.id = generateUuidFromStr(linkedAccountId + context.request
                .primaryAccountCompute.endpointLink);
        cd.documentSelfLink = UriUtils.buildUriPath(ComputeDescriptionService.FACTORY_LINK, cd.id);
        cd.name = primaryAccountCompute.name + "_" + linkedAccountId;
        cd.endpointLink = primaryAccountCompute.endpointLink;
        if (cd.endpointLinks == null) {
            cd.endpointLinks = new HashSet<>();
        }
        cd.endpointLinks.add(primaryAccountCompute.endpointLink);
        cd.computeHostLink = primaryAccountCompute.computeHostLink;
        return cd;
    }

    /**
     * creates compute state for the identified linked account
     * @return
     */
    private ComputeState populateComputeState(AwsMissingResourcesEnumContext context,
            String linkedAccountId) {
        ComputeState computeState = new ComputeState();
        computeState.id = generateUuidFromStr(linkedAccountId + context.request
                .primaryAccountCompute.endpointLink);
        ComputeState primaryAccountCompute = context.request.primaryAccountCompute;
        computeState.name = primaryAccountCompute.name + "_" + linkedAccountId;
        computeState.resourcePoolLink = primaryAccountCompute.resourcePoolLink;
        computeState.type = primaryAccountCompute.type;
        computeState.adapterManagementReference = primaryAccountCompute.adapterManagementReference;
        computeState.tenantLinks = primaryAccountCompute.tenantLinks;
        computeState.creationTimeMicros = Utils.getNowMicrosUtc();
        computeState.customProperties = new HashMap<>();
        computeState.customProperties.put(AWSConstants.AWS_ACCOUNT_ID_KEY, linkedAccountId);
        computeState.customProperties.put(EndpointAllocationTaskService.CUSTOM_PROP_ENPOINT_TYPE,
                primaryAccountCompute.customProperties
                        .get(EndpointAllocationTaskService.CUSTOM_PROP_ENPOINT_TYPE));
        computeState.customProperties.put(AWSConstants.ACCOUNT_IS_AUTO_DISCOVERED, Boolean.TRUE.toString());
        computeState.documentSelfLink = UriUtils
                .buildUriPath(ComputeService.FACTORY_LINK, computeState.id);
        computeState.endpointLink = primaryAccountCompute.endpointLink;
        if (computeState.endpointLinks == null) {
            computeState.endpointLinks = new HashSet<>();
        }
        computeState.endpointLinks.add(primaryAccountCompute.endpointLink);
        return computeState;
    }

    private String generateUuidFromStr(String linkedAccountId) {
        return UUID.nameUUIDFromBytes(linkedAccountId.getBytes(StandardCharsets.UTF_8))
                .toString().replace("-", "");
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy