You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2015/08/19 13:09:23 UTC
[05/72] [abbrv] incubator-brooklyn git commit: BROOKLYN-162 - apply
org.apache package prefix to software-base, tidying package names,
and moving a few sensory things to core
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
new file mode 100644
index 0000000..124e00a
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxFeedTest.java
@@ -0,0 +1,422 @@
+/*
+ * 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.sensor.feed.jmx;
+
+import static org.apache.brooklyn.test.TestUtils.executeUntilSucceeds;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.StandardEmitterMBean;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+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.core.test.entity.TestEntityImpl;
+import org.apache.brooklyn.entity.core.AbstractEntity;
+import org.apache.brooklyn.entity.core.Attributes;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.entity.java.JmxSupport;
+import org.apache.brooklyn.entity.java.UsesJmx;
+import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
+import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
+import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
+import org.apache.brooklyn.sensor.core.BasicAttributeSensor;
+import org.apache.brooklyn.sensor.core.BasicNotificationSensor;
+import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
+import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
+import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.sensor.feed.jmx.JmxNotificationFilters;
+import org.apache.brooklyn.sensor.feed.jmx.JmxNotificationSubscriptionConfig;
+import org.apache.brooklyn.sensor.feed.jmx.JmxOperationPollConfig;
+import org.apache.brooklyn.sensor.feed.jmx.JmxValueFunctions;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.test.TestUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.testng.collections.Lists;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
+import org.apache.brooklyn.location.basic.SimulatedLocation;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Test the operation of the {@link JmxFeed} class.
+ * <p>
+ * Also confirm some of the JMX setup done by {@link JmxSupport} and {@link JmxHelper},
+ * based on ports in {@link UsesJmx}.
+ * <p>
+ * TODO tests of other JMX_AGENT_MODE are done in ActiveMqIntegrationTest;
+ * would be nice to promote some to live here
+ */
+public class JmxFeedTest {
+
+ // FIXME Move out the JmxHelper tests into the JmxHelperTest class
+
+ // FIXME Also test that setting poll period takes effect
+
+ private static final Logger log = LoggerFactory.getLogger(JmxFeedTest.class);
+
+ private static final int TIMEOUT_MS = 5000;
+ private static final int SHORT_WAIT_MS = 250;
+
+ private JmxService jmxService;
+ private TestApplication app;
+ private TestEntity entity;
+ private JmxFeed feed;
+ private JmxHelper jmxHelper;
+
+ private AttributeSensor<Integer> intAttribute = Sensors.newIntegerSensor("brooklyn.test.intAttribute", "Brooklyn testing int attribute");
+ private AttributeSensor<String> stringAttribute = Sensors.newStringSensor("brooklyn.test.stringAttribute", "Brooklyn testing string attribute");
+ private BasicAttributeSensor<Map> mapAttribute = new BasicAttributeSensor<Map>(Map.class, "brooklyn.test.mapAttribute", "Brooklyn testing map attribute");
+ private String objectName = "Brooklyn:type=MyTestMBean,name=myname";
+ private ObjectName jmxObjectName;
+ private String attributeName = "myattrib";
+ private String opName = "myop";
+
+ public static class TestEntityWithJmx extends TestEntityImpl {
+ @Override public void init() {
+ setAttribute(Attributes.HOSTNAME, "localhost");
+ setAttribute(UsesJmx.JMX_PORT,
+ LocalhostMachineProvisioningLocation.obtainPort(PortRanges.fromString("40123+")));
+ // only supports no-agent, at the moment
+ setConfig(UsesJmx.JMX_AGENT_MODE, JmxAgentModes.NONE);
+ setAttribute(UsesJmx.RMI_REGISTRY_PORT, -1); // -1 means to use the JMX_PORT only
+ ConfigToAttributes.apply(this, UsesJmx.JMX_CONTEXT);
+ }
+ }
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ jmxObjectName = new ObjectName(objectName);
+
+ // Create an entity and configure it with the above JMX service
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class).impl(TestEntityWithJmx.class));
+ app.start(ImmutableList.of(new SimulatedLocation()));
+
+ jmxHelper = new JmxHelper(entity);
+
+ jmxService = new JmxService(entity);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (feed != null) feed.stop();
+ if (jmxHelper != null) jmxHelper.disconnect();
+ if (jmxService != null) jmxService.shutdown();
+ if (app != null) Entities.destroyAll(app.getManagementContext());
+ feed = null;
+ }
+
+ @Test
+ public void testJmxAttributePollerReturnsMBeanAttribute() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, 42), objectName);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .pollAttribute(new JmxAttributePollConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .period(50)
+ .attributeName(attributeName))
+ .build();
+
+ // Starts with value defined when registering...
+ assertSensorEventually(intAttribute, 42, TIMEOUT_MS);
+
+ // Change the value and check it updates
+ mbean.updateAttributeValue(attributeName, 64);
+ assertSensorEventually(intAttribute, 64, TIMEOUT_MS);
+ }
+
+ @Test
+ public void testJmxAttributeOfTypeTabularDataProviderConvertedToMap() throws Exception {
+ // Create the CompositeType and TabularData
+ CompositeType compositeType = new CompositeType(
+ "typeName",
+ "description",
+ new String[] {"myint", "mystring", "mybool"}, // item names
+ new String[] {"myint", "mystring", "mybool"}, // item descriptions, can't be null or empty string
+ new OpenType<?>[] {SimpleType.INTEGER, SimpleType.STRING, SimpleType.BOOLEAN}
+ );
+ TabularType tt = new TabularType(
+ "typeName",
+ "description",
+ compositeType,
+ new String[] {"myint"}
+ );
+ TabularDataSupport tds = new TabularDataSupport(tt);
+ tds.put(new CompositeDataSupport(
+ compositeType,
+ new String[] {"mybool", "myint", "mystring"},
+ new Object[] {true, 1234, "on"}
+ ));
+
+ // Create MBean
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(attributeName, tds), objectName);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .pollAttribute(new JmxAttributePollConfig<Map>(mapAttribute)
+ .objectName(objectName)
+ .attributeName(attributeName)
+ .onSuccess((Function)JmxValueFunctions.tabularDataToMap()))
+ .build();
+
+ // Starts with value defined when registering...
+ assertSensorEventually(
+ mapAttribute,
+ ImmutableMap.of("myint", 1234, "mystring", "on", "mybool", Boolean.TRUE),
+ TIMEOUT_MS);
+ }
+
+ @Test
+ public void testJmxOperationPolledForSensor() throws Exception {
+ // This is awful syntax...
+ final int opReturnVal = 123;
+ final AtomicInteger invocationCount = new AtomicInteger();
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], Integer.class.getName(), MBeanOperationInfo.ACTION);
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(
+ Collections.emptyMap(),
+ ImmutableMap.of(opInfo, new Function<Object[], Integer>() {
+ public Integer apply(Object[] args) {
+ invocationCount.incrementAndGet(); return opReturnVal;
+ }}),
+ objectName);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .pollOperation(new JmxOperationPollConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .operationName(opName))
+ .build();
+
+ TestUtils.executeUntilSucceeds(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ assertTrue(invocationCount.get() > 0, "invocationCount="+invocationCount);
+ assertEquals(entity.getAttribute(intAttribute), (Integer)opReturnVal);
+ }});
+ }
+
+ @Test
+ public void testJmxOperationWithArgPolledForSensor() throws Exception {
+ // This is awful syntax...
+ MBeanParameterInfo paramInfo = new MBeanParameterInfo("param1", String.class.getName(), "my param1");
+ MBeanParameterInfo[] paramInfos = new MBeanParameterInfo[] {paramInfo};
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", paramInfos, String.class.getName(), MBeanOperationInfo.ACTION);
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(
+ Collections.emptyMap(),
+ ImmutableMap.of(opInfo, new Function<Object[], String>() {
+ public String apply(Object[] args) {
+ return args[0]+"suffix";
+ }}),
+ objectName);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .pollOperation(new JmxOperationPollConfig<String>(stringAttribute)
+ .objectName(objectName)
+ .operationName(opName)
+ .operationParams(ImmutableList.of("myprefix")))
+ .build();
+
+ assertSensorEventually(stringAttribute, "myprefix"+"suffix", TIMEOUT_MS);
+ }
+
+ @Test
+ public void testJmxNotificationSubscriptionForSensor() throws Exception {
+ final String one = "notification.one", two = "notification.two";
+ final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
+ final AtomicInteger sequence = new AtomicInteger(0);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .notificationFilter(JmxNotificationFilters.matchesType(one)))
+ .build();
+
+ // Notification updates the sensor
+ // Note that subscription is done async, so can't just send notification immediately during test.
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ sendNotification(mbean, one, sequence.getAndIncrement(), 123);
+ assertEquals(entity.getAttribute(intAttribute), (Integer)123);
+ }});
+
+ // But other notification types are ignored
+ sendNotification(mbean, two, sequence.getAndIncrement(), -1);
+
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ assertEquals(entity.getAttribute(intAttribute), (Integer)123);
+ }});
+ }
+
+ @Test
+ public void testJmxNotificationSubscriptionForSensorParsingNotification() throws Exception {
+ final String one = "notification.one", two = "notification.two";
+ final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
+ final AtomicInteger sequence = new AtomicInteger(0);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .notificationFilter(JmxNotificationFilters.matchesType(one))
+ .onNotification(new Function<Notification, Integer>() {
+ public Integer apply(Notification notif) {
+ return (Integer) notif.getUserData();
+ }
+ }))
+ .build();
+
+
+ // Notification updates the sensor
+ // Note that subscription is done async, so can't just send notification immediately during test.
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ sendNotification(mbean, one, sequence.getAndIncrement(), 123);
+ assertEquals(entity.getAttribute(intAttribute), (Integer)123);
+ }});
+ }
+
+ @Test
+ public void testJmxNotificationMultipleSubscriptionUsingListener() throws Exception {
+ final String one = "notification.one";
+ final String two = "notification.two";
+ final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of(one, two), objectName);
+ final AtomicInteger sequence = new AtomicInteger(0);
+
+ feed = JmxFeed.builder()
+ .entity(entity)
+ .subscribeToNotification(new JmxNotificationSubscriptionConfig<Integer>(intAttribute)
+ .objectName(objectName)
+ .notificationFilter(JmxNotificationFilters.matchesTypes(one, two)))
+ .build();
+
+ // Notification updates the sensor
+ // Note that subscription is done async, so can't just send notification immediately during test.
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ sendNotification(mbean, one, sequence.getAndIncrement(), 123);
+ assertEquals(entity.getAttribute(intAttribute), (Integer)123);
+ }});
+
+ // And wildcard means other notifications also received
+ sendNotification(mbean, two, sequence.getAndIncrement(), 456);
+ assertSensorEventually(intAttribute, 456, TIMEOUT_MS);
+ }
+
+ // Test reproduces functionality used in Monterey, for Venue entity being told of requestActor
+ @Test
+ public void testSubscribeToJmxNotificationAndEmitCorrespondingNotificationSensor() throws Exception {
+ TestApplication app2 = new TestApplicationImpl();
+ final EntityWithEmitter entity = new EntityWithEmitter(app2);
+ Entities.startManagement(app2);
+ try {
+ app2.start(ImmutableList.of(new SimulatedLocation()));
+
+ final List<SensorEvent<String>> received = Lists.newArrayList();
+ app2.subscribe(null, EntityWithEmitter.MY_NOTIF, new SensorEventListener<String>() {
+ public void onEvent(SensorEvent<String> event) {
+ received.add(event);
+ }});
+
+ final StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of("one"), objectName);
+ final AtomicInteger sequence = new AtomicInteger(0);
+
+ jmxHelper.connect(TIMEOUT_MS);
+ jmxHelper.addNotificationListener(jmxObjectName, new NotificationListener() {
+ public void handleNotification(Notification notif, Object callback) {
+ if (notif.getType().equals("one")) {
+ entity.emit(EntityWithEmitter.MY_NOTIF, (String) notif.getUserData());
+ }
+ }});
+
+
+ Asserts.succeedsEventually(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ sendNotification(mbean, "one", sequence.getAndIncrement(), "abc");
+ assertTrue(received.size() > 0, "received size should be bigger than 0");
+ assertEquals(received.get(0).getValue(), "abc");
+ }});
+ } finally {
+ Entities.destroyAll(app2.getManagementContext());
+ }
+ }
+
+ public static class EntityWithEmitter extends AbstractEntity {
+ public static final BasicNotificationSensor<String> MY_NOTIF = new BasicNotificationSensor<String>(String.class, "test.myNotif", "My notif");
+
+ public EntityWithEmitter(Entity owner) {
+ super(owner);
+ }
+ public EntityWithEmitter(Map flags) {
+ super(flags);
+ }
+ public EntityWithEmitter(Map flags, Entity owner) {
+ super(flags, owner);
+ }
+ }
+
+ private Notification sendNotification(StandardEmitterMBean mbean, String type, long seq, Object userData) {
+ Notification notif = new Notification(type, mbean, seq);
+ notif.setUserData(userData);
+ mbean.sendNotification(notif);
+ return notif;
+ }
+
+ private <T> void assertSensorEventually(final AttributeSensor<T> sensor, final T expectedVal, long timeout) {
+ executeUntilSucceeds(ImmutableMap.of("timeout", timeout), new Callable<Void>() {
+ public Void call() {
+ assertEquals(entity.getAttribute(sensor), expectedVal);
+ return null;
+ }});
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelperTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelperTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelperTest.java
new file mode 100644
index 0000000..058947c
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/JmxHelperTest.java
@@ -0,0 +1,311 @@
+/*
+ * 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.sensor.feed.jmx;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.fail;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.management.DynamicMBean;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.StandardEmitterMBean;
+
+import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
+import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
+import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.test.TestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.jclouds.util.Throwables2;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.testng.collections.Lists;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class JmxHelperTest {
+
+ private static final Logger log = LoggerFactory.getLogger(JmxHelperTest.class);
+
+ private static final String LOCALHOST_NAME = "localhost";
+
+ private static final int TIMEOUT_MS = 5000;
+ private static final int SHORT_WAIT_MS = 250;
+
+ private JmxService jmxService;
+ private JmxHelper jmxHelper;
+
+ private String objectName = "Brooklyn:type=MyTestMBean,name=myname";
+ private String objectNameWithWildcard = "Brooklyn:type=MyTestMBean,name=mynam*";
+ private ObjectName jmxObjectName;
+ private ObjectName jmxObjectNameWithWildcard;
+ private String attributeName = "myattrib";
+ private String opName = "myop";
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ jmxObjectName = new ObjectName(objectName);
+ jmxObjectNameWithWildcard = new ObjectName(objectNameWithWildcard);
+ jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
+ jmxHelper = new JmxHelper(jmxService.getUrl());
+ jmxHelper.setMinTimeBetweenReconnectAttempts(0);
+ jmxHelper.connect(TIMEOUT_MS);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (jmxHelper != null) jmxHelper.disconnect();
+ if (jmxService != null) jmxService.shutdown();
+ jmxHelper = null;
+ jmxService = null;
+ }
+
+ @Test
+ public void testGetAttribute() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+ assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval");
+ }
+
+ @Test
+ public void testGetAttributeUsingObjectNameWildcard() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+ assertEquals(jmxHelper.getAttribute(jmxObjectNameWithWildcard, "myattr"), "myval");
+ }
+
+ @Test
+ public void testSetAttribute() throws Exception {
+ DynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+
+ jmxHelper.setAttribute(jmxObjectName, "myattr", "abc");
+ Object actual = jmxHelper.getAttribute(jmxObjectName, "myattr");
+ assertEquals(actual, "abc");
+ }
+
+ @Test
+ public void testSetAttributeUsingObjectNameWildcard() throws Exception {
+ DynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+
+ jmxHelper.setAttribute(jmxObjectNameWithWildcard, "myattr", "abc");
+ Object actual = jmxHelper.getAttribute(jmxObjectName, "myattr");
+ assertEquals(actual, "abc");
+ }
+
+ @Test
+ public void testInvokeOperationWithNoArgs() throws Exception {
+ final String opReturnVal = "my result";
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], String.class.getName(), MBeanOperationInfo.ACTION);
+ Function<Object[], String> opImpl = new Function<Object[], String>() {
+ @Override public String apply(Object[] args) {
+ assertEquals(args.length, 0, "args="+args);
+ return opReturnVal;
+ }
+ };
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
+
+ assertEquals(jmxHelper.operation(objectName, opName), opReturnVal);
+ }
+
+ @Test
+ public void testInvokeOperationUsingObjectNameWildcard() throws Exception {
+ final String opReturnVal = "my result";
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(opName, "my descr", new MBeanParameterInfo[0], String.class.getName(), MBeanOperationInfo.ACTION);
+ Function<Object[], String> opImpl = new Function<Object[], String>() {
+ @Override public String apply(Object[] args) {
+ assertEquals(args.length, 0, "args="+args);
+ return opReturnVal;
+ }
+ };
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
+
+ assertEquals(jmxHelper.operation(objectNameWithWildcard, opName), opReturnVal);
+ }
+
+ @Test
+ public void testInvokeOperationWithArgs() throws Exception {
+ final String opReturnPrefix = "my result prefix/";
+ String opParam1 = "my param 1";
+ MBeanOperationInfo opInfo = new MBeanOperationInfo(
+ opName,
+ "my descr",
+ new MBeanParameterInfo[] {new MBeanParameterInfo("myParam1", String.class.getName(), "my param1 descr")},
+ String.class.getName(),
+ MBeanOperationInfo.ACTION);
+ Function<Object[],String> opImpl = new Function<Object[],String>() {
+ public String apply(Object[] input) {
+ return opReturnPrefix+input[0];
+ }
+ };
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(ImmutableMap.of(), ImmutableMap.of(opInfo, opImpl), objectName);
+
+ assertEquals(jmxHelper.operation(objectName, opName, opParam1), opReturnPrefix+opParam1);
+ }
+
+ @Test
+ public void testReconnectsOnJmxServerTemporaryFailure() throws Exception {
+ int port = jmxService.getJmxPort();
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of("myattr", "myval"), objectName);
+ assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval");
+
+ // Simulate temporary network-failure
+ jmxService.shutdown();
+
+ // Ensure that we have a failed query while the "network is down"
+ try {
+ jmxHelper.getAttribute(jmxObjectName, attributeName);
+ fail();
+ } catch (Exception e) {
+ if (Throwables2.getFirstThrowableOfType(e, IOException.class) == null) {
+ throw e;
+ }
+ }
+
+ // Simulate the network restarting
+ jmxService = new JmxService(LOCALHOST_NAME, port);
+
+ GeneralisedDynamicMBean mbean2 = jmxService.registerMBean(MutableMap.of("myattr", "myval2"), objectName);
+ assertEquals(jmxHelper.getAttribute(jmxObjectName, "myattr"), "myval2");
+ }
+
+ @Test(expectedExceptions = {IllegalStateException.class})
+ public void testJmxCheckInstanceExistsEventuallyThrowsIfNotFound() throws Exception {
+ jmxHelper.assertMBeanExistsEventually(new ObjectName("Brooklyn:type=DoesNotExist,name=doesNotExist"), 1L);
+ }
+
+ @Test
+ public void testJmxObjectCheckExistsEventuallyReturnsIfFoundImmediately() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
+ jmxHelper.assertMBeanExistsEventually(jmxObjectName, 1L);
+ }
+
+ @Test
+ public void testJmxObjectCheckExistsEventuallyTakingLongReturnsIfFoundImmediately() throws Exception {
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
+ jmxHelper.assertMBeanExistsEventually(jmxObjectName, 1L);
+ }
+
+ @Test
+ public void testJmxObjectCheckExistsEventuallyReturnsIfCreatedDuringPolling() throws Exception {
+ Thread t = new Thread(new Runnable() {
+ public void run() {
+ try {
+ Thread.sleep(SHORT_WAIT_MS);
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(objectName);
+ } catch (InterruptedException e) {
+ return; // graceful return
+ } catch (Exception e) {
+ throw Exceptions.propagate(e);
+ }
+ }});
+ try {
+ t.start();
+
+ jmxHelper.assertMBeanExistsEventually(jmxObjectName, TIMEOUT_MS);
+ } finally {
+ t.interrupt();
+ t.join(TIMEOUT_MS);
+ assertFalse(t.isAlive());
+ }
+ }
+
+ @Test
+ public void testSubscribeToJmxNotificationsDirectlyWithJmxHelper() throws Exception {
+ StandardEmitterMBean mbean = jmxService.registerMBean(ImmutableList.of("one"), objectName);
+ int sequence = 0;
+ final List<Notification> received = Lists.newArrayList();
+
+ jmxHelper.addNotificationListener(jmxObjectName, new NotificationListener() {
+ public void handleNotification(Notification notif, Object callback) {
+ received.add(notif);
+ }});
+
+
+ final Notification notif = sendNotification(mbean, "one", sequence++, "abc");
+
+ TestUtils.executeUntilSucceeds(ImmutableMap.of("timeout", TIMEOUT_MS), new Runnable() {
+ public void run() {
+ assertEquals(received.size(), 1);
+ assertNotificationsEqual(received.get(0), notif);
+ }});
+ }
+
+ // Visual-inspection test that LOG.warn happens only once; TODO setup a listener to the logging output
+ @Test
+ public void testMBeanNotFoundLoggedOnlyOncePerUrl() throws Exception {
+ ObjectName wrongObjectName = new ObjectName("DoesNotExist:type=DoesNotExist");
+
+ // Expect just one log message about:
+ // JMX object DoesNotExist:type=DoesNotExist not found at service:jmx:rmi://localhost:1099/jndi/rmi://localhost:9001/jmxrmi"
+ for (int i = 0; i < 10; i++) {
+ jmxHelper.findMBean(wrongObjectName);
+ }
+
+ jmxService.shutdown();
+ jmxHelper.disconnect();
+
+ jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
+ jmxHelper = new JmxHelper(jmxService.getUrl());
+ jmxHelper.connect();
+
+ // Expect just one log message about:
+ // JMX object DoesNotExist:type=DoesNotExist not found at service:jmx:rmi://localhost:1099/jndi/rmi://localhost:9001/jmxrmi"
+ for (int i = 0; i < 10; i++) {
+ jmxHelper.findMBean(wrongObjectName);
+ }
+ }
+
+ private JmxService newJmxServiceRetrying(String host, int retries) throws Exception {
+ Exception lastexception = null;
+ for (int i = 0; i < retries; i++) {
+ try {
+ return new JmxService(host, (int)(11000+(500*Math.random())));
+ } catch (Exception e) {
+ log.debug("Unable to create JMX service during test - "+retries+" retries remaining");
+ lastexception = e;
+ }
+ }
+ throw lastexception;
+ }
+
+ private Notification sendNotification(StandardEmitterMBean mbean, String type, long seq, Object userData) {
+ Notification notif = new Notification(type, mbean, seq);
+ notif.setUserData(userData);
+ mbean.sendNotification(notif);
+ return notif;
+ }
+
+ private void assertNotificationsEqual(Notification n1, Notification n2) {
+ assertEquals(n1.getType(), n2.getType());
+ assertEquals(n1.getSequenceNumber(), n2.getSequenceNumber());
+ assertEquals(n1.getUserData(), n2.getUserData());
+ assertEquals(n1.getTimeStamp(), n2.getTimeStamp());
+ assertEquals(n1.getMessage(), n2.getMessage());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
new file mode 100644
index 0000000..f4a72cd
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/sensor/feed/jmx/RebindJmxFeedTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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.sensor.feed.jmx;
+
+import static org.testng.Assert.assertEquals;
+
+import java.util.Collection;
+
+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.api.sensor.Feed;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.core.test.entity.TestEntityImpl;
+import org.apache.brooklyn.entity.core.Attributes;
+import org.apache.brooklyn.entity.java.UsesJmx;
+import org.apache.brooklyn.entity.java.UsesJmx.JmxAgentModes;
+import org.apache.brooklyn.entity.software.base.test.jmx.GeneralisedDynamicMBean;
+import org.apache.brooklyn.entity.software.base.test.jmx.JmxService;
+import org.apache.brooklyn.sensor.core.Sensors;
+import org.apache.brooklyn.sensor.feed.ConfigToAttributes;
+import org.apache.brooklyn.sensor.feed.jmx.JmxAttributePollConfig;
+import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
+import org.apache.brooklyn.sensor.feed.jmx.JmxHelper;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.PortRanges;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+public class RebindJmxFeedTest extends RebindTestFixtureWithApp {
+
+ private static final Logger log = LoggerFactory.getLogger(RebindJmxFeedTest.class);
+
+ private static final String LOCALHOST_NAME = "localhost";
+
+ static final AttributeSensor<String> SENSOR_STRING = Sensors.newStringSensor("aString", "");
+ static final AttributeSensor<Integer> SENSOR_INT = Sensors.newIntegerSensor( "aLong", "");
+
+ static final String JMX_ATTRIBUTE_NAME = "myattr";
+ static final String OBJECT_NAME = "Brooklyn:type=MyTestMBean,name=myname";
+
+ private JmxService jmxService;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // Create an entity and configure it with the above JMX service
+ //jmxService = newJmxServiceRetrying(LOCALHOST_NAME, 5);
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ if (jmxService != null) jmxService.shutdown();
+ super.tearDown();
+ }
+
+ @Test
+ public void testJmxFeedIsPersisted() throws Exception {
+ runJmxFeedIsPersisted(false);
+ }
+
+ @Test
+ public void testJmxFeedIsPersistedWithPreCreatedJmxHelper() throws Exception {
+ runJmxFeedIsPersisted(true);
+ }
+
+ protected void runJmxFeedIsPersisted(boolean preCreateJmxHelper) throws Exception {
+ TestEntity origEntity = origApp.createAndManageChild(EntitySpec.create(TestEntity.class).impl(MyEntityWithJmxFeedImpl.class)
+ .configure(MyEntityWithJmxFeedImpl.PRE_CREATE_JMX_HELPER, preCreateJmxHelper));
+ origApp.start(ImmutableList.<Location>of());
+
+ jmxService = new JmxService(origEntity);
+ GeneralisedDynamicMBean mbean = jmxService.registerMBean(MutableMap.of(JMX_ATTRIBUTE_NAME, "myval"), OBJECT_NAME);
+
+ EntityTestUtils.assertAttributeEqualsEventually(origEntity, SENSOR_STRING, "myval");
+ assertEquals(origEntity.feeds().getFeeds().size(), 1);
+
+ newApp = rebind();
+ TestEntity newEntity = (TestEntity) Iterables.getOnlyElement(newApp.getChildren());
+
+ Collection<Feed> newFeeds = newEntity.feeds().getFeeds();
+ assertEquals(newFeeds.size(), 1);
+
+ // Expect the feed to still be polling
+ newEntity.setAttribute(SENSOR_STRING, null);
+ EntityTestUtils.assertAttributeEqualsEventually(newEntity, SENSOR_STRING, "myval");
+ }
+
+ public static class MyEntityWithJmxFeedImpl extends TestEntityImpl {
+ public static final ConfigKey<Boolean> PRE_CREATE_JMX_HELPER = ConfigKeys.newBooleanConfigKey("test.rebindjmx.preCreateJmxHelper", "", false);
+
+ @Override
+ public void start(Collection<? extends Location> locs) {
+ // TODO Auto-generated method stub
+ super.start(locs);
+
+ setAttribute(Attributes.HOSTNAME, "localhost");
+ setAttribute(UsesJmx.JMX_PORT,
+ LocalhostMachineProvisioningLocation.obtainPort(PortRanges.fromString("40123+")));
+ // only supports no-agent, at the moment
+ setConfig(UsesJmx.JMX_AGENT_MODE, JmxAgentModes.NONE);
+ setAttribute(UsesJmx.RMI_REGISTRY_PORT, -1); // -1 means to use the JMX_PORT only
+ ConfigToAttributes.apply(this, UsesJmx.JMX_CONTEXT);
+
+ JmxFeed.Builder feedBuilder = JmxFeed.builder()
+ .entity(this)
+ .pollAttribute(new JmxAttributePollConfig<String>(SENSOR_STRING)
+ .objectName(OBJECT_NAME)
+ .period(50)
+ .attributeName(JMX_ATTRIBUTE_NAME));
+ if (getConfig(PRE_CREATE_JMX_HELPER)) {
+ JmxHelper jmxHelper = new JmxHelper(this);
+ feedBuilder.helper(jmxHelper);
+ }
+ addFeed(feedBuilder.build());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasksTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasksTest.java b/software/base/src/test/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasksTest.java
new file mode 100644
index 0000000..073a8df
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/sensor/ssh/SshEffectorTasksTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.sensor.ssh;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.mgmt.ManagementContext;
+import org.apache.brooklyn.api.mgmt.TaskAdaptable;
+import org.apache.brooklyn.api.mgmt.TaskFactory;
+import org.apache.brooklyn.core.test.entity.TestApplication;
+import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
+import org.apache.brooklyn.util.core.task.ssh.SshFetchTaskWrapper;
+import org.apache.brooklyn.util.core.task.ssh.SshPutTaskWrapper;
+import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
+import org.apache.brooklyn.util.exceptions.PropagatedRuntimeException;
+import org.apache.brooklyn.util.net.Urls;
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.basic.LocalhostMachineProvisioningLocation;
+import org.apache.brooklyn.location.basic.SshMachineLocation;
+
+import com.google.common.io.Files;
+
+public class SshEffectorTasksTest {
+
+ private static final Logger log = LoggerFactory.getLogger(SshEffectorTasksTest.class);
+
+ TestApplication app;
+ ManagementContext mgmt;
+ SshMachineLocation host;
+ File tempDir;
+
+ boolean failureExpected;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setup() throws Exception {
+ app = TestApplication.Factory.newManagedInstanceForTests();
+ mgmt = app.getManagementContext();
+
+ LocalhostMachineProvisioningLocation lhc = mgmt.getLocationManager().createLocation(LocationSpec.create(LocalhostMachineProvisioningLocation.class));
+ host = lhc.obtain();
+ app.start(Arrays.asList(host));
+ clearExpectedFailure();
+ tempDir = Files.createTempDir();
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (mgmt != null) Entities.destroyAll(mgmt);
+ mgmt = null;
+ FileUtils.deleteDirectory(tempDir);
+ checkExpectedFailure();
+ }
+
+ protected void checkExpectedFailure() {
+ if (failureExpected) {
+ clearExpectedFailure();
+ Assert.fail("Test should have thrown an exception but it did not.");
+ }
+ }
+
+ protected void clearExpectedFailure() {
+ failureExpected = false;
+ }
+
+ protected void setExpectingFailure() {
+ failureExpected = true;
+ }
+
+ public <T extends TaskAdaptable<?>> T submit(final TaskFactory<T> taskFactory) {
+ return Entities.submit(app, taskFactory);
+ }
+
+ // ------------------- basic ssh
+
+ @Test(groups="Integration")
+ public void testSshEchoHello() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.ssh("sleep 1 ; echo hello world"));
+ Assert.assertFalse(t.isDone());
+ Assert.assertEquals(t.get(), (Integer)0);
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ Assert.assertEquals(t.getStdout().trim(), "hello world");
+ }
+
+ @Test(groups="Integration")
+ public void testSshPut() throws IOException {
+ String fn = Urls.mergePaths(tempDir.getPath(), "f1");
+ SshPutTaskWrapper t = submit(SshEffectorTasks.put(fn).contents("hello world"));
+ t.block();
+ Assert.assertEquals(FileUtils.readFileToString(new File(fn)), "hello world");
+ // and make sure this doesn't throw
+ Assert.assertTrue(t.isDone());
+ Assert.assertTrue(t.isSuccessful());
+ Assert.assertEquals(t.get(), null);
+ Assert.assertEquals(t.getExitCode(), (Integer)0);
+ }
+
+ @Test(groups="Integration")
+ public void testSshFetch() throws IOException {
+ String fn = Urls.mergePaths(tempDir.getPath(), "f2");
+ FileUtils.write(new File(fn), "hello fetched world");
+
+ SshFetchTaskWrapper t = submit(SshEffectorTasks.fetch(fn));
+ t.block();
+
+ Assert.assertTrue(t.isDone());
+ Assert.assertEquals(t.get(), "hello fetched world");
+ }
+
+ // ----------------- pid stuff
+
+ @Test(groups="Integration")
+ public void testNonRunningPid() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(99999));
+ Assert.assertNotEquals(t.getTask().getUnchecked(), (Integer)0);
+ Assert.assertNotEquals(t.getExitCode(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(99999));
+ Assert.assertFalse(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testNonRunningPidRequired() {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidRunning(99999));
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ }
+ checkExpectedFailure();
+ }
+
+ public static Integer getMyPid() {
+ try {
+ java.lang.management.RuntimeMXBean runtime =
+ java.lang.management.ManagementFactory.getRuntimeMXBean();
+ java.lang.reflect.Field jvm = runtime.getClass().getDeclaredField("jvm");
+ jvm.setAccessible(true);
+// sun.management.VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+ Object mgmt = jvm.get(runtime);
+ java.lang.reflect.Method pid_method =
+ mgmt.getClass().getDeclaredMethod("getProcessId");
+ pid_method.setAccessible(true);
+
+ return (Integer) pid_method.invoke(mgmt);
+ } catch (Exception e) {
+ throw new PropagatedRuntimeException("Test depends on (fragile) getMyPid method which does not work here", e);
+ }
+ }
+
+ @Test(groups="Integration")
+ public void testRunningPid() {
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidRunning(getMyPid()));
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidRunning(getMyPid()));
+ Assert.assertTrue(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testRunningPidFromFile() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<Integer> t = submit(SshEffectorTasks.codePidFromFileRunning(f.getPath()));
+ Assert.assertEquals(t.getTask().getUnchecked(), (Integer)0);
+ ProcessTaskWrapper<Boolean> t2 = submit(SshEffectorTasks.isPidFromFileRunning(f.getPath()));
+ Assert.assertTrue(t2.getTask().getUnchecked());
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailure() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( "99999".getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)1);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailureNoSuchFile() throws IOException {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/path/does/not/exist/SADVQW"));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)1);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnFailureTooManyFiles() throws IOException {
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning("/*"));
+
+ setExpectingFailure();
+ try {
+ t.getTask().getUnchecked();
+ } catch (Exception e) {
+ log.info("The error if required PID is not found is: "+e);
+ clearExpectedFailure();
+ Assert.assertTrue(e.toString().contains("Process with PID"), "Expected nice clue in error but got: "+e);
+ Assert.assertEquals(t.getExitCode(), (Integer)2);
+ }
+ checkExpectedFailure();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnSuccess() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()));
+
+ t.getTask().getUnchecked();
+ }
+
+ @Test(groups="Integration")
+ public void testRequirePidFromFileOnSuccessAcceptsWildcards() throws IOException {
+ File f = File.createTempFile("testBrooklynPid", ".pid");
+ Files.write( (""+getMyPid()).getBytes(), f );
+ ProcessTaskWrapper<?> t = submit(SshEffectorTasks.requirePidFromFileRunning(f.getPath()+"*"));
+
+ t.getTask().getUnchecked();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/brooklyn/entity/basic/frogs.txt
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/brooklyn/entity/basic/frogs.txt b/software/base/src/test/resources/brooklyn/entity/basic/frogs.txt
deleted file mode 100644
index a3f617a..0000000
--- a/software/base/src/test/resources/brooklyn/entity/basic/frogs.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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.
-#
-# The Frogs
-
-Frogs:
-> Brekekekex koax koax.
-
-Dionysus:
-> Go to hell with your koax
-> koax and nothing but koax!
-
-- Artistophanes, c. 400 BC
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/brooklyn/entity/basic/template.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/brooklyn/entity/basic/template.yaml b/software/base/src/test/resources/brooklyn/entity/basic/template.yaml
deleted file mode 100644
index 4d2b29e..0000000
--- a/software/base/src/test/resources/brooklyn/entity/basic/template.yaml
+++ /dev/null
@@ -1,23 +0,0 @@
-[#ftl]
-# 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.
-
-entity.hostname:
- ${driver.hostname}
-entity.address:
- ${driver.address}
-frogs: 12
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/brooklyn/entity/basic/template_with_extra_substitutions.txt
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/brooklyn/entity/basic/template_with_extra_substitutions.txt b/software/base/src/test/resources/brooklyn/entity/basic/template_with_extra_substitutions.txt
deleted file mode 100644
index 8330e3e..0000000
--- a/software/base/src/test/resources/brooklyn/entity/basic/template_with_extra_substitutions.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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.
-
-${myname}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-tests.pem
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-tests.pem b/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-tests.pem
deleted file mode 100644
index 4ca4d00..0000000
--- a/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-tests.pem
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEArJZcg6Y9BuPYuLWgcloS/cH6HzqQqQegW+5d7cgRZC1CCo4e
-GxVglEZXuko4N0PVK2E2khGiMEymVXWqmrHAnTSqV1COmRfxxOxGvmQRleDWMhED
-j2KoOwggwsaoHBEdrZ6NX+yv3iFiOS5fz3Klkt3kPXcXZJGiFsOtyZaSxK/m26no
-upS6ouChmk9TD8YcCQzdUGNAWwyzhiDg5DwqnnNQQUKvQyJuV/nyxwRMcpoNazca
-ghr2KalSF92sonnPzMz2gWhKxWVVbnTSafWQcWY+ov/TiyBHsLXO3/OrHaj7h+SF
-UUfWryHyqZI/eQeoWD/cPGtr8qVELIqhCq8OkQIDAQABAoIBAAS2Eg5x8kaG37qj
-Ep8sgEo3Clnh4mMK10DLL/s2s+rVJXFeUcoRelJx3SEzt3civeXyQGgaXSAOZ5f7
-n02bvpNMBb5eb5YURkBG5uN5ndVGjvJM7pjya385CJPoklw5x2Ke6mMM9fwNUz4W
-Wv0xtv1cW0emQZg4NYGDk/Hlz1nZG+y5j0esRlIiknYqdfuXtaQbVI/jGSyNXFVI
-uVkKCwq+k6HnIkjFEZdvQPRPaGMT4cMwczVr8hCIOfCJEVremEJ0GFnazr9iNEVu
-18YJzOEaqPLgVvjt59o+D+CoZS7U74WX6scCsFCkHLdnxlfNC/qkrn2SEaVyrfeP
-cqPLZJUCgYEA1qmmQzuNzWMhsOVty3EI4M2mePF0iM2P/wHc1ry9lddqdqTSGV7x
-NwzGNZ/OqN9UIR/3chyFXQuegz5VZxsrdIyxcgCmM2cDDxny3pr0Lct39gsWuc9g
-BhebUDP7PoF2g2f4AAllVR6atClwXoKfARoXlmbjfOJSB/q1zXWYNW8CgYEAzdJ/
-2o1B4iwDipKxJE2luuaMN4zqRbKdokBJYw0b1TOOcsyNwB5h0TGcJNFMuIqBeWCK
-J3wr7FTOfy3Qsbf3Vc5Le6NdaHomy7+HEwVMzyEPVNKumHqEL9U3Yheu5TVLLKMU
-rYBXXpoN/XXm9XxvRGhGu7Wu99ye37hIa4Qy+/8CgYB/JWlHdWTefJMeFibcU41w
-qh6qkEn4Jdner5nAz3Zz5G447BNN18CEXNqiNI/R0sYgALEuM9qCbDltf2RSd/Nb
-S2JnJh9LXv6e2T3TwHBVF6lsYNELKdu0gBMMhF2SflhWKSTp0KbmrgPwJoNaV4Aa
-xPunqDWiaOMxurwogDixnQKBgGgGQs5P5IOOIUARQeyKPgAHc8jDtMgDLX6KpUyl
-nHKV+yH0VpRKBsA3JabKDc+bWTLiYxDvxjdM6Y0Ht9mKlDxO5oGXoKckTaVeqMMp
-Q5fQKrKBRPMVwOd4COTP+XopBFSMG/BQ1Feg3v9CbreV65qUZWOLwOHPJJEHz7pf
-d3E7AoGBAMPkKjDuhU8YTpB6H4KlCM+9p/6yE7umoWMPJm70301XxBoQA8spkS3o
-K2s2xL7+MuppvLv0xqyZ1vtvqmUMrw/eisQWekGobEiutk+DuxegRlpUkH0s6CH4
-lypeh/FpGdLayAn84ALIEYhCsr0SnJtEL1MEO9qPKJY24Hl6ATCC
------END RSA PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-validator.pem
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-validator.pem b/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-validator.pem
deleted file mode 100644
index 7fb694c..0000000
--- a/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-validator.pem
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEowIBAAKCAQEA1L/awgkt+AxAHc76IeJAsZYj0ZoW8pP0Ff2SL8ZmkoGOT3C6
-d6DhQ8H194YTYNZ+w+D4K6DkNf8MqoFnQnLyQHlALd+giCE9mS1SUS0YBBdXbGh/
-320cosPqvMrT16nxbTLz7rgGNYSvgS5tnFYIADv4AzvXZMOZ20VXkDNCiqG0Pqy5
-qAMvmNGJNpDfERebdQUoZpqPJysJYXmy2cKYm5cfsDCxmL9iGyPjHazU6FizC50M
-SJ+ZGtqVEB/0d4p4u/pHAZQJCFdxJszHqBbYfQDFJso9lAdkM/11Tq5NtBH3cTPi
-SfcFIWLSS4qu1RcRmURRtsZTr/4FOKcYWpmLcwIDAQABAoIBACLzzi3YsjuxT4tW
-KNQORtCmOQZDiYea9Rvzx+OfddSWAlpcy9XBkaC/Kfjbhy1+r97ghAUu7q9MUrlk
-fyF0nwYmpXuj5MzYoTUcNAzwGqT5bLx7wp5jX7QB+fvAWuNwoSBuoZLTmvmJ7geM
-KCfqHnBjadCmMTH1zL4wez1Onp0FvRDXGPGjERQGptpejTL8PBaarzF2Ufewb/0z
-2/Icl1RAGHNkJHJjedL2mgtKHzW/JTBLcMjN1+PL4pLMriXCTP3VZZlezx8RXrnW
-DTFWe6G8gcPhYh0ni3wtoI/ENvXORg+wFXa2B/FKRObTu+vyYyvDgUSB2TI5LebX
-XsuWEEECgYEA/f9gkab9+m9JDz7AYDF4f+YzECdZwA0ntAnA5Qb/zWnjbcbtOMMF
-lNEm+m9J9GoorSpO9e/4Z61dtEsuX9Vr2tyKSnamNQT2vI+WIUIbGMWFq/VNi390
-o0jQWhEead/xu5BFbLEBD651+NBQGBCQi8slzOAL6jqP8qEGeaYaauECgYEA1m06
-wdHM3U5wwCGsyzTloGZ0LtTFO6oKYPpU/MItEESqVY1grFh5Sqa6tyJEq0jZSdKM
-eXzlqSyJQbaHd85PJnDkVnJVpdeqRj1eMHtv9+s3A8kOzSww+FL7KJHUrnNBZ7MK
-J7wdPtzYBFL124NAhbTaR6+Kv1ZSUpkGFRCV9NMCgYBtMy5BcJog4Vd3xnLO6HX2
-BvJNL53Wg9FeBhN4Y9n2Zl/xAmVa0f3ETWeEo/QXsMxsJpRsCA+0A0UWDnyRlyAX
-qFmMShaLFOc/ijvxcIpVzBX8KCp+nv12dgedsV5yBmXXTd+LK05Zf5gYsPa+YeDD
-OUO3IVv+B897cN9nzZHuAQKBgGIC44ycXUv7AsaPne/0adF7gze0wcKX4s6ZHie6
-ieaZvFIGoV2lwytAMrBq1YCFd+yqdNNDJ6bAWKzUxe8ZOkyT5YsuD8ASaB5bBqaa
-hX+I4Ei2qjFWNbwMEgllPxXOUOMZj1bCQYvuXj77vK1tvRxgojWKI5150381uvX9
-8s1JAoGBAO73ig60VNqPTHg1KDZ7SdAW0KbNiAV+xojvW9pkH5M1vCllz+lpeW1l
-jZFbnL013r5UvzRgwqIuw4t+gZikfIZgPwP8Z2BGtIzNiIHy/RLzOawsPTTXczZA
-hHI2e54G9DgCi8h4LXhFavVykTkNTP62S6za4VTEjxERdWxIBnfL
------END RSA PRIVATE KEY-----
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/knife.rb
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/knife.rb b/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/knife.rb
deleted file mode 100644
index d52e492..0000000
--- a/software/base/src/test/resources/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/knife.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# 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.
-#
-
-current_dir = File.dirname(__FILE__)
-log_level :info
-log_location STDOUT
-node_name "brooklyn-tests"
-client_key "#{current_dir}/brooklyn-tests.pem"
-validation_client_name "brooklyn-validator"
-validation_key "#{current_dir}/brooklyn-validator.pem"
-chef_server_url "https://api.opscode.com/organizations/brooklyn"
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-tests.pem
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-tests.pem b/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-tests.pem
new file mode 100644
index 0000000..4ca4d00
--- /dev/null
+++ b/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-tests.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEArJZcg6Y9BuPYuLWgcloS/cH6HzqQqQegW+5d7cgRZC1CCo4e
+GxVglEZXuko4N0PVK2E2khGiMEymVXWqmrHAnTSqV1COmRfxxOxGvmQRleDWMhED
+j2KoOwggwsaoHBEdrZ6NX+yv3iFiOS5fz3Klkt3kPXcXZJGiFsOtyZaSxK/m26no
+upS6ouChmk9TD8YcCQzdUGNAWwyzhiDg5DwqnnNQQUKvQyJuV/nyxwRMcpoNazca
+ghr2KalSF92sonnPzMz2gWhKxWVVbnTSafWQcWY+ov/TiyBHsLXO3/OrHaj7h+SF
+UUfWryHyqZI/eQeoWD/cPGtr8qVELIqhCq8OkQIDAQABAoIBAAS2Eg5x8kaG37qj
+Ep8sgEo3Clnh4mMK10DLL/s2s+rVJXFeUcoRelJx3SEzt3civeXyQGgaXSAOZ5f7
+n02bvpNMBb5eb5YURkBG5uN5ndVGjvJM7pjya385CJPoklw5x2Ke6mMM9fwNUz4W
+Wv0xtv1cW0emQZg4NYGDk/Hlz1nZG+y5j0esRlIiknYqdfuXtaQbVI/jGSyNXFVI
+uVkKCwq+k6HnIkjFEZdvQPRPaGMT4cMwczVr8hCIOfCJEVremEJ0GFnazr9iNEVu
+18YJzOEaqPLgVvjt59o+D+CoZS7U74WX6scCsFCkHLdnxlfNC/qkrn2SEaVyrfeP
+cqPLZJUCgYEA1qmmQzuNzWMhsOVty3EI4M2mePF0iM2P/wHc1ry9lddqdqTSGV7x
+NwzGNZ/OqN9UIR/3chyFXQuegz5VZxsrdIyxcgCmM2cDDxny3pr0Lct39gsWuc9g
+BhebUDP7PoF2g2f4AAllVR6atClwXoKfARoXlmbjfOJSB/q1zXWYNW8CgYEAzdJ/
+2o1B4iwDipKxJE2luuaMN4zqRbKdokBJYw0b1TOOcsyNwB5h0TGcJNFMuIqBeWCK
+J3wr7FTOfy3Qsbf3Vc5Le6NdaHomy7+HEwVMzyEPVNKumHqEL9U3Yheu5TVLLKMU
+rYBXXpoN/XXm9XxvRGhGu7Wu99ye37hIa4Qy+/8CgYB/JWlHdWTefJMeFibcU41w
+qh6qkEn4Jdner5nAz3Zz5G447BNN18CEXNqiNI/R0sYgALEuM9qCbDltf2RSd/Nb
+S2JnJh9LXv6e2T3TwHBVF6lsYNELKdu0gBMMhF2SflhWKSTp0KbmrgPwJoNaV4Aa
+xPunqDWiaOMxurwogDixnQKBgGgGQs5P5IOOIUARQeyKPgAHc8jDtMgDLX6KpUyl
+nHKV+yH0VpRKBsA3JabKDc+bWTLiYxDvxjdM6Y0Ht9mKlDxO5oGXoKckTaVeqMMp
+Q5fQKrKBRPMVwOd4COTP+XopBFSMG/BQ1Feg3v9CbreV65qUZWOLwOHPJJEHz7pf
+d3E7AoGBAMPkKjDuhU8YTpB6H4KlCM+9p/6yE7umoWMPJm70301XxBoQA8spkS3o
+K2s2xL7+MuppvLv0xqyZ1vtvqmUMrw/eisQWekGobEiutk+DuxegRlpUkH0s6CH4
+lypeh/FpGdLayAn84ALIEYhCsr0SnJtEL1MEO9qPKJY24Hl6ATCC
+-----END RSA PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-validator.pem
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-validator.pem b/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-validator.pem
new file mode 100644
index 0000000..7fb694c
--- /dev/null
+++ b/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/brooklyn-validator.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA1L/awgkt+AxAHc76IeJAsZYj0ZoW8pP0Ff2SL8ZmkoGOT3C6
+d6DhQ8H194YTYNZ+w+D4K6DkNf8MqoFnQnLyQHlALd+giCE9mS1SUS0YBBdXbGh/
+320cosPqvMrT16nxbTLz7rgGNYSvgS5tnFYIADv4AzvXZMOZ20VXkDNCiqG0Pqy5
+qAMvmNGJNpDfERebdQUoZpqPJysJYXmy2cKYm5cfsDCxmL9iGyPjHazU6FizC50M
+SJ+ZGtqVEB/0d4p4u/pHAZQJCFdxJszHqBbYfQDFJso9lAdkM/11Tq5NtBH3cTPi
+SfcFIWLSS4qu1RcRmURRtsZTr/4FOKcYWpmLcwIDAQABAoIBACLzzi3YsjuxT4tW
+KNQORtCmOQZDiYea9Rvzx+OfddSWAlpcy9XBkaC/Kfjbhy1+r97ghAUu7q9MUrlk
+fyF0nwYmpXuj5MzYoTUcNAzwGqT5bLx7wp5jX7QB+fvAWuNwoSBuoZLTmvmJ7geM
+KCfqHnBjadCmMTH1zL4wez1Onp0FvRDXGPGjERQGptpejTL8PBaarzF2Ufewb/0z
+2/Icl1RAGHNkJHJjedL2mgtKHzW/JTBLcMjN1+PL4pLMriXCTP3VZZlezx8RXrnW
+DTFWe6G8gcPhYh0ni3wtoI/ENvXORg+wFXa2B/FKRObTu+vyYyvDgUSB2TI5LebX
+XsuWEEECgYEA/f9gkab9+m9JDz7AYDF4f+YzECdZwA0ntAnA5Qb/zWnjbcbtOMMF
+lNEm+m9J9GoorSpO9e/4Z61dtEsuX9Vr2tyKSnamNQT2vI+WIUIbGMWFq/VNi390
+o0jQWhEead/xu5BFbLEBD651+NBQGBCQi8slzOAL6jqP8qEGeaYaauECgYEA1m06
+wdHM3U5wwCGsyzTloGZ0LtTFO6oKYPpU/MItEESqVY1grFh5Sqa6tyJEq0jZSdKM
+eXzlqSyJQbaHd85PJnDkVnJVpdeqRj1eMHtv9+s3A8kOzSww+FL7KJHUrnNBZ7MK
+J7wdPtzYBFL124NAhbTaR6+Kv1ZSUpkGFRCV9NMCgYBtMy5BcJog4Vd3xnLO6HX2
+BvJNL53Wg9FeBhN4Y9n2Zl/xAmVa0f3ETWeEo/QXsMxsJpRsCA+0A0UWDnyRlyAX
+qFmMShaLFOc/ijvxcIpVzBX8KCp+nv12dgedsV5yBmXXTd+LK05Zf5gYsPa+YeDD
+OUO3IVv+B897cN9nzZHuAQKBgGIC44ycXUv7AsaPne/0adF7gze0wcKX4s6ZHie6
+ieaZvFIGoV2lwytAMrBq1YCFd+yqdNNDJ6bAWKzUxe8ZOkyT5YsuD8ASaB5bBqaa
+hX+I4Ei2qjFWNbwMEgllPxXOUOMZj1bCQYvuXj77vK1tvRxgojWKI5150381uvX9
+8s1JAoGBAO73ig60VNqPTHg1KDZ7SdAW0KbNiAV+xojvW9pkH5M1vCllz+lpeW1l
+jZFbnL013r5UvzRgwqIuw4t+gZikfIZgPwP8Z2BGtIzNiIHy/RLzOawsPTTXczZA
+hHI2e54G9DgCi8h4LXhFavVykTkNTP62S6za4VTEjxERdWxIBnfL
+-----END RSA PRIVATE KEY-----
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/knife.rb
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/knife.rb b/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/knife.rb
new file mode 100644
index 0000000..d52e492
--- /dev/null
+++ b/software/base/src/test/resources/org/apache/brooklyn/entity/chef/hosted-chef-brooklyn-credentials/knife.rb
@@ -0,0 +1,27 @@
+#
+# 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.
+#
+
+current_dir = File.dirname(__FILE__)
+log_level :info
+log_location STDOUT
+node_name "brooklyn-tests"
+client_key "#{current_dir}/brooklyn-tests.pem"
+validation_client_name "brooklyn-validator"
+validation_key "#{current_dir}/brooklyn-validator.pem"
+chef_server_url "https://api.opscode.com/organizations/brooklyn"
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/frogs.txt
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/frogs.txt b/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/frogs.txt
new file mode 100644
index 0000000..a3f617a
--- /dev/null
+++ b/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/frogs.txt
@@ -0,0 +1,27 @@
+# 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.
+#
+# The Frogs
+
+Frogs:
+> Brekekekex koax koax.
+
+Dionysus:
+> Go to hell with your koax
+> koax and nothing but koax!
+
+- Artistophanes, c. 400 BC
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/template.yaml
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/template.yaml b/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/template.yaml
new file mode 100644
index 0000000..4d2b29e
--- /dev/null
+++ b/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/template.yaml
@@ -0,0 +1,23 @@
+[#ftl]
+# 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.
+
+entity.hostname:
+ ${driver.hostname}
+entity.address:
+ ${driver.address}
+frogs: 12
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/template_with_extra_substitutions.txt
----------------------------------------------------------------------
diff --git a/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/template_with_extra_substitutions.txt b/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/template_with_extra_substitutions.txt
new file mode 100644
index 0000000..8330e3e
--- /dev/null
+++ b/software/base/src/test/resources/org/apache/brooklyn/entity/software/base/template_with_extra_substitutions.txt
@@ -0,0 +1,18 @@
+# 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.
+
+${myname}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java
index 9762d5c..94b03bf 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNode.java
@@ -22,16 +22,12 @@ import org.apache.brooklyn.api.entity.ImplementedBy;
import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
-
-import brooklyn.entity.basic.SoftwareProcess;
-
import org.apache.brooklyn.entity.core.Attributes;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
-
-import brooklyn.entity.java.UsesJava;
-import brooklyn.entity.java.UsesJavaMXBeans;
-import brooklyn.entity.java.UsesJmx;
-
+import org.apache.brooklyn.entity.java.UsesJava;
+import org.apache.brooklyn.entity.java.UsesJavaMXBeans;
+import org.apache.brooklyn.entity.java.UsesJmx;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.location.basic.PortRanges;
import org.apache.brooklyn.sensor.core.AttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeDriver.java
index 708e0e8..de01b6b 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeDriver.java
@@ -18,7 +18,7 @@
*/
package org.apache.brooklyn.entity.database.crate;
-import brooklyn.entity.java.JavaSoftwareProcessDriver;
+import org.apache.brooklyn.entity.java.JavaSoftwareProcessDriver;
public interface CrateNodeDriver extends JavaSoftwareProcessDriver {
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
index 5cf4065..7e4f314 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeImpl.java
@@ -20,16 +20,15 @@ package org.apache.brooklyn.entity.database.crate;
import org.apache.brooklyn.core.config.render.RendererHints;
import org.apache.brooklyn.entity.core.Attributes;
+import org.apache.brooklyn.entity.java.JavaAppUtils;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.sensor.enricher.Enrichers;
import org.apache.brooklyn.sensor.feed.http.HttpFeed;
import org.apache.brooklyn.sensor.feed.http.HttpPollConfig;
import org.apache.brooklyn.sensor.feed.http.HttpValueFunctions;
+import org.apache.brooklyn.sensor.feed.jmx.JmxFeed;
import org.apache.brooklyn.util.guava.Functionals;
-import brooklyn.entity.basic.SoftwareProcessImpl;
-import brooklyn.entity.java.JavaAppUtils;
-import brooklyn.event.feed.jmx.JmxFeed;
-
public class CrateNodeImpl extends SoftwareProcessImpl implements CrateNode{
private JmxFeed jmxFeed;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeSshDriver.java
index f72c071..fbfe9dd 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/crate/CrateNodeSshDriver.java
@@ -24,11 +24,10 @@ import java.util.List;
import org.apache.brooklyn.api.internal.EntityLocal;
import org.apache.brooklyn.entity.core.Entities;
+import org.apache.brooklyn.entity.java.JavaSoftwareProcessSshDriver;
import com.google.common.collect.ImmutableList;
-import brooklyn.entity.java.JavaSoftwareProcessSshDriver;
-
import org.apache.brooklyn.location.basic.SshMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.net.Urls;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbDriver.java
index 066a73b..05c097a 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbDriver.java
@@ -18,10 +18,9 @@
*/
package org.apache.brooklyn.entity.database.mariadb;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessDriver;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import brooklyn.entity.basic.SoftwareProcessDriver;
-
/**
* The {@link SoftwareProcessDriver} for MariaDB.
*/
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java
index 5612b5b..a5a91f6 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNode.java
@@ -25,12 +25,10 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
-
-import brooklyn.entity.basic.SoftwareProcess;
-
import org.apache.brooklyn.entity.core.Attributes;
import org.apache.brooklyn.entity.database.DatabaseNode;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.location.basic.PortRanges;
import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
index 632e3f2..0b5becf 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbNodeImpl.java
@@ -20,10 +20,8 @@ package org.apache.brooklyn.entity.database.mariadb;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.SoftwareProcessImpl;
-
import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.apache.brooklyn.location.basic.Locations;
import org.apache.brooklyn.location.basic.SshMachineLocation;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
index 054e5fa..300cc35 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mariadb/MariaDbSshDriver.java
@@ -33,17 +33,13 @@ import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver;
-
import org.apache.brooklyn.entity.core.Attributes;
import org.apache.brooklyn.entity.core.Entities;
import org.apache.brooklyn.entity.database.DatastoreMixins;
-
-import brooklyn.entity.software.SshEffectorTasks;
-
+import org.apache.brooklyn.entity.software.base.AbstractSoftwareProcessSshDriver;
import org.apache.brooklyn.api.location.OsDetails;
import org.apache.brooklyn.location.basic.SshMachineLocation;
+import org.apache.brooklyn.sensor.ssh.SshEffectorTasks;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.task.DynamicTasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlDriver.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlDriver.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlDriver.java
index b11d22b..461369b 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlDriver.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlDriver.java
@@ -18,10 +18,9 @@
*/
package org.apache.brooklyn.entity.database.mysql;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessDriver;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
-import brooklyn.entity.basic.SoftwareProcessDriver;
-
/**
* The {@link SoftwareProcessDriver} for MySQL.
*/
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
index b9e9f2c..be837c4 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNode.java
@@ -25,14 +25,12 @@ import org.apache.brooklyn.api.sensor.AttributeSensor;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.MapConfigKey;
-
-import brooklyn.entity.basic.SoftwareProcess;
-
import org.apache.brooklyn.effector.core.MethodEffector;
import org.apache.brooklyn.entity.annotation.Effector;
import org.apache.brooklyn.entity.annotation.EffectorParam;
import org.apache.brooklyn.entity.core.Attributes;
import org.apache.brooklyn.entity.database.DatastoreMixins.DatastoreCommon;
+import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.location.basic.PortRanges;
import org.apache.brooklyn.sensor.core.BasicAttributeSensorAndConfigKey;
import org.apache.brooklyn.sensor.core.PortAttributeSensorAndConfigKey;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/64c2b2e5/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
----------------------------------------------------------------------
diff --git a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
index 5d1462f..4f0ae7d 100644
--- a/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
+++ b/software/database/src/main/java/org/apache/brooklyn/entity/database/mysql/MySqlNodeImpl.java
@@ -22,11 +22,9 @@ import java.util.Map;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.effector.core.EffectorBody;
+import org.apache.brooklyn.entity.software.base.SoftwareProcessImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.basic.SoftwareProcessImpl;
-
import org.apache.brooklyn.location.basic.Locations;
import org.apache.brooklyn.location.basic.SshMachineLocation;
import org.apache.brooklyn.sensor.feed.ssh.SshFeed;