You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by dr...@apache.org on 2017/02/06 12:36:20 UTC

[1/2] brooklyn-server git commit: BROOKLYN-425: softwareProcess.rebind execs with entity context

Repository: brooklyn-server
Updated Branches:
  refs/heads/master 55ec074f4 -> 5c5d578f4


BROOKLYN-425: softwareProcess.rebind execs with entity context


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

Branch: refs/heads/master
Commit: d9e4c6f3e7ffa6bd5c17c99bc6c6c9d4690b1ae6
Parents: 0570ca5
Author: Aled Sage <al...@gmail.com>
Authored: Thu Jan 12 18:16:49 2017 +0000
Committer: Aled Sage <al...@gmail.com>
Committed: Tue Jan 24 15:42:08 2017 +0000

----------------------------------------------------------------------
 .../entity/machine/AddMachineMetrics.java       |   2 +-
 .../software/base/SoftwareProcessImpl.java      |  42 +++---
 .../machine/MachineEntityJcloudsRebindTest.java | 142 +++++++++++++++++++
 .../entity/machine/MachineEntityRebindTest.java |  20 ++-
 4 files changed, 179 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d9e4c6f3/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
index 5746f60..a89e479 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
@@ -88,6 +88,7 @@ public class AddMachineMetrics implements EntityInitializer {
     public static SshFeed createMachineMetricsFeed(EntityLocal entity) {
         boolean retrieveUsageMetrics = entity.config().get(SoftwareProcess.RETRIEVE_USAGE_METRICS);
         return SshFeed.builder()
+                .uniqueTag("machineMetricsFeed")
                 .period(Duration.THIRTY_SECONDS)
                 .entity(entity)
                 .poll(SshPollConfig.forSensor(MachineAttributes.UPTIME)
@@ -159,5 +160,4 @@ public class AddMachineMetrics implements EntityInitializer {
                         }))
                 .build();
     }
-
 }

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d9e4c6f3/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
index 0d2661e..595be97 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/software/base/SoftwareProcessImpl.java
@@ -18,25 +18,12 @@
  */
 package org.apache.brooklyn.entity.software.base;
 
-import groovy.time.TimeDuration;
-
 import java.util.Collection;
 import java.util.Map;
 import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.brooklyn.location.jclouds.networking.NetworkingEffectors;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Functions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntityLocal;
 import org.apache.brooklyn.api.entity.drivers.DriverDependentEntity;
@@ -60,17 +47,29 @@ import org.apache.brooklyn.core.location.LocationConfigKeys;
 import org.apache.brooklyn.core.location.cloud.CloudLocationConfig;
 import org.apache.brooklyn.feed.function.FunctionFeed;
 import org.apache.brooklyn.feed.function.FunctionPollConfig;
+import org.apache.brooklyn.location.jclouds.networking.NetworkingEffectors;
 import org.apache.brooklyn.location.ssh.SshMachineLocation;
 import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.collections.MutableSet;
 import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.core.task.BasicTask;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.core.task.ScheduledTask;
 import org.apache.brooklyn.util.core.task.Tasks;
 import org.apache.brooklyn.util.exceptions.Exceptions;
 import org.apache.brooklyn.util.guava.Maybe;
 import org.apache.brooklyn.util.time.CountdownTimer;
 import org.apache.brooklyn.util.time.Duration;
 import org.apache.brooklyn.util.time.Time;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
+
+import groovy.time.TimeDuration;
 
 /**
  * An {@link Entity} representing a piece of software which can be installed, run, and controlled.
@@ -389,21 +388,26 @@ public abstract class SoftwareProcessImpl extends AbstractEntity implements Soft
         } else {
             long delay = (long) (Math.random() * configuredMaxDelay.toMilliseconds());
             LOG.debug("Scheduled reconnection of sensors on {} in {}ms", this, delay);
-            Timer timer = new Timer();
-            timer.schedule(new TimerTask() {
-                @Override public void run() {
+            
+            // This is functionally equivalent to new scheduledExecutor.schedule(job, delay, TimeUnit.MILLISECONDS).
+            // It uses the entity's execution context to schedule and thus execute the job.
+            Map<?,?> flags = MutableMap.of("delay", Duration.millis(delay), "maxIterations", 1, "cancelOnException", true);
+            Callable<Void> job = new Callable<Void>() {
+                public Void call() {
                     try {
                         if (getManagementSupport().isNoLongerManaged()) {
                             LOG.debug("Entity {} no longer managed; ignoring scheduled connect sensors on rebind", SoftwareProcessImpl.this);
-                            return;
+                            return null;
                         }
                         connectSensors();
                     } catch (Throwable e) {
                         LOG.warn("Problem connecting sensors on rebind of "+SoftwareProcessImpl.this, e);
                         Exceptions.propagateIfFatal(e);
                     }
-                }
-            }, delay);
+                    return null;
+                }};
+            ScheduledTask scheduledTask = new ScheduledTask(flags, new BasicTask<Void>(job));
+            getExecutionContext().submit(scheduledTask);
         }
         // don't wait here - it may be long-running, e.g. if remote entity has died, and we don't want to block rebind waiting or cause it to fail
         // the service will subsequently show service not up and thus failure

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d9e4c6f3/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityJcloudsRebindTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityJcloudsRebindTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityJcloudsRebindTest.java
new file mode 100644
index 0000000..196a51c
--- /dev/null
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityJcloudsRebindTest.java
@@ -0,0 +1,142 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.brooklyn.entity.machine;
+
+import static org.testng.Assert.fail;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.sensor.Feed;
+import org.apache.brooklyn.core.entity.Attributes;
+import org.apache.brooklyn.core.entity.EntityAsserts;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
+import org.apache.brooklyn.location.jclouds.JcloudsLocation;
+import org.apache.brooklyn.location.jclouds.JcloudsRebindStubUnitTest;
+import org.apache.brooklyn.location.jclouds.StubbedComputeServiceRegistry;
+import org.apache.brooklyn.test.Asserts;
+import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool;
+import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool.CustomResponse;
+import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool.ExecCmd;
+import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool.ExecParams;
+import org.apache.brooklyn.util.time.Duration;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+
+public class MachineEntityJcloudsRebindTest extends JcloudsRebindStubUnitTest {
+
+    //TODO To decrease noisy erroneous warnings, could also stub the response for
+    // "free | grep Mem" etc in initSshCustomResponses()
+
+    @Override
+    @BeforeMethod(alwaysRun=true)
+    public void setUp() throws Exception {
+        super.setUp();
+        initSshCustomResponses();
+    }
+
+    private void initSshCustomResponses() {
+        RecordingSshTool.setCustomResponse("cat /proc/uptime", new RecordingSshTool.CustomResponseGenerator() {
+            private final AtomicInteger counter = new AtomicInteger(1);
+            @Override
+            public CustomResponse generate(ExecParams execParams) throws Exception {
+                return new CustomResponse(0, Integer.toString(counter.getAndIncrement()), "");
+            }});
+        RecordingSshTool.setCustomResponse(".*/etc/os-release.*", new RecordingSshTool.CustomResponseGenerator() {
+            @Override
+            public CustomResponse generate(ExecParams execParams) throws Exception {
+                String stdout = Joiner.on("\n").join(
+                        "name:centos",
+                        "version:7.0",
+                        "architecture:myarch",
+                        "ram:1024",
+                        "cpus:1");
+                return new CustomResponse(0, stdout, "");
+            }});
+    }
+    
+    // See https://issues.apache.org/jira/browse/BROOKLYN-425
+    @Test
+    @Override
+    public void testRebind() throws Exception {
+        this.nodeCreator = newNodeCreator();
+        this.computeServiceRegistry = new StubbedComputeServiceRegistry(nodeCreator, false);
+        JcloudsLocation origJcloudsLoc = newJcloudsLocation(computeServiceRegistry);
+    
+        MachineEntity machine = origApp.createAndManageChild(EntitySpec.create(MachineEntity.class)
+                .configure(MachineEntity.MAXIMUM_REBIND_SENSOR_CONNECT_DELAY, Duration.millis(100)));
+        origApp.start(ImmutableList.of(origJcloudsLoc));
+        EntityAsserts.assertAttributeEqualsEventually(machine, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+        
+        RecordingSshTool.clear();
+        initSshCustomResponses();
+        rebind();
+        
+        Entity newMachine = mgmt().getEntityManager().getEntity(machine.getId());
+        EntityAsserts.assertAttributeEqualsEventually(newMachine, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
+        
+        // Expect SshMachineLocation.inferMachineDetails to have successfully retrieved os details,
+        // which we've stubbed to return centos (in ssh call).
+        assertRecordedSshCmdContainsEventually("/etc/os-release");
+        
+        // TODO Would like to assert that we have the feed, but it's not actually added to the entity!
+        // See AddMachineMetrics.createMachineMetricsFeed, which doesn't call `feeds().addFeed()` so
+        // it's not persisted and is not accessible from entity.feeds().getFeeds(). Instead, it just
+        // adds the entity to the feed (which is the old way, for if your feed is not persistable).
+        //     assertHasFeedEventually(newMachine, "machineMetricsFeed");
+
+        // TODO AddMachineMetrics.createMachineMetricsFeed poll period is not configurable; 
+        // we'd have to wait 30 seconds for a change.
+        //     EntityAsserts.assertAttributeChangesEventually(newMachine, MachineAttributes.UPTIME);
+    }
+    
+    private void assertRecordedSshCmdContainsEventually(final String expected) {
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                List<ExecCmd> cmds = RecordingSshTool.getExecCmds();
+                for (ExecCmd cmd : cmds) {
+                    if (cmd.commands.toString().contains(expected)) {
+                        return;
+                    }
+                }
+                fail("Commands (" + expected + ") not contain in " + cmds);
+            }});
+    }
+    
+    @SuppressWarnings("unused")
+    private void assertHasFeedEventually(final Entity entity, final String uniqueTag) {
+        Asserts.succeedsEventually(new Runnable() {
+            public void run() {
+                Collection<Feed> feeds = ((EntityInternal)entity).feeds().getFeeds();
+                for (Feed feed : feeds) {
+                    if (uniqueTag.equals(feed.getUniqueTag())) {
+                        return;
+                    }
+                }
+                fail("No feed found with uniqueTag "+uniqueTag+" in entity "+entity+"; feeds="+feeds);
+            }});
+    }
+}

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/d9e4c6f3/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityRebindTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityRebindTest.java b/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityRebindTest.java
index 2480ee6..f9f9d41 100644
--- a/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityRebindTest.java
+++ b/software/base/src/test/java/org/apache/brooklyn/entity/machine/MachineEntityRebindTest.java
@@ -20,25 +20,31 @@ package org.apache.brooklyn.entity.machine;
 
 import org.apache.brooklyn.api.entity.Entity;
 import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
 import org.apache.brooklyn.core.entity.Attributes;
 import org.apache.brooklyn.core.entity.EntityAsserts;
 import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
 import org.apache.brooklyn.core.mgmt.rebind.RebindTestFixtureWithApp;
-import org.apache.brooklyn.entity.software.base.EmptySoftwareProcess;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
+import org.apache.brooklyn.util.core.internal.ssh.RecordingSshTool;
 import org.testng.annotations.Test;
 
 import com.google.common.collect.ImmutableList;
 
 public class MachineEntityRebindTest extends RebindTestFixtureWithApp {
 
-    @Test(groups = "Integration")
+    @Test
     public void testRebindToMachineEntity() throws Exception {
-        EmptySoftwareProcess machine = origApp.createAndManageChild(EntitySpec.create(EmptySoftwareProcess.class));
-        origApp.start(ImmutableList.of(origManagementContext.getLocationRegistry().getLocationManaged("localhost")));
+        SshMachineLocation loc = mgmt().getLocationManager().createLocation(LocationSpec.create(SshMachineLocation.class)
+                .configure("address", "localhost")
+                .configure(SshMachineLocation.SSH_TOOL_CLASS, RecordingSshTool.class.getName()));
+        MachineEntity machine = origApp.createAndManageChild(EntitySpec.create(MachineEntity.class));
+        origApp.start(ImmutableList.of(loc));
         EntityAsserts.assertAttributeEqualsEventually(machine, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
-        rebind(false);
-        Entity machine2 = newManagementContext.getEntityManager().getEntity(machine.getId());
+        
+        rebind();
+        
+        Entity machine2 = mgmt().getEntityManager().getEntity(machine.getId());
         EntityAsserts.assertAttributeEqualsEventually(machine2, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
     }
-
 }


[2/2] brooklyn-server git commit: This closes #534

Posted by dr...@apache.org.
This closes #534


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

Branch: refs/heads/master
Commit: 5c5d578f4e3c53e065cc84104fe7a4456ff5d764
Parents: 55ec074 d9e4c6f
Author: Duncan Godwin <dr...@googlemail.com>
Authored: Mon Feb 6 12:35:41 2017 +0000
Committer: Duncan Godwin <dr...@googlemail.com>
Committed: Mon Feb 6 12:35:41 2017 +0000

----------------------------------------------------------------------
 .../entity/machine/AddMachineMetrics.java       |   2 +-
 .../software/base/SoftwareProcessImpl.java      |  42 +++---
 .../machine/MachineEntityJcloudsRebindTest.java | 142 +++++++++++++++++++
 .../entity/machine/MachineEntityRebindTest.java |  20 ++-
 4 files changed, 179 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/5c5d578f/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
----------------------------------------------------------------------
diff --cc software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
index 5fafa44,a89e479..8c6d5d0
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/AddMachineMetrics.java
@@@ -86,9 -85,10 +86,10 @@@ public class AddMachineMetrics implemen
  
      }
  
 -    public static SshFeed createMachineMetricsFeed(EntityLocal entity) {
 +    public static SshFeed createMachineMetricsFeed(Entity entity) {
          boolean retrieveUsageMetrics = entity.config().get(SoftwareProcess.RETRIEVE_USAGE_METRICS);
          return SshFeed.builder()
+                 .uniqueTag("machineMetricsFeed")
                  .period(Duration.THIRTY_SECONDS)
                  .entity(entity)
                  .poll(SshPollConfig.forSensor(MachineAttributes.UPTIME)