com.vmware.photon.controller.model.adapters.vsphere.TestVSphereProvisionWithStaticIpTask.java Source code

Java tutorial

Introduction

Here is the source code for com.vmware.photon.controller.model.adapters.vsphere.TestVSphereProvisionWithStaticIpTask.java

Source

/*
 * 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.vsphere;

import static org.junit.Assert.assertEquals;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.apache.commons.io.IOUtils;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;

import com.vmware.photon.controller.model.ComputeProperties;
import com.vmware.photon.controller.model.adapterapi.EnumerationAction;
import com.vmware.photon.controller.model.adapters.vsphere.util.VimNames;
import com.vmware.photon.controller.model.resources.ComputeDescriptionService;
import com.vmware.photon.controller.model.resources.ComputeDescriptionService.ComputeDescription;
import com.vmware.photon.controller.model.resources.ComputeDescriptionService.ComputeDescription.ComputeType;
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.PowerState;
import com.vmware.photon.controller.model.resources.DiskService;
import com.vmware.photon.controller.model.resources.DiskService.DiskState;
import com.vmware.photon.controller.model.resources.DiskService.DiskState.BootConfig;
import com.vmware.photon.controller.model.resources.DiskService.DiskState.BootConfig.FileEntry;
import com.vmware.photon.controller.model.resources.DiskService.DiskType;
import com.vmware.photon.controller.model.resources.NetworkInterfaceDescriptionService.IpAssignment;
import com.vmware.photon.controller.model.resources.NetworkInterfaceDescriptionService.NetworkInterfaceDescription;
import com.vmware.photon.controller.model.resources.NetworkService;
import com.vmware.photon.controller.model.resources.NetworkService.NetworkState;
import com.vmware.photon.controller.model.resources.SubnetService.SubnetState;
import com.vmware.photon.controller.model.tasks.ProvisionComputeTaskService.ProvisionComputeTaskState;
import com.vmware.photon.controller.model.tasks.ResourceEnumerationTaskService;
import com.vmware.photon.controller.model.tasks.ResourceEnumerationTaskService.ResourceEnumerationTaskState;
import com.vmware.photon.controller.model.tasks.TaskOption;
import com.vmware.photon.controller.model.tasks.TestUtils;
import com.vmware.xenon.common.Operation;
import com.vmware.xenon.common.ServiceDocument;
import com.vmware.xenon.common.UriUtils;
import com.vmware.xenon.common.Utils;
import com.vmware.xenon.services.common.QueryTask;
import com.vmware.xenon.services.common.QueryTask.Query;
import com.vmware.xenon.services.common.QueryTask.QuerySpecification;
import com.vmware.xenon.services.common.QueryTask.QuerySpecification.QueryOption;
import com.vmware.xenon.services.common.ServiceUriPaths;

/**
 * This test provisions a VM from a template. It populates the OVF environment with a "user-data"
 * property.
 */
@Ignore
public class TestVSphereProvisionWithStaticIpTask extends BaseVSphereAdapterTest {
    private ComputeDescription computeHostDescription;
    private ComputeState computeHost;
    private NetworkState network;

    @Test
    public void deployByCloningWithCustomization() throws Throwable {
        this.nicDescription = new NetworkInterfaceDescription();
        this.nicDescription.assignment = IpAssignment.STATIC;
        this.nicDescription.address = "10.0.0.2";

        this.subnet = new SubnetState();
        this.subnet.dnsSearchDomains = Collections.singleton("local");
        this.subnet.name = "my-subnet";
        this.subnet.gatewayAddress = "10.0.0.1";
        this.subnet.dnsServerAddresses = Collections.singleton("8.8.8.8");
        this.subnet.domain = "local";
        this.subnet.subnetCIDR = "10.0.0.0/24";

        // Create a resource pool where the VM will be housed
        this.resourcePool = createResourcePool();
        this.auth = createAuth();

        this.computeHostDescription = createComputeHostDescription();
        this.computeHost = createComputeHost();

        // enumerate all resources hoping to find the template
        doRefresh();
        snapshotFactoryState("networks", NetworkService.class);

        // find the template by vm name
        // template must have vm-tools and cloud-config installed
        ComputeState template = findTemplate();

        this.network = fetchServiceState(NetworkState.class, findPortGroup(networkId));

        // create instance by cloning
        ComputeDescription vmDescription = createVmDescription();
        ComputeState vm = createVmState(vmDescription, template.documentSelfLink);

        // kick off a provision task to do the actual VM creation
        ProvisionComputeTaskState outTask = createProvisionTask(vm);
        awaitTaskEnd(outTask);

        vm = getComputeState(vm);

        if (!isMock()) {
            assertEquals(vm.address, this.nicDescription.address);
        }

        deleteVmAndWait(vm);
    }

    private <T extends ServiceDocument> T fetchServiceState(Class<T> bodyType, String networkLink) {
        Operation op = Operation.createGet(this.host, networkLink);
        op = this.host.waitForResponse(op);
        return op.getBody(bodyType);
    }

    protected String findPortGroup(String name) throws Throwable {
        Query q = Query.Builder.create().addKindFieldClause(NetworkState.class)
                .addFieldClause(QuerySpecification.buildCompositeFieldName(
                        NetworkState.FIELD_NAME_CUSTOM_PROPERTIES, CustomProperties.TYPE), VimNames.TYPE_PORTGROUP)
                .addFieldClause(NetworkState.FIELD_NAME_NAME, name).build();

        QueryTask task = QueryTask.Builder.createDirectTask().setQuery(q).build();

        Operation op = Operation.createPost(this.host, ServiceUriPaths.CORE_QUERY_TASKS).setBody(task);

        Operation result = this.host.waitForResponse(op);

        try {
            return result.getBody(QueryTask.class).results.documentLinks.get(0);
        } catch (Exception e) {
            Assert.fail(e.getMessage());
            return null;
        }
    }

    private ComputeState findTemplate() throws InterruptedException, ExecutionException, TimeoutException {
        String templateVmName = System.getProperty("vc.templateVmName");
        QuerySpecification qs = new QuerySpecification();
        qs.options.add(QueryOption.EXPAND_CONTENT);

        qs.query.addBooleanClause(Query.Builder.create()
                .addFieldClause(ComputeState.FIELD_NAME_NAME, templateVmName)
                .addFieldClause(ServiceDocument.FIELD_NAME_KIND, Utils.buildKind(ComputeState.class)).build());
        QueryTask qt = QueryTask.create(qs).setDirect(true);

        Operation op = Operation.createPost(UriUtils.buildUri(this.host, ServiceUriPaths.CORE_QUERY_TASKS))
                .setBody(qt);

        QueryTask result = this.host.sendWithFuture(op).thenApply(o -> o.getBody(QueryTask.class)).get(10,
                TimeUnit.SECONDS);

        return Utils.fromJson(result.results.documents.values().iterator().next(), ComputeState.class);
    }

    private void doRefresh() throws Throwable {
        ResourceEnumerationTaskState task = new ResourceEnumerationTaskState();
        task.adapterManagementReference = this.computeHost.adapterManagementReference;

        if (isMock()) {
            task.options = EnumSet.of(TaskOption.IS_MOCK);
        }

        task.enumerationAction = EnumerationAction.REFRESH;
        task.parentComputeLink = this.computeHost.documentSelfLink;
        task.resourcePoolLink = this.resourcePool.documentSelfLink;

        ResourceEnumerationTaskState outTask = TestUtils.doPost(this.host, task, ResourceEnumerationTaskState.class,
                UriUtils.buildUri(this.host, ResourceEnumerationTaskService.FACTORY_LINK));

        this.host.waitForFinishedTask(ResourceEnumerationTaskState.class, outTask.documentSelfLink);
    }

    private ComputeState createVmState(ComputeDescription vmDescription, String templateComputeLink)
            throws Throwable {
        ComputeState computeState = new ComputeState();
        computeState.id = vmDescription.name;
        computeState.documentSelfLink = computeState.id;
        computeState.descriptionLink = vmDescription.documentSelfLink;
        computeState.resourcePoolLink = this.resourcePool.documentSelfLink;
        computeState.adapterManagementReference = getAdapterManagementReference();
        computeState.name = vmDescription.name;

        computeState.powerState = PowerState.ON;

        computeState.parentLink = this.computeHost.documentSelfLink;

        computeState.networkInterfaceLinks = new ArrayList<>(1);
        computeState.networkInterfaceLinks
                .add(createNic("nic for " + this.networkId, this.network.documentSelfLink));

        computeState.diskLinks = new ArrayList<>(1);

        Query q = createQueryForComputeResource();
        CustomProperties.of(computeState).put(ComputeProperties.RESOURCE_GROUP_NAME, this.vcFolder)
                .put(ComputeProperties.PLACEMENT_LINK, findFirstMatching(q, ComputeState.class).documentSelfLink)
                .put(CustomProperties.TEMPLATE_LINK, templateComputeLink);

        ComputeState returnState = TestUtils.doPost(this.host, computeState, ComputeState.class,
                UriUtils.buildUri(this.host, ComputeService.FACTORY_LINK));
        return returnState;
    }

    private DiskState createBootDisk(String cloudConfig) throws Throwable {
        DiskState res = new DiskState();
        res.bootOrder = 1;
        res.type = DiskType.HDD;
        res.id = res.name = "boot-disk";
        res.sourceImageReference = URI.create("file:///dev/null");

        res.bootConfig = new BootConfig();
        res.bootConfig.files = new FileEntry[] { new FileEntry(), new FileEntry() };
        res.bootConfig.files[0].path = "user-data";
        res.bootConfig.files[0].contents = cloudConfig;

        res.bootConfig.files[1].path = "public-keys";
        res.bootConfig.files[1].contents = IOUtils.toString(new File("src/test/resources/testkey.pub").toURI());

        return TestUtils.doPost(this.host, res, DiskState.class,
                UriUtils.buildUri(this.host, DiskService.FACTORY_LINK));
    }

    private ComputeDescription createVmDescription() throws Throwable {
        ComputeDescription computeDesc = new ComputeDescription();

        computeDesc.id = getVmName();
        computeDesc.documentSelfLink = computeDesc.id;
        computeDesc.supportedChildren = new ArrayList<>();
        computeDesc.instanceAdapterReference = UriUtils.buildUri(this.host, VSphereUriPaths.INSTANCE_SERVICE);
        computeDesc.authCredentialsLink = this.auth.documentSelfLink;
        computeDesc.name = computeDesc.id;
        computeDesc.dataStoreId = this.dataStoreId;

        return TestUtils.doPost(this.host, computeDesc, ComputeDescription.class,
                UriUtils.buildUri(this.host, ComputeDescriptionService.FACTORY_LINK));
    }

    /**
     * Create a compute host representing a vcenter server
     */
    private ComputeState createComputeHost() throws Throwable {
        ComputeState computeState = new ComputeState();
        computeState.id = UUID.randomUUID().toString();
        computeState.name = this.computeHostDescription.name;
        computeState.documentSelfLink = computeState.id;
        computeState.descriptionLink = this.computeHostDescription.documentSelfLink;
        computeState.resourcePoolLink = this.resourcePool.documentSelfLink;
        computeState.adapterManagementReference = getAdapterManagementReference();

        ComputeState returnState = TestUtils.doPost(this.host, computeState, ComputeState.class,
                UriUtils.buildUri(this.host, ComputeService.FACTORY_LINK));
        return returnState;
    }

    private ComputeDescription createComputeHostDescription() throws Throwable {
        ComputeDescription computeDesc = new ComputeDescription();

        computeDesc.id = UUID.randomUUID().toString();
        computeDesc.name = computeDesc.id;
        computeDesc.documentSelfLink = computeDesc.id;
        computeDesc.supportedChildren = new ArrayList<>();
        computeDesc.supportedChildren.add(ComputeType.VM_GUEST.name());
        computeDesc.instanceAdapterReference = UriUtils.buildUri(this.host, VSphereUriPaths.INSTANCE_SERVICE);
        computeDesc.authCredentialsLink = this.auth.documentSelfLink;
        computeDesc.enumerationAdapterReference = UriUtils.buildUri(this.host, VSphereUriPaths.ENUMERATION_SERVICE);
        computeDesc.regionId = this.datacenterId;

        return TestUtils.doPost(this.host, computeDesc, ComputeDescription.class,
                UriUtils.buildUri(this.host, ComputeDescriptionService.FACTORY_LINK));
    }

    private String getVmName() {
        return "vm-" + String.valueOf(System.currentTimeMillis());
    }
}