You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/08/07 01:59:54 UTC
[3/6] incubator-brooklyn git commit: package rename to
org.apache.brooklyn: sandbox
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/main/resources/brooklyn/entity/salt/minion
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/resources/brooklyn/entity/salt/minion b/sandbox/extra/src/main/resources/brooklyn/entity/salt/minion
deleted file mode 100644
index cff42c7..0000000
--- a/sandbox/extra/src/main/resources/brooklyn/entity/salt/minion
+++ /dev/null
@@ -1,52 +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.
-#
-# SaltStack Minion Configuration
-#
-# /etc/salt/minion
-##
-
-# The salt master server
-master: ${entity.master.hostname}
-ipv6: False
-retry_dns: 30
-master_port: ${entity.master.saltPort,c} # 4506
-acceptance_wait_time: 30
-acceptance_wait_time_max: 300
-
-# Minion configuration
-id: ${entity.id}
-user: root
-backup_mode: minion
-
-# Directory settings
-root_dir: /
-pidfile: ${runDir}/salt-minion.pid
-pki_dir: ${runDir}/pki
-cachedir: ${runDir}/cache
-log_file: ${runDir}/minion.log
-key_logfile: ${runDir}/key.log
-
-#verify_env: True
-#cache_jobs: True # Debugging
-
-output: nested
-color: False
-log_level: info
-log_level_logfile: debug # Debugging
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/master
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/master b/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/master
new file mode 100644
index 0000000..72d7eb9
--- /dev/null
+++ b/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/master
@@ -0,0 +1,65 @@
+[#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.
+#
+# /etc/salt/master
+##
+
+#interface: 0.0.0.0
+#ipv6: False
+#publish_port: ${entity.publishPort,c} # 4505
+
+#user: root
+#max_open_files: 100000
+#worker_threads: 5
+ret_port: ${entity.saltPort,c} # 4506
+
+root_dir: /
+pidfile: ${driver.pidFile}
+pki_dir: ${runDir}/pki
+cachedir: ${runDir}/cache
+log_file: ${driver.logFileLocation}
+key_logfile: ${runDir}/key.log
+
+#verify_env: True
+#keep_jobs: 24
+
+#timeout: 5
+#loop_interval: 60
+
+output: nested
+color: False
+log_level: info
+log_level_logfile: debug # Debugging
+
+#job_cache: True
+#minion_data_cache: True
+
+#open_mode: False
+#auto_accept: False
+#autosign_file: autosign.conf
+#permissive_pki_access: False
+
+fileserver_backend:
+ - git
+
+gitfs_remotes:
+ - git://github.com/saltstack/salt-states.git
+ - git://github.com/saltstack-formulas/postgres-formula.git
+ - ${entity.remoteUrl}
+ # TODO iterate through formula URLs
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/masterless
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/masterless b/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/masterless
new file mode 100644
index 0000000..ba41c6e
--- /dev/null
+++ b/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/masterless
@@ -0,0 +1,53 @@
+[#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.
+#
+# SaltStack Masterless Minion Configuration
+#
+# /etc/salt/minion
+##
+
+# Minion configuration
+id: ${entity.id}
+user: root
+backup_mode: minion
+
+# Directory settings
+root_dir: /
+pidfile: ${runDir}/salt-minion.pid
+pki_dir: ${runDir}/pki
+cachedir: ${runDir}/cache
+log_file: ${runDir}/minion.log
+key_logfile: ${runDir}/key.log
+
+file_client: local
+file_roots:
+ base:
+ - ${runDir}/base
+[#list formulas?keys as formulaName]
+ - ${installDir}/${formulaName}
+[/#list]
+
+#verify_env: True
+#cache_jobs: True # Debugging
+
+output: nested
+color: False
+log_level: info
+log_level_logfile: debug # Debugging
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/minion
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/minion b/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/minion
new file mode 100644
index 0000000..cff42c7
--- /dev/null
+++ b/sandbox/extra/src/main/resources/org/apache/brooklyn/entity/salt/minion
@@ -0,0 +1,52 @@
+[#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.
+#
+# SaltStack Minion Configuration
+#
+# /etc/salt/minion
+##
+
+# The salt master server
+master: ${entity.master.hostname}
+ipv6: False
+retry_dns: 30
+master_port: ${entity.master.saltPort,c} # 4506
+acceptance_wait_time: 30
+acceptance_wait_time_max: 300
+
+# Minion configuration
+id: ${entity.id}
+user: root
+backup_mode: minion
+
+# Directory settings
+root_dir: /
+pidfile: ${runDir}/salt-minion.pid
+pki_dir: ${runDir}/pki
+cachedir: ${runDir}/cache
+log_file: ${runDir}/minion.log
+key_logfile: ${runDir}/key.log
+
+#verify_env: True
+#cache_jobs: True # Debugging
+
+output: nested
+color: False
+log_level: info
+log_level_logfile: debug # Debugging
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java b/sandbox/extra/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
deleted file mode 100644
index a44efa9..0000000
--- a/sandbox/extra/src/test/java/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
+++ /dev/null
@@ -1,109 +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.
- */
-package brooklyn.entity.database.postgresql;
-
-import java.util.Random;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.Entities;
-import brooklyn.entity.database.VogellaExampleAccess;
-import brooklyn.entity.effector.EffectorTasks;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.salt.SaltConfig;
-import brooklyn.entity.salt.SaltLiveTestSupport;
-import brooklyn.entity.software.SshEffectorTasks;
-import brooklyn.location.PortRange;
-import brooklyn.location.basic.PortRanges;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.util.task.system.ProcessTaskWrapper;
-import brooklyn.util.time.Duration;
-
-import com.google.common.collect.ImmutableList;
-
-/**
- * Tests Salt installation of {@link PostgreSqlNode} entity.
- */
-public class PostgreSqlSaltLiveTest extends SaltLiveTestSupport {
-
- private static final Logger log = LoggerFactory.getLogger(PostgreSqlSaltLiveTest.class);
-
- private PostgreSqlNode psql;
-
- @Override
- @AfterMethod(alwaysRun=true)
- public void tearDown() throws Exception {
- try {
- if (psql != null) psql.stop();
- } finally {
- super.tearDown();
- }
- }
-
- @Test(groups="Live")
- public void testPostgresStartsAndStops() throws Exception {
- psql = app.createAndManageChild(EntitySpec.create(PostgreSqlNode.class, PostgreSqlNodeSaltImpl.class)
- .configure(SaltConfig.MASTERLESS_MODE, true));
-
- app.start(ImmutableList.of(targetLocation));
-
- Entities.submit(psql, SshEffectorTasks.ssh("ps aux | grep [p]ostgres").requiringExitCodeZero());
- SshMachineLocation targetMachine = EffectorTasks.getSshMachine(psql);
-
- psql.stop();
-
- try {
- // if host is still contactable ensure postgres is not running
- ProcessTaskWrapper<Integer> t = Entities.submit(app, SshEffectorTasks.ssh("ps aux | grep [p]ostgres").machine(targetMachine).allowingNonZeroExitCode());
- t.getTask().blockUntilEnded(Duration.TEN_SECONDS);
- if (!t.isDone()) {
- Assert.fail("Task not finished yet: "+t.getTask());
- }
- Assert.assertNotEquals(t.get(), (Integer)0, "Task ended with code "+t.get()+"; output: "+t.getStdout() );
- } catch (Exception e) {
- // host has been killed, that is fine
- log.info("Machine "+targetMachine+" destroyed on stop (expected - "+e+")");
- }
- }
-
- @Test(groups="Live")
- public void testPostgresScriptAndAccess() throws Exception {
- SaltLiveTestSupport.createLocation(mgmt);
- PortRange randomPort = PortRanges.fromString(""+(5420+new Random().nextInt(10))+"+");
- psql = app.createAndManageChild(EntitySpec.create(PostgreSqlNode.class, PostgreSqlNodeSaltImpl.class)
- .configure(SaltConfig.MASTERLESS_MODE, true)
- .configure(PostgreSqlNode.CREATION_SCRIPT_CONTENTS, PostgreSqlIntegrationTest.CREATION_SCRIPT)
- .configure(PostgreSqlNode.POSTGRESQL_PORT, randomPort));
-
- app.start(ImmutableList.of(targetLocation));
-
- String url = psql.getAttribute(PostgreSqlNode.DATASTORE_URL);
- log.info("Trying to connect to "+psql+" at "+url);
- Assert.assertNotNull(url);
- Assert.assertTrue(url.contains("542"));
-
- new VogellaExampleAccess("org.postgresql.Driver", url).readModifyAndRevertDataBase();
- }
-
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/test/java/brooklyn/entity/salt/SaltConfigsTest.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/brooklyn/entity/salt/SaltConfigsTest.java b/sandbox/extra/src/test/java/brooklyn/entity/salt/SaltConfigsTest.java
deleted file mode 100644
index 6706748..0000000
--- a/sandbox/extra/src/test/java/brooklyn/entity/salt/SaltConfigsTest.java
+++ /dev/null
@@ -1,69 +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.
- */
-package brooklyn.entity.salt;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.testng.Assert;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.Test;
-
-import brooklyn.entity.basic.ApplicationBuilder;
-import brooklyn.entity.basic.Entities;
-import brooklyn.test.entity.TestApplication;
-
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-
-public class SaltConfigsTest {
-
- private TestApplication app = null;
-
- @AfterMethod(alwaysRun=true)
- public void tearDown() {
- if (app!=null) Entities.destroyAll(app.getManagementContext());
- app = null;
- }
-
- @Test
- public void testAddToRunList() {
- app = ApplicationBuilder.newManagedApp(TestApplication.class);
- SaltConfigs.addToRunList(app, "a", "b");
- Set<? extends String> runs = app.getConfig(SaltConfig.SALT_RUN_LIST);
- Assert.assertEquals(runs, ImmutableSet.of("a", "b"));
- }
-
- @Test
- public void testAddToFormulas() {
- app = ApplicationBuilder.newManagedApp(TestApplication.class);
- SaltConfigs.addToFormulas(app, "k1", "v1");
- SaltConfigs.addToFormulas(app, "k2", "v2");
- Map<String, String> formulas = app.getConfig(SaltConfig.SALT_FORMULAS);
- Assert.assertEquals(formulas, ImmutableMap.of("k1", "v1", "k2", "v2"));
- }
-
- @Test
- public void testAddLaunchAttributes() {
- app = ApplicationBuilder.newManagedApp(TestApplication.class);
- SaltConfigs.addLaunchAttributes(app, ImmutableMap.of("k1", "v1"));
- Map<String, Object> attribs = app.getConfig(SaltConfig.SALT_LAUNCH_ATTRIBUTES);
- Assert.assertEquals(attribs, ImmutableMap.of("k1", "v1"));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/test/java/brooklyn/entity/salt/SaltLiveTestSupport.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/brooklyn/entity/salt/SaltLiveTestSupport.java b/sandbox/extra/src/test/java/brooklyn/entity/salt/SaltLiveTestSupport.java
deleted file mode 100644
index 6cb7409..0000000
--- a/sandbox/extra/src/test/java/brooklyn/entity/salt/SaltLiveTestSupport.java
+++ /dev/null
@@ -1,68 +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.
- */
-package brooklyn.entity.salt;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.BeforeMethod;
-
-import brooklyn.entity.BrooklynAppLiveTestSupport;
-import brooklyn.location.Location;
-import brooklyn.location.MachineProvisioningLocation;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.management.ManagementContext;
-
-public class SaltLiveTestSupport extends BrooklynAppLiveTestSupport {
-
- private static final Logger log = LoggerFactory.getLogger(SaltLiveTestSupport.class);
-
- protected MachineProvisioningLocation<? extends SshMachineLocation> targetLocation;
-
- @Override
- @BeforeMethod(alwaysRun=true)
- public void setUp() throws Exception {
- super.setUp();
-
- targetLocation = createLocation();
- }
-
- protected MachineProvisioningLocation<? extends SshMachineLocation> createLocation() {
- return createLocation(mgmt);
- }
-
- /**
- * Convenience for setting up a pre-built or fixed IP machine.
- * <p>
- * Useful if you are unable to set up Salt on localhost,
- * and for ensuring tests against Salt always use the same
- * configured location.
- */
- @SuppressWarnings("unchecked")
- public static MachineProvisioningLocation<? extends SshMachineLocation> createLocation(ManagementContext mgmt) {
- Location bestLocation = mgmt.getLocationRegistry().resolveIfPossible("named:SaltTests");
- if (bestLocation==null) {
- log.info("using AWS for salt tests because named:SaltTests does not exist");
- bestLocation = mgmt.getLocationRegistry().resolveIfPossible("jclouds:aws-ec2:us-east-1");
- }
- if (bestLocation==null) {
- throw new IllegalStateException("Need a location called named:SaltTests or AWS configured for these tests");
- }
- return (MachineProvisioningLocation<? extends SshMachineLocation>)bestLocation;
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
new file mode 100644
index 0000000..250cc03
--- /dev/null
+++ b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/database/postgresql/PostgreSqlSaltLiveTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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.database.postgresql;
+
+import java.util.Random;
+
+import org.apache.brooklyn.entity.database.postgresql.PostgreSqlNodeSaltImpl;
+import org.apache.brooklyn.entity.salt.SaltConfig;
+import org.apache.brooklyn.entity.salt.SaltLiveTestSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.database.VogellaExampleAccess;
+import brooklyn.entity.database.postgresql.PostgreSqlIntegrationTest;
+import brooklyn.entity.database.postgresql.PostgreSqlNode;
+import brooklyn.entity.effector.EffectorTasks;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.entity.software.SshEffectorTasks;
+import brooklyn.location.PortRange;
+import brooklyn.location.basic.PortRanges;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.util.task.system.ProcessTaskWrapper;
+import brooklyn.util.time.Duration;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Tests Salt installation of {@link PostgreSqlNode} entity.
+ */
+public class PostgreSqlSaltLiveTest extends SaltLiveTestSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(PostgreSqlSaltLiveTest.class);
+
+ private PostgreSqlNode psql;
+
+ @Override
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ try {
+ if (psql != null) psql.stop();
+ } finally {
+ super.tearDown();
+ }
+ }
+
+ @Test(groups="Live")
+ public void testPostgresStartsAndStops() throws Exception {
+ psql = app.createAndManageChild(EntitySpec.create(PostgreSqlNode.class, PostgreSqlNodeSaltImpl.class)
+ .configure(SaltConfig.MASTERLESS_MODE, true));
+
+ app.start(ImmutableList.of(targetLocation));
+
+ Entities.submit(psql, SshEffectorTasks.ssh("ps aux | grep [p]ostgres").requiringExitCodeZero());
+ SshMachineLocation targetMachine = EffectorTasks.getSshMachine(psql);
+
+ psql.stop();
+
+ try {
+ // if host is still contactable ensure postgres is not running
+ ProcessTaskWrapper<Integer> t = Entities.submit(app, SshEffectorTasks.ssh("ps aux | grep [p]ostgres").machine(targetMachine).allowingNonZeroExitCode());
+ t.getTask().blockUntilEnded(Duration.TEN_SECONDS);
+ if (!t.isDone()) {
+ Assert.fail("Task not finished yet: "+t.getTask());
+ }
+ Assert.assertNotEquals(t.get(), (Integer)0, "Task ended with code "+t.get()+"; output: "+t.getStdout() );
+ } catch (Exception e) {
+ // host has been killed, that is fine
+ log.info("Machine "+targetMachine+" destroyed on stop (expected - "+e+")");
+ }
+ }
+
+ @Test(groups="Live")
+ public void testPostgresScriptAndAccess() throws Exception {
+ SaltLiveTestSupport.createLocation(mgmt);
+ PortRange randomPort = PortRanges.fromString(""+(5420+new Random().nextInt(10))+"+");
+ psql = app.createAndManageChild(EntitySpec.create(PostgreSqlNode.class, PostgreSqlNodeSaltImpl.class)
+ .configure(SaltConfig.MASTERLESS_MODE, true)
+ .configure(PostgreSqlNode.CREATION_SCRIPT_CONTENTS, PostgreSqlIntegrationTest.CREATION_SCRIPT)
+ .configure(PostgreSqlNode.POSTGRESQL_PORT, randomPort));
+
+ app.start(ImmutableList.of(targetLocation));
+
+ String url = psql.getAttribute(PostgreSqlNode.DATASTORE_URL);
+ log.info("Trying to connect to "+psql+" at "+url);
+ Assert.assertNotNull(url);
+ Assert.assertTrue(url.contains("542"));
+
+ new VogellaExampleAccess("org.postgresql.Driver", url).readModifyAndRevertDataBase();
+ }
+
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/test/java/org/apache/brooklyn/entity/salt/SaltConfigsTest.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/salt/SaltConfigsTest.java b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/salt/SaltConfigsTest.java
new file mode 100644
index 0000000..cf1a800
--- /dev/null
+++ b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/salt/SaltConfigsTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.salt;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.entity.salt.SaltConfig;
+import org.apache.brooklyn.entity.salt.SaltConfigs;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.basic.ApplicationBuilder;
+import brooklyn.entity.basic.Entities;
+import brooklyn.test.entity.TestApplication;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+
+public class SaltConfigsTest {
+
+ private TestApplication app = null;
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() {
+ if (app!=null) Entities.destroyAll(app.getManagementContext());
+ app = null;
+ }
+
+ @Test
+ public void testAddToRunList() {
+ app = ApplicationBuilder.newManagedApp(TestApplication.class);
+ SaltConfigs.addToRunList(app, "a", "b");
+ Set<? extends String> runs = app.getConfig(SaltConfig.SALT_RUN_LIST);
+ Assert.assertEquals(runs, ImmutableSet.of("a", "b"));
+ }
+
+ @Test
+ public void testAddToFormulas() {
+ app = ApplicationBuilder.newManagedApp(TestApplication.class);
+ SaltConfigs.addToFormulas(app, "k1", "v1");
+ SaltConfigs.addToFormulas(app, "k2", "v2");
+ Map<String, String> formulas = app.getConfig(SaltConfig.SALT_FORMULAS);
+ Assert.assertEquals(formulas, ImmutableMap.of("k1", "v1", "k2", "v2"));
+ }
+
+ @Test
+ public void testAddLaunchAttributes() {
+ app = ApplicationBuilder.newManagedApp(TestApplication.class);
+ SaltConfigs.addLaunchAttributes(app, ImmutableMap.of("k1", "v1"));
+ Map<String, Object> attribs = app.getConfig(SaltConfig.SALT_LAUNCH_ATTRIBUTES);
+ Assert.assertEquals(attribs, ImmutableMap.of("k1", "v1"));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/extra/src/test/java/org/apache/brooklyn/entity/salt/SaltLiveTestSupport.java
----------------------------------------------------------------------
diff --git a/sandbox/extra/src/test/java/org/apache/brooklyn/entity/salt/SaltLiveTestSupport.java b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/salt/SaltLiveTestSupport.java
new file mode 100644
index 0000000..8fbc14f
--- /dev/null
+++ b/sandbox/extra/src/test/java/org/apache/brooklyn/entity/salt/SaltLiveTestSupport.java
@@ -0,0 +1,68 @@
+/*
+ * 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.salt;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.BeforeMethod;
+
+import brooklyn.entity.BrooklynAppLiveTestSupport;
+import brooklyn.location.Location;
+import brooklyn.location.MachineProvisioningLocation;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.management.ManagementContext;
+
+public class SaltLiveTestSupport extends BrooklynAppLiveTestSupport {
+
+ private static final Logger log = LoggerFactory.getLogger(SaltLiveTestSupport.class);
+
+ protected MachineProvisioningLocation<? extends SshMachineLocation> targetLocation;
+
+ @Override
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ super.setUp();
+
+ targetLocation = createLocation();
+ }
+
+ protected MachineProvisioningLocation<? extends SshMachineLocation> createLocation() {
+ return createLocation(mgmt);
+ }
+
+ /**
+ * Convenience for setting up a pre-built or fixed IP machine.
+ * <p>
+ * Useful if you are unable to set up Salt on localhost,
+ * and for ensuring tests against Salt always use the same
+ * configured location.
+ */
+ @SuppressWarnings("unchecked")
+ public static MachineProvisioningLocation<? extends SshMachineLocation> createLocation(ManagementContext mgmt) {
+ Location bestLocation = mgmt.getLocationRegistry().resolveIfPossible("named:SaltTests");
+ if (bestLocation==null) {
+ log.info("using AWS for salt tests because named:SaltTests does not exist");
+ bestLocation = mgmt.getLocationRegistry().resolveIfPossible("jclouds:aws-ec2:us-east-1");
+ }
+ if (bestLocation==null) {
+ throw new IllegalStateException("Need a location called named:SaltTests or AWS configured for these tests");
+ }
+ return (MachineProvisioningLocation<? extends SshMachineLocation>)bestLocation;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java b/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
deleted file mode 100644
index 5fe96cd..0000000
--- a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixFeed.java
+++ /dev/null
@@ -1,463 +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.
- */
-package brooklyn.entity.monitoring.zabbix;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.net.URI;
-import java.net.URL;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.http.client.HttpClient;
-import org.apache.http.impl.NoConnectionReuseStrategy;
-import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.Attributes;
-import brooklyn.entity.basic.ConfigKeys;
-import brooklyn.entity.basic.EntityFunctions;
-import brooklyn.entity.basic.EntityLocal;
-import brooklyn.event.feed.AbstractFeed;
-import brooklyn.event.feed.AttributePollHandler;
-import brooklyn.event.feed.PollHandler;
-import brooklyn.event.feed.Poller;
-import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.Location;
-import brooklyn.location.MachineLocation;
-import brooklyn.location.access.BrooklynAccessUtils;
-import brooklyn.location.basic.SupportsPortForwarding;
-import brooklyn.util.http.HttpTool;
-import brooklyn.util.http.HttpToolResponse;
-import brooklyn.util.net.Cidr;
-
-import com.google.common.base.Function;
-import com.google.common.base.Functions;
-import com.google.common.base.Objects;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicates;
-import com.google.common.base.Supplier;
-import com.google.common.base.Suppliers;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.common.net.HostAndPort;
-import com.google.common.reflect.TypeToken;
-import com.google.gson.JsonObject;
-
-public class ZabbixFeed extends AbstractFeed {
-
- public static final Logger log = LoggerFactory.getLogger(ZabbixFeed.class);
-
- public static final String JSON_ITEM_GET =
- "{ \"jsonrpc\":\"2.0\",\"method\":\"item.get\"," +
- "\"params\":{\"output\":\"extend\"," +
- "\"filter\":{\"hostid\":[\"{{hostId}}\"],\"key_\":\"{{itemKey}}\"}}," +
- "\"auth\":\"{{token}}\",\"id\":{{id}}}";
- public static final String JSON_USER_LOGIN =
- "{ \"jsonrpc\":\"2.0\",\"method\":\"user.login\"," +
- "\"params\":{\"user\":\"{{username}}\",\"password\":\"{{password}}\"}," +
- "\"id\":0 }";
- public static final String JSON_HOST_CREATE =
- "{ \"jsonrpc\":\"2.0\",\"method\":\"host.create\"," +
- "\"params\":{\"host\":\"{{host}}\"," +
- "\"interfaces\":[{\"type\":1,\"main\":1,\"useip\":1,\"ip\":\"{{ip}}\",\"dns\":\"\",\"port\":\"{{port}}\"}]," +
- "\"groups\":[{\"groupid\":\"{{groupId}}\"}]," +
- "\"templates\":[{\"templateid\":\"{{templateId}}\"}]}," +
- "\"auth\":\"{{token}}\",\"id\":{{id}}}";
-
- private static final AtomicInteger id = new AtomicInteger(0);
-
- @SuppressWarnings("serial")
- public static final ConfigKey<Set<ZabbixPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
- new TypeToken<Set<ZabbixPollConfig<?>>>() {},
- "polls");
-
- @SuppressWarnings("serial")
- public static final ConfigKey<Supplier<URI>> BASE_URI_PROVIDER = ConfigKeys.newConfigKey(
- new TypeToken<Supplier<URI>>() {},
- "baseUriProvider");
-
- public static final ConfigKey<Integer> GROUP_ID = ConfigKeys.newIntegerConfigKey("groupId");
-
- public static final ConfigKey<Integer> TEMPLATE_ID = ConfigKeys.newIntegerConfigKey("templateId");
-
- @SuppressWarnings("serial")
- public static final ConfigKey<Function<? super EntityLocal, String>> UNIQUE_HOSTNAME_GENERATOR = ConfigKeys.newConfigKey(
- new TypeToken<Function<? super EntityLocal, String>>() {},
- "uniqueHostnameGenerator");
-
- public static Builder<ZabbixFeed, ?> builder() {
- return new ConcreteBuilder();
- }
-
- private static class ConcreteBuilder extends Builder<ZabbixFeed, ConcreteBuilder> {
- }
-
- public static class Builder<T extends ZabbixFeed, B extends Builder<T,B>> {
- private EntityLocal entity;
- private Supplier<URI> baseUriProvider;
- private long period = 500;
- private TimeUnit periodUnits = TimeUnit.MILLISECONDS;
- private List<ZabbixPollConfig<?>> polls = Lists.newArrayList();
- private URI baseUri;
- private boolean suspended = false;
- private volatile boolean built;
- private ZabbixServer server;
- private String username;
- private String password;
- private Integer sessionTimeout;
- private Integer groupId;
- private Integer templateId;
- private Function<? super EntityLocal, String> uniqueHostnameGenerator = Functions.compose(
- EntityFunctions.id(),
- EntityFunctions.locationMatching(Predicates.instanceOf(MachineLocation.class)));
- private String uniqueTag;
-
- @SuppressWarnings("unchecked")
- protected B self() {
- return (B) this;
- }
-
- public B entity(EntityLocal val) {
- this.entity = val;
- return self();
- }
- public B baseUri(Supplier<URI> val) {
- if (baseUri!=null && val!=null)
- throw new IllegalStateException("Builder cannot take both a URI and a URI Provider");
- this.baseUriProvider = val;
- return self();
- }
- public B baseUri(URI val) {
- if (baseUriProvider!=null && val!=null)
- throw new IllegalStateException("Builder cannot take both a URI and a URI Provider");
- this.baseUri = val;
- return self();
- }
- public B baseUrl(URL val) {
- return baseUri(URI.create(val.toString()));
- }
- public B baseUri(String val) {
- return baseUri(URI.create(val));
- }
- public B period(long millis) {
- return period(millis, TimeUnit.MILLISECONDS);
- }
- public B period(long val, TimeUnit units) {
- this.period = val;
- this.periodUnits = units;
- return self();
- }
- public B poll(ZabbixPollConfig<?> config) {
- polls.add(config);
- return self();
- }
- public B suspended() {
- return suspended(true);
- }
- public B suspended(boolean startsSuspended) {
- this.suspended = startsSuspended;
- return self();
- }
-
- public B server(final ZabbixServer server) {
- this.server = server;
- baseUri(URI.create(server.getConfig(ZabbixServer.ZABBIX_SERVER_API_URL)));
- username(server.getConfig(ZabbixServer.ZABBIX_SERVER_USERNAME));
- password(server.getConfig(ZabbixServer.ZABBIX_SERVER_PASSWORD));
- sessionTimeout(server.getConfig(ZabbixServer.ZABBIX_SESSION_TIMEOUT));
- return self();
- }
- public B username(String username) {
- this.username = username;
- return self();
- }
- public B password(String password) {
- this.password = password;
- return self();
- }
- public B sessionTimeout(Integer sessionTimeout) {
- this.sessionTimeout = sessionTimeout;
- return self();
- }
- public B groupId(Integer groupId) {
- this.groupId = groupId;
- return self();
- }
- public B templateId(Integer templateId) {
- this.templateId = templateId;
- return self();
- }
- public B register(Integer groupId, Integer templateId) {
- this.groupId = groupId;
- this.templateId = templateId;
- return self();
- }
- /**
- * For generating the name to be used when registering the zabbix agent with the zabbix server.
- * When called, guarantees that the entity will have a {@link MachineLocation} (see {@link Entity#getLocations()}).
- * Must return a non-empty string that will be unique across all machines where zabbix agents are installed.
- */
- public B uniqueHostnameGenerator(Function<? super EntityLocal, String> val) {
- this.uniqueHostnameGenerator = checkNotNull(val, "uniqueHostnameGenerator");
- return self();
- }
-
- public Builder uniqueTag(String uniqueTag) {
- this.uniqueTag = uniqueTag;
- return this;
- }
-
- @SuppressWarnings("unchecked")
- public T build() {
- // If server not set and other config not available, try to obtain from entity config
- if (server == null
- && (baseUri == null || baseUriProvider == null)
- && username == null && password == null && sessionTimeout == null) {
- ZabbixServer server = Preconditions.checkNotNull(entity.getConfig(ZabbixMonitored.ZABBIX_SERVER), "The ZABBIX_SERVER config key must be set on the entity");
- server(server);
- }
- // Now create feed
- T result = (T) new ZabbixFeed(this);
- result.setEntity(checkNotNull(entity, "entity"));
- built = true;
- if (suspended) result.suspend();
- result.start();
- return result;
- }
- @Override
- protected void finalize() {
- if (!built) log.warn("ZabbixFeed.Builder created, but build() never called");
- }
- }
-
- protected static class ZabbixPollIdentifier {
- final String itemName;
-
- protected ZabbixPollIdentifier(String itemName) {
- this.itemName = checkNotNull(itemName, "itemName");
- }
-
- @Override
- public int hashCode() {
- return Objects.hashCode(itemName);
- }
-
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof ZabbixPollIdentifier)) {
- return false;
- }
- ZabbixPollIdentifier o = (ZabbixPollIdentifier) other;
- return Objects.equal(itemName, o.itemName);
- }
- }
-
- // Flag set when the Zabbix agent is registered for a host
- protected final AtomicBoolean registered = new AtomicBoolean(false);
-
- /**
- * For rebind; do not call directly; use builder
- */
- public ZabbixFeed() {
- }
-
- protected ZabbixFeed(final Builder<? extends ZabbixFeed, ?> builder) {
- setConfig(BASE_URI_PROVIDER, builder.baseUriProvider);
- if (builder.baseUri != null) {
- if (builder.baseUriProvider != null) {
- throw new IllegalStateException("Not permitted to supply baseUri and baseUriProvider");
- }
- setConfig(BASE_URI_PROVIDER, Suppliers.ofInstance(builder.baseUri));
- } else {
- setConfig(BASE_URI_PROVIDER, checkNotNull(builder.baseUriProvider, "baseUriProvider and baseUri"));
- }
-
- setConfig(GROUP_ID, checkNotNull(builder.groupId, "Zabbix groupId must be set"));
- setConfig(TEMPLATE_ID, checkNotNull(builder.templateId, "Zabbix templateId must be set"));
- setConfig(UNIQUE_HOSTNAME_GENERATOR, checkNotNull(builder.uniqueHostnameGenerator, "uniqueHostnameGenerator"));
-
- Set<ZabbixPollConfig<?>> polls = Sets.newLinkedHashSet();
- for (ZabbixPollConfig<?> config : builder.polls) {
- @SuppressWarnings({ "unchecked", "rawtypes" })
- ZabbixPollConfig<?> configCopy = new ZabbixPollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period, builder.periodUnits);
- polls.add(configCopy);
- }
- setConfig(POLLS, polls);
- initUniqueTag(builder.uniqueTag, polls);
- }
-
- @Override
- protected void preStart() {
- final Supplier<URI> baseUriProvider = getConfig(BASE_URI_PROVIDER);
- final Function<? super EntityLocal, String> uniqueHostnameGenerator = getConfig(UNIQUE_HOSTNAME_GENERATOR);
- final Integer groupId = getConfig(GROUP_ID);
- final Integer templateId = getConfig(TEMPLATE_ID);
- final Set<ZabbixPollConfig<?>> polls = getConfig(POLLS);
-
- log.info("starting zabbix feed for {}", entity);
-
- // TODO if supplier returns null, we may wish to defer initialization until url available?
- // TODO for https should we really trust all?
- final HttpClient httpClient = HttpTool.httpClientBuilder()
- .trustAll()
- .clientConnectionManager(new ThreadSafeClientConnManager())
- .reuseStrategy(new NoConnectionReuseStrategy())
- .uri(baseUriProvider.get())
- .build();
-
- // Registration job, calls Zabbix host.create API
- final Callable<HttpToolResponse> registerJob = new Callable<HttpToolResponse>() {
- @Override
- public HttpToolResponse call() throws Exception {
- if (!registered.get()) {
- // Find the first machine, if available
- Optional<Location> location = Iterables.tryFind(entity.getLocations(), Predicates.instanceOf(MachineLocation.class));
- if (!location.isPresent()) {
- return null; // Do nothing until location is present
- }
- MachineLocation machine = (MachineLocation) location.get();
-
- String host = uniqueHostnameGenerator.apply(entity);
-
- // Select address and port using port-forwarding if available
- String address = entity.getAttribute(Attributes.ADDRESS);
- Integer port = entity.getAttribute(ZabbixMonitored.ZABBIX_AGENT_PORT);
- if (machine instanceof SupportsPortForwarding) {
- Cidr management = entity.getConfig(BrooklynAccessUtils.MANAGEMENT_ACCESS_CIDR);
- HostAndPort forwarded = ((SupportsPortForwarding) machine).getSocketEndpointFor(management, port);
- address = forwarded.getHostText();
- port = forwarded.getPort();
- }
-
- // Fill in the JSON template and POST it
- byte[] body = JSON_HOST_CREATE
- .replace("{{token}}", entity.getConfig(ZabbixMonitored.ZABBIX_SERVER).getAttribute(ZabbixServer.ZABBIX_TOKEN))
- .replace("{{host}}", host)
- .replace("{{ip}}", address)
- .replace("{{port}}", Integer.toString(port))
- .replace("{{groupId}}", Integer.toString(groupId))
- .replace("{{templateId}}", Integer.toString(templateId))
- .replace("{{id}}", Integer.toString(id.incrementAndGet()))
- .getBytes();
-
- return HttpTool.httpPost(httpClient, baseUriProvider.get(), ImmutableMap.of("Content-Type", "application/json"), body);
- }
- return null;
- }
- };
-
- // The handler for the registration job
- PollHandler<? super HttpToolResponse> registrationHandler = new PollHandler<HttpToolResponse>() {
- @Override
- public void onSuccess(HttpToolResponse val) {
- if (registered.get() || val == null) {
- return; // Skip if we are registered already or no data from job
- }
- JsonObject response = HttpValueFunctions.jsonContents().apply(val).getAsJsonObject();
- if (response.has("error")) {
- // Parse the JSON error object and log the message
- JsonObject error = response.get("error").getAsJsonObject();
- String message = error.get("message").getAsString();
- String data = error.get("data").getAsString();
- log.warn("zabbix failed registering host - {}: {}", message, data);
- } else if (response.has("result")) {
- // Parse the JSON result object and save the hostId
- JsonObject result = response.get("result").getAsJsonObject();
- String hostId = result.get("hostids").getAsJsonArray().get(0).getAsString();
- // Update the registered status if not set
- if (registered.compareAndSet(false, true)) {
- entity.setAttribute(ZabbixMonitored.ZABBIX_AGENT_HOSTID, hostId);
- log.info("zabbix registered host as id {}", hostId);
- }
- } else {
- throw new IllegalStateException(String.format("zabbix host registration returned invalid result: %s", response.toString()));
- }
- }
- @Override
- public boolean checkSuccess(HttpToolResponse val) {
- return (val.getResponseCode() == 200);
- }
- @Override
- public void onFailure(HttpToolResponse val) {
- log.warn("zabbix sever returned failure code: {}", val.getResponseCode());
- }
- @Override
- public void onException(Exception exception) {
- log.warn("zabbix exception registering host", exception);
- }
- @Override
- public String toString() {
- return super.toString()+"["+getDescription()+"]";
- }
- @Override
- public String getDescription() {
- return "Zabbix rest poll";
- }
- };
-
- // Schedule registration attempt once per second
- getPoller().scheduleAtFixedRate(registerJob, registrationHandler, 1000l); // TODO make configurable
-
- // Create a polling job for each Zabbix metric
- for (final ZabbixPollConfig<?> config : polls) {
- Callable<HttpToolResponse> pollJob = new Callable<HttpToolResponse>() {
- @Override
- public HttpToolResponse call() throws Exception {
- if (registered.get()) {
- if (log.isTraceEnabled()) log.trace("zabbix polling {} for {}", entity, config);
- byte[] body = JSON_ITEM_GET
- .replace("{{token}}", entity.getConfig(ZabbixMonitored.ZABBIX_SERVER).getAttribute(ZabbixServer.ZABBIX_TOKEN))
- .replace("{{hostId}}", entity.getAttribute(ZabbixMonitored.ZABBIX_AGENT_HOSTID))
- .replace("{{itemKey}}", config.getItemKey())
- .replace("{{id}}", Integer.toString(id.incrementAndGet()))
- .getBytes();
-
- return HttpTool.httpPost(httpClient, baseUriProvider.get(), ImmutableMap.of("Content-Type", "application/json"), body);
- } else {
- throw new IllegalStateException("zabbix agent not yet registered");
- }
- }
- };
-
- // Schedule the Zabbix polling job
- AttributePollHandler<? super HttpToolResponse> pollHandler = new AttributePollHandler<HttpToolResponse>(config, entity, this);
- long minPeriod = Integer.MAX_VALUE; // TODO make configurable
- if (config.getPeriod() > 0) minPeriod = Math.min(minPeriod, config.getPeriod());
- getPoller().scheduleAtFixedRate(pollJob, pollHandler, minPeriod);
- }
-
- }
-
- @SuppressWarnings("unchecked")
- protected Poller<HttpToolResponse> getPoller() {
- return (Poller<HttpToolResponse>) super.getPoller();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java b/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java
deleted file mode 100644
index fbaab5d..0000000
--- a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixMonitored.java
+++ /dev/null
@@ -1,38 +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.
- */
-package brooklyn.entity.monitoring.zabbix;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.event.basic.PortAttributeSensorAndConfigKey;
-import brooklyn.util.flags.SetFromFlag;
-
-public interface ZabbixMonitored {
-
- /** The entity representing the Zabbix server monitoring an entity. */
- @SetFromFlag("zabbixServer")
- ConfigKey<ZabbixServer> ZABBIX_SERVER = new BasicConfigKey<ZabbixServer>(ZabbixServer.class, "zabbix.server.entity", "Zabbix server for this entity");
-
- PortAttributeSensorAndConfigKey ZABBIX_AGENT_PORT = new PortAttributeSensorAndConfigKey("zabbix.agent.port", "The port the Zabbix agent is listening on", "10050+");
-
- AttributeSensor<String> ZABBIX_AGENT_HOSTID = new BasicAttributeSensor<String>(String.class, "zabbix.agent.hostid", "The hostId for a Zabbix monitored agent");
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java b/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java
deleted file mode 100644
index 743df8b..0000000
--- a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixPollConfig.java
+++ /dev/null
@@ -1,75 +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.
- */
-package brooklyn.entity.monitoring.zabbix;
-
-import javax.annotation.Nullable;
-
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.feed.PollConfig;
-import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.event.feed.http.JsonFunctions;
-import brooklyn.util.collections.MutableList;
-import brooklyn.util.http.HttpToolResponse;
-
-import com.google.common.base.Function;
-import com.google.common.base.Preconditions;
-import com.google.gson.JsonElement;
-
-public class ZabbixPollConfig<T> extends PollConfig<HttpToolResponse, T, ZabbixPollConfig<T>> {
-
- private String itemKey;
-
- public ZabbixPollConfig(AttributeSensor<T> sensor) {
- super(sensor);
- // Add onSuccess method to extract the last value of the item
- // FIXME Fix generics
- onSuccess((Function)HttpValueFunctions.chain(
- HttpValueFunctions.jsonContents(),
- new Function<JsonElement, JsonElement>() {
- @Override
- public JsonElement apply(@Nullable JsonElement input) {
- Preconditions.checkNotNull(input, "JSON input");
- return input.getAsJsonObject().get("result")
- .getAsJsonArray().get(0)
- .getAsJsonObject().get("lastvalue");
- }
- },
- JsonFunctions.cast(getSensor().getType())));
- }
-
- public ZabbixPollConfig(ZabbixPollConfig<T> other) {
- super(other);
- this.itemKey = other.getItemKey();
- }
-
- public String getItemKey() {
- return itemKey;
- }
-
- public ZabbixPollConfig<T> itemKey(String val) {
- this.itemKey = val;
- return this;
- }
-
- @Override
- protected MutableList<Object> equalsFields() {
- return super.equalsFields().appendIfNotNull(itemKey);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixServer.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixServer.java b/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixServer.java
deleted file mode 100644
index b5987c5..0000000
--- a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixServer.java
+++ /dev/null
@@ -1,52 +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.
- */
-package brooklyn.entity.monitoring.zabbix;
-
-import brooklyn.config.ConfigKey;
-import brooklyn.entity.Entity;
-import brooklyn.entity.proxying.ImplementedBy;
-import brooklyn.event.AttributeSensor;
-import brooklyn.event.basic.BasicAttributeSensor;
-import brooklyn.event.basic.BasicConfigKey;
-import brooklyn.util.flags.SetFromFlag;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-
-@ImplementedBy(ZabbixServerImpl.class)
-public interface ZabbixServer extends Entity {
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @SetFromFlag("filter")
- ConfigKey<Predicate<? super Entity>> ENTITY_FILTER = new BasicConfigKey(Predicate.class, "zabbix.server.filter", "Filter for entities which will automatically be monitored", Predicates.instanceOf(ZabbixMonitored.class));
-
- @SetFromFlag("serverApiUrl")
- ConfigKey<String> ZABBIX_SERVER_API_URL = new BasicConfigKey<String>(String.class, "zabbix.server.apiUrl", "Main Zabbix server API URL");
-
- @SetFromFlag("username")
- ConfigKey<String> ZABBIX_SERVER_USERNAME = new BasicConfigKey<String>(String.class, "zabbix.server.username", "Zabbix server API login user");
-
- @SetFromFlag("password")
- ConfigKey<String> ZABBIX_SERVER_PASSWORD = new BasicConfigKey<String>(String.class, "zabbix.server.password", "Zabbix server API login password");
-
- ConfigKey<Integer> ZABBIX_SESSION_TIMEOUT = new BasicConfigKey<Integer>(Integer.class, "zabbix.server.sessionTimeout", "Zabbix server API session timeout period (seconds)", 3600);
-
- AttributeSensor<String> ZABBIX_TOKEN = new BasicAttributeSensor<String>(String.class, "zabbix.server.token", "Zabbix server API authentication token");
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/070b5ca7/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java
----------------------------------------------------------------------
diff --git a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java b/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java
deleted file mode 100644
index 43d5f64..0000000
--- a/sandbox/monitoring/src/main/java/brooklyn/entity/monitoring/zabbix/ZabbixServerImpl.java
+++ /dev/null
@@ -1,143 +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.
- */
-package brooklyn.entity.monitoring.zabbix;
-
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import brooklyn.entity.Entity;
-import brooklyn.entity.basic.AbstractEntity;
-import brooklyn.entity.basic.DynamicGroup;
-import brooklyn.entity.group.AbstractMembershipTrackingPolicy;
-import brooklyn.entity.proxying.EntitySpec;
-import brooklyn.entity.trait.Startable;
-import brooklyn.event.feed.http.HttpFeed;
-import brooklyn.event.feed.http.HttpPollConfig;
-import brooklyn.event.feed.http.HttpValueFunctions;
-import brooklyn.location.Location;
-import brooklyn.location.basic.SshMachineLocation;
-import brooklyn.policy.PolicySpec;
-
-import com.google.common.base.Functions;
-import com.google.common.base.Optional;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Multimap;
-
-public class ZabbixServerImpl extends AbstractEntity implements ZabbixServer {
-
- private static final Logger log = LoggerFactory.getLogger(ZabbixServerImpl.class);
-
- private Object[] mutex = new Object[0];
- private DynamicGroup monitoredEntities;
- private AgentTrackingPolicy policy;
- private Multimap<Location, Entity> entityLocations = HashMultimap.create();
-
- private transient HttpFeed login;
-
- @Override
- public void init() {
- super.init();
- Predicate<? super Entity> filter = getConfig(ENTITY_FILTER);
- monitoredEntities = addChild(EntitySpec.create(DynamicGroup.class)
- .configure(DynamicGroup.ENTITY_FILTER, filter)
- .displayName("agents"));
- }
-
- @Override
- public void onManagementStarted() {
- final byte[] jsonData = ZabbixFeed.JSON_USER_LOGIN
- .replace("{{username}}", getConfig(ZABBIX_SERVER_USERNAME))
- .replace("{{password}}", getConfig(ZABBIX_SERVER_PASSWORD))
- .getBytes();
- login = HttpFeed.builder()
- .entity(this)
- .baseUri(getConfig(ZABBIX_SERVER_API_URL))
- .headers(ImmutableMap.of("Content-Type", "application/json"))
- .poll(new HttpPollConfig<String>(ZABBIX_TOKEN)
- .method("POST")
- .body(jsonData)
- .onFailure(Functions.constant(""))
- .onSuccess(HttpValueFunctions.jsonContents("result", String.class)))
- .build();
-
- policy = addPolicy(PolicySpec.create(AgentTrackingPolicy.class)
- .displayName("Zabbix Agent Tracker")
- .configure("group", monitoredEntities));
-
- for (Entity each : monitoredEntities.getMembers()) {
- added(each);
- }
-
- setAttribute(Startable.SERVICE_UP, true);
- }
-
- public static class AgentTrackingPolicy extends AbstractMembershipTrackingPolicy {
- @Override
- protected void onEntityChange(Entity member) {
- ((ZabbixServerImpl)entity).added(member); }
- @Override
- protected void onEntityAdded(Entity member) {
- } // Ignore
- @Override
- protected void onEntityRemoved(Entity member) {
- ((ZabbixServerImpl)entity).removed(member);
- }
- }
-
- public void added(Entity member) {
- synchronized (mutex) {
- Optional<Location> location = Iterables.tryFind(member.getLocations(), Predicates.instanceOf(SshMachineLocation.class));
- if (location.isPresent() && member.getAttribute(Startable.SERVICE_UP)) {
- SshMachineLocation machine = (SshMachineLocation) location.get();
- if (!entityLocations.containsKey(machine)) {
- entityLocations.put(machine, member);
- // Configure the Zabbix agent
- List<String> commands = ImmutableList.<String>builder()
- .add("sed -i.bk 's/\\$HOSTNAME/" + machine.getDisplayName() + "/' /etc/zabbix/zabbix_agentd.conf")
- .add("zabbix_agentd")
- .build();
- int result = machine.execCommands("configuring zabbix_agentd", commands);
- if (result == 0) {
- log.info("zabbix_agentd configured on {} at {}", member, machine);
- } else {
- log.warn("failed to configure zabbix_agentd on {}, status {}", machine, result);
- }
- }
- } else {
- log.warn("zabbix added({}) called but no location or service not started", member);
- }
- }
- }
-
- public void removed(Entity member) {
- synchronized (mutex) {
- for (Location location : member.getLocations()) {
- entityLocations.remove(location, member);
- }
- }
- }
-
-}