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);
+ }
+}