From ec3684d4ce33dc338a73c4f4c149565aac0da019 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Fri, 11 Mar 2016 19:34:29 +0000 Subject: [PATCH 1/3] Adds tests for out-of-the-box ExternalConfigSuppliers --- .../InPlaceExternalConfigSupplierTest.java | 60 ++++++++++++++ ...pertiesFileExternalConfigSupplierTest.java | 81 +++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 core/src/test/java/org/apache/brooklyn/core/config/external/InPlaceExternalConfigSupplierTest.java create mode 100644 core/src/test/java/org/apache/brooklyn/core/config/external/PropertiesFileExternalConfigSupplierTest.java diff --git a/core/src/test/java/org/apache/brooklyn/core/config/external/InPlaceExternalConfigSupplierTest.java b/core/src/test/java/org/apache/brooklyn/core/config/external/InPlaceExternalConfigSupplierTest.java new file mode 100644 index 0000000000..2746d31193 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/config/external/InPlaceExternalConfigSupplierTest.java @@ -0,0 +1,60 @@ +/* + * 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.core.config.external; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.internal.BrooklynProperties; +import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; +import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.Test; + +public class InPlaceExternalConfigSupplierTest { + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(InPlaceExternalConfigSupplierTest.class); + + protected ManagementContextInternal mgmt; + + @AfterMethod(alwaysRun=true) + public void tearDown() throws Exception { + try { + if (mgmt != null) Entities.destroyAll(mgmt); + } finally { + mgmt = null; + } + } + + @Test + public void testInPlace() throws Exception { + BrooklynProperties props = BrooklynProperties.Factory.newEmpty(); + props.put("brooklyn.external.foo", InPlaceExternalConfigSupplier.class.getName()); + props.put("brooklyn.external.foo.mykey", "myval"); + + mgmt = LocalManagementContextForTests.newInstance(props); + + assertEquals(mgmt.getExternalConfigProviderRegistry().getConfig("foo", "mykey"), "myval"); + assertNull(mgmt.getExternalConfigProviderRegistry().getConfig("foo", "wrongkey")); + } +} diff --git a/core/src/test/java/org/apache/brooklyn/core/config/external/PropertiesFileExternalConfigSupplierTest.java b/core/src/test/java/org/apache/brooklyn/core/config/external/PropertiesFileExternalConfigSupplierTest.java new file mode 100644 index 0000000000..329ddcce30 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/config/external/PropertiesFileExternalConfigSupplierTest.java @@ -0,0 +1,81 @@ +/* + * 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.core.config.external; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.io.File; + +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.internal.BrooklynProperties; +import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; +import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.io.Files; + +public class PropertiesFileExternalConfigSupplierTest { + + // TODO I (Aled) thought that the ExternalConfigSuppliers were re-initialised when + // mgmt.reloadBrooklynProperties was called, but that doesn't seem to be the case. + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(PropertiesFileExternalConfigSupplierTest.class); + + protected File propsFile; + protected ManagementContextInternal mgmt; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + propsFile = File.createTempFile("PropertiesFileExternalConfigSupplierTest", ".properties"); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() throws Exception { + try { + if (mgmt != null) Entities.destroyAll(mgmt); + } finally { + mgmt = null; + if (propsFile != null) propsFile.delete(); + } + } + + @Test + public void testFromProperties() throws Exception { + String contents = + "mykey=myval"+"\n"+ + "mykey2=myval2"; + Files.write(contents, propsFile, Charsets.UTF_8); + BrooklynProperties props = BrooklynProperties.Factory.newEmpty(); + props.put("brooklyn.external.foo", PropertiesFileExternalConfigSupplier.class.getName()); + props.put("brooklyn.external.foo.propertiesUrl", propsFile.toURI().toString()); + + mgmt = LocalManagementContextForTests.newInstance(props); + + assertEquals(mgmt.getExternalConfigProviderRegistry().getConfig("foo", "mykey"), "myval"); + assertEquals(mgmt.getExternalConfigProviderRegistry().getConfig("foo", "mykey2"), "myval2"); + assertNull(mgmt.getExternalConfigProviderRegistry().getConfig("foo", "wrongkey")); + } +} From 3e2a664ecb20ecd82f37bd52f5d2fe6698807309 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Fri, 11 Mar 2016 19:34:54 +0000 Subject: [PATCH 2/3] Adds UrlsExternalConfigSupplier --- .../AbstractExternalConfigSupplier.java | 7 +- .../external/UrlsExternalConfigSupplier.java | 83 ++++++++++++++ .../UrlsExternalConfigSupplierTest.java | 103 ++++++++++++++++++ 3 files changed, 190 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/org/apache/brooklyn/core/config/external/UrlsExternalConfigSupplier.java create mode 100644 core/src/test/java/org/apache/brooklyn/core/config/external/UrlsExternalConfigSupplierTest.java diff --git a/core/src/main/java/org/apache/brooklyn/core/config/external/AbstractExternalConfigSupplier.java b/core/src/main/java/org/apache/brooklyn/core/config/external/AbstractExternalConfigSupplier.java index 18b25ebb4c..2288414d54 100644 --- a/core/src/main/java/org/apache/brooklyn/core/config/external/AbstractExternalConfigSupplier.java +++ b/core/src/main/java/org/apache/brooklyn/core/config/external/AbstractExternalConfigSupplier.java @@ -18,8 +18,9 @@ */ package org.apache.brooklyn.core.config.external; -import org.apache.brooklyn.api.mgmt.ManagementContext; +import static com.google.common.base.Preconditions.checkNotNull; +import org.apache.brooklyn.api.mgmt.ManagementContext; /** * Default superclass for all {@link ExternalConfigSupplier} implementations. @@ -30,8 +31,8 @@ abstract public class AbstractExternalConfigSupplier implements ExternalConfigSu private final String name; protected AbstractExternalConfigSupplier(ManagementContext managementContext, String name) { - this.managementContext = managementContext; - this.name = name; + this.managementContext = checkNotNull(managementContext, "managementContext"); + this.name = checkNotNull(name, "name"); } public ManagementContext getManagementContext() { diff --git a/core/src/main/java/org/apache/brooklyn/core/config/external/UrlsExternalConfigSupplier.java b/core/src/main/java/org/apache/brooklyn/core/config/external/UrlsExternalConfigSupplier.java new file mode 100644 index 0000000000..0cd677fc40 --- /dev/null +++ b/core/src/main/java/org/apache/brooklyn/core/config/external/UrlsExternalConfigSupplier.java @@ -0,0 +1,83 @@ +/* + * 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.core.config.external; + +import java.io.IOException; +import java.util.Map; + +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.util.core.ResourceUtils; + +import com.google.common.base.Objects; +import com.google.common.collect.Maps; + + +/** + * This is configured with references to URLs or files. When calling {@link #get(String)} it + * retrieves the String contents of that file. See {@link ResourceUtils#getResourceAsString(String)} + * for details of the type of URL/file references supported. + * + * Example configuration could be: + *
+ * brooklyn.external.foo = brooklyn.management.config.external.FilesExternalConfigSupplier
+ * brooklyn.external.foo.authorized_keys = classpath://authorized_keys
+ * brooklyn.external.foo.privateSshKey = /path/to/privateKey
+ * brooklyn.external.foo.initScript = https://brooklyn.example.com/config/initScript.sh
+ * 
+ */ +public class UrlsExternalConfigSupplier extends AbstractExternalConfigSupplier { + + // TODO Should we cache (for some short period of time)? + + private final Map config; + private final ResourceUtils resourceUtils; + + public UrlsExternalConfigSupplier(ManagementContext managementContext, String name, Map config) throws IOException { + super(managementContext, name); + this.config = config; + resourceUtils = ResourceUtils.create( + managementContext.getCatalogClassLoader(), + this, + UrlsExternalConfigSupplier.class.getSimpleName()+"("+getName()+")"); + + Map missing = Maps.newLinkedHashMap(); + for (Map.Entry entry : config.entrySet()) { + String target = entry.getValue(); + if (!resourceUtils.doesUrlExist(target)) { + missing.put(entry.getKey(), entry.getValue()); + } + } + if (missing.size() > 0) { + throw new IllegalStateException("URLs for external config '"+getName()+"' not found: "+missing); + } + } + + @Override + public String toString() { + return Objects.toStringHelper(this).add("name", getName()).toString(); + } + + public String get(String key) { + String target = config.get(key); + if (target == null) { + throw new IllegalArgumentException("Unknown key '"+key+"' for "+toString()); + } + return resourceUtils.getResourceAsString(target); + } +} diff --git a/core/src/test/java/org/apache/brooklyn/core/config/external/UrlsExternalConfigSupplierTest.java b/core/src/test/java/org/apache/brooklyn/core/config/external/UrlsExternalConfigSupplierTest.java new file mode 100644 index 0000000000..84c9d93b76 --- /dev/null +++ b/core/src/test/java/org/apache/brooklyn/core/config/external/UrlsExternalConfigSupplierTest.java @@ -0,0 +1,103 @@ +/* + * 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.core.config.external; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + +import java.io.File; +import java.util.List; + +import org.apache.brooklyn.core.entity.Entities; +import org.apache.brooklyn.core.internal.BrooklynProperties; +import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; +import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests; +import org.apache.brooklyn.test.Asserts; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.common.base.Charsets; +import com.google.common.collect.Lists; +import com.google.common.io.Files; + +public class UrlsExternalConfigSupplierTest { + + // TODO I (Aled) thought that the ExternalConfigSuppliers were re-initialised when + // mgmt.reloadBrooklynProperties was called, but that doesn't seem to be the case. + + @SuppressWarnings("unused") + private static final Logger LOG = LoggerFactory.getLogger(UrlsExternalConfigSupplierTest.class); + + protected List files; + protected ManagementContextInternal mgmt; + + @BeforeMethod(alwaysRun=true) + public void setUp() throws Exception { + files = Lists.newArrayList(); + } + + @AfterMethod(alwaysRun=true) + public void tearDown() throws Exception { + try { + if (mgmt != null) Entities.destroyAll(mgmt); + } finally { + mgmt = null; + + if (files != null) { + for (File file : files) { + file.delete(); + } + } + } + } + + @Test + public void testFromUrls() throws Exception { + File f1 = makeTempFile("my1"); + File f2 = makeTempFile("my2"); + + BrooklynProperties props = BrooklynProperties.Factory.newEmpty(); + props.put("brooklyn.external.foo", UrlsExternalConfigSupplier.class.getName()); + props.put("brooklyn.external.foo.mykey1", f1.toURI().toString()); + props.put("brooklyn.external.foo.mykey2", f2.getAbsolutePath()); + + mgmt = LocalManagementContextForTests.newInstance(props); + + assertEquals(mgmt.getExternalConfigProviderRegistry().getConfig("foo", "mykey1"), "my1"); + assertEquals(mgmt.getExternalConfigProviderRegistry().getConfig("foo", "mykey2"), "my2"); + + // TODO PropertiesFileExternalConfigSupplier just returns null; want consistency. + // But feels right to throw? + try { + String result = mgmt.getExternalConfigProviderRegistry().getConfig("foo", "wrongkey"); + Asserts.shouldHaveFailedPreviously("result="+result); + } catch (Exception e) { + Asserts.expectedFailureContains(e, "Unknown key"); + } + } + + private File makeTempFile(String contents) throws Exception { + File result = File.createTempFile("UrlsFileExternalConfigSupplierTest", ".txt"); + Files.write(contents, result, Charsets.UTF_8); + return result; + } +} From 6dcb2309b9cfbe241f0143110c57a14263209b01 Mon Sep 17 00:00:00 2001 From: Aled Sage Date: Fri, 11 Mar 2016 19:35:54 +0000 Subject: [PATCH 3/3] WindowsFeed: change SSH to WinRM --- .../brooklyn/feed/windows/WindowsPerformanceCounterFeed.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java index 1939ed0252..0677e97bf4 100644 --- a/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java +++ b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java @@ -71,7 +71,7 @@ *

To use this feed, you must provide the entity, and a collection of mappings between Windows performance counter * names and Brooklyn attribute sensors.

* - *

This feed uses SSH to invoke the windows utility typeperf to query for a specific set of performance + *

This feed uses WinRM to invoke the windows utility typeperf to query for a specific set of performance * counters, by name. The values are extracted from the response, and published to the entity's sensors.

* *

Example: