org.apache.brooklyn.launcher.BrooklynLauncherTest.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.brooklyn.launcher.BrooklynLauncherTest.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 org.apache.brooklyn.launcher;

import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;

import java.io.File;
import java.net.URI;

import org.apache.brooklyn.api.entity.Application;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.core.catalog.internal.CatalogInitialization;
import org.apache.brooklyn.core.internal.BrooklynProperties;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
import org.apache.brooklyn.core.server.BrooklynServerConfig;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
import org.apache.brooklyn.core.test.entity.TestApplication;
import org.apache.brooklyn.core.test.entity.TestApplicationImpl;
import org.apache.brooklyn.core.test.entity.TestEntity;
import org.apache.brooklyn.launcher.common.BrooklynPropertiesFactoryHelperTest;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
import org.apache.brooklyn.rest.BrooklynWebConfig;
import org.apache.brooklyn.util.http.HttpAsserts;
import org.apache.brooklyn.util.http.HttpTool;
import org.apache.brooklyn.util.http.HttpToolResponse;
import org.apache.brooklyn.util.io.FileUtil;
import org.apache.brooklyn.util.net.Urls;
import org.apache.brooklyn.util.os.Os;
import org.apache.brooklyn.util.text.Strings;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;

import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.io.Files;

public class BrooklynLauncherTest {

    private BrooklynLauncher launcher;

    @AfterMethod(alwaysRun = true)
    public void tearDown() throws Exception {
        if (launcher != null)
            launcher.terminate();
        launcher = null;
    }

    // Integration because takes a few seconds to start web-console
    @Test(groups = "Integration")
    public void testStartsWebServerOnExpectectedPort() throws Exception {
        launcher = newLauncherForTests(true).webconsolePort("10000+").installSecurityFilter(false).start();

        String webServerUrlStr = launcher.getServerDetails().getWebServerUrl();
        URI webServerUri = new URI(webServerUrlStr);

        assertEquals(launcher.getApplications(), ImmutableList.of());
        assertTrue(webServerUri.getPort() >= 10000 && webServerUri.getPort() < 10100,
                "port=" + webServerUri.getPort() + "; uri=" + webServerUri);
        HttpAsserts.assertUrlReachable(webServerUrlStr);
    }

    // Integration because takes a few seconds to start web-console
    @Test(groups = "Integration")
    public void testWebServerTempDirRespectsDataDirConfig() throws Exception {
        String dataDirName = ".brooklyn-foo" + Strings.makeRandomId(4);
        String dataDir = "~/" + dataDirName;

        launcher = newLauncherForTests(true).brooklynProperties(BrooklynServerConfig.MGMT_BASE_DIR, dataDir)
                .start();

        ManagementContext managementContext = launcher.getServerDetails().getManagementContext();
        String expectedTempDir = Os.mergePaths(Os.home(), dataDirName, "planes",
                managementContext.getManagementPlaneId(), managementContext.getManagementNodeId(), "jetty");

        File webappTempDir = launcher.getServerDetails().getWebServer().getWebappTempDir();
        assertEquals(webappTempDir.getAbsolutePath(), expectedTempDir);
    }

    // Integration because takes a few seconds to start web-console
    @Test(groups = "Integration")
    public void testStartsWebServerWithoutAuthentication() throws Exception {
        launcher = newLauncherForTests(true).start();
        String uri = launcher.getServerDetails().getWebServerUrl();

        HttpToolResponse response = HttpTool.execAndConsume(HttpTool.httpClientBuilder().build(), new HttpGet(uri));
        assertEquals(response.getResponseCode(), 200);
    }

    // Integration because takes a few seconds to start web-console
    @Test(groups = "Integration")
    public void testStartsWebServerWithCredentials() throws Exception {
        launcher = newLauncherForTests(true).webconsolePort("10000+")
                .brooklynProperties(BrooklynWebConfig.USERS, "myname")
                .brooklynProperties(BrooklynWebConfig.PASSWORD_FOR_USER("myname"), "mypassword").start();
        String uri = launcher.getServerDetails().getWebServerUrl();

        HttpToolResponse response = HttpTool.execAndConsume(HttpTool.httpClientBuilder().build(), new HttpGet(uri));
        assertEquals(response.getResponseCode(), 401);

        HttpToolResponse response2 = HttpTool.execAndConsume(
                HttpTool.httpClientBuilder().uri(uri)
                        .credentials(new UsernamePasswordCredentials("myname", "mypassword")).build(),
                new HttpGet(uri));
        assertEquals(response2.getResponseCode(), 200);
    }

    @Test
    public void testCanDisableWebServerStartup() throws Exception {
        launcher = newLauncherForTests(true).webconsole(false).start();

        assertNull(launcher.getServerDetails().getWebServer());
        assertNull(launcher.getServerDetails().getWebServerUrl());
        Assert.assertTrue(((ManagementContextInternal) launcher.getServerDetails().getManagementContext()).errors()
                .isEmpty());
    }

    @Test
    public void testStartsAppInstance() throws Exception {
        launcher = newLauncherForTests(true).webconsole(false)
                .application(EntitySpec.create(TestApplicationImpl.class)).start();

        assertOnlyApp(launcher, TestApplication.class);
    }

    @Test
    public void testStartsAppFromSpec() throws Exception {
        launcher = newLauncherForTests(true).webconsole(false).application(EntitySpec.create(TestApplication.class))
                .start();

        assertOnlyApp(launcher, TestApplication.class);
    }

    @Test
    @SuppressWarnings("deprecation")
    public void testStartsAppFromBuilder() throws Exception {
        launcher = newLauncherForTests(true).webconsole(false)
                .application(new org.apache.brooklyn.core.entity.factory.ApplicationBuilder(
                        EntitySpec.create(TestApplication.class)) {
                    @Override
                    protected void doBuild() {
                    }
                }).start();

        assertOnlyApp(launcher, TestApplication.class);
    }

    @Test
    public void testStartsAppFromYAML() throws Exception {
        String yaml = "name: example-app\n" + "services:\n"
                + "- serviceType: org.apache.brooklyn.core.test.entity.TestEntity\n" + "  name: test-app";
        launcher = newLauncherForTests(true).webconsole(false).application(yaml).start();

        assertEquals(launcher.getApplications().size(), 1, "apps=" + launcher.getApplications());
        Application app = Iterables.getOnlyElement(launcher.getApplications());
        assertEquals(app.getChildren().size(), 1, "children=" + app.getChildren());
        assertTrue(Iterables.getOnlyElement(app.getChildren()) instanceof TestEntity);
    }

    @Test // may take 2s initializing location if running this test case alone, but noise if running suite 
    public void testStartsAppInSuppliedLocations() throws Exception {
        launcher = newLauncherForTests(true).webconsole(false).location("localhost")
                .application(EntitySpec.create(TestApplication.class)).start();

        Application app = Iterables.find(launcher.getApplications(), Predicates.instanceOf(TestApplication.class));
        assertOnlyLocation(app, LocalhostMachineProvisioningLocation.class);
    }

    @Test
    public void testUsesSuppliedManagementContext() throws Exception {
        LocalManagementContext myManagementContext = LocalManagementContextForTests.newInstance();
        launcher = newLauncherForTests(false).webconsole(false).managementContext(myManagementContext).start();

        assertSame(launcher.getServerDetails().getManagementContext(), myManagementContext);
    }

    @Test
    public void testUsesSuppliedBrooklynProperties() throws Exception {
        BrooklynProperties props = LocalManagementContextForTests.builder(true).buildProperties();
        props.put("mykey", "myval");
        launcher = newLauncherForTests(false).webconsole(false).brooklynProperties(props).start();

        assertEquals(launcher.getServerDetails().getManagementContext().getConfig().getFirst("mykey"), "myval");
    }

    @Test
    public void testUsesSupplementaryBrooklynProperties() throws Exception {
        launcher = newLauncherForTests(true).webconsole(false).brooklynProperties("mykey", "myval").start();

        assertEquals(launcher.getServerDetails().getManagementContext().getConfig().getFirst("mykey"), "myval");
    }

    @Test
    public void testReloadBrooklynPropertiesRestoresProgrammaticProperties() throws Exception {
        launcher = newLauncherForTests(true).webconsole(false).brooklynProperties("mykey", "myval").start();
        LocalManagementContext managementContext = (LocalManagementContext) launcher.getServerDetails()
                .getManagementContext();
        assertEquals(managementContext.getConfig().getFirst("mykey"), "myval");
        managementContext.getBrooklynProperties().put("mykey", "newval");
        assertEquals(managementContext.getConfig().getFirst("mykey"), "newval");
        managementContext.reloadBrooklynProperties();
        assertEquals(managementContext.getConfig().getFirst("mykey"), "myval");
    }

    @Test
    public void testReloadBrooklynPropertiesFromFile() throws Exception {
        File globalPropertiesFile = File.createTempFile("local-brooklyn-properties-test", ".properties");
        FileUtil.setFilePermissionsTo600(globalPropertiesFile);
        try {
            String property = "mykey=myval";
            Files.append(BrooklynPropertiesFactoryHelperTest.getMinimalLauncherPropertiesString() + property,
                    globalPropertiesFile, Charsets.UTF_8);
            launcher = newLauncherForTests(false).webconsole(false)
                    .globalBrooklynPropertiesFile(globalPropertiesFile.getAbsolutePath()).start();
            LocalManagementContext managementContext = (LocalManagementContext) launcher.getServerDetails()
                    .getManagementContext();
            assertEquals(managementContext.getConfig().getFirst("mykey"), "myval");
            property = "mykey=newval";
            Files.write(BrooklynPropertiesFactoryHelperTest.getMinimalLauncherPropertiesString() + property,
                    globalPropertiesFile, Charsets.UTF_8);
            managementContext.reloadBrooklynProperties();
            assertEquals(managementContext.getConfig().getFirst("mykey"), "newval");
        } finally {
            globalPropertiesFile.delete();
        }
    }

    @Test // takes a bit of time because starts webapp, but also tests rest api so useful
    public void testErrorsCaughtByApiAndRestApiWorks() throws Exception {
        launcher = newLauncherForTests(true)
                .catalogInitialization(new CatalogInitialization(null, false, null, false)
                        .addPopulationCallback(new Function<CatalogInitialization, Void>() {
                            @Override
                            public Void apply(CatalogInitialization input) {
                                throw new RuntimeException("deliberate-exception-for-testing");
                            }
                        }))
                .installSecurityFilter(false).start();
        // such an error should be thrown, then caught in this calling thread
        ManagementContext mgmt = launcher.getServerDetails().getManagementContext();
        Assert.assertFalse(((ManagementContextInternal) mgmt).errors().isEmpty());
        Assert.assertTrue(((ManagementContextInternal) mgmt).errors().get(0).toString().contains("deliberate"),
                "" + ((ManagementContextInternal) mgmt).errors());
        HttpAsserts.assertContentMatches(
                Urls.mergePaths(launcher.getServerDetails().getWebServerUrl(), "v1/server/up"), "true");
        HttpAsserts.assertContentMatches(
                Urls.mergePaths(launcher.getServerDetails().getWebServerUrl(), "v1/server/healthy"), "false");
        // TODO test errors api?
    }

    private BrooklynLauncher newLauncherForTests(boolean minimal) {
        Preconditions.checkArgument(launcher == null, "can only be used if no launcher yet");
        BrooklynLauncher launcher = BrooklynLauncher.newInstance();
        if (minimal)
            launcher.brooklynProperties(LocalManagementContextForTests.builder(true).buildProperties());
        return launcher;
    }

    private void assertOnlyApp(BrooklynLauncher launcher, Class<? extends Application> expectedType) {
        assertEquals(launcher.getApplications().size(), 1, "apps=" + launcher.getApplications());
        assertNotNull(
                Iterables.find(launcher.getApplications(), Predicates.instanceOf(TestApplication.class), null),
                "apps=" + launcher.getApplications());
    }

    private void assertOnlyLocation(Application app, Class<? extends Location> expectedType) {
        assertEquals(app.getLocations().size(), 1, "locs=" + app.getLocations());
        assertNotNull(
                Iterables.find(app.getLocations(),
                        Predicates.instanceOf(LocalhostMachineProvisioningLocation.class), null),
                "locs=" + app.getLocations());
    }
}