You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by dr...@apache.org on 2017/05/03 08:51:35 UTC

[2/3] brooklyn-server git commit: Add 'templates.customize' and 'files.customize' capability.

Add 'templates.customize' and 'files.customize' capability.


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/c00af93f
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/c00af93f
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/c00af93f

Branch: refs/heads/master
Commit: c00af93f232e01a50cc3d30490749bc13d722598
Parents: 71eef9d
Author: Geoff Macartney <ge...@cloudsoftcorp.com>
Authored: Fri Apr 28 21:29:39 2017 +0100
Committer: Geoff Macartney <ge...@cloudsoftcorp.com>
Committed: Tue May 2 09:53:29 2017 +0100

----------------------------------------------------------------------
 .../core/entity/BrooklynConfigKeys.java         |   1 +
 .../base/AbstractSoftwareProcessDriver.java     |  20 +++
 .../base/AbstractSoftwareProcessSshDriver.java  |  13 ++
 .../base/EmptySoftwareProcessSshDriver.java     |  15 +-
 .../entity/software/base/SoftwareProcess.java   |  29 ++++
 .../SoftwareProcessDriverCopyResourcesTest.java | 142 +++++++++++++++++++
 6 files changed, 218 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c00af93f/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java b/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
index 40baf65..e0bb6c5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/BrooklynConfigKeys.java
@@ -192,6 +192,7 @@ public class BrooklynConfigKeys {
     public static final ConfigKey<Boolean> INSTALL_LATCH = newBooleanConfigKey("install.latch", "Latch for blocking install until ready");
     public static final ConfigKey<Boolean> RUNTIME_RESOURCES_LATCH = newBooleanConfigKey("resources.runtime.latch", "Latch for blocking runtime resources until ready");
     public static final ConfigKey<Boolean> CUSTOMIZE_LATCH = newBooleanConfigKey("customize.latch", "Latch for blocking customize until ready");
+    public static final ConfigKey<Boolean> CUSTOMIZE_RESOURCES_LATCH = newBooleanConfigKey("resources.customize.latch", "Latch for blocking customize resources until ready");
     public static final ConfigKey<Boolean> LAUNCH_LATCH = newBooleanConfigKey("launch.latch", "Latch for blocking launch until ready");
 
     public static final ConfigKey<Duration> START_TIMEOUT = newConfigKey(

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c00af93f/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java
index a91d1f1..b582776 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessDriver.java
@@ -173,6 +173,12 @@ public abstract class AbstractSoftwareProcessDriver implements SoftwareProcessDr
             }});
 
             DynamicTasks.queue("customize", new Runnable() { @Override public void run() {
+                DynamicTasks.queue("copy-pre-customize-resources", new Runnable() { @Override public void run() {
+                    try (CloseableLatch value = waitForLatch(BrooklynConfigKeys.CUSTOMIZE_RESOURCES_LATCH)) {
+                        copyCustomizeResources();
+                    }
+                }});
+
                 DynamicTasks.queue("pre-customize-command", new Runnable() { @Override public void run() {
                     runPreCustomizeCommand();
                 }});
@@ -402,6 +408,20 @@ public abstract class AbstractSoftwareProcessDriver implements SoftwareProcessDr
         copyResources(getInstallDir(), entity.getConfig(SoftwareProcess.INSTALL_FILES), entity.getConfig(SoftwareProcess.INSTALL_TEMPLATES));
     }
 
+    /**
+     * Files and templates to be copied to the server <em>before</em> customize. This allows the {@link #customize()}
+     * process to have access to all required resources.
+     * <p>
+     * Will be prefixed with the entity's {@link #getInstallDir() install directory} if relative.
+     *
+     * @see SoftwareProcess#INSTALL_FILES
+     * @see SoftwareProcess#INSTALL_TEMPLATES
+     * @see #copyRuntimeResources()
+     */
+    public void copyCustomizeResources() {
+        copyResources(getInstallDir(), entity.getConfig(SoftwareProcess.CUSTOMIZE_FILES), entity.getConfig(SoftwareProcess.CUSTOMIZE_TEMPLATES));
+    }
+
     protected void copyResources(String destinationParentDir, Map<String, String> files, Map<String, String> templates) {
         if (files == null) files = Collections.emptyMap();
         if (templates == null) templates = Collections.emptyMap();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c00af93f/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
index 642326f..c071acd 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/AbstractSoftwareProcessSshDriver.java
@@ -304,6 +304,19 @@ public abstract class AbstractSoftwareProcessSshDriver extends AbstractSoftwareP
         }
     }
 
+    @Override
+    public void copyCustomizeResources() {
+        getLocation().acquireMutex("customizing " + elvis(entity, this), "installation lock at host for files and templates");
+        try {
+            super.copyCustomizeResources();
+        } catch (Exception e) {
+            log.warn("Error copying customize resources", e);
+            throw Exceptions.propagate(e);
+        } finally {
+            getLocation().releaseMutex("customizing " + elvis(entity, this));
+        }
+    }
+
     private void executeSuccessfully(ConfigKey<String> configKey, String label) {
         if(Strings.isNonBlank(getEntity().getConfig(configKey))) {
             log.debug("Executing {} on entity {}", label, entity.getDisplayName());

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c00af93f/software/base/src/main/java/org/apache/brooklyn/entity/software/base/EmptySoftwareProcessSshDriver.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/EmptySoftwareProcessSshDriver.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/EmptySoftwareProcessSshDriver.java
index 2c82148..ab5a877 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/EmptySoftwareProcessSshDriver.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/EmptySoftwareProcessSshDriver.java
@@ -54,13 +54,24 @@ public class EmptySoftwareProcessSshDriver extends AbstractSoftwareProcessSshDri
     }
 
     @Override
-    public void copyRuntimeResources() { 
+    public void copyCustomizeResources() {
+        Map<String, String> customizeFiles = entity.getConfig(SoftwareProcess.CUSTOMIZE_FILES);
+        Map<String, String> customizeTemplates = entity.getConfig(SoftwareProcess.CUSTOMIZE_TEMPLATES);
+        if ((customizeFiles!=null && !customizeFiles.isEmpty())
+            || (customizeTemplates!=null && !customizeTemplates.isEmpty())) {
+            // only do this if there are files, to prevent unnecessary `mkdir`
+            super.copyCustomizeResources();
+        }        
+    }
+
+    @Override
+    public void copyRuntimeResources() {
         Map<String, String> runtimeFiles = entity.getConfig(SoftwareProcess.RUNTIME_FILES);
         Map<String, String> runtimeTemplates = entity.getConfig(SoftwareProcess.RUNTIME_TEMPLATES);
         if ((runtimeFiles!=null && !runtimeFiles.isEmpty()) || (runtimeTemplates!=null && !runtimeTemplates.isEmpty())) {
             // only do this if there are files, to prevent unnecessary `mkdir`
             super.copyRuntimeResources();
-        }        
+        }
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c00af93f/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
index e8dfced..1e4ace6 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcess.java
@@ -235,6 +235,35 @@ public interface SoftwareProcess extends Entity, Startable {
             .build();
 
     /**
+     * Files to be copied to the server before customize.
+     * <p>
+     * Map of {@code classpath://foo/file.txt} (or other url) source to destination path,
+     * as {@code subdir/file} relative to installation directory or {@code /absolute/path/to/file}.
+     *
+     * @see #INSTALL_TEMPLATES
+     */
+    @Beta
+    @SetFromFlag("customizeFiles")
+    MapConfigKey<String> CUSTOMIZE_FILES = new MapConfigKey.Builder<String>(String.class, "files.customize")
+            .description("Mapping of files, to be copied before customize, to destination name relative to installDir")
+            .typeInheritance(BasicConfigInheritance.DEEP_MERGE)
+            .runtimeInheritance(BasicConfigInheritance.NOT_REINHERITED_ELSE_DEEP_MERGE)
+            .build();
+
+    /**
+     * Templates to be filled in and then copied to the server before customize.
+     *
+     * @see #INSTALL_FILES
+     */
+    @Beta
+    @SetFromFlag("customizeTemplates")
+    MapConfigKey<String> CUSTOMIZE_TEMPLATES = new MapConfigKey.Builder<String>(String.class, "templates.customize")
+            .description("Mapping of templates, to be filled in and copied before customize, to destination name relative to installDir")
+            .typeInheritance(BasicConfigInheritance.DEEP_MERGE)
+            .runtimeInheritance(BasicConfigInheritance.NOT_REINHERITED_ELSE_DEEP_MERGE)
+            .build();
+
+    /**
      * Files to be copied to the server after customisation.
      * <p>
      * Map of {@code classpath://foo/file.txt} (or other url) source to destination path,

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/c00af93f/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/SoftwareProcessDriverCopyResourcesTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/SoftwareProcessDriverCopyResourcesTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/SoftwareProcessDriverCopyResourcesTest.java
new file mode 100644
index 0000000..8333871
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/software/base/lifecycle/SoftwareProcessDriverCopyResourcesTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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.entity.software.base.lifecycle;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Properties;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.config.MapConfigKey;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.entity.factory.ApplicationBuilder;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
+import org.apache.brooklyn.entity.software.base.VanillaSoftwareProcess;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.util.os.Os;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Files;
+
+public class SoftwareProcessDriverCopyResourcesTest {
+
+    File installDir;
+    File runDir;
+    File sourceFileDir;
+    File sourceTemplateDir;
+
+    private LocalManagementContext managementContext;
+    private TestApplication app;
+
+    private Location location;
+
+    private static final String TEST_CONTENT_FILE = "testing123";
+    private static final String TEST_CONTENT_TEMPLATE = "id=${entity.id}";
+
+    @BeforeMethod(alwaysRun = true)
+    public void setUp() {
+        managementContext = new LocalManagementContextForTests();
+        app = ApplicationBuilder.newManagedApp(TestApplication.class, managementContext);
+
+        sourceFileDir = Os.newTempDir(getClass().getSimpleName());
+        sourceTemplateDir = Os.newTempDir(getClass().getSimpleName());
+
+        installDir = Os.newTempDir(getClass().getSimpleName());
+        runDir = Os.newTempDir(getClass().getSimpleName());
+
+        location = new LocalhostMachineProvisioningLocation();
+    }
+
+    @Test
+    public void testPreInstallPhase() throws Exception {
+        testPhase(SoftwareProcess.PRE_INSTALL_FILES, SoftwareProcess.PRE_INSTALL_TEMPLATES, SoftwareProcess.INSTALL_DIR);
+    }
+
+    @Test
+    public void testInstallPhase() throws Exception {
+        testPhase(SoftwareProcess.INSTALL_FILES, SoftwareProcess.INSTALL_TEMPLATES, SoftwareProcess.INSTALL_DIR);
+    }
+
+    @Test
+    public void testCustomisePhase() throws Exception {
+        testPhase(SoftwareProcess.CUSTOMIZE_FILES, SoftwareProcess.CUSTOMIZE_TEMPLATES, SoftwareProcess.INSTALL_DIR);
+    }
+
+    @Test
+    public void testRuntimePhase() throws Exception {
+        testPhase(SoftwareProcess.RUNTIME_FILES, SoftwareProcess.RUNTIME_TEMPLATES, SoftwareProcess.RUN_DIR);
+    }
+
+    private void testPhase(MapConfigKey<String> filePhase, MapConfigKey<String> templatePhase,
+                           AttributeSensor<String> directory) throws IOException {
+
+        File file1 = new File(sourceFileDir, "file1");
+        Files.write(TEST_CONTENT_FILE, file1, Charset.defaultCharset());
+        File template1 = new File(sourceTemplateDir, "template1");
+        Files.write(TEST_CONTENT_TEMPLATE, template1, Charset.defaultCharset());
+        final EmptySoftwareProcess testEntity =
+            app.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class)
+                .configure(VanillaSoftwareProcess.LAUNCH_COMMAND, "true")
+                .configure(filePhase.getName(),
+                    ImmutableMap.of(file1.getAbsolutePath(), "file1"))
+                .configure(templatePhase.getName(),
+                    ImmutableMap.of(template1.getAbsolutePath(), "template1")));
+
+        app.start(ImmutableList.of(location));
+        final String installDirName = testEntity.sensors().get(directory);
+        assertNotNull(installDirName);
+        final File installDir = new File(installDirName);
+
+        final File file1Installed = new File(installDir, "file1");
+        final String firstLine = Files.readFirstLine(file1Installed, Charset.defaultCharset());
+        assertEquals(TEST_CONTENT_FILE, firstLine);
+
+        final File template1Installed = new File(installDir, "template1");
+        Properties props = new Properties();
+        final FileInputStream templateStream = new FileInputStream(template1Installed);
+        props.load(templateStream);
+        assertEquals(props.getProperty("id"), testEntity.getId());
+    }
+
+    @AfterMethod(alwaysRun = true)
+    public void tearDown() {
+        app.stop();
+        if (managementContext != null) Entities.destroyAll(managementContext);
+        app = null;
+        Os.deleteRecursively(sourceFileDir);
+        Os.deleteRecursively(sourceTemplateDir);
+        Os.deleteRecursively(installDir);
+        Os.deleteRecursively(runDir);
+    }
+}