You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jo...@apache.org on 2014/10/06 23:03:23 UTC
[01/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Repository: ambari
Updated Branches:
refs/heads/trunk 0d953b468 -> 80bceaf3a
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6ba11a2a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6ba11a2a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6ba11a2a
Branch: refs/heads/trunk
Commit: 6ba11a2a94d1646a08bf49215e6776870302325e
Parents: 7bb0194 3c13f40
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Aug 25 08:31:55 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Aug 25 08:31:55 2014 -0400
----------------------------------------------------------------------
.../scripts/controllers/users/UsersShowCtrl.js | 65 +++--
.../ui/admin-web/app/scripts/services/User.js | 3 +-
.../resources/ui/admin-web/app/styles/main.css | 12 +-
.../admin-web/app/views/ambariViews/create.html | 6 +-
.../admin-web/app/views/ambariViews/edit.html | 95 ++++----
.../admin-web/app/views/ambariViews/list.html | 81 -------
.../app/views/ambariViews/listTable.html | 2 +-
.../app/views/clusters/manageAccess.html | 75 +++---
.../ui/admin-web/app/views/groups/list.html | 10 +-
.../ui/admin-web/app/views/users/show.html | 2 +-
ambari-admin/src/main/resources/view.xml | 1 +
.../libraries/providers/hdfs_directory.py | 2 +-
.../api/services/ConfigurationService.java | 2 +-
.../server/api/util/StackExtensionHelper.java | 69 ++++--
.../server/configuration/Configuration.java | 8 -
.../server/controller/AmbariHandlerList.java | 151 ++++++++++++
.../ambari/server/controller/AmbariServer.java | 13 +-
.../server/controller/ControllerModule.java | 2 +
.../server/controller/FailsafeHandlerList.java | 40 +++-
.../internal/ClientConfigResourceProvider.java | 2 +-
.../internal/ConfigGroupResourceProvider.java | 26 +-
.../internal/ViewInstanceResourceProvider.java | 6 +-
.../ambari/server/orm/dao/PrincipalDAO.java | 16 +-
.../apache/ambari/server/orm/dao/RoleDAO.java | 69 ------
.../ambari/server/orm/dao/ServiceConfigDAO.java | 9 +-
.../apache/ambari/server/orm/dao/UserDAO.java | 8 -
.../server/orm/entities/ConfigGroupEntity.java | 11 +
.../server/orm/entities/PrincipalEntity.java | 5 +
.../ambari/server/orm/entities/RoleEntity.java | 70 ------
.../ambari/server/orm/entities/UserEntity.java | 11 -
.../server/orm/entities/ViewInstanceEntity.java | 20 ++
.../AmbariLdapAuthoritiesPopulator.java | 134 +----------
.../AmbariLocalUserDetailsService.java | 8 +-
.../server/security/authorization/User.java | 9 -
.../server/security/authorization/Users.java | 147 +-----------
.../internal/InternalAuthenticationToken.java | 30 ++-
.../server/state/cluster/ClusterImpl.java | 8 +-
.../server/state/configgroup/ConfigGroup.java | 4 +
.../state/configgroup/ConfigGroupImpl.java | 21 ++
.../server/upgrade/UpgradeCatalog170.java | 56 +++--
.../server/view/ViewInstanceHandlerList.java | 43 ++++
.../apache/ambari/server/view/ViewRegistry.java | 58 ++---
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 16 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 16 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 18 +-
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 20 +-
.../src/main/resources/META-INF/persistence.xml | 1 -
.../services/HBASE/package/scripts/params.py | 1 +
.../HDFS/package/scripts/hdfs_namenode.py | 2 +-
.../services/HDFS/package/scripts/params.py | 1 +
.../HIVE/package/scripts/hcat_service_check.py | 27 ++-
.../services/HIVE/package/scripts/params.py | 1 +
.../MAPREDUCE/configuration/core-site.xml | 20 --
.../MAPREDUCE/package/scripts/params.py | 1 +
.../services/OOZIE/package/scripts/params.py | 1 +
.../services/WEBHCAT/package/scripts/params.py | 1 +
.../services/HBASE/package/scripts/params.py | 1 +
.../HDFS/package/scripts/hdfs_namenode.py | 2 +-
.../services/HDFS/package/scripts/params.py | 1 +
.../HIVE/package/scripts/hcat_service_check.py | 27 ++-
.../HIVE/package/scripts/install_jars.py | 2 +-
.../services/HIVE/package/scripts/params.py | 1 +
.../services/OOZIE/package/scripts/params.py | 1 +
.../services/PIG/package/scripts/params.py | 1 +
.../services/WEBHCAT/package/scripts/params.py | 1 +
.../services/WEBHCAT/package/scripts/webhcat.py | 2 +-
.../YARN/configuration-mapred/core-site.xml | 20 --
.../services/YARN/configuration/core-site.xml | 20 --
.../services/YARN/package/scripts/params.py | 1 +
.../services/FALCON/package/scripts/params.py | 1 +
.../services/YARN/package/scripts/params.py | 1 +
.../services/FALCON/package/scripts/params.py | 1 +
.../services/YARN/configuration/core-site.xml | 20 --
.../api/util/StackExtensionHelperTest.java | 235 ++++++++-----------
.../controller/AmbariHandlerListTest.java | 107 +++++++++
.../AmbariManagementControllerTest.java | 11 -
.../apache/ambari/server/orm/OrmTestHelper.java | 26 +-
.../ambari/server/orm/dao/UserDAOTest.java | 40 +---
...uthenticationProviderForDNWithSpaceTest.java | 38 ---
.../AmbariLdapAuthenticationProviderTest.java | 39 ---
.../AmbariLdapDataPopulatorTest.java | 2 -
.../AmbariLocalUserDetailsServiceTest.java | 7 -
.../TestAmbariLdapAuthoritiesPopulator.java | 212 +----------------
.../security/authorization/TestUsers.java | 87 -------
.../server/upgrade/UpgradeCatalog170Test.java | 8 +-
.../ambari/server/upgrade/UpgradeTest.java | 8 -
.../ambari/server/view/ViewRegistryTest.java | 8 +-
.../1.3.2/HIVE/test_hive_service_check.py | 3 +-
.../python/stacks/1.3.2/configs/secured.json | 3 +-
.../2.0.6/HIVE/test_hive_service_check.py | 3 +-
.../python/stacks/2.0.6/configs/secured.json | 5 +-
.../test/python/stacks/2.1/configs/secured.json | 5 +-
ambari-web/app/app.js | 31 +--
ambari-web/app/config.js | 1 -
.../controllers/global/cluster_controller.js | 8 +-
ambari-web/app/controllers/installer.js | 7 -
ambari-web/app/controllers/main.js | 1 +
.../app/controllers/main/admin/repositories.js | 8 +-
.../app/controllers/main/views_controller.js | 80 ++++++-
.../app/controllers/wizard/step5_controller.js | 29 ++-
.../app/controllers/wizard/step6_controller.js | 35 +--
ambari-web/app/mappers/stack_service_mapper.js | 2 +
ambari-web/app/mappers/users_mapper.js | 2 +-
ambari-web/app/messages.js | 2 -
ambari-web/app/mixins.js | 1 +
ambari-web/app/mixins/common/blueprint.js | 70 ++++++
ambari-web/app/router.js | 115 +++++----
ambari-web/app/routes/add_service_routes.js | 4 +-
ambari-web/app/routes/installer.js | 2 +-
ambari-web/app/routes/main.js | 22 --
ambari-web/app/routes/views.js | 53 +++++
ambari-web/app/templates/application.hbs | 6 +-
ambari-web/app/utils/ajax/ajax.js | 4 +-
ambari-web/app/utils/blueprint.js | 4 +
ambari-web/app/views/main/admin/repositories.js | 4 +-
ambari-web/app/views/main/menu.js | 7 +-
ambari-web/app/views/main/views_view.js | 4 +-
ambari-web/app/views/wizard/controls_view.js | 1 +
ambari-web/test/app_test.js | 14 +-
.../test/controllers/wizard/step4_test.js | 6 +-
ambari-web/test/mappers/users_mapper_test.js | 2 +-
121 files changed, 1352 insertions(+), 1659 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6ba11a2a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6ba11a2a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6ba11a2a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6ba11a2a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6ba11a2a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6ba11a2a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6ba11a2a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6ba11a2a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
[25/50] [abbrv] git commit: AMBARI-7336 - Alerts: Create Default
AlertGroup When Service Is Installed (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7336 - Alerts: Create Default AlertGroup When Service Is Installed (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b7ae2d74
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b7ae2d74
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b7ae2d74
Branch: refs/heads/trunk
Commit: b7ae2d74adcd07759b2308bc2a7b0f8115480a7e
Parents: 17b8e79
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Sep 16 12:26:36 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Sep 16 12:26:36 2014 -0400
----------------------------------------------------------------------
.../server/controller/ControllerModule.java | 2 +
.../apache/ambari/server/events/AlertEvent.java | 2 +-
.../ambari/server/events/AmbariEvent.java | 75 ++++++++++
.../ambari/server/events/ServiceEvent.java | 75 ++++++++++
.../server/events/ServiceInstalledEvent.java | 52 +++++++
.../events/listeners/AlertReceivedListener.java | 4 +-
.../listeners/AlertServiceStateListener.java | 147 +++++++++++++++++++
.../listeners/AlertStateChangedListener.java | 2 +
.../events/publishers/AlertEventPublisher.java | 8 +-
.../events/publishers/AmbariEventPublisher.java | 66 +++++++++
.../apache/ambari/server/state/ServiceImpl.java | 49 ++-----
.../state/alerts/AlertEventPublisherTest.java | 132 +++++++++++++++++
12 files changed, 572 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 8413762..349e465 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -52,6 +52,7 @@ import org.apache.ambari.server.controller.internal.MemberResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.events.listeners.AlertReceivedListener;
+import org.apache.ambari.server.events.listeners.AlertServiceStateListener;
import org.apache.ambari.server.events.listeners.AlertStateChangedListener;
import org.apache.ambari.server.orm.DBAccessor;
import org.apache.ambari.server.orm.DBAccessorImpl;
@@ -313,5 +314,6 @@ public class ControllerModule extends AbstractModule {
// them as eager singletons to have them register with the eventbus
bind(AlertReceivedListener.class).asEagerSingleton();
bind(AlertStateChangedListener.class).asEagerSingleton();
+ bind(AlertServiceStateListener.class).asEagerSingleton();
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java
index a75477d..767cb6b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java
@@ -20,7 +20,7 @@ package org.apache.ambari.server.events;
import org.apache.ambari.server.state.Alert;
/**
- * The {@link AlertEvent} class the base for all events related to alerts.
+ * The {@link AlertEvent} class is the base for all events related to alerts.
*/
public abstract class AlertEvent {
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
new file mode 100644
index 0000000..dda18c7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
@@ -0,0 +1,75 @@
+/**
+ * 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.ambari.server.events;
+
+
+/**
+ * The {@link AmbariEvent} class is the base for all events in Ambari.
+ */
+public abstract class AmbariEvent {
+
+ /**
+ * The {@link AmbariEventType} defines the type of Ambari event.
+ */
+ public enum AmbariEventType {
+ /**
+ * A service was successfully installed.
+ */
+ SERVICE_INSTALL_SUCCESS;
+ }
+
+ /**
+ * The concrete event's type.
+ */
+ protected final AmbariEventType m_eventType;
+
+ /**
+ * The cluster ID.
+ */
+ protected final long m_clusterId;
+
+ /**
+ * Constructor.
+ *
+ * @param eventType
+ * the type of event (not {@code null}).
+ * @param clusterId
+ */
+ public AmbariEvent(AmbariEventType eventType, long clusterId) {
+ m_eventType = eventType;
+ m_clusterId = clusterId;
+ }
+
+ /**
+ * Gets the cluster ID that the event belongs to.
+ *
+ * @return the ID of the cluster.
+ */
+ public long getClusterId() {
+ return m_clusterId;
+ }
+
+ /**
+ * Gets the type of {@link AmbariEvent}.
+ *
+ * @return the event type (never {@code null}).
+ */
+ public AmbariEventType getType() {
+ return m_eventType;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
new file mode 100644
index 0000000..5e01431
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
@@ -0,0 +1,75 @@
+/**
+ * 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.ambari.server.events;
+
+
+/**
+ * The {@link ServiceEvent} class is the base for all service events in Ambari.
+ */
+public abstract class ServiceEvent extends AmbariEvent {
+
+ /**
+ * The name of the service.
+ */
+ protected final String m_serviceName;
+
+ /**
+ * The name of the services' stack.
+ */
+ protected final String m_stackName;
+
+ /**
+ * The version of the services' stack.
+ */
+ protected final String m_stackVersion;
+
+ /**
+ * Constructor.
+ *
+ * @param eventType
+ * @param clusterId
+ */
+ public ServiceEvent(AmbariEventType eventType, long clusterId,
+ String stackName, String stackVersion, String serviceName) {
+ super(eventType, clusterId);
+ m_stackName = stackName;
+ m_stackVersion = stackVersion;
+ m_serviceName = serviceName;
+ }
+
+ /**
+ * @return the serviceName (never {@code null}).
+ */
+ public String getServiceName() {
+ return m_serviceName;
+ }
+
+ /**
+ * @return the stackName (never {@code null}).
+ */
+ public String getStackName() {
+ return m_stackName;
+ }
+
+ /**
+ * @return the stackVersion (never {@code null}).
+ */
+ public String getStackVersion() {
+ return m_stackVersion;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceInstalledEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceInstalledEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceInstalledEvent.java
new file mode 100644
index 0000000..c2b6e7a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceInstalledEvent.java
@@ -0,0 +1,52 @@
+/**
+ * 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.ambari.server.events;
+
+/**
+ * The {@link ServiceInstalledEvent} class is fired when a service is
+ * successfully installed.
+ */
+public class ServiceInstalledEvent extends ServiceEvent {
+ /**
+ * Constructor.
+ *
+ * @param clusterId
+ * @param stackName
+ * @param stackVersion
+ * @param serviceName
+ */
+ public ServiceInstalledEvent(long clusterId, String stackName,
+ String stackVersion, String serviceName) {
+ super(AmbariEventType.SERVICE_INSTALL_SUCCESS, clusterId, stackName,
+ stackVersion, serviceName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder("ServiceInstalledEvent{ ");
+ buffer.append("cluserId=").append(m_clusterId);
+ buffer.append(", stackName=").append(m_stackName);
+ buffer.append(", stackVersion=").append(m_stackVersion);
+ buffer.append(", serviceName=").append(m_serviceName);
+ buffer.append("}");
+ return buffer.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
index 1bdd7e2..519ceeb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
@@ -38,7 +38,7 @@ import com.google.inject.Singleton;
/**
* The {@link AlertReceivedListener} class handles {@link AlertReceivedEvent}
- * and updates the appropirate DAOs. It may also fire new
+ * and updates the appropriate DAOs. It may also fire new
* {@link AlertStateChangeEvent} when an {@link AlertState} change is detected.
*/
@Singleton
@@ -80,6 +80,8 @@ public class AlertReceivedListener {
@Subscribe
@AllowConcurrentEvents
public void onAlertEvent(AlertReceivedEvent event) {
+ LOG.debug(event);
+
long clusterId = event.getClusterId();
Alert alert = event.getAlert();
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
new file mode 100644
index 0000000..906d52d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
@@ -0,0 +1,147 @@
+/**
+ * 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.ambari.server.events.listeners;
+
+import java.text.MessageFormat;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.AmbariServer;
+import org.apache.ambari.server.controller.ControllerModule;
+import org.apache.ambari.server.events.ServiceInstalledEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.eventbus.AllowConcurrentEvents;
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AlertServiceStateListener} class handles
+ * {@link ServiceInstalledEvent} and ensures that {@link AlertDefinitionEntity}
+ * and {@link AlertGroupEntity} instances are correctly populated.
+ */
+@Singleton
+public class AlertServiceStateListener {
+ /**
+ * Logger.
+ */
+ private static Log LOG = LogFactory.getLog(AlertServiceStateListener.class);
+
+ /**
+ * Services metainfo; injected lazily as a {@link Provider} since JPA is not
+ * fully initialized when this singleton is eagerly instantiated. See
+ * {@link AmbariServer#main(String[])} and the ordering of
+ * {@link ControllerModule} and {@link GuiceJpaInitializer}.
+ */
+ @Inject
+ private Provider<AmbariMetaInfo> m_metaInfoProvider;
+
+ /**
+ * Used when a service is installed to read alert definitions from the stack
+ * and coerce them into {@link AlertDefinitionEntity}.
+ */
+ @Inject
+ private AlertDefinitionFactory m_alertDefinitionFactory;
+
+ /**
+ * Used when a service is installed to insert a default
+ * {@link AlertGroupEntity} into the database.
+ */
+ @Inject
+ private AlertDispatchDAO m_alertDispatchDao;
+
+ /**
+ * Used when a service is installed to insert {@link AlertDefinitionEntity}
+ * into the database.
+ */
+ @Inject
+ private AlertDefinitionDAO m_definitionDao;
+
+ /**
+ * Constructor.
+ *
+ * @param publisher
+ */
+ @Inject
+ public AlertServiceStateListener(AmbariEventPublisher publisher) {
+ publisher.register(this);
+ }
+
+
+ /**
+ * Handles service installed events by populating the database with all known
+ * alert definitions for the newly installed service and creates the service's
+ * default alert group.
+ *
+ * @param event
+ * the published event being handled (not {@code null}).
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ public void onAmbariEvent(ServiceInstalledEvent event) {
+ LOG.debug(event);
+
+ long clusterId = event.getClusterId();
+ String stackName = event.getStackName();
+ String stackVersion = event.getStackVersion();
+ String serviceName = event.getServiceName();
+
+ // populate alert definitions for the new service from the database, but
+ // don't worry about sending down commands to the agents; the host
+ // components are not yet bound to the hosts so we'd have no way of knowing
+ // which hosts are invalidated; do that in another impl
+ try {
+ Set<AlertDefinition> alertDefinitions = m_metaInfoProvider.get().getAlertDefinitions(
+ stackName, stackVersion, serviceName);
+
+ for (AlertDefinition definition : alertDefinitions) {
+ AlertDefinitionEntity entity = m_alertDefinitionFactory.coerce(
+ clusterId,
+ definition);
+
+ m_definitionDao.create(entity);
+ }
+ } catch (AmbariException ae) {
+ String message = MessageFormat.format(
+ "Unable to populate alert definitions from the database during installation of {0}",
+ serviceName);
+ LOG.error(message, ae);
+ }
+
+ // create the default alert group for the new service
+ AlertGroupEntity serviceAlertGroup = new AlertGroupEntity();
+ serviceAlertGroup.setClusterId(clusterId);
+ serviceAlertGroup.setDefault(true);
+ serviceAlertGroup.setGroupName(serviceName);
+ serviceAlertGroup.setServiceName(serviceName);
+
+ m_alertDispatchDao.create(serviceAlertGroup);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
index a327110..ac22f88 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
@@ -72,6 +72,8 @@ public class AlertStateChangedListener {
@Subscribe
@AllowConcurrentEvents
public void onAlertEvent(AlertStateChangeEvent event) {
+ LOG.debug(event);
+
AlertHistoryEntity history = event.getNewHistoricalEntry();
AlertDefinitionEntity definition = history.getAlertDefinition();
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java b/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
index e42e317..f1a0b3e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
@@ -42,13 +42,13 @@ public final class AlertEventPublisher {
/**
* A multi-threaded event bus that can handle dispatching {@link AlertEvent}s.
*/
- private final EventBus s_eventBus;
+ private final EventBus m_eventBus;
/**
* Constructor.
*/
public AlertEventPublisher() {
- s_eventBus = new AsyncEventBus(Executors.newFixedThreadPool(2,
+ m_eventBus = new AsyncEventBus(Executors.newFixedThreadPool(2,
new AlertEventBusThreadFactory()));
}
@@ -59,7 +59,7 @@ public final class AlertEventPublisher {
* @param event
*/
public void publish(AlertEvent event) {
- s_eventBus.post(event);
+ m_eventBus.post(event);
}
/**
@@ -70,7 +70,7 @@ public final class AlertEventPublisher {
* the listener to receive events.
*/
public void register(Object object) {
- s_eventBus.register(object);
+ m_eventBus.register(object);
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AmbariEventPublisher.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AmbariEventPublisher.java b/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AmbariEventPublisher.java
new file mode 100644
index 0000000..0236e03
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AmbariEventPublisher.java
@@ -0,0 +1,66 @@
+/**
+ * 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.ambari.server.events.publishers;
+
+import org.apache.ambari.server.events.AmbariEvent;
+
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AmbariEventPublisher} is used to publish instances of
+ * {@link AmbariEvent} to any {@link Subscribe} interested. It uses a
+ * single-threaded, serial {@link EventBus}.
+ */
+@Singleton
+public final class AmbariEventPublisher {
+
+ /**
+ * A single threaded event bus for processing Ambari events in serial.
+ */
+ private final EventBus m_eventBus;
+
+ /**
+ * Constructor.
+ */
+ public AmbariEventPublisher() {
+ m_eventBus = new EventBus("ambari-event-bus");
+ }
+
+ /**
+ * Publishes the specified event to all registered listeners that
+ * {@link Subscribe} to any of the {@link AmbariEvent} instances.
+ *
+ * @param event
+ */
+ public void publish(AmbariEvent event) {
+ m_eventBus.post(event);
+ }
+
+ /**
+ * Register a listener to receive events. The listener should use the
+ * {@link Subscribe} annotation.
+ *
+ * @param object
+ * the listener to receive events.
+ */
+ public void register(Object object) {
+ m_eventBus.register(object);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
index b2b84fc..e6b5921 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
@@ -20,7 +20,6 @@ package org.apache.ambari.server.state;
import java.util.HashMap;
import java.util.Map;
-import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -28,18 +27,16 @@ import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ServiceComponentNotFoundException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.ServiceResponse;
-import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.events.ServiceInstalledEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.dao.ClusterDAO;
import org.apache.ambari.server.orm.dao.ClusterServiceDAO;
import org.apache.ambari.server.orm.dao.ServiceDesiredStateDAO;
-import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.ClusterEntity;
import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity;
-import org.apache.ambari.server.state.alert.AlertDefinition;
-import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -80,18 +77,10 @@ public class ServiceImpl implements Service {
private AmbariMetaInfo ambariMetaInfo;
/**
- * Used when a service is installed to insert {@link AlertDefinitionEntity}
- * into the database.
+ * Used to publish events relating to service CRUD operations.
*/
@Inject
- private AlertDefinitionDAO alertDefinitionDAO;
-
- /**
- * Used when a service is installed to read alert definitions from the stack
- * and coerce them into {@link AlertDefinitionEntity}.
- */
- @Inject
- private AlertDefinitionFactory alertDefinitionFactory;
+ private AmbariEventPublisher eventPublisher;
private void init() {
// TODO load from DB during restart?
@@ -476,6 +465,15 @@ public class ServiceImpl implements Service {
refresh();
cluster.refresh();
persisted = true;
+
+ // publish the service installed event
+ StackId stackId = cluster.getDesiredStackVersion();
+
+ ServiceInstalledEvent event = new ServiceInstalledEvent(
+ getClusterId(), stackId.getStackName(),
+ stackId.getStackVersion(), getName());
+
+ eventPublisher.publish(event);
} else {
saveIfPersisted();
}
@@ -491,7 +489,6 @@ public class ServiceImpl implements Service {
@Transactional
protected void persistEntities() {
long clusterId = cluster.getClusterId();
- StackId stackId = cluster.getDesiredStackVersion();
ClusterEntity clusterEntity = clusterDAO.findById(clusterId);
serviceEntity.setClusterEntity(clusterEntity);
@@ -501,26 +498,6 @@ public class ServiceImpl implements Service {
clusterDAO.merge(clusterEntity);
clusterServiceDAO.merge(serviceEntity);
serviceDesiredStateDAO.merge(serviceDesiredStateEntity);
-
- // populate alert definitions for the new service from the database, but
- // don't worry about sending down commands to the agents; the host
- // components are not yet bound to the hosts so we'd have no way of knowing
- // which hosts are invalidated; do that in another impl
- try{
- Set<AlertDefinition> alertDefinitions = ambariMetaInfo.getAlertDefinitions(
- stackId.getStackName(), stackId.getStackVersion(), getName());
-
- for (AlertDefinition definition : alertDefinitions) {
- AlertDefinitionEntity entity = alertDefinitionFactory.coerce(clusterId,
- definition);
-
- alertDefinitionDAO.create(entity);
- }
- } catch( AmbariException ae ){
- LOG.error(
- "Unable to populate alert definitions from the database during installation of {}",
- getName(), ae);
- }
}
@Transactional
http://git-wip-us.apache.org/repos/asf/ambari/blob/b7ae2d74/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java
new file mode 100644
index 0000000..482b5ef
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java
@@ -0,0 +1,132 @@
+/**
+ * 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.ambari.server.state.alerts;
+
+import junit.framework.Assert;
+
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.events.AmbariEvent;
+import org.apache.ambari.server.events.listeners.AlertServiceStateListener;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceFactory;
+import org.apache.ambari.server.state.StackId;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+
+/**
+ * Tests that {@link AmbariEvent} instances are fired correctly and that alert
+ * data is bootstrapped into the database.
+ */
+public class AlertEventPublisherTest {
+
+ private AlertDispatchDAO dispatchDao;
+ private AlertDefinitionDAO definitionDao;
+ private Clusters clusters;
+ private Cluster cluster;
+ private String clusterName;
+ private Injector injector;
+ private ServiceFactory serviceFactory;
+ private AmbariMetaInfo metaInfo;
+
+ /**
+ *
+ */
+ @Before
+ public void setup() throws Exception {
+ injector = Guice.createInjector(new InMemoryDefaultTestModule());
+ injector.getInstance(GuiceJpaInitializer.class);
+
+ // force singleton init via Guice so the listener registers with the bus
+ injector.getInstance(AlertServiceStateListener.class);
+
+ dispatchDao = injector.getInstance(AlertDispatchDAO.class);
+ definitionDao = injector.getInstance(AlertDefinitionDAO.class);
+ clusters = injector.getInstance(Clusters.class);
+ serviceFactory = injector.getInstance(ServiceFactory.class);
+
+ metaInfo = injector.getInstance(AmbariMetaInfo.class);
+ metaInfo.init();
+
+ clusterName = "foo";
+ clusters.addCluster(clusterName);
+ cluster = clusters.getCluster(clusterName);
+ cluster.setDesiredStackVersion(new StackId("HDP", "2.0.6"));
+ Assert.assertNotNull(cluster);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @After
+ public void teardown() throws Exception {
+ injector.getInstance(PersistService.class).stop();
+ injector = null;
+ }
+
+ /**
+ * Tests that a default {@link AlertGroupEntity} is created when a service is
+ * installed.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testDefaultAlertGroupCreation() throws Exception {
+ Assert.assertEquals(0, dispatchDao.findAllGroups().size());
+ installHdfsService();
+ Assert.assertEquals(1, dispatchDao.findAllGroups().size());
+ }
+
+ /**
+ * Tests that all {@link AlertDefinitionEntity} instances are created for the
+ * installed service.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testAlertDefinitionInsertion() throws Exception {
+ Assert.assertEquals(0, definitionDao.findAll().size());
+ installHdfsService();
+ Assert.assertEquals(4, definitionDao.findAll().size());
+ }
+
+ /**
+ * Calls {@link Service#persist()} to mock a service install.
+ */
+ private void installHdfsService() throws Exception {
+ String serviceName = "HDFS";
+ Service service = serviceFactory.createNew(cluster, serviceName);
+ cluster.addService(service);
+ service.persist();
+ service = cluster.getService(serviceName);
+
+ Assert.assertNotNull(service);
+ }
+}
[08/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c13730a0
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c13730a0
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c13730a0
Branch: refs/heads/trunk
Commit: c13730a065646ba404c91f0f06819c71d669ebe7
Parents: 2f5c78e 866f5b2
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Sep 1 07:39:49 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Sep 1 07:39:49 2014 -0400
----------------------------------------------------------------------
.../ambariViews/CreateViewInstanceCtrl.js | 5 +-
.../controllers/ambariViews/ViewsListCtrl.js | 6 +-
.../controllers/groups/GroupsCreateCtrl.js | 1 +
.../controllers/users/UsersCreateCtrl.js | 1 +
.../scripts/controllers/users/UsersShowCtrl.js | 21 +-
.../admin-web/app/scripts/services/uiAlert.js | 21 +-
.../app/views/ambariViews/listTable.html | 3 +
.../ui/admin-web/app/views/leftNavbar.html | 2 +-
ambari-client/groovy-client/pom.xml | 4 +
.../ambari/groovy/client/AmbariClient.groovy | 506 +++++++++++++++++--
.../client/InvalidBlueprintException.groovy | 28 +
.../InvalidHostGroupHostAssociation.groovy | 39 ++
.../resources/blueprints/hdp-multinode-default | 182 +++++++
.../resources/blueprints/hdp-singlenode-default | 133 +++++
.../resources/blueprints/lambda-architecture | 8 +-
.../resources/blueprints/multi-node-hdfs-yarn | 4 +-
.../resources/blueprints/single-node-hdfs-yarn | 2 +-
.../groovy/client/AmbariBlueprintsTest.groovy | 95 ++++
.../ambari/groovy/client/AmbariHostsTest.groovy | 34 +-
.../groovy/client/AmbariRecommendTest.groovy | 150 ++++++
.../groovy/client/AmbariServicesTest.groovy | 63 +++
.../ambari/groovy/client/TestResources.groovy | 2 +
.../src/test/resources/blueprint-config.json | 61 +++
.../test/resources/hdp-multinode-default.json | 200 ++++++++
.../test/resources/hdp-multinode-default2.json | 164 ++++++
.../resources/multi-node-hdfs-yarn-config.json | 89 ++++
.../test/resources/multi-node-hdfs-yarn.json | 83 +++
.../server/api/handlers/DeleteHandler.java | 9 +-
.../controller/AmbariActionExecutionHelper.java | 4 +-
.../AmbariManagementControllerImpl.java | 12 +-
.../controller/MaintenanceStateHelper.java | 49 +-
.../internal/ComponentResourceProvider.java | 2 -
.../internal/ConfigGroupResourceProvider.java | 2 +-
.../internal/HostResourceProvider.java | 12 +-
.../internal/ServiceResourceProvider.java | 12 +-
.../controller/jmx/JMXPropertyProvider.java | 81 ++-
.../orm/dao/ConfigGroupHostMappingDAO.java | 2 +
.../apache/ambari/server/state/ConfigImpl.java | 17 +-
.../server/state/cluster/ClusterImpl.java | 52 +-
.../state/configgroup/ConfigGroupImpl.java | 41 +-
.../HIVE/package/scripts/hive_client.py | 3 +-
.../HIVE/package/scripts/hive_metastore.py | 3 +-
.../HIVE/package/scripts/hive_server.py | 3 +-
.../HIVE/package/scripts/mysql_server.py | 4 +-
.../services/HIVE/package/scripts/params.py | 10 +
.../resources/stacks/HDP/2.1/repos/repoinfo.xml | 14 +-
.../server/api/handlers/DeleteHandlerTest.java | 36 +-
.../controller/MaintenanceStateHelperTest.java | 34 +-
.../controller/jmx/JMXPropertyProviderTest.java | 49 +-
.../server/state/cluster/ClusterTest.java | 122 ++++-
.../ambari/server/state/host/HostTest.java | 8 -
.../HDP/0.1/services/MAPREDUCE/metainfo.xml | 6 +
.../ambari/shell/commands/BasicCommands.java | 74 ---
.../ambari/shell/commands/ClusterCommands.java | 3 +-
.../ambari/shell/commands/ServiceCommands.java | 155 ++++++
.../apache/ambari/shell/completion/Service.java | 31 ++
.../configuration/ConverterConfiguration.java | 6 +
.../shell/converter/ServiceConverter.java | 55 ++
.../ambari/shell/flash/InstallProgress.java | 2 +-
.../shell/commands/ClusterCommandsTest.java | 5 +-
.../shell/commands/ServiceCommandsTest.java | 70 +++
ambari-web/app/assets/licenses/NOTICE.txt | 4 +-
ambari-web/app/config.js | 2 +-
.../nameNode/step5_controller.js | 26 +-
.../nameNode/step9_controller.js | 8 +-
.../highAvailability/progress_controller.js | 23 +
.../resourceManager/step4_controller.js | 11 +-
.../security/security_progress_controller.js | 45 +-
ambari-web/app/controllers/main/host/details.js | 22 +-
ambari-web/app/controllers/main/service.js | 134 +++--
.../controllers/main/service/info/configs.js | 77 +--
.../main/service/reassign/step4_controller.js | 73 ++-
.../app/controllers/wizard/step4_controller.js | 4 +-
.../app/controllers/wizard/step6_controller.js | 22 +-
.../app/controllers/wizard/step8_controller.js | 69 +--
ambari-web/app/messages.js | 16 +-
ambari-web/app/mixins/common/serverValidator.js | 20 +-
ambari-web/app/models/service_config.js | 5 +
ambari-web/app/models/service_config_version.js | 12 +-
ambari-web/app/models/stack_service.js | 10 +-
ambari-web/app/styles/application.less | 14 +-
.../common/configs/compare_property.hbs | 2 +-
.../common/configs/config_history_flow.hbs | 32 +-
.../configs/config_recommendation_popup.hbs | 28 +
.../common/configs/overriddenProperty.hbs | 2 +-
.../common/configs/service_config_category.hbs | 4 +-
.../templates/main/dashboard/config_history.hbs | 8 +-
.../main/dashboard/plus_button_filter.hbs | 2 +-
ambari-web/app/templates/main/menu_item.hbs | 6 +-
ambari-web/app/templates/wizard/step6.hbs | 27 +-
.../wizard/step6/step6_issues_popup.hbs | 41 ++
ambari-web/app/templates/wizard/step7.hbs | 2 +-
ambari-web/app/utils/ajax/ajax.js | 67 ++-
.../views/common/configs/config_history_flow.js | 134 +++--
ambari-web/app/views/main/dashboard/widgets.js | 12 +-
ambari-web/app/views/main/menu.js | 2 +-
ambari-web/app/views/main/service.js | 1 +
ambari-web/app/views/main/views/details.js | 28 +
.../test/controllers/main/service_test.js | 254 ++++++++++
.../jquery.iframe-auto-height.plugin.1.9.5.js | 224 ++++++++
.../app/assets/data/resource/cluster_name.json | 12 +
.../assets/data/resource/components_hosts.json | 16 +
.../app/controllers/slider_apps_controller.js | 50 ++
.../ui/app/controllers/tooltip_controller.js | 19 +
.../src/main/resources/ui/app/helpers/ajax.js | 2 +
.../ui/app/mappers/slider_apps_mapper.js | 3 +-
.../main/resources/ui/app/models/slider_app.js | 5 +
.../src/main/resources/ui/app/routes/main.js | 12 +
.../resources/ui/app/styles/application.less | 13 +
.../resources/ui/app/templates/application.hbs | 1 +
.../ui/app/templates/common/app_tooltip.hbs | 28 +
.../ui/app/templates/slider_app/summary.hbs | 50 +-
.../resources/ui/app/templates/slider_apps.hbs | 2 +-
.../src/main/resources/ui/app/translations.js | 8 +-
.../ui/app/views/slider_app/summary_view.js | 21 +-
.../resources/ui/app/views/slider_apps_view.js | 18 +-
.../slider/src/main/resources/ui/config.js | 2 +
.../ui/vendor/scripts/common/bs-popover.min.js | 1 +
118 files changed, 3958 insertions(+), 673 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c13730a0/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index b181399,06f46fe..0d4f6aa
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@@ -1687,18 -1646,29 +1680,29 @@@ public class ClusterImpl implements Clu
serviceConfigVersionResponse.setClusterName(getClusterName());
serviceConfigVersionResponse.setServiceName(serviceConfigEntity.getServiceName());
serviceConfigVersionResponse.setVersion(serviceConfigEntity.getVersion());
- serviceConfigVersionResponse.setCreateTime(serviceConfigEntity.getCreateTimestamp());
+ serviceConfigVersionResponse.setCreateTime(serviceConfigEntity.getCreateTimestamp());
serviceConfigVersionResponse.setUserName(serviceConfigEntity.getUser());
serviceConfigVersionResponse.setNote(serviceConfigEntity.getNote());
- if (clusterConfigGroups != null) {
- ConfigGroup configGroup = clusterConfigGroups.get(serviceConfigEntity.getGroupId());
+
+ Long groupId = serviceConfigEntity.getGroupId();
+
+ if (groupId != null) {
+ serviceConfigVersionResponse.setGroupId(groupId);
+ ConfigGroup configGroup = null;
+ if (clusterConfigGroups != null) {
+ configGroup = clusterConfigGroups.get(groupId);
+ }
+
if (configGroup != null) {
- serviceConfigVersionResponse.setGroupId(configGroup.getId());
serviceConfigVersionResponse.setGroupName(configGroup.getName());
+ } else {
+ serviceConfigVersionResponse.setGroupName("deleted");
}
+ } else {
+ serviceConfigVersionResponse.setGroupId(-1L); // -1 if no group
+ serviceConfigVersionResponse.setGroupName("default");
}
-
return serviceConfigVersionResponse;
}
[29/50] [abbrv] git commit: AMBARI-7410. Alerts: add aggregate type
and processing (ncole)
Posted by jo...@apache.org.
AMBARI-7410. Alerts: add aggregate type and processing (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/179290e0
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/179290e0
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/179290e0
Branch: refs/heads/trunk
Commit: 179290e0fc5370b9d46a18d5ba9d187d6c1112c8
Parents: ba325d0
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Sep 19 10:55:54 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Sep 19 10:56:10 2014 -0400
----------------------------------------------------------------------
.../server/api/services/AmbariMetaInfo.java | 22 ++-
.../AlertDefinitionResourceProvider.java | 11 +-
.../listeners/AlertAggregateListener.java | 144 +++++++++++++++
.../events/listeners/AlertReceivedListener.java | 14 +-
.../apache/ambari/server/orm/dao/AlertsDAO.java | 52 ++++++
.../server/orm/entities/AlertCurrentEntity.java | 1 +
.../orm/entities/AlertDefinitionEntity.java | 14 +-
.../state/alert/AlertDefinitionFactory.java | 2 +-
.../ambari/server/state/alert/MetricSource.java | 46 ++++-
.../stacks/HDP/2.0.6/services/HBASE/alerts.json | 4 +-
.../stacks/HDP/2.0.6/services/HDFS/alerts.json | 30 +++-
.../server/api/services/AmbariMetaInfoTest.java | 4 +-
.../AlertDefinitionResourceProviderTest.java | 4 +-
.../AlertGroupResourceProviderTest.java | 2 +-
.../apache/ambari/server/orm/OrmTestHelper.java | 3 +-
.../server/orm/dao/AlertDefinitionDAOTest.java | 9 +-
.../server/orm/dao/AlertDispatchDAOTest.java | 3 +-
.../ambari/server/orm/dao/AlertsDAOTest.java | 83 ++++++++-
.../state/cluster/AlertDataManagerTest.java | 174 ++++++++++++++++++-
.../stacks/HDP/2.0.5/services/HDFS/alerts.json | 19 +-
20 files changed, 592 insertions(+), 49 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index e3e5779..ec53afc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -31,7 +31,6 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -48,6 +47,7 @@ import org.apache.ambari.server.api.util.StackExtensionHelper;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.customactions.ActionDefinition;
import org.apache.ambari.server.customactions.ActionDefinitionManager;
+import org.apache.ambari.server.events.listeners.AlertAggregateListener;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.MetainfoDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
@@ -66,6 +66,7 @@ import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
+import org.apache.ambari.server.state.alert.SourceType;
import org.apache.ambari.server.state.stack.LatestRepoCallable;
import org.apache.ambari.server.state.stack.MetricDefinition;
import org.apache.ambari.server.state.stack.RepositoryXml;
@@ -1205,9 +1206,7 @@ public class AmbariMetaInfo {
}
// for every cluster
- Set<Entry<String, Cluster>> clusterEntries = clusterMap.entrySet();
- for (Entry<String, Cluster> clusterEntry : clusterEntries) {
- Cluster cluster = clusterEntry.getValue();
+ for (Cluster cluster : clusterMap.values()) {
long clusterId = cluster.getClusterId();
StackId stackId = cluster.getDesiredStackVersion();
StackInfo stackInfo = getStackInfo(stackId.getStackName(),
@@ -1246,7 +1245,7 @@ public class AmbariMetaInfo {
List<AlertDefinitionEntity> persist = new ArrayList<AlertDefinitionEntity>();
List<AlertDefinitionEntity> entities = alertDefinitionDao.findAll(clusterId);
- // create a map of the enntities for fast extraction
+ // create a map of the entities for fast extraction
Map<String, AlertDefinitionEntity> mappedEntities = new HashMap<String, AlertDefinitionEntity>(100);
for (AlertDefinitionEntity entity : entities) {
mappedEntities.put(entity.getDefinitionName(), entity);
@@ -1279,9 +1278,20 @@ public class AmbariMetaInfo {
LOG.info("Merging Alert Definition {} into the database",
entity.getDefinitionName());
}
-
alertDefinitionDao.createOrUpdate(entity);
}
+
+ // all definitions have been resolved. pull and initialize the aggregates
+ for (AlertDefinitionEntity def : alertDefinitionDao.findAll(cluster.getClusterId())) {
+ if (def.getSourceType().equals(SourceType.AGGREGATE)) {
+ AlertDefinition realDef = alertDefinitionFactory.coerce(def);
+
+ AlertAggregateListener listener = injector.getInstance(AlertAggregateListener.class);
+
+ listener.addAggregateType(cluster.getClusterId(), realDef);
+ }
+ }
+
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
index c63f063..7cb9886 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
@@ -310,7 +310,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
String definitionName = (String) requestMap.get(ALERT_DEF_NAME);
String serviceName = (String) requestMap.get(ALERT_DEF_SERVICE_NAME);
String componentName = (String) requestMap.get(ALERT_DEF_COMPONENT_NAME);
- String sourceType = (String) requestMap.get(ALERT_DEF_SOURCE_TYPE);
+ String type = (String) requestMap.get(ALERT_DEF_SOURCE_TYPE);
String label = (String) requestMap.get(ALERT_DEF_LABEL);
String desiredScope = (String) requestMap.get(ALERT_DEF_SCOPE);
@@ -330,6 +330,11 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
if (null != desiredScope && desiredScope.length() > 0) {
scope = Scope.valueOf(desiredScope);
}
+
+ SourceType sourceType = null;
+ if (null != type && type.length() > 0) {
+ sourceType = SourceType.valueOf(type);
+ }
// if not specified when creating an alert definition, the scope is
// assumed to be ANY
@@ -354,7 +359,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
throw new IllegalArgumentException("Service name must be specified");
}
- if (bCreate && StringUtils.isEmpty(sourceType)) {
+ if (bCreate && null == sourceType) {
throw new IllegalArgumentException(String.format(
"Source type must be specified and one of %s",
EnumSet.allOf(SourceType.class)));
@@ -439,7 +444,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
}
if (null != enabled) {
- entity.setEnabled(enabled);
+ entity.setEnabled(enabled.booleanValue());
}
if (null != interval) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
new file mode 100644
index 0000000..8340c26
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
@@ -0,0 +1,144 @@
+/**
+ * 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.ambari.server.events.listeners;
+
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.ambari.server.events.AlertReceivedEvent;
+import org.apache.ambari.server.events.publishers.AlertEventPublisher;
+import org.apache.ambari.server.orm.dao.AlertSummaryDTO;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.alert.AggregateSource;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.Reporting;
+import org.apache.ambari.server.state.alert.Reporting.ReportTemplate;
+
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+
+/**
+ * Used to aggregate alerts.
+ */
+public class AlertAggregateListener {
+
+ @Inject
+ private AlertsDAO m_alertsDao = null;
+
+ private AlertEventPublisher m_publisher = null;
+ private Map<Long, Map<String, AlertDefinition>> m_aggregateMap =
+ new HashMap<Long, Map<String, AlertDefinition>>();
+
+ @Inject
+ public AlertAggregateListener(AlertEventPublisher publisher) {
+ m_publisher = publisher;
+
+ publisher.register(this);
+ }
+
+ /**
+ * Consume an alert that was received.
+ */
+ @Subscribe
+ public void onAlertEvent(AlertReceivedEvent event) {
+ AlertDefinition def = getAggregateDefinition(event.getClusterId(), event.getAlert().getName());
+
+ if (null == def || null == m_alertsDao) {
+ return;
+ }
+
+ AggregateSource as = (AggregateSource) def.getSource();
+
+ AlertSummaryDTO summary = m_alertsDao.findAggregateCounts(
+ event.getClusterId(), as.getAlertName());
+
+ Alert alert = new Alert(def.getName(), null, def.getServiceName(),
+ null, null, AlertState.UNKNOWN);
+ alert.setLabel(def.getLabel());
+ alert.setTimestamp(System.currentTimeMillis());
+
+ if (0 == summary.getOkCount()) {
+ alert.setText("Cannot determine, there are no records");
+ } else if (summary.getUnknownCount() > 0) {
+ alert.setText("There are alerts with status UNKNOWN.");
+ } else {
+ Reporting reporting = as.getReporting();
+
+ int numerator = summary.getCriticalCount() + summary.getWarningCount();
+ int denominator = summary.getOkCount();
+ double value = (double)(numerator) / denominator;
+
+ if (value > reporting.getCritical().getValue().doubleValue()) {
+ alert.setState(AlertState.CRITICAL);
+ alert.setText(MessageFormat.format(reporting.getCritical().getText(),
+ Integer.valueOf(denominator), Integer.valueOf(numerator)));
+
+ } else if (value > reporting.getWarning().getValue().doubleValue()) {
+ alert.setState(AlertState.WARNING);
+ alert.setText(MessageFormat.format(reporting.getWarning().getText(),
+ Integer.valueOf(denominator), Integer.valueOf(numerator)));
+
+ } else {
+ alert.setState(AlertState.OK);
+ alert.setText(MessageFormat.format(reporting.getOk().getText(),
+ Integer.valueOf(denominator), Integer.valueOf(numerator)));
+ }
+
+ }
+
+ // make a new event and allow others to consume it
+ AlertReceivedEvent aggEvent = new AlertReceivedEvent(event.getClusterId(), alert);
+
+ m_publisher.publish(aggEvent);
+ }
+
+ private AlertDefinition getAggregateDefinition(long clusterId, String name) {
+ Long id = Long.valueOf(clusterId);
+ if (!m_aggregateMap.containsKey(id))
+ return null;
+
+ if (!m_aggregateMap.get(id).containsKey(name))
+ return null;
+
+ return m_aggregateMap.get(id).get(name);
+ }
+
+ /**
+ * @param source the aggregate source
+ */
+ public void addAggregateType(long clusterId, AlertDefinition definition) {
+ Long id = Long.valueOf(clusterId);
+
+ if (!m_aggregateMap.containsKey(id)) {
+ m_aggregateMap.put(id, new HashMap<String, AlertDefinition>());
+ }
+
+ Map<String, AlertDefinition> map = m_aggregateMap.get(id);
+
+ AggregateSource as = (AggregateSource) definition.getSource();
+
+ map.put(as.getAlertName(), definition);
+ }
+
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
index 0f1b49a..fb7a608 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
@@ -85,9 +85,15 @@ public class AlertReceivedListener {
long clusterId = event.getClusterId();
Alert alert = event.getAlert();
- AlertCurrentEntity current = m_alertsDao.findCurrentByHostAndName(clusterId,
- alert.getHost(), alert.getName());
-
+ AlertCurrentEntity current = null;
+
+ if (null == alert.getHost()) {
+ current = m_alertsDao.findCurrentByNameNoHost(clusterId, alert.getName());
+ } else {
+ current = m_alertsDao.findCurrentByHostAndName(clusterId, alert.getHost(),
+ alert.getName());
+ }
+
if (null == current) {
AlertDefinitionEntity definition = m_definitionDao.findByName(clusterId,
alert.getName());
@@ -122,7 +128,7 @@ public class AlertReceivedListener {
current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
m_alertsDao.merge(current);
-
+
// broadcast the alert changed event for other subscribers
AlertStateChangeEvent alertChangedEvent = new AlertStateChangeEvent(
event.getClusterId(), event.getAlert(), current.getAlertHistory(),
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index a274089..aba41a5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -457,5 +457,57 @@ public class AlertsDAO {
public void remove(AlertCurrentEntity alert) {
entityManagerProvider.get().remove(merge(alert));
}
+
+ /**
+ * Finds the aggregate counts for an alert name, across all hosts.
+ * @param clusterId the cluster id
+ * @param alertName the name of the alert to find the aggregate
+ * @return the summary data
+ */
+ @RequiresSession
+ public AlertSummaryDTO findAggregateCounts(long clusterId, String alertName) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("SELECT NEW %s (");
+ sb.append("COUNT(history), ");
+ sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END), ");
+ sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END), ");
+ sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END)) ");
+ sb.append("FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId");
+ sb.append(" AND history.alertDefinition.definitionName = :definitionName");
+
+ String str = String.format(sb.toString(),
+ AlertSummaryDTO.class.getName(),
+ AlertState.class.getName(), AlertState.WARNING.name(),
+ AlertState.class.getName(), AlertState.CRITICAL.name(),
+ AlertState.class.getName(), AlertState.UNKNOWN.name());
+
+ TypedQuery<AlertSummaryDTO> query = entityManagerProvider.get().createQuery(
+ str, AlertSummaryDTO.class);
+
+ query.setParameter("clusterId", Long.valueOf(clusterId));
+ query.setParameter("definitionName", alertName);
+
+ return daoUtils.selectSingle(query);
+ }
+
+ /**
+ * Locate the current alert for the provided service and alert name, but when
+ * host is not set ({@code IS NULL}).
+ * @param clusterId the cluster id
+ * @param serviceName the service name
+ * @param alertName the name of the alert
+ * @return the current record, or {@code null} if not found
+ */
+ @RequiresSession
+ public AlertCurrentEntity findCurrentByNameNoHost(long clusterId, String alertName) {
+
+ TypedQuery<AlertCurrentEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertCurrentEntity.findByNameAndNoHost", AlertCurrentEntity.class);
+
+ query.setParameter("clusterId", Long.valueOf(clusterId));
+ query.setParameter("definitionName", alertName);
+
+ return daoUtils.selectOne(query);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
index c24ac17..5b54d57 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
@@ -51,6 +51,7 @@ import org.apache.ambari.server.state.MaintenanceState;
@NamedQuery(name = "AlertCurrentEntity.findByService", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.serviceName = :serviceName AND history.alertDefinition.scope IN :inlist"),
@NamedQuery(name = "AlertCurrentEntity.findByHost", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.hostName = :hostName AND history.alertDefinition.scope IN :inlist"),
@NamedQuery(name = "AlertCurrentEntity.findByHostAndName", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.alertDefinition.definitionName = :definitionName AND history.hostName = :hostName"),
+ @NamedQuery(name = "AlertCurrentEntity.findByNameAndNoHost", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.alertDefinition.definitionName = :definitionName AND history.hostName IS NULL"),
@NamedQuery(name = "AlertCurrentEntity.removeByHistoryId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.alertId = :historyId"),
@NamedQuery(name = "AlertCurrentEntity.removeByDefinitionId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertDefinition.definitionId = :definitionId") })
public class AlertCurrentEntity {
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
index b4b8a44..8548fda 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
@@ -43,6 +43,7 @@ import javax.persistence.TableGenerator;
import javax.persistence.UniqueConstraint;
import org.apache.ambari.server.state.alert.Scope;
+import org.apache.ambari.server.state.alert.SourceType;
/**
* The {@link AlertDefinitionEntity} class is used to model an alert that needs
@@ -106,7 +107,8 @@ public class AlertDefinitionEntity {
private String serviceName;
@Column(name = "source_type", nullable = false, length = 255)
- private String sourceType;
+ @Enumerated(value = EnumType.STRING)
+ private SourceType sourceType;
/**
* Bi-directional many-to-many association to {@link AlertGroupEntity}
@@ -266,7 +268,7 @@ public class AlertDefinitionEntity {
* otherwise.
*/
public boolean getEnabled() {
- return enabled == 0 ? false : true;
+ return enabled == Integer.valueOf(0) ? false : true;
}
/**
@@ -277,7 +279,7 @@ public class AlertDefinitionEntity {
* otherwise.
*/
public void setEnabled(boolean enabled) {
- this.enabled = enabled ? 1 : 0;
+ this.enabled = enabled ? Integer.valueOf(1) : Integer.valueOf(0);
}
/**
@@ -344,16 +346,14 @@ public class AlertDefinitionEntity {
/**
* @return
*/
- // !!! FIXME: Create enumeration for this
- public String getSourceType() {
+ public SourceType getSourceType() {
return sourceType;
}
/**
* @param sourceType
*/
- // !!! FIXME: Create enumeration for this
- public void setSourceType(String sourceType) {
+ public void setSourceType(SourceType sourceType) {
this.sourceType = sourceType;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
index f16f4a6..f8e44bd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
@@ -203,7 +203,7 @@ public class AlertDefinitionFactory {
entity.setScope(scope);
Source source = definition.getSource();
- entity.setSourceType(source.getType().name());
+ entity.setSourceType(source.getType());
try {
String sourceJson = m_gson.toJson(source);
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
index 530c1bb..15351d9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
@@ -17,6 +17,10 @@
*/
package org.apache.ambari.server.state.alert;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
import com.google.gson.annotations.SerializedName;
/**
@@ -31,7 +35,7 @@ public class MetricSource extends Source {
private String m_uri = null;
@SerializedName("jmx")
- private Object jmxInfo = null;
+ private JmxInfo jmxInfo = null;
@SerializedName("ganglia")
private String gangliaInfo = null;
@@ -39,7 +43,7 @@ public class MetricSource extends Source {
/**
* @return the jmx info, if this metric is jmx-based
*/
- public Object getJmxInfo() {
+ public JmxInfo getJmxInfo() {
return jmxInfo;
}
@@ -116,4 +120,42 @@ public class MetricSource extends Source {
return true;
}
+
+ /**
+ * Represents the {@code jmx} element in a Metric alert.
+ */
+ public static class JmxInfo {
+ @SerializedName("property_list")
+ private List<String> propertyList;
+
+ private String value;
+
+ public List<String> getPropertyList() {
+ return propertyList;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (!JmxInfo.class.isInstance(object)) {
+ return false;
+ }
+
+ JmxInfo other = (JmxInfo)object;
+
+ List<String> list1 = new ArrayList<String>(propertyList);
+ List<String> list2 = new ArrayList<String>(other.propertyList);
+
+ if ((null == list1 && null != list2) || (null != list1 && null == list2)) {
+ return false;
+ }
+
+ // !!! even if out of order, this is enough to fail
+ return list1.equals(list2);
+
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/alerts.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/alerts.json
index 3958106..2e21aad 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/alerts.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HBASE/alerts.json
@@ -5,7 +5,7 @@
"name": "hbase_master_process",
"label": "HBase Master Process",
"interval": 1,
- "scope": "any",
+ "scope": "ANY",
"source": {
"type": "PORT",
"uri": "{{hbase-site/hbase.master.port}}",
@@ -21,4 +21,4 @@
}
}
]
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
index 00286b1..88503af 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
@@ -1,11 +1,35 @@
{
- "service": [],
+ "service": [
+ {
+ "name": "percent_datanode",
+ "label": "Percent DataNodes live",
+ "interval": 1,
+ "scope": "SERVICE",
+ "source": {
+ "type": "AGGREGATE",
+ "alert_name": "datanode_process",
+ "reporting": {
+ "ok": {
+ "text": "OK: total: <{0}>, affected: <{1}>"
+ },
+ "warning": {
+ "text": "OK: total: <{0}>, affected: <{1}>",
+ "value": 0.1
+ },
+ "critical": {
+ "text": "CRITICAL: total: <{0}>, affected <{1}>",
+ "value": 0.3
+ }
+ }
+ }
+ }
+ ],
"NAMENODE": [
{
"name": "namenode_process",
"label": "NameNode Process",
"interval": 1,
- "scope": "any",
+ "scope": "ANY",
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.namenode.http-address}}",
@@ -24,7 +48,7 @@
"name": "check_cpu",
"label": "NameNode host CPU utilization",
"interval": 2,
- "scope": "any",
+ "scope": "ANY",
"source": {
"type": "METRIC",
"uri": "{{hdfs-site/dfs.namenode.http-address}}",
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 66c0b3d..23d0efa 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -1530,7 +1530,7 @@ public class AmbariMetaInfoTest {
expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
expect(cluster.getDesiredStackVersion()).andReturn(stackId).anyTimes();
expect(cluster.getServices()).andReturn(clusterServiceMap).anyTimes();
- expect(dao.findAll(EasyMock.anyInt())).andReturn(entities);
+ expect(dao.findAll(EasyMock.anyInt())).andReturn(entities).atLeastOnce();
dao.createOrUpdate(EasyMock.anyObject(AlertDefinitionEntity.class));
EasyMock.expectLastCall().times(4);
@@ -1549,7 +1549,7 @@ public class AmbariMetaInfoTest {
expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
expect(cluster.getDesiredStackVersion()).andReturn(stackId).anyTimes();
expect(cluster.getServices()).andReturn(clusterServiceMap).anyTimes();
- expect(dao.findAll(EasyMock.anyInt())).andReturn(entities);
+ expect(dao.findAll(EasyMock.anyInt())).andReturn(entities).atLeastOnce();
EasyMock.replay(clusters, cluster, dao);
metaInfo.reconcileAlertDefinitions(clusters);
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
index 7ea2ffe..78655dd 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
@@ -264,7 +264,7 @@ public class AlertDefinitionResourceProviderTest {
Assert.assertEquals(Integer.valueOf(1), entity.getScheduleInterval());
Assert.assertEquals(Scope.ANY, entity.getScope());
Assert.assertEquals("HDFS", entity.getServiceName());
- Assert.assertEquals("METRIC", entity.getSourceType());
+ Assert.assertEquals(SourceType.METRIC, entity.getSourceType());
Assert.assertEquals("Mock Label (Create)", entity.getLabel());
// verify Source
@@ -474,7 +474,7 @@ public class AlertDefinitionResourceProviderTest {
entity.setHash(DEFINITION_UUID);
entity.setScheduleInterval(Integer.valueOf(2));
entity.setServiceName(null);
- entity.setSourceType(SourceType.METRIC.name());
+ entity.setSourceType(SourceType.METRIC);
entity.setSource(sourceJson);
return Arrays.asList(entity);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
index ddfc75a..d2ce6fb 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
@@ -478,7 +478,7 @@ public class AlertGroupResourceProviderTest {
entity.setHash(DEFINITION_UUID);
entity.setScheduleInterval(Integer.valueOf(2));
entity.setServiceName(null);
- entity.setSourceType(SourceType.METRIC.name());
+ entity.setSourceType(SourceType.METRIC);
entity.setSource(null);
Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
index a9d126c..08cd7b8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
@@ -61,6 +61,7 @@ import org.apache.ambari.server.orm.entities.StageEntity;
import org.apache.ambari.server.orm.entities.UserEntity;
import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.alert.Scope;
+import org.apache.ambari.server.state.alert.SourceType;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.Assert;
@@ -330,7 +331,7 @@ public class OrmTestHelper {
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
definition.setSource("Source " + System.currentTimeMillis());
- definition.setSourceType("SCRIPT");
+ definition.setSourceType(SourceType.SCRIPT);
alertDefinitionDAO.create(definition);
return alertDefinitionDAO.findById(definition.getDefinitionId());
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index cdca3dd..3e20cd6 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -45,6 +45,7 @@ import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.NotificationState;
import org.apache.ambari.server.state.alert.Scope;
+import org.apache.ambari.server.state.alert.SourceType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -97,7 +98,7 @@ public class AlertDefinitionDAOTest {
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
definition.setSource("Source " + i);
- definition.setSourceType("SCRIPT");
+ definition.setSourceType(SourceType.SCRIPT);
dao.create(definition);
}
@@ -118,7 +119,7 @@ public class AlertDefinitionDAOTest {
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
definition.setSource("Source " + i);
- definition.setSourceType("SCRIPT");
+ definition.setSourceType(SourceType.SCRIPT);
dao.create(definition);
}
@@ -133,7 +134,7 @@ public class AlertDefinitionDAOTest {
definition.setScheduleInterval(60);
definition.setScope(Scope.HOST);
definition.setSource("Source " + i);
- definition.setSourceType("SCRIPT");
+ definition.setSourceType(SourceType.SCRIPT);
dao.create(definition);
}
@@ -148,7 +149,7 @@ public class AlertDefinitionDAOTest {
definition.setScheduleInterval(60);
definition.setScope(Scope.HOST);
definition.setSource("Source " + i);
- definition.setSourceType("SCRIPT");
+ definition.setSourceType(SourceType.SCRIPT);
dao.create(definition);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
index 2c3a876..7f4deda 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
@@ -41,6 +41,7 @@ import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.NotificationState;
import org.apache.ambari.server.state.alert.Scope;
+import org.apache.ambari.server.state.alert.SourceType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -431,7 +432,7 @@ public class AlertDispatchDAOTest {
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
definition.setSource("Source " + i);
- definition.setSourceType("SCRIPT");
+ definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index a397da4..9e638e8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -40,6 +40,7 @@ import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.alert.Scope;
+import org.apache.ambari.server.state.alert.SourceType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -84,7 +85,7 @@ public class AlertsDAOTest {
definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.SERVICE);
definition.setSource("Source " + i);
- definition.setSourceType("SCRIPT");
+ definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
}
@@ -208,7 +209,7 @@ public class AlertsDAOTest {
hostDef.setScheduleInterval(Integer.valueOf(60));
hostDef.setScope(Scope.HOST);
hostDef.setSource("HostService");
- hostDef.setSourceType("SCRIPT");
+ hostDef.setSourceType(SourceType.SCRIPT);
definitionDao.create(hostDef);
// history for the definition
@@ -395,5 +396,83 @@ public class AlertsDAOTest {
assertEquals(0, summary.getCriticalCount());
assertEquals(0, summary.getCriticalCount());
+ }
+
+ @Test
+ public void testFindAggregates() throws Exception {
+ // definition
+ AlertDefinitionEntity definition = new AlertDefinitionEntity();
+ definition.setDefinitionName("many_per_cluster");
+ definition.setServiceName("ServiceName");
+ definition.setComponentName(null);
+ definition.setClusterId(clusterId);
+ definition.setHash(UUID.randomUUID().toString());
+ definition.setScheduleInterval(Integer.valueOf(60));
+ definition.setScope(Scope.SERVICE);
+ definition.setSource("SourceScript");
+ definition.setSourceType(SourceType.SCRIPT);
+ definitionDao.create(definition);
+
+ // history record #1 and current
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setAlertDefinition(definition);
+ history.setAlertInstance(null);
+ history.setAlertLabel("");
+ history.setAlertState(AlertState.OK);
+ history.setAlertText("");
+ history.setAlertTimestamp(Long.valueOf(1L));
+ history.setClusterId(clusterId);
+ history.setComponentName("");
+ history.setHostName("h1");
+ history.setServiceName("ServiceName");
+
+ AlertCurrentEntity current = new AlertCurrentEntity();
+ current.setAlertHistory(history);
+ current.setLatestTimestamp(Long.valueOf(1L));
+ current.setOriginalTimestamp(Long.valueOf(1L));
+ dao.merge(current);
+
+ // history record #2 and current
+ history = new AlertHistoryEntity();
+ history.setAlertDefinition(definition);
+ history.setAlertInstance(null);
+ history.setAlertLabel("");
+ history.setAlertState(AlertState.OK);
+ history.setAlertText("");
+ history.setAlertTimestamp(Long.valueOf(1L));
+ history.setClusterId(clusterId);
+ history.setComponentName("");
+ history.setHostName("h2");
+ history.setServiceName("ServiceName");
+
+ current = new AlertCurrentEntity();
+ current.setAlertHistory(history);
+ current.setLatestTimestamp(Long.valueOf(1L));
+ current.setOriginalTimestamp(Long.valueOf(1L));
+ dao.merge(current);
+
+ AlertSummaryDTO summary = dao.findAggregateCounts(clusterId.longValue(), "many_per_cluster");
+ assertEquals(2, summary.getOkCount());
+ assertEquals(0, summary.getWarningCount());
+ assertEquals(0, summary.getCriticalCount());
+ assertEquals(0, summary.getUnknownCount());
+
+ AlertCurrentEntity c = dao.findCurrentByHostAndName(clusterId.longValue(),
+ "h2", "many_per_cluster");
+ AlertHistoryEntity h = c.getAlertHistory();
+ h.setAlertState(AlertState.CRITICAL);
+ dao.merge(h);
+
+ summary = dao.findAggregateCounts(clusterId.longValue(), "many_per_cluster");
+ assertEquals(2, summary.getOkCount());
+ assertEquals(0, summary.getWarningCount());
+ assertEquals(1, summary.getCriticalCount());
+ assertEquals(0, summary.getUnknownCount());
+
+ summary = dao.findAggregateCounts(clusterId.longValue(), "foo");
+ assertEquals(0, summary.getOkCount());
+ assertEquals(0, summary.getWarningCount());
+ assertEquals(0, summary.getCriticalCount());
+ assertEquals(0, summary.getUnknownCount());
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
index bbf7774..00ba942 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
@@ -20,17 +20,22 @@ package org.apache.ambari.server.state.cluster;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.ambari.server.events.AlertEvent;
import org.apache.ambari.server.events.AlertReceivedEvent;
import org.apache.ambari.server.events.AlertStateChangeEvent;
+import org.apache.ambari.server.events.listeners.AlertAggregateListener;
import org.apache.ambari.server.events.listeners.AlertReceivedListener;
import org.apache.ambari.server.events.listeners.AlertStateChangedListener;
+import org.apache.ambari.server.events.publishers.AlertEventPublisher;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
@@ -45,15 +50,25 @@ import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.alert.AggregateSource;
+import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
+import org.apache.ambari.server.state.alert.Reporting;
+import org.apache.ambari.server.state.alert.Reporting.ReportTemplate;
import org.apache.ambari.server.state.alert.Scope;
+import org.apache.ambari.server.state.alert.Source;
+import org.apache.ambari.server.state.alert.SourceType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import com.google.gson.Gson;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.persist.PersistService;
+
/**
* Tests the management of {@link AlertEvent}s in the system.
*/
@@ -94,7 +109,7 @@ public class AlertDataManagerTest {
definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.SERVICE);
definition.setSource("Source " + i);
- definition.setSourceType("SCRIPT");
+ definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
}
}
@@ -253,4 +268,161 @@ public class AlertDataManagerTest {
notices = dispatchDao.findAllNotices();
assertEquals(1, notices.size());
}
+
+ @Test
+ public void testAggregateAlerts() throws Exception {
+ // create definition
+ AlertDefinitionEntity definition = new AlertDefinitionEntity();
+ definition.setDefinitionName("to_aggregate");
+ definition.setLabel("My Label");
+ definition.setServiceName("SERVICE");
+ definition.setComponentName(null);
+ definition.setClusterId(clusterId);
+ definition.setHash(UUID.randomUUID().toString());
+ definition.setScheduleInterval(Integer.valueOf(60));
+ definition.setScope(Scope.HOST);
+ definition.setSource("Source");
+ definition.setSourceType(SourceType.SCRIPT);
+ definitionDao.create(definition);
+
+ // create aggregate of definition
+ AlertDefinitionEntity aggDef = new AlertDefinitionEntity();
+ aggDef.setDefinitionName("aggregate_test");
+ aggDef.setServiceName("SERVICE");
+ aggDef.setComponentName(null);
+ aggDef.setClusterId(clusterId);
+ aggDef.setHash(UUID.randomUUID().toString());
+ aggDef.setScheduleInterval(Integer.valueOf(60));
+ aggDef.setScope(Scope.SERVICE);
+
+ AggregateSource source = new AggregateSource();
+
+ source.setAlertName("to_aggregate");
+ // !!! type is protected
+ Field field = Source.class.getDeclaredField("type");
+ field.setAccessible(true);
+ field.set(source, SourceType.AGGREGATE);
+
+ Reporting reporting = new Reporting();
+
+ ReportTemplate template = new ReportTemplate();
+ template.setText("You are good {1}/{0}");
+ reporting.setOk(template);
+
+ template = new ReportTemplate();
+ template.setText("Going bad {1}/{0}");
+ template.setValue(Double.valueOf(0.33d));
+ reporting.setWarning(template);
+
+ template = new ReportTemplate();
+ template.setText("On fire! {1}/{0}");
+ template.setValue(Double.valueOf(0.66d));
+ reporting.setCritical(template);
+
+ source.setReporting(reporting);
+
+ Gson gson = new Gson();
+
+ aggDef.setSource(gson.toJson(source));
+ aggDef.setSourceType(SourceType.AGGREGATE);
+ definitionDao.create(aggDef);
+
+ // add current and history across four hosts
+ for (int i = 0; i < 4; i++) {
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setAlertDefinition(definition);
+ history.setAlertInstance(null);
+ history.setAlertLabel(definition.getLabel());
+ history.setAlertState(AlertState.OK);
+ history.setAlertText("OK");
+ history.setAlertTimestamp(Long.valueOf(1));
+ history.setClusterId(clusterId);
+ history.setComponentName(definition.getComponentName());
+ history.setHostName("h" + (i+1));
+ history.setServiceName(definition.getServiceName());
+ dao.create(history);
+
+ AlertCurrentEntity current = new AlertCurrentEntity();
+ current.setAlertHistory(history);
+ current.setLatestText(history.getAlertText());
+ current.setLatestTimestamp(Long.valueOf(1L));
+ current.setOriginalTimestamp(Long.valueOf(1L));
+ dao.merge(current);
+ }
+
+ AlertEventPublisher publisher = injector.getInstance(AlertEventPublisher.class);
+
+ // !!! need a synchronous op for testing
+ field = AlertEventPublisher.class.getDeclaredField("m_eventBus");
+ field.setAccessible(true);
+ field.set(publisher, new EventBus());
+
+ final AtomicReference<Alert> ref = new AtomicReference<Alert>();
+ publisher.register(new TestListener() {
+ @Subscribe
+ public void catchIt(AlertReceivedEvent event) {
+ ref.set(event.getAlert());
+ }
+ });
+
+ AlertAggregateListener listener = injector.getInstance(AlertAggregateListener.class);
+ AlertDefinitionFactory factory = new AlertDefinitionFactory();
+ listener.addAggregateType(clusterId.longValue(), factory.coerce(aggDef));
+
+ // any alert and event will do that is for the definition since an aggregate
+ // checks them all regardless of state
+ Alert alert = new Alert(
+ definition.getDefinitionName(),
+ null,
+ definition.getServiceName(),
+ definition.getComponentName(),
+ "h1",
+ AlertState.OK);
+ AlertReceivedEvent event = new AlertReceivedEvent(clusterId.longValue(), alert);
+
+ listener.onAlertEvent(event);
+ assertNotNull(ref.get());
+ assertEquals(AlertState.OK, ref.get().getState());
+ assertTrue(ref.get().getText().indexOf("0/4") > -1);
+
+ // check if one is critical, still ok
+ AlertCurrentEntity current = dao.findCurrentByHostAndName(
+ clusterId.longValue(), "h1", definition.getDefinitionName());
+ current.getAlertHistory().setAlertState(AlertState.CRITICAL);
+ dao.merge(current.getAlertHistory());
+
+ listener.onAlertEvent(event);
+ assertEquals("aggregate_test", ref.get().getName());
+ assertEquals(AlertState.OK, ref.get().getState());
+ assertTrue(ref.get().getText().indexOf("1/4") > -1);
+
+ // two are either warning or critical, warning
+ current = dao.findCurrentByHostAndName(
+ clusterId.longValue(), "h2", definition.getDefinitionName());
+ current.getAlertHistory().setAlertState(AlertState.WARNING);
+ dao.merge(current.getAlertHistory());
+
+ listener.onAlertEvent(event);
+ assertEquals("aggregate_test", ref.get().getName());
+ assertEquals(AlertState.WARNING, ref.get().getState());
+ assertTrue(ref.get().getText().indexOf("2/4") > -1);
+
+ // three make it critical
+ current = dao.findCurrentByHostAndName(
+ clusterId.longValue(), "h3", definition.getDefinitionName());
+ current.getAlertHistory().setAlertState(AlertState.CRITICAL);
+ dao.merge(current.getAlertHistory());
+
+ listener.onAlertEvent(event);
+ assertEquals("aggregate_test", ref.get().getName());
+ assertEquals(AlertState.CRITICAL, ref.get().getState());
+ assertTrue(ref.get().getText().indexOf("3/4") > -1);
+ }
+
+ /**
+ * Test interface collects aggregate alert invocations
+ */
+ private static interface TestListener {
+ public void catchIt(AlertReceivedEvent event);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/179290e0/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json
index f4a3001..0077bad 100644
--- a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json
+++ b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json
@@ -1,13 +1,18 @@
{
- "service": [],
+ "service": [
+ ],
"NAMENODE": [
{
"name": "namenode_cpu",
"label": "NameNode host CPU Utilization",
- "scope": "host",
+ "scope": "ANY",
"source": {
"type": "METRIC",
- "jmx": "java.lang:type=OperatingSystem/SystemCpuLoad",
+ "jmx": {
+ "property_list": [
+ "java.lang:type=OperatingSystem/SystemCpuLoad"
+ ]
+ },
"host": "{{hdfs-site/dfs.namenode.secondary.http-address}}",
"reporting": {
"ok": {
@@ -28,7 +33,7 @@
"name": "namenode_process",
"label": "NameNode process",
"interval": 1,
- "scope": "any",
+ "scope": "ANY",
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.namenode.http-address}}",
@@ -47,7 +52,7 @@
"name": "hdfs_last_checkpoint",
"label": "Last Checkpoint Time",
"interval": 1,
- "scope": "service",
+ "SCOPE": "service",
"enabled": false,
"source": {
"type": "SCRIPT",
@@ -60,7 +65,7 @@
"name": "secondary_namenode_process",
"label": "Secondary NameNode process",
"interval": 1,
- "scope": "any",
+ "scope": "ANY",
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.namenode.secondary.http-address}}",
@@ -69,4 +74,4 @@
}
],
"DATANODE": []
-}
\ No newline at end of file
+}
[41/50] [abbrv] git commit: AMBARI-7540 - Alerts: Stack Alerts Should
Not Be Merged Into the DB (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7540 - Alerts: Stack Alerts Should Not Be Merged Into the DB (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a42b7272
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a42b7272
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a42b7272
Branch: refs/heads/trunk
Commit: a42b727260fde066429347f640c4cb1958f712e3
Parents: f923fd8
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Sep 29 11:06:22 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Sep 29 12:17:53 2014 -0400
----------------------------------------------------------------------
.../ambari_agent/dummy_files/definitions.json | 2 +-
.../server/api/services/AmbariMetaInfo.java | 17 ++++++--
.../stacks/HDP/2.0.6/services/HDFS/alerts.json | 6 +++
.../server/api/services/AmbariMetaInfoTest.java | 42 ++++++++++++++++++++
4 files changed, 62 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a42b7272/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
index 8e01833..6e80dea 100644
--- a/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
+++ b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
@@ -15,7 +15,7 @@
"component": "NAMENODE",
"label": "NameNode process",
"interval": 6,
- "scope": "host",
+ "scope": "HOST",
"uuid": "3f82ae27-fa6a-465b-b77d-67963ac55d2f",
"enabled": true,
"source": {
http://git-wip-us.apache.org/repos/asf/ambari/blob/a42b7272/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index c15f73b..28dd397 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -197,6 +197,7 @@ public class AmbariMetaInfo {
alertDefinitionFactory = injector.getInstance(AlertDefinitionFactory.class);
alertDefinitionDao = injector.getInstance(AlertDefinitionDAO.class);
+ eventPublisher = injector.getInstance(AmbariEventPublisher.class);
}
/**
@@ -1275,12 +1276,20 @@ public class AmbariMetaInfo {
continue;
}
- // if the definition exists in the stack and the database and they are
- // not deeply equal, then merge the stack definition into the database
+ // definitions from the stack that are altered will not be overwritten;
+ // use the REST APIs to modify them instead
AlertDefinition databaseDefinition = alertDefinitionFactory.coerce(entity);
if (!stackDefinition.deeplyEquals(databaseDefinition)) {
- entity = alertDefinitionFactory.merge(stackDefinition, entity);
- persist.add(entity);
+ // this is the code that would normally merge the stack definition
+ // into the database; this is not the behavior we want today
+
+ // entity = alertDefinitionFactory.merge(stackDefinition, entity);
+ // persist.add(entity);
+
+ LOG.debug(
+ "The alert named {} has been modified from the stack definition and will not be merged",
+ stackDefinition.getName());
+
continue;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a42b7272/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
index 620c89f..d81170a 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
@@ -5,6 +5,7 @@
"label": "Percent DataNodes Live",
"interval": 1,
"scope": "SERVICE",
+ "enabled": true,
"source": {
"type": "AGGREGATE",
"alert_name": "datanode_process",
@@ -30,6 +31,7 @@
"label": "NameNode Process",
"interval": 1,
"scope": "ANY",
+ "enabled": true,
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.namenode.http-address}}",
@@ -49,6 +51,7 @@
"label": "NameNode host CPU utilization",
"interval": 2,
"scope": "ANY",
+ "enabled": true,
"source": {
"type": "METRIC",
"uri": "{{hdfs-site/dfs.namenode.http-address}}",
@@ -81,6 +84,7 @@
"label": "Secondary NameNode Process",
"interval": 1,
"scope": "any",
+ "enabled": true,
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.namenode.secondary.http-address}}",
@@ -102,6 +106,7 @@
"label": "JournalNode Process",
"interval": 1,
"scope": "host",
+ "enabled": true,
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.journalnode.http-address}}",
@@ -123,6 +128,7 @@
"label": "DateNode Process",
"interval": 1,
"scope": "host",
+ "enabled": true,
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.datanode.http.address}}",
http://git-wip-us.apache.org/repos/asf/ambari/blob/a42b7272/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 4c59a36..613b950 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -47,7 +47,12 @@ import org.apache.ambari.server.api.util.StackExtensionHelper;
import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.OrmTestHelper;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.state.AutoDeployInfo;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.ComponentInfo;
import org.apache.ambari.server.state.CustomCommandDefinition;
import org.apache.ambari.server.state.DependencyInfo;
@@ -56,6 +61,7 @@ import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.RepositoryInfo;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.Stack;
+import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.PortSource;
@@ -1617,6 +1623,42 @@ public class AmbariMetaInfoTest {
assertNotNull(reporting.getWarning().getValue());
}
+ /**
+ * Tests merging stack-based with existing definitions works
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testAlertDefinitionMerging() throws Exception {
+ injector.getInstance(OrmTestHelper.class).createCluster();
+ Clusters clusters = injector.getInstance(Clusters.class);
+ Cluster cluster = clusters.getClusterById(1);
+ cluster.setDesiredStackVersion(
+ new StackId(STACK_NAME_HDP, "2.0.6"));
+
+ cluster.addService("HDFS");
+
+ metaInfo.reconcileAlertDefinitions(clusters);
+
+ AlertDefinitionDAO dao = injector.getInstance(AlertDefinitionDAO.class);
+ List<AlertDefinitionEntity> definitions = dao.findAll();
+ assertEquals(4, definitions.size());
+
+ for (AlertDefinitionEntity definition : definitions) {
+ definition.setScheduleInterval(28);
+ dao.merge(definition);
+ }
+
+ metaInfo.reconcileAlertDefinitions(clusters);
+
+ definitions = dao.findAll();
+ assertEquals(4, definitions.size());
+
+ for (AlertDefinitionEntity definition : definitions) {
+ assertEquals(28, definition.getScheduleInterval().intValue());
+ }
+ }
+
private AmbariMetaInfo setupTempAmbariMetaInfo(String buildDir)
throws Exception {
File stackRootTmp = new File(buildDir + "/ambari-metaInfo");
[28/50] [abbrv] git commit: AMBARI-7391 - Alerts: Scan Database For
Pending AlertNoticeEntity (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7391 - Alerts: Scan Database For Pending AlertNoticeEntity (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ba325d08
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ba325d08
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ba325d08
Branch: refs/heads/trunk
Commit: ba325d0831e9816992849490766e511450ef7f3a
Parents: f1018b1
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Sep 18 11:20:44 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Sep 18 15:21:26 2014 -0400
----------------------------------------------------------------------
ambari-server/pom.xml | 10 +
.../ambari/server/controller/AmbariServer.java | 12 +
.../server/controller/ControllerModule.java | 22 ++
.../events/listeners/AlertReceivedListener.java | 7 +-
.../listeners/AlertServiceStateListener.java | 20 +-
.../listeners/AlertStateChangedListener.java | 4 +-
.../events/publishers/AlertEventPublisher.java | 14 +-
.../server/notifications/DispatchCallback.java | 50 ++++
.../server/notifications/DispatchFactory.java | 62 +++++
.../server/notifications/DispatchRunnable.java | 60 +++++
.../server/notifications/Notification.java | 57 +++++
.../notifications/NotificationDispatcher.java | 47 ++++
.../dispatchers/EmailDispatcher.java | 60 +++++
.../server/orm/dao/AlertDefinitionDAO.java | 15 +-
.../ambari/server/orm/dao/AlertDispatchDAO.java | 69 +++++-
.../server/orm/entities/AlertCurrentEntity.java | 38 +--
.../server/orm/entities/AlertGroupEntity.java | 3 +-
.../server/orm/entities/AlertNoticeEntity.java | 2 +
.../ambari/server/state/alert/TargetType.java | 15 +-
.../server/state/cluster/ClusterImpl.java | 7 +-
.../services/AlertNoticeDispatchService.java | 231 +++++++++++++++++++
.../apache/ambari/server/orm/OrmTestHelper.java | 37 +++
.../server/orm/dao/AlertDefinitionDAOTest.java | 11 +-
.../server/orm/dao/AlertDispatchDAOTest.java | 40 +++-
24 files changed, 847 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index b07afbf..d83db61 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -1418,6 +1418,16 @@
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
+ <dependency>
+ <groupId>com.sun.mail</groupId>
+ <artifactId>mailapi</artifactId>
+ <version>1.5.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.sun.mail</groupId>
+ <artifactId>smtp</artifactId>
+ <version>1.5.2</version>
+ </dependency>
</dependencies>
<!--<reporting> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId> <version>2.5.2</version> </plugin>
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 7354706..57b678a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -113,10 +113,12 @@ import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
+import com.google.common.util.concurrent.ServiceManager;
import com.google.gson.Gson;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
+import com.google.inject.Scopes;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.persist.Transactional;
@@ -147,6 +149,13 @@ public class AmbariServer {
@Inject
@Named("dbInitNeeded")
boolean dbInitNeeded;
+
+ /**
+ * Guava service manager singleton (bound with {@link Scopes#SINGLETON}).
+ */
+ @Inject
+ private ServiceManager serviceManager;
+
/**
* The singleton view registry.
*/
@@ -473,6 +482,9 @@ public class AmbariServer {
executionScheduleManager.start();
LOG.info("********* Started Scheduled Request Manager **********");
+ serviceManager.startAsync();
+ LOG.info("********* Started Services **********");
+
server.join();
LOG.info("Joined the Server");
} catch (BadPaddingException bpe){
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 349e465..cfab1f8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -33,9 +33,11 @@ import static org.eclipse.persistence.config.PersistenceUnitProperties.JDBC_USER
import static org.eclipse.persistence.config.PersistenceUnitProperties.THROW_EXCEPTIONS;
import java.security.SecureRandom;
+import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
+import java.util.Set;
import org.apache.ambari.server.actionmanager.ActionDBAccessor;
import org.apache.ambari.server.actionmanager.ActionDBAccessorImpl;
@@ -88,6 +90,7 @@ import org.apache.ambari.server.state.host.HostImpl;
import org.apache.ambari.server.state.scheduler.RequestExecution;
import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
import org.apache.ambari.server.state.scheduler.RequestExecutionImpl;
+import org.apache.ambari.server.state.services.AlertNoticeDispatchService;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostImpl;
import org.apache.ambari.server.view.ViewInstanceHandlerList;
import org.eclipse.jetty.server.SessionIdManager;
@@ -98,6 +101,7 @@ import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
import org.springframework.web.filter.DelegatingFilterProxy;
+import com.google.common.util.concurrent.ServiceManager;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.AbstractModule;
@@ -226,6 +230,7 @@ public class ControllerModule extends AbstractModule {
requestStaticInjection(ExecutionCommandWrapper.class);
+ bindServices();
bindEagerSingletons();
}
@@ -306,6 +311,23 @@ public class ControllerModule extends AbstractModule {
}
/**
+ * Bind all {@link com.google.common.util.concurrent.Service} singleton
+ * instances and then register them with a singleton {@link ServiceManager}.
+ */
+ private void bindServices() {
+ Set<com.google.common.util.concurrent.Service> services = new HashSet<com.google.common.util.concurrent.Service>();
+
+ AlertNoticeDispatchService alertNoticeDispatchService = new AlertNoticeDispatchService();
+
+ bind(AlertNoticeDispatchService.class).toInstance(
+ alertNoticeDispatchService);
+
+ services.add(alertNoticeDispatchService);
+ ServiceManager manager = new ServiceManager(services);
+ bind(ServiceManager.class).toInstance(manager);
+ }
+
+ /**
* Initializes all eager singletons that should be instantiated as soon as
* possible and not wait for injection.
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
index 519ceeb..0f1b49a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
@@ -113,6 +113,10 @@ public class AlertReceivedListener {
AlertHistoryEntity history = createHistory(clusterId,
current.getAlertHistory().getAlertDefinition(), alert);
+ // manually create the new history entity since we are merging into
+ // an existing current entity
+ m_alertsDao.create(history);
+
current.setAlertHistory(history);
current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
@@ -121,7 +125,8 @@ public class AlertReceivedListener {
// broadcast the alert changed event for other subscribers
AlertStateChangeEvent alertChangedEvent = new AlertStateChangeEvent(
- event.getClusterId(), event.getAlert(), history, oldState);
+ event.getClusterId(), event.getAlert(), current.getAlertHistory(),
+ oldState);
m_alertEventPublisher.publish(alertChangedEvent);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
index 906d52d..f1ce617 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
@@ -113,6 +113,17 @@ public class AlertServiceStateListener {
String stackVersion = event.getStackVersion();
String serviceName = event.getServiceName();
+ // create the default alert group for the new service; this MUST be done
+ // before adding definitions so that they are properly added to the
+ // default group
+ AlertGroupEntity serviceAlertGroup = new AlertGroupEntity();
+ serviceAlertGroup.setClusterId(clusterId);
+ serviceAlertGroup.setDefault(true);
+ serviceAlertGroup.setGroupName(serviceName);
+ serviceAlertGroup.setServiceName(serviceName);
+
+ m_alertDispatchDao.create(serviceAlertGroup);
+
// populate alert definitions for the new service from the database, but
// don't worry about sending down commands to the agents; the host
// components are not yet bound to the hosts so we'd have no way of knowing
@@ -134,14 +145,5 @@ public class AlertServiceStateListener {
serviceName);
LOG.error(message, ae);
}
-
- // create the default alert group for the new service
- AlertGroupEntity serviceAlertGroup = new AlertGroupEntity();
- serviceAlertGroup.setClusterId(clusterId);
- serviceAlertGroup.setDefault(true);
- serviceAlertGroup.setGroupName(serviceName);
- serviceAlertGroup.setServiceName(serviceName);
-
- m_alertDispatchDao.create(serviceAlertGroup);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
index ac22f88..b2f08d7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
@@ -19,6 +19,7 @@ package org.apache.ambari.server.events.listeners;
import java.util.List;
import java.util.Set;
+import java.util.UUID;
import org.apache.ambari.server.events.AlertStateChangeEvent;
import org.apache.ambari.server.events.publishers.AlertEventPublisher;
@@ -89,11 +90,12 @@ public class AlertStateChangedListener {
for (AlertTargetEntity target : targets) {
AlertNoticeEntity notice = new AlertNoticeEntity();
+ notice.setUuid(UUID.randomUUID().toString());
notice.setAlertTarget(target);
notice.setAlertHistory(event.getNewHistoricalEntry());
notice.setNotifyState(NotificationState.PENDING);
- m_alertsDispatchDao.merge(notice);
+ m_alertsDispatchDao.create(notice);
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java b/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
index f1a0b3e..006837a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
@@ -17,8 +17,10 @@
*/
package org.apache.ambari.server.events.publishers;
-import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.ambari.server.events.AlertEvent;
@@ -48,8 +50,14 @@ public final class AlertEventPublisher {
* Constructor.
*/
public AlertEventPublisher() {
- m_eventBus = new AsyncEventBus(Executors.newFixedThreadPool(2,
- new AlertEventBusThreadFactory()));
+ // create a fixed executor that is unbounded for now and will run rejected
+ // requests in the calling thread to prevent loss of alert handling
+ ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 0L,
+ TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(),
+ new AlertEventBusThreadFactory(),
+ new ThreadPoolExecutor.CallerRunsPolicy());
+
+ m_eventBus = new AsyncEventBus(executor);
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchCallback.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchCallback.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchCallback.java
new file mode 100644
index 0000000..e4e944d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchCallback.java
@@ -0,0 +1,50 @@
+/**
+ * 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.ambari.server.notifications;
+
+import java.util.List;
+
+/**
+ * The {@link DispatchCallback} interface is used by an {@link NotificationDispatcher} to
+ * callback to an interested party when a {@link Notification} delivery is
+ * attempted.
+ * <p/>
+ * This class can be used to let the caller know the success or failure status
+ * of the outbound {@link Notification}.
+ */
+public interface DispatchCallback {
+
+ /**
+ * Invoked when a {@link Notification} was successfully dispatched.
+ *
+ * @param callbackIds
+ * a list of unique IDs that the caller can use to identify the
+ * {@link Notification} that was dispatched.
+ */
+ public void onSuccess(List<String> callbackIds);
+
+ /**
+ * Invoked when a {@link Notification} failed to be dispatched.
+ *
+ * @param callbackIds
+ * a list of unique IDs that the caller can use to identify the
+ * {@link Notification} that was dispatched.
+ */
+ public void onFailure(List<String> callbackIds);
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java
new file mode 100644
index 0000000..3414035
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java
@@ -0,0 +1,62 @@
+/**
+ * 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.ambari.server.notifications;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.ambari.server.notifications.dispatchers.EmailDispatcher;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link DispatchFactory} is used to provide singleton instances of
+ * {@link NotificationDispatcher} based on a supplied type.
+ */
+@Singleton
+public final class DispatchFactory {
+
+ /**
+ * Mapping of dispatch type to dispatcher singleton.
+ */
+ private final Map<String, NotificationDispatcher> m_dispatchers = new HashMap<String, NotificationDispatcher>();
+
+ /**
+ * Constructor.
+ *
+ */
+ @Inject
+ public DispatchFactory(Injector injector) {
+ EmailDispatcher emailDispatcher = injector.getInstance(EmailDispatcher.class);
+
+ m_dispatchers.put(emailDispatcher.getType(), emailDispatcher);
+ }
+
+ /**
+ * Gets a dispatcher based on the type.
+ *
+ * @param type
+ * the type (not {@code null}).
+ * @return a dispatcher instance, or {@code null} if none.
+ */
+ public NotificationDispatcher getDispatcher(String type) {
+ return m_dispatchers.get(type);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchRunnable.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchRunnable.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchRunnable.java
new file mode 100644
index 0000000..dcc2103
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchRunnable.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.notifications;
+
+import java.util.concurrent.Executor;
+
+/**
+ * The {@link DispatchRunnable} class is a simple {@link Runnable} that can be
+ * used to pass a {@link Notification} to an {@link NotificationDispatcher} via an
+ * {@link Executor}.
+ */
+public final class DispatchRunnable implements Runnable {
+
+ /**
+ * The dispatcher to dispatch to.
+ */
+ private final NotificationDispatcher m_dispatcher;
+
+ /**
+ * The notification to dispatch.
+ */
+ private final Notification m_notification;
+
+ /**
+ * Constructor.
+ *
+ * @param dispatcher
+ * the dispatcher to dispatch to (not {@code null}).
+ * @param notification
+ * the notification to dispatch (not {@code null}).
+ */
+ public DispatchRunnable(NotificationDispatcher dispatcher, Notification notification) {
+ m_dispatcher = dispatcher;
+ m_notification = notification;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void run() {
+ m_dispatcher.dispatch(m_notification);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java
new file mode 100644
index 0000000..08c5242
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java
@@ -0,0 +1,57 @@
+/**
+ * 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.ambari.server.notifications;
+
+import java.util.List;
+
+/**
+ * The {@link Notification} class is a generic way to relay content through an
+ * {@link NotificationDispatcher}.
+ */
+public class Notification {
+
+ /**
+ *
+ */
+ public String Subject;
+
+ /**
+ * The main content of the notification.
+ */
+ public String Body;
+
+ /**
+ * An optional callback implementation that the dispatcher can use to report
+ * success/failure on delivery.
+ */
+ public DispatchCallback Callback;
+
+ /**
+ * An option list of unique IDs that will identify the origins of this
+ * notification.
+ */
+ public List<String> CallbackIds;
+
+ /**
+ * Constructor.
+ *
+ */
+ public Notification() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/notifications/NotificationDispatcher.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/NotificationDispatcher.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/NotificationDispatcher.java
new file mode 100644
index 0000000..10946be
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/NotificationDispatcher.java
@@ -0,0 +1,47 @@
+/**
+ * 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.ambari.server.notifications;
+
+
+/**
+ * The {@link NotificationDispatcher} interface represents a mechanism for dispatching a
+ * {@link Notification}.
+ * <p/>
+ * Dispatchers should, in general, be singletons. They should also invoke the
+ * appropriate methods on {@link Notification#Callback} to indicate a success or
+ * failure during dispatch.
+ */
+public interface NotificationDispatcher {
+
+ /**
+ * Gets the type of dispatcher. The type of each different dispatcher should
+ * be unique.
+ *
+ * @return the dispatcher's type (never {@code null}).
+ */
+ public String getType();
+
+ /**
+ * Dispatches the specified notification.
+ *
+ * @param notification
+ * the notificationt to dispatch (not {@code null}).
+ */
+ public void dispatch(Notification notification);
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java
new file mode 100644
index 0000000..d0858d3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.notifications.dispatchers;
+
+import org.apache.ambari.server.notifications.NotificationDispatcher;
+import org.apache.ambari.server.notifications.Notification;
+import org.apache.ambari.server.state.alert.TargetType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link EmailDispatcher} class is used to dispatch {@link Notification}
+ * via JavaMail.
+ */
+@Singleton
+public class EmailDispatcher implements NotificationDispatcher {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(EmailDispatcher.class);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getType() {
+ return TargetType.EMAIL.name();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispatch(Notification notification) {
+ LOG.info("Sending email: {}", notification);
+
+ // callback to inform the interested parties about the successful dispatch
+ if (null != notification.Callback) {
+ notification.Callback.onSuccess(notification.CallbackIds);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
index f410c39..570f268 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
@@ -26,6 +26,7 @@ import javax.persistence.TypedQuery;
import org.apache.ambari.server.controller.RootServiceResponseFactory;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
import org.apache.ambari.server.state.alert.Scope;
import com.google.inject.Inject;
@@ -125,7 +126,7 @@ public class AlertDefinitionDAO {
/**
* Gets all of the alert definitions for the list of IDs given.
- *
+ *
* @param definitionIds
* the IDs of the definitions to retrieve.
* @return the definition or an empty list (never {@code null}).
@@ -246,7 +247,9 @@ public class AlertDefinitionDAO {
}
/**
- * Persists a new alert definition.
+ * Persists a new alert definition, also creating the associated
+ * {@link AlertGroupEntity} relationship for the definition's service default
+ * group.
*
* @param alertDefinition
* the definition to persist (not {@code null}).
@@ -254,6 +257,13 @@ public class AlertDefinitionDAO {
@Transactional
public void create(AlertDefinitionEntity alertDefinition) {
entityManagerProvider.get().persist(alertDefinition);
+
+ AlertGroupEntity group = dispatchDao.findDefaultServiceGroup(alertDefinition.getServiceName());
+
+ if (null != group) {
+ group.addAlertDefinition(alertDefinition);
+ dispatchDao.merge(group);
+ }
}
/**
@@ -305,7 +315,6 @@ public class AlertDefinitionDAO {
*/
@Transactional
public void remove(AlertDefinitionEntity alertDefinition) {
- alertDefinition = merge(alertDefinition);
dispatchDao.removeNoticeByDefinitionId(alertDefinition.getDefinitionId());
alertsDao.removeByDefinitionId(alertDefinition.getDefinitionId());
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
index 6d4d19b..2239c8f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
@@ -26,6 +26,7 @@ import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertGroupEntity;
import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.NotificationState;
import org.apache.ambari.server.state.alert.AlertGroup;
import com.google.inject.Inject;
@@ -101,6 +102,37 @@ public class AlertDispatchDAO {
}
/**
+ * Gets a notification with the specified UUID.
+ *
+ * @param uuid
+ * the UUID of the notification to retrieve.
+ * @return the notification or {@code null} if none exists.
+ */
+ public AlertNoticeEntity findNoticeByUuid(String uuid) {
+ TypedQuery<AlertNoticeEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertNoticeEntity.findByUuid", AlertNoticeEntity.class);
+
+ query.setParameter("uuid", uuid);
+
+ return daoUtils.selectOne(query);
+ }
+
+ /**
+ * Gets all {@link AlertNoticeEntity} instances that are
+ * {@link NotificationState#PENDING} and not yet dispatched.
+ *
+ * @return the notices that are waiting to be dispatched, or an empty list
+ * (never {@code null}).
+ */
+ public List<AlertNoticeEntity> findPendingNotices() {
+ TypedQuery<AlertNoticeEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertNoticeEntity.findByState", AlertNoticeEntity.class);
+
+ query.setParameter("notifyState", NotificationState.PENDING);
+ return daoUtils.selectList(query);
+ }
+
+ /**
* Gets an alert group with the specified name across all clusters. Alert
* group names are unique within a cluster.
*
@@ -195,12 +227,13 @@ public class AlertDispatchDAO {
/**
* Gets all of the {@link AlertGroup} instances that include the specified
- * alert definition.
+ * alert definition. Service default groups will also be returned.
*
* @param definitionEntity
* the definition that the group must include (not {@code null}).
* @return all alert groups that have an association with the specified
- * definition or empty list if none exist (never {@code null}).
+ * definition and the definition's service default group or empty list
+ * if none exist (never {@code null}).
*/
public List<AlertGroupEntity> findGroupsByDefinition(
AlertDefinitionEntity definitionEntity) {
@@ -214,6 +247,23 @@ public class AlertDispatchDAO {
}
/**
+ * Gets the default group for the specified service.
+ *
+ * @param serviceName
+ * the name of the service (not {@code null}).
+ * @return the default group, or {@code null} if the service name is not valid
+ * for an installed service; otherwise {@code null} should not be
+ * possible.
+ */
+ public AlertGroupEntity findDefaultServiceGroup(String serviceName) {
+ TypedQuery<AlertGroupEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertGroupEntity.findServiceDefaultGroup", AlertGroupEntity.class);
+
+ query.setParameter("serviceName", serviceName);
+ return daoUtils.selectSingle(query);
+ }
+
+ /**
* Gets all alert notifications stored in the database.
*
* @return all alert notifications or empty list if none exist (never
@@ -289,6 +339,21 @@ public class AlertDispatchDAO {
}
/**
+ * Removes all {@link AlertDefinitionEntity} that are associated with the
+ * specified cluster ID.
+ *
+ * @param clusterId
+ * the cluster ID.
+ */
+ @Transactional
+ public void removeAllGroups(long clusterId) {
+ List<AlertGroupEntity> groups = findAllGroups(clusterId);
+ for (AlertGroupEntity group : groups) {
+ remove(group);
+ }
+ }
+
+ /**
* Persists new alert targets.
*
* @param entities
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
index 8db89f7..c24ac17 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
@@ -69,14 +69,15 @@ public class AlertCurrentEntity {
@Column(name = "original_timestamp", nullable = false)
private Long originalTimestamp;
-
+
@Column(name = "latest_text", length = 4000)
private String latestText = null;
/**
* Unidirectional one-to-one association to {@link AlertHistoryEntity}
*/
- @OneToOne(cascade = { CascadeType.PERSIST })
+ @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE,
+ CascadeType.REFRESH })
@JoinColumn(name = "history_id", unique = true, nullable = false)
private AlertHistoryEntity alertHistory;
@@ -95,7 +96,7 @@ public class AlertCurrentEntity {
/**
* Gets the unique ID for this current alert.
- *
+ *
* @return the ID (never {@code null}).
*/
public Long getAlertId() {
@@ -104,7 +105,7 @@ public class AlertCurrentEntity {
/**
* Sets the unique ID for this current alert.
- *
+ *
* @param alertId
* the ID (not {@code null}).
*/
@@ -115,7 +116,7 @@ public class AlertCurrentEntity {
/**
* Gets the time, in millis, that the last instance of this alert state was
* received.
- *
+ *
* @return the time of the most recently received alert data for this instance
* (never {@code null}).
*/
@@ -126,7 +127,7 @@ public class AlertCurrentEntity {
/**
* Sets the time, in millis, that the last instance of this alert state was
* received.
- *
+ *
* @param latestTimestamp
* the time of the most recently received alert data for this
* instance (never {@code null}).
@@ -137,7 +138,7 @@ public class AlertCurrentEntity {
/**
* Gets the current maintenance state for the alert.
- *
+ *
* @return the current maintenance state (never {@code null}).
*/
public MaintenanceState getMaintenanceState() {
@@ -146,7 +147,7 @@ public class AlertCurrentEntity {
/**
* Sets the current maintenance state for the alert.
- *
+ *
* @param maintenanceState
* the state to set (not {@code null}).
*/
@@ -157,7 +158,7 @@ public class AlertCurrentEntity {
/**
* Gets the time, in milliseconds, when the alert was first received with the
* current state.
- *
+ *
* @return the time of the first instance of this alert.
*/
public Long getOriginalTimestamp() {
@@ -167,14 +168,14 @@ public class AlertCurrentEntity {
/**
* Sets the time, in milliseconds, when the alert was first received with the
* current state.
- *
+ *
* @param originalTimestamp
* the time of the first instance of this alert (not {@code null}).
*/
public void setOriginalTimestamp(Long originalTimestamp) {
this.originalTimestamp = originalTimestamp;
}
-
+
/**
* Gets the latest text for this alert. History will not get a new record on
* update when the state is the same, but the text may be changed. For example,
@@ -183,7 +184,7 @@ public class AlertCurrentEntity {
public String getLatestText() {
return latestText;
}
-
+
/**
* Sets the latest text. {@link #getLatestText()}
*/
@@ -194,7 +195,7 @@ public class AlertCurrentEntity {
/**
* Gets the associated {@link AlertHistoryEntity} entry for this current alert
* instance.
- *
+ *
* @return the most recently received history entry (never {@code null}).
*/
public AlertHistoryEntity getAlertHistory() {
@@ -204,7 +205,7 @@ public class AlertCurrentEntity {
/**
* Gets the associated {@link AlertHistoryEntity} entry for this current alert
* instance.
- *
+ *
* @param alertHistory
* the most recently received history entry (not {@code null}).
*/
@@ -218,16 +219,19 @@ public class AlertCurrentEntity {
*/
@Override
public boolean equals(Object object) {
- if (this == object)
+ if (this == object) {
return true;
+ }
- if (object == null || getClass() != object.getClass())
+ if (object == null || getClass() != object.getClass()) {
return false;
+ }
AlertCurrentEntity that = (AlertCurrentEntity) object;
- if (alertId != null ? !alertId.equals(that.alertId) : that.alertId != null)
+ if (alertId != null ? !alertId.equals(that.alertId) : that.alertId != null) {
return false;
+ }
return true;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
index e7fa9c6..1cc9bcc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
@@ -49,7 +49,8 @@ import javax.persistence.UniqueConstraint;
@NamedQuery(name = "AlertGroupEntity.findAllInCluster", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.clusterId = :clusterId"),
@NamedQuery(name = "AlertGroupEntity.findByName", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName"),
@NamedQuery(name = "AlertGroupEntity.findByNameInCluster", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName AND alertGroup.clusterId = :clusterId"),
- @NamedQuery(name = "AlertGroupEntity.findByAssociatedDefinition", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE :alertDefinition MEMBER OF alertGroup.alertDefinitions"), })
+ @NamedQuery(name = "AlertGroupEntity.findByAssociatedDefinition", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE :alertDefinition MEMBER OF alertGroup.alertDefinitions"),
+ @NamedQuery(name = "AlertGroupEntity.findServiceDefaultGroup", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.serviceName = :serviceName AND alertGroup.isDefault = 1") })
public class AlertGroupEntity {
@Id
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java
index c9470ce..d0d4c9a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java
@@ -46,6 +46,8 @@ import org.apache.ambari.server.state.NotificationState;
@TableGenerator(name = "alert_notice_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "alert_notice_id_seq", initialValue = 0, allocationSize = 1)
@NamedQueries({
@NamedQuery(name = "AlertNoticeEntity.findAll", query = "SELECT notice FROM AlertNoticeEntity notice"),
+ @NamedQuery(name = "AlertNoticeEntity.findByState", query = "SELECT notice FROM AlertNoticeEntity notice WHERE notice.notifyState = :notifyState"),
+ @NamedQuery(name = "AlertNoticeEntity.findByUuid", query = "SELECT notice FROM AlertNoticeEntity notice WHERE notice.uuid = :uuid"),
@NamedQuery(name = "AlertNoticeEntity.removeByDefinitionId", query = "DELETE FROM AlertNoticeEntity notice WHERE notice.alertHistory.alertDefinition.definitionId = :definitionId") })
public class AlertNoticeEntity {
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java
index e2564cc..9f3b5d8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java
@@ -17,7 +17,6 @@
*/
package org.apache.ambari.server.state.alert;
-import org.apache.ambari.server.orm.dao.AlertsDAO;
/**
* The {@link TargetType} enumeration is used to represent the built-in target
@@ -31,7 +30,17 @@ public enum TargetType {
EMAIL,
/**
- * {@link AlertsDAO} will be distributed via SNMP.
+ * Alerts will be distributed via SNMP.
*/
- SNMP;
+ SNMP,
+
+ /**
+ * Alerts will be distributed to Nagios.
+ */
+ NAGIOS,
+
+ /**
+ * Alerts will be distributed to a logger.
+ */
+ LOG;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index d938771..ff973f6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -37,6 +37,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import javax.persistence.RollbackException;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ConfigGroupNotFoundException;
import org.apache.ambari.server.ObjectNotFoundException;
import org.apache.ambari.server.ParentObjectNotFoundException;
import org.apache.ambari.server.ServiceComponentHostNotFoundException;
@@ -50,6 +51,7 @@ import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.cache.ConfigGroupHostMapping;
import org.apache.ambari.server.orm.cache.HostConfigMapping;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
import org.apache.ambari.server.orm.dao.ClusterDAO;
import org.apache.ambari.server.orm.dao.ClusterStateDAO;
import org.apache.ambari.server.orm.dao.ConfigGroupHostMappingDAO;
@@ -106,7 +108,6 @@ import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.persist.Transactional;
-import org.apache.ambari.server.ConfigGroupNotFoundException;
public class ClusterImpl implements Cluster {
@@ -191,6 +192,9 @@ public class ClusterImpl implements Cluster {
@Inject
private AlertDefinitionDAO alertDefinitionDAO;
+ @Inject
+ private AlertDispatchDAO alertDispatchDAO;
+
private volatile boolean svcHostsLoaded = false;
private volatile Multimap<String, String> serviceConfigTypes;
@@ -1363,6 +1367,7 @@ public class ClusterImpl implements Cluster {
protected void removeEntities() throws AmbariException {
long clusterId = getClusterId();
alertDefinitionDAO.removeAll(clusterId);
+ alertDispatchDAO.removeAllGroups(clusterId);
clusterDAO.removeByPK(clusterId);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
new file mode 100644
index 0000000..7025e14
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
@@ -0,0 +1,231 @@
+/**
+ * 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.ambari.server.state.services;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.ambari.server.events.AlertEvent;
+import org.apache.ambari.server.notifications.DispatchFactory;
+import org.apache.ambari.server.notifications.DispatchRunnable;
+import org.apache.ambari.server.notifications.DispatchCallback;
+import org.apache.ambari.server.notifications.NotificationDispatcher;
+import org.apache.ambari.server.notifications.Notification;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.NotificationState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.util.concurrent.AbstractScheduledService;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AlertNoticeDispatchService} is used to scan the database for
+ * {@link AlertNoticeEntity} that are in the {@link NotificationState#PENDING}.
+ * It will then process them through the dispatch system.
+ */
+@Singleton
+public class AlertNoticeDispatchService extends AbstractScheduledService {
+
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(AlertNoticeDispatchService.class);
+
+ /**
+ * Dispatch DAO to query pending {@link AlertNoticeEntity} instances from.
+ */
+ @Inject
+ private AlertDispatchDAO m_dao;
+
+ /**
+ * The factory used to get an {@link NotificationDispatcher} instance to submit to the
+ * {@link #m_executor}.
+ */
+ @Inject
+ private DispatchFactory m_dispatchFactory;
+
+ /**
+ * The executor responsible for dispatching.
+ */
+ private final ThreadPoolExecutor m_executor;
+
+ /**
+ * Constructor.
+ */
+ public AlertNoticeDispatchService() {
+ m_executor = new ThreadPoolExecutor(0, 2, 5L,
+ TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(),
+ new AlertDispatchThreadFactory(),
+ new ThreadPoolExecutor.CallerRunsPolicy());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void runOneIteration() throws Exception {
+ List<AlertNoticeEntity> pending = m_dao.findPendingNotices();
+ if (pending.size() == 0) {
+ return;
+ }
+
+ LOG.info("There are {} pending alert notices about to be dispatched..."
+ + pending.size());
+
+ // combine all histories by target
+ Map<AlertTargetEntity, List<AlertNoticeEntity>> aggregateMap = new HashMap<AlertTargetEntity, List<AlertNoticeEntity>>(
+ pending.size());
+
+ for (AlertNoticeEntity notice : pending) {
+ AlertTargetEntity target = notice.getAlertTarget();
+
+ List<AlertNoticeEntity> notices = aggregateMap.get(target);
+ if (null == notices) {
+ notices = new ArrayList<AlertNoticeEntity>();
+ aggregateMap.put(target, notices);
+ }
+
+ notices.add(notice);
+ }
+
+ Set<AlertTargetEntity> targets = aggregateMap.keySet();
+ for (AlertTargetEntity target : targets) {
+ List<AlertNoticeEntity> notices = aggregateMap.get(target);
+ if (null == notices || notices.size() == 0) {
+ continue;
+ }
+
+ Notification notification = new Notification();
+ notification.Subject = target.getTargetName();
+ notification.Body = target.getDescription();
+ notification.Callback = new AlertNoticeDispatchCallback();
+ notification.CallbackIds = new ArrayList<String>(notices.size());
+
+ for (AlertNoticeEntity notice : notices) {
+ notification.CallbackIds.add(notice.getUuid());
+ }
+
+ NotificationDispatcher dispatcher = m_dispatchFactory.getDispatcher(target.getNotificationType());
+ DispatchRunnable runnable = new DispatchRunnable(dispatcher, notification);
+
+ m_executor.execute(runnable);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p/>
+ * Returns a schedule that starts after 1 minute and runs every minute after
+ * {@link #runOneIteration()} completes.
+ */
+ @Override
+ protected Scheduler scheduler() {
+ return Scheduler.newFixedDelaySchedule(1, 1, TimeUnit.MINUTES);
+ }
+
+ /**
+ * A custom {@link ThreadFactory} for the threads that will handle dispatching
+ * {@link AlertNoticeEntity} instances. Threads created will have slightly
+ * reduced priority since {@link AlertEvent} instances are not critical to the
+ * system.
+ */
+ private static final class AlertDispatchThreadFactory implements
+ ThreadFactory {
+
+ private static final AtomicInteger s_threadIdPool = new AtomicInteger(1);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread thread = new Thread(r, "alert-dispatch-"
+ + s_threadIdPool.getAndIncrement());
+
+ thread.setDaemon(false);
+ thread.setPriority(Thread.NORM_PRIORITY - 1);
+
+ return thread;
+ }
+ }
+
+ /**
+ * The {@link AlertNoticeDispatchCallback} is used to receive a callback from
+ * the dispatch framework and then update the {@link AlertNoticeEntity}
+ * {@link NotificationState}.
+ */
+ private final class AlertNoticeDispatchCallback implements
+ DispatchCallback {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onSuccess(List<String> callbackIds) {
+ for (String callbackId : callbackIds) {
+ updateAlertNotice(callbackId, NotificationState.DELIVERED);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onFailure(List<String> callbackIds) {
+ for (String callbackId : callbackIds) {
+ updateAlertNotice(callbackId, NotificationState.FAILED);
+ }
+ }
+
+ /**
+ * Updates the {@link AlertNoticeEntity} matching the given UUID with the
+ * specified state.
+ *
+ * @param uuid
+ * @param state
+ */
+ private void updateAlertNotice(String uuid, NotificationState state) {
+ try {
+ AlertNoticeEntity entity = m_dao.findNoticeByUuid(uuid);
+ if (null == entity) {
+ LOG.warn("Unable to find an alert notice with UUID {}", uuid);
+ return;
+ }
+
+ entity.setNotifyState(state);
+ m_dao.merge(entity);
+ } catch (Exception exception) {
+ LOG.error(
+ "Unable to update the alert notice with UUID {} to {}, notifications will continue to be sent",
+ uuid, state, exception);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
index 526104f..a9d126c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
@@ -18,6 +18,9 @@
package org.apache.ambari.server.orm;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -353,4 +356,38 @@ public class OrmTestHelper {
alertDispatchDAO.create(group);
return alertDispatchDAO.findGroupById(group.getGroupId());
}
+
+ /**
+ * Creates some default alert groups for various services used in the tests.
+ *
+ * @param clusterId
+ * @return
+ * @throws Exception
+ */
+ @Transactional
+ public List<AlertGroupEntity> createDefaultAlertGroups(long clusterId)
+ throws Exception {
+ AlertGroupEntity hdfsGroup = new AlertGroupEntity();
+ hdfsGroup.setDefault(true);
+ hdfsGroup.setClusterId(clusterId);
+ hdfsGroup.setGroupName("HDFS");
+ hdfsGroup.setServiceName("HDFS");
+
+ AlertGroupEntity oozieGroup = new AlertGroupEntity();
+ oozieGroup.setDefault(true);
+ oozieGroup.setClusterId(clusterId);
+ oozieGroup.setGroupName("OOZIE");
+ oozieGroup.setServiceName("OOZIE");
+
+ alertDispatchDAO.create(hdfsGroup);
+ alertDispatchDAO.create(oozieGroup);
+
+ List<AlertGroupEntity> defaultGroups = alertDispatchDAO.findAllGroups(clusterId);
+ assertEquals(2, defaultGroups.size());
+ assertNotNull(alertDispatchDAO.findDefaultServiceGroup("HDFS"));
+ assertNotNull(alertDispatchDAO.findDefaultServiceGroup("OOZIE"));
+
+ return defaultGroups;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index f7deef5..cdca3dd 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -72,16 +72,19 @@ public class AlertDefinitionDAOTest {
*
*/
@Before
- public void setup() {
+ public void setup() throws Exception {
injector = Guice.createInjector(new InMemoryDefaultTestModule());
injector.getInstance(GuiceJpaInitializer.class);
+ dispatchDao = injector.getInstance(AlertDispatchDAO.class);
dao = injector.getInstance(AlertDefinitionDAO.class);
alertsDao = injector.getInstance(AlertsDAO.class);
- dispatchDao = injector.getInstance(AlertDispatchDAO.class);
helper = injector.getInstance(OrmTestHelper.class);
clusterId = helper.createCluster();
+ // create required default groups
+ helper.createDefaultAlertGroups(clusterId);
+
// create 8 HDFS alerts
int i = 0;
for (; i < 8; i++) {
@@ -148,7 +151,6 @@ public class AlertDefinitionDAOTest {
definition.setSourceType("SCRIPT");
dao.create(definition);
}
-
}
@After
@@ -287,7 +289,6 @@ public class AlertDefinitionDAOTest {
history.setAlertState(AlertState.OK);
history.setAlertText("Alert Text");
history.setAlertTimestamp(calendar.getTimeInMillis());
-// alertsDao.create(history);
AlertCurrentEntity current = new AlertCurrentEntity();
current.setAlertHistory(history);
@@ -359,5 +360,7 @@ public class AlertDefinitionDAOTest {
assertNull(clusterDAO.findById(clusterId));
assertNull(dao.findById(definition.getDefinitionId()));
+
+ assertEquals(0, dispatchDao.findAllGroups(clusterId).size());
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ba325d08/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
index 1103961..2c3a876 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
@@ -35,7 +35,11 @@ import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.NotificationState;
import org.apache.ambari.server.state.alert.Scope;
import org.junit.After;
import org.junit.Before;
@@ -54,6 +58,7 @@ public class AlertDispatchDAOTest {
Injector injector;
AlertDispatchDAO dao;
AlertDefinitionDAO definitionDao;
+ AlertsDAO alertsDao;
OrmTestHelper helper;
/**
@@ -64,6 +69,7 @@ public class AlertDispatchDAOTest {
injector = Guice.createInjector(new InMemoryDefaultTestModule());
injector.getInstance(GuiceJpaInitializer.class);
dao = injector.getInstance(AlertDispatchDAO.class);
+ alertsDao = injector.getInstance(AlertsDAO.class);
definitionDao = injector.getInstance(AlertDefinitionDAO.class);
helper = injector.getInstance(OrmTestHelper.class);
@@ -352,7 +358,7 @@ public class AlertDispatchDAOTest {
/**
* Tests finding groups by a definition ID that they are associatd with.
- *
+ *
* @throws Exception
*/
@Test
@@ -380,6 +386,38 @@ public class AlertDispatchDAOTest {
}
/**
+ * @throws Exception
+ */
+ @Test
+ public void testFindNoticeByUuid() throws Exception {
+ List<AlertDefinitionEntity> definitions = createDefinitions();
+ AlertDefinitionEntity definition = definitions.get(0);
+
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setServiceName(definition.getServiceName());
+ history.setClusterId(clusterId);
+ history.setAlertDefinition(definition);
+ history.setAlertLabel("Label");
+ history.setAlertState(AlertState.OK);
+ history.setAlertText("Alert Text");
+ history.setAlertTimestamp(System.currentTimeMillis());
+ alertsDao.create(history);
+
+ AlertTargetEntity target = helper.createAlertTarget();
+
+ AlertNoticeEntity notice = new AlertNoticeEntity();
+ notice.setUuid(UUID.randomUUID().toString());
+ notice.setAlertTarget(target);
+ notice.setAlertHistory(history);
+ notice.setNotifyState(NotificationState.PENDING);
+ dao.create(notice);
+
+ AlertNoticeEntity actual = dao.findNoticeByUuid(notice.getUuid());
+ assertEquals(notice.getNotificationId(), actual.getNotificationId());
+ assertNull(dao.findNoticeByUuid("DEADBEEF"));
+ }
+
+ /**
* @return
*/
private List<AlertDefinitionEntity> createDefinitions() throws Exception {
[45/50] [abbrv] AMBARI-7642 - Alerts: Maintenance Mode Should Prevent
Alert Notifications (jonathanhurley)
Posted by jo...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index 0cc2ae7..a2023d8 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -24,14 +24,21 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
+import junit.framework.Assert;
+
+import org.apache.ambari.server.events.listeners.AlertMaintenanceModeListener;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
@@ -39,13 +46,26 @@ import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentFactory;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.ServiceComponentHostFactory;
+import org.apache.ambari.server.state.ServiceFactory;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.alert.Scope;
import org.apache.ambari.server.state.alert.SourceType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import com.google.common.eventbus.EventBus;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.persist.PersistService;
@@ -55,25 +75,46 @@ import com.google.inject.persist.PersistService;
*/
public class AlertsDAOTest {
- static Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+ final static String HOSTNAME = "c6401.ambari.apache.org";
+ final static Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+
+ private Clusters m_clusters;
+ private Long m_clusterId;
+ private Injector m_injector;
+ private OrmTestHelper m_helper;
+ private AlertsDAO m_dao;
+ private AlertDefinitionDAO m_definitionDao;
- private Long clusterId;
- private Injector injector;
- private OrmTestHelper helper;
- private AlertsDAO dao;
- private AlertDefinitionDAO definitionDao;
+ private ServiceFactory m_serviceFactory;
+ private ServiceComponentFactory m_componentFactory;
+ private ServiceComponentHostFactory m_schFactory;
+ private AmbariEventPublisher m_eventPublisher;
/**
*
*/
@Before
public void setup() throws Exception {
- injector = Guice.createInjector(new InMemoryDefaultTestModule());
- injector.getInstance(GuiceJpaInitializer.class);
- helper = injector.getInstance(OrmTestHelper.class);
- clusterId = helper.createCluster();
- dao = injector.getInstance(AlertsDAO.class);
- definitionDao = injector.getInstance(AlertDefinitionDAO.class);
+ m_injector = Guice.createInjector(new InMemoryDefaultTestModule());
+ m_injector.getInstance(GuiceJpaInitializer.class);
+ m_helper = m_injector.getInstance(OrmTestHelper.class);
+ m_clusterId = m_helper.createCluster();
+ m_dao = m_injector.getInstance(AlertsDAO.class);
+ m_definitionDao = m_injector.getInstance(AlertDefinitionDAO.class);
+ m_serviceFactory = m_injector.getInstance(ServiceFactory.class);
+ m_componentFactory = m_injector.getInstance(ServiceComponentFactory.class);
+ m_schFactory = m_injector.getInstance(ServiceComponentHostFactory.class);
+ m_eventPublisher = m_injector.getInstance(AmbariEventPublisher.class);
+ m_clusters = m_injector.getInstance(Clusters.class);
+
+ // register a listener
+ EventBus synchronizedBus = new EventBus();
+ synchronizedBus.register(m_injector.getInstance(AlertMaintenanceModeListener.class));
+
+ // !!! need a synchronous op for testing
+ Field field = AmbariEventPublisher.class.getDeclaredField("m_eventBus");
+ field.setAccessible(true);
+ field.set(m_eventPublisher, synchronizedBus);
// create 5 definitions
for (int i = 0; i < 5; i++) {
@@ -81,16 +122,16 @@ public class AlertsDAOTest {
definition.setDefinitionName("Alert Definition " + i);
definition.setServiceName("Service " + i);
definition.setComponentName(null);
- definition.setClusterId(clusterId);
+ definition.setClusterId(m_clusterId);
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.SERVICE);
definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
- definitionDao.create(definition);
+ m_definitionDao.create(definition);
}
- List<AlertDefinitionEntity> definitions = definitionDao.findAll();
+ List<AlertDefinitionEntity> definitions = m_definitionDao.findAll();
assertNotNull(definitions);
assertEquals(5, definitions.size());
@@ -102,7 +143,7 @@ public class AlertsDAOTest {
for (int i = 0; i < 10; i++) {
AlertHistoryEntity history = new AlertHistoryEntity();
history.setServiceName(definition.getServiceName());
- history.setClusterId(clusterId);
+ history.setClusterId(m_clusterId);
history.setAlertDefinition(definition);
history.setAlertLabel(definition.getDefinitionName() + " " + i);
history.setAlertText(definition.getDefinitionName() + " " + i);
@@ -117,13 +158,13 @@ public class AlertsDAOTest {
// increase the days for each
calendar.add(Calendar.DATE, 1);
- dao.create(history);
+ m_dao.create(history);
}
}
// for each definition, create a current alert
for (AlertDefinitionEntity definition : definitions) {
- List<AlertHistoryEntity> alerts = dao.findAll();
+ List<AlertHistoryEntity> alerts = m_dao.findAll();
AlertHistoryEntity history = null;
for (AlertHistoryEntity alert : alerts) {
if (definition.equals(alert.getAlertDefinition())) {
@@ -138,7 +179,7 @@ public class AlertsDAOTest {
current.setLatestTimestamp(new Date().getTime());
current.setOriginalTimestamp(new Date().getTime() - 10800000);
current.setMaintenanceState(MaintenanceState.OFF);
- dao.create(current);
+ m_dao.create(current);
}
}
@@ -147,8 +188,8 @@ public class AlertsDAOTest {
*/
@After
public void teardown() {
- injector.getInstance(PersistService.class).stop();
- injector = null;
+ m_injector.getInstance(PersistService.class).stop();
+ m_injector = null;
}
@@ -157,7 +198,7 @@ public class AlertsDAOTest {
*/
@Test
public void testFindAll() {
- List<AlertHistoryEntity> alerts = dao.findAll(clusterId);
+ List<AlertHistoryEntity> alerts = m_dao.findAll(m_clusterId);
assertNotNull(alerts);
assertEquals(50, alerts.size());
}
@@ -167,7 +208,7 @@ public class AlertsDAOTest {
*/
@Test
public void testFindAllCurrent() {
- List<AlertCurrentEntity> currentAlerts = dao.findCurrent();
+ List<AlertCurrentEntity> currentAlerts = m_dao.findCurrent();
assertNotNull(currentAlerts);
assertEquals(5, currentAlerts.size());
}
@@ -177,19 +218,19 @@ public class AlertsDAOTest {
*/
@Test
public void testFindCurrentByService() {
- List<AlertCurrentEntity> currentAlerts = dao.findCurrent();
+ List<AlertCurrentEntity> currentAlerts = m_dao.findCurrent();
AlertCurrentEntity current = currentAlerts.get(0);
AlertHistoryEntity history = current.getAlertHistory();
assertNotNull(history);
- currentAlerts = dao.findCurrentByService(clusterId,
+ currentAlerts = m_dao.findCurrentByService(m_clusterId,
history.getServiceName());
assertNotNull(currentAlerts);
assertEquals(1, currentAlerts.size());
- currentAlerts = dao.findCurrentByService(clusterId, "foo");
+ currentAlerts = m_dao.findCurrentByService(m_clusterId, "foo");
assertNotNull(currentAlerts);
assertEquals(0, currentAlerts.size());
@@ -205,18 +246,18 @@ public class AlertsDAOTest {
hostDef.setDefinitionName("Host Alert Definition ");
hostDef.setServiceName("HostService");
hostDef.setComponentName(null);
- hostDef.setClusterId(clusterId);
+ hostDef.setClusterId(m_clusterId);
hostDef.setHash(UUID.randomUUID().toString());
hostDef.setScheduleInterval(Integer.valueOf(60));
hostDef.setScope(Scope.HOST);
hostDef.setSource("{\"type\" : \"SCRIPT\"}");
hostDef.setSourceType(SourceType.SCRIPT);
- definitionDao.create(hostDef);
+ m_definitionDao.create(hostDef);
// history for the definition
AlertHistoryEntity history = new AlertHistoryEntity();
history.setServiceName(hostDef.getServiceName());
- history.setClusterId(clusterId);
+ history.setClusterId(m_clusterId);
history.setAlertDefinition(hostDef);
history.setAlertLabel(hostDef.getDefinitionName());
history.setAlertText(hostDef.getDefinitionName());
@@ -229,14 +270,15 @@ public class AlertsDAOTest {
current.setOriginalTimestamp(1L);
current.setLatestTimestamp(2L);
current.setAlertHistory(history);
- dao.create(current);
+ m_dao.create(current);
- List<AlertCurrentEntity> currentAlerts = dao.findCurrentByHost(clusterId, history.getHostName());
+ List<AlertCurrentEntity> currentAlerts = m_dao.findCurrentByHost(
+ m_clusterId, history.getHostName());
assertNotNull(currentAlerts);
assertEquals(1, currentAlerts.size());
- currentAlerts = dao.findCurrentByHost(clusterId, "foo");
+ currentAlerts = m_dao.findCurrentByHost(m_clusterId, "foo");
assertNotNull(currentAlerts);
assertEquals(0, currentAlerts.size());
@@ -252,20 +294,21 @@ public class AlertsDAOTest {
allStates.add(AlertState.WARNING);
allStates.add(AlertState.CRITICAL);
- List<AlertHistoryEntity> history = dao.findAll(clusterId, allStates);
+ List<AlertHistoryEntity> history = m_dao.findAll(m_clusterId, allStates);
assertNotNull(history);
assertEquals(50, history.size());
- history = dao.findAll(clusterId, Collections.singletonList(AlertState.OK));
+ history = m_dao.findAll(m_clusterId,
+ Collections.singletonList(AlertState.OK));
assertNotNull(history);
assertEquals(40, history.size());
- history = dao.findAll(clusterId,
+ history = m_dao.findAll(m_clusterId,
Collections.singletonList(AlertState.CRITICAL));
assertNotNull(history);
assertEquals(10, history.size());
- history = dao.findAll(clusterId,
+ history = m_dao.findAll(m_clusterId,
Collections.singletonList(AlertState.WARNING));
assertNotNull(history);
assertEquals(0, history.size());
@@ -280,14 +323,14 @@ public class AlertsDAOTest {
calendar.set(2014, Calendar.JANUARY, 1);
// on or after 1/1/2014
- List<AlertHistoryEntity> history = dao.findAll(clusterId,
+ List<AlertHistoryEntity> history = m_dao.findAll(m_clusterId,
calendar.getTime(), null);
assertNotNull(history);
assertEquals(50, history.size());
// on or before 1/1/2014
- history = dao.findAll(clusterId, null, calendar.getTime());
+ history = m_dao.findAll(m_clusterId, null, calendar.getTime());
assertNotNull(history);
assertEquals(1, history.size());
@@ -298,27 +341,29 @@ public class AlertsDAOTest {
calendar.set(2014, Calendar.JANUARY, 10);
Date endDate = calendar.getTime();
- history = dao.findAll(clusterId, startDate, endDate);
+ history = m_dao.findAll(m_clusterId, startDate, endDate);
assertNotNull(history);
assertEquals(6, history.size());
// after 3/1
calendar.set(2014, Calendar.MARCH, 5);
- history = dao.findAll(clusterId, calendar.getTime(), null);
+ history = m_dao.findAll(m_clusterId, calendar.getTime(), null);
assertNotNull(history);
assertEquals(0, history.size());
- history = dao.findAll(clusterId, endDate, startDate);
+ history = m_dao.findAll(m_clusterId, endDate, startDate);
assertNotNull(history);
assertEquals(0, history.size());
}
@Test
public void testFindCurrentByHostAndName() throws Exception {
- AlertCurrentEntity entity = dao.findCurrentByHostAndName(clusterId.longValue(), "h2", "Alert Definition 1");
+ AlertCurrentEntity entity = m_dao.findCurrentByHostAndName(
+ m_clusterId.longValue(), "h2", "Alert Definition 1");
assertNull(entity);
- entity = dao.findCurrentByHostAndName(clusterId.longValue(), "h1", "Alert Definition 1");
+ entity = m_dao.findCurrentByHostAndName(m_clusterId.longValue(), "h1",
+ "Alert Definition 1");
assertNotNull(entity);
assertNotNull(entity.getAlertHistory());
@@ -330,25 +375,29 @@ public class AlertsDAOTest {
*/
@Test
public void testFindCurrentSummary() throws Exception {
- AlertSummaryDTO summary = dao.findCurrentCounts(clusterId.longValue(), null, null);
+ AlertSummaryDTO summary = m_dao.findCurrentCounts(m_clusterId.longValue(),
+ null, null);
assertEquals(5, summary.getOkCount());
- AlertHistoryEntity h1 = dao.findCurrentByCluster(clusterId.longValue()).get(2).getAlertHistory();
- AlertHistoryEntity h2 = dao.findCurrentByCluster(clusterId.longValue()).get(3).getAlertHistory();
- AlertHistoryEntity h3 = dao.findCurrentByCluster(clusterId.longValue()).get(4).getAlertHistory();
+ AlertHistoryEntity h1 = m_dao.findCurrentByCluster(m_clusterId.longValue()).get(
+ 2).getAlertHistory();
+ AlertHistoryEntity h2 = m_dao.findCurrentByCluster(m_clusterId.longValue()).get(
+ 3).getAlertHistory();
+ AlertHistoryEntity h3 = m_dao.findCurrentByCluster(m_clusterId.longValue()).get(
+ 4).getAlertHistory();
h1.setAlertState(AlertState.WARNING);
- dao.merge(h1);
+ m_dao.merge(h1);
h2.setAlertState(AlertState.CRITICAL);
- dao.merge(h2);
+ m_dao.merge(h2);
h3.setAlertState(AlertState.UNKNOWN);
- dao.merge(h3);
+ m_dao.merge(h3);
int ok = 0;
int warn = 0;
int crit = 0;
int unk = 0;
- for (AlertCurrentEntity h : dao.findCurrentByCluster(clusterId.longValue())) {
+ for (AlertCurrentEntity h : m_dao.findCurrentByCluster(m_clusterId.longValue())) {
switch (h.getAlertHistory().getAlertState()) {
case CRITICAL:
crit++;
@@ -366,7 +415,7 @@ public class AlertsDAOTest {
}
- summary = dao.findCurrentCounts(clusterId.longValue(), null, null);
+ summary = m_dao.findCurrentCounts(m_clusterId.longValue(), null, null);
// !!! db-to-db compare
assertEquals(ok, summary.getOkCount());
assertEquals(warn, summary.getWarningCount());
@@ -379,19 +428,20 @@ public class AlertsDAOTest {
assertEquals(1, summary.getCriticalCount());
assertEquals(1, summary.getCriticalCount());
- summary = dao.findCurrentCounts(clusterId.longValue(), "Service 0", null);
+ summary = m_dao.findCurrentCounts(m_clusterId.longValue(), "Service 0",
+ null);
assertEquals(1, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(0, summary.getCriticalCount());
assertEquals(0, summary.getCriticalCount());
- summary = dao.findCurrentCounts(clusterId.longValue(), null, "h1");
+ summary = m_dao.findCurrentCounts(m_clusterId.longValue(), null, "h1");
assertEquals(2, summary.getOkCount());
assertEquals(1, summary.getWarningCount());
assertEquals(1, summary.getCriticalCount());
assertEquals(1, summary.getCriticalCount());
- summary = dao.findCurrentCounts(clusterId.longValue(), "foo", null);
+ summary = m_dao.findCurrentCounts(m_clusterId.longValue(), "foo", null);
assertEquals(0, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(0, summary.getCriticalCount());
@@ -405,13 +455,13 @@ public class AlertsDAOTest {
definition.setDefinitionName("many_per_cluster");
definition.setServiceName("ServiceName");
definition.setComponentName(null);
- definition.setClusterId(clusterId);
+ definition.setClusterId(m_clusterId);
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.SERVICE);
definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
- definitionDao.create(definition);
+ m_definitionDao.create(definition);
// history record #1 and current
AlertHistoryEntity history = new AlertHistoryEntity();
@@ -421,7 +471,7 @@ public class AlertsDAOTest {
history.setAlertState(AlertState.OK);
history.setAlertText("");
history.setAlertTimestamp(Long.valueOf(1L));
- history.setClusterId(clusterId);
+ history.setClusterId(m_clusterId);
history.setComponentName("");
history.setHostName("h1");
history.setServiceName("ServiceName");
@@ -430,7 +480,7 @@ public class AlertsDAOTest {
current.setAlertHistory(history);
current.setLatestTimestamp(Long.valueOf(1L));
current.setOriginalTimestamp(Long.valueOf(1L));
- dao.merge(current);
+ m_dao.merge(current);
// history record #2 and current
history = new AlertHistoryEntity();
@@ -440,7 +490,7 @@ public class AlertsDAOTest {
history.setAlertState(AlertState.OK);
history.setAlertText("");
history.setAlertTimestamp(Long.valueOf(1L));
- history.setClusterId(clusterId);
+ history.setClusterId(m_clusterId);
history.setComponentName("");
history.setHostName("h2");
history.setServiceName("ServiceName");
@@ -449,27 +499,30 @@ public class AlertsDAOTest {
current.setAlertHistory(history);
current.setLatestTimestamp(Long.valueOf(1L));
current.setOriginalTimestamp(Long.valueOf(1L));
- dao.merge(current);
+ m_dao.merge(current);
- AlertSummaryDTO summary = dao.findAggregateCounts(clusterId.longValue(), "many_per_cluster");
+ AlertSummaryDTO summary = m_dao.findAggregateCounts(
+ m_clusterId.longValue(), "many_per_cluster");
assertEquals(2, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(0, summary.getCriticalCount());
assertEquals(0, summary.getUnknownCount());
- AlertCurrentEntity c = dao.findCurrentByHostAndName(clusterId.longValue(),
+ AlertCurrentEntity c = m_dao.findCurrentByHostAndName(
+ m_clusterId.longValue(),
"h2", "many_per_cluster");
AlertHistoryEntity h = c.getAlertHistory();
h.setAlertState(AlertState.CRITICAL);
- dao.merge(h);
+ m_dao.merge(h);
- summary = dao.findAggregateCounts(clusterId.longValue(), "many_per_cluster");
+ summary = m_dao.findAggregateCounts(m_clusterId.longValue(),
+ "many_per_cluster");
assertEquals(2, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(1, summary.getCriticalCount());
assertEquals(0, summary.getUnknownCount());
- summary = dao.findAggregateCounts(clusterId.longValue(), "foo");
+ summary = m_dao.findAggregateCounts(m_clusterId.longValue(), "foo");
assertEquals(0, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(0, summary.getCriticalCount());
@@ -484,7 +537,7 @@ public class AlertsDAOTest {
*/
@Test
public void testJPAInnerEntityStaleness() {
- List<AlertCurrentEntity> currents = dao.findCurrent();
+ List<AlertCurrentEntity> currents = m_dao.findCurrent();
AlertCurrentEntity current = currents.get(0);
AlertHistoryEntity oldHistory = current.getAlertHistory();
@@ -506,14 +559,14 @@ public class AlertsDAOTest {
newHistory.setHostName(oldHistory.getHostName());
newHistory.setServiceName(oldHistory.getServiceName());
- dao.create(newHistory);
+ m_dao.create(newHistory);
assertTrue(newHistory.getAlertId().longValue() != oldHistory.getAlertId().longValue());
current.setAlertHistory(newHistory);
- dao.merge(current);
+ m_dao.merge(current);
- AlertCurrentEntity newCurrent = dao.findCurrentByHostAndName(
+ AlertCurrentEntity newCurrent = m_dao.findCurrentByHostAndName(
newHistory.getClusterId(),
newHistory.getHostName(),
newHistory.getAlertDefinition().getDefinitionName());
@@ -524,4 +577,267 @@ public class AlertsDAOTest {
assertEquals(newHistory.getAlertState(),
newCurrent.getAlertHistory().getAlertState());
}
+
+ /**
+ * Tests that maintenance mode is set correctly on notices.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testMaintenanceMode() throws Exception {
+ Cluster cluster = initializeNewCluster();
+
+ List<AlertCurrentEntity> currents = m_dao.findCurrent();
+ for (AlertCurrentEntity current : currents) {
+ m_dao.remove(current);
+ }
+
+ // create some definitions
+ AlertDefinitionEntity namenode = new AlertDefinitionEntity();
+ namenode.setDefinitionName("NAMENODE");
+ namenode.setServiceName("HDFS");
+ namenode.setComponentName("NAMENODE");
+ namenode.setClusterId(cluster.getClusterId());
+ namenode.setHash(UUID.randomUUID().toString());
+ namenode.setScheduleInterval(Integer.valueOf(60));
+ namenode.setScope(Scope.ANY);
+ namenode.setSource("{\"type\" : \"SCRIPT\"}");
+ namenode.setSourceType(SourceType.SCRIPT);
+ m_definitionDao.create(namenode);
+
+ AlertDefinitionEntity datanode = new AlertDefinitionEntity();
+ datanode.setDefinitionName("DATANODE");
+ datanode.setServiceName("HDFS");
+ datanode.setComponentName("DATANODE");
+ datanode.setClusterId(cluster.getClusterId());
+ datanode.setHash(UUID.randomUUID().toString());
+ datanode.setScheduleInterval(Integer.valueOf(60));
+ datanode.setScope(Scope.HOST);
+ datanode.setSource("{\"type\" : \"SCRIPT\"}");
+ datanode.setSourceType(SourceType.SCRIPT);
+ m_definitionDao.create(datanode);
+
+ AlertDefinitionEntity aggregate = new AlertDefinitionEntity();
+ aggregate.setDefinitionName("DATANODE_UP");
+ aggregate.setServiceName("HDFS");
+ aggregate.setComponentName(null);
+ aggregate.setClusterId(cluster.getClusterId());
+ aggregate.setHash(UUID.randomUUID().toString());
+ aggregate.setScheduleInterval(Integer.valueOf(60));
+ aggregate.setScope(Scope.SERVICE);
+ aggregate.setSource("{\"type\" : \"SCRIPT\"}");
+ aggregate.setSourceType(SourceType.SCRIPT);
+ m_definitionDao.create(aggregate);
+
+ // create some history
+ AlertHistoryEntity nnHistory = new AlertHistoryEntity();
+ nnHistory.setAlertState(AlertState.OK);
+ nnHistory.setServiceName(namenode.getServiceName());
+ nnHistory.setComponentName(namenode.getComponentName());
+ nnHistory.setClusterId(cluster.getClusterId());
+ nnHistory.setAlertDefinition(namenode);
+ nnHistory.setAlertLabel(namenode.getDefinitionName());
+ nnHistory.setAlertText(namenode.getDefinitionName());
+ nnHistory.setAlertTimestamp(calendar.getTimeInMillis());
+ nnHistory.setHostName(HOSTNAME);
+ m_dao.create(nnHistory);
+
+ AlertCurrentEntity nnCurrent = new AlertCurrentEntity();
+ nnCurrent.setAlertHistory(nnHistory);
+ nnCurrent.setLatestText(nnHistory.getAlertText());
+ nnCurrent.setMaintenanceState(MaintenanceState.OFF);
+ nnCurrent.setOriginalTimestamp(System.currentTimeMillis());
+ nnCurrent.setLatestTimestamp(System.currentTimeMillis());
+ m_dao.create(nnCurrent);
+
+ AlertHistoryEntity dnHistory = new AlertHistoryEntity();
+ dnHistory.setAlertState(AlertState.WARNING);
+ dnHistory.setServiceName(datanode.getServiceName());
+ dnHistory.setComponentName(datanode.getComponentName());
+ dnHistory.setClusterId(cluster.getClusterId());
+ dnHistory.setAlertDefinition(datanode);
+ dnHistory.setAlertLabel(datanode.getDefinitionName());
+ dnHistory.setAlertText(datanode.getDefinitionName());
+ dnHistory.setAlertTimestamp(calendar.getTimeInMillis());
+ dnHistory.setHostName(HOSTNAME);
+ m_dao.create(dnHistory);
+
+ AlertCurrentEntity dnCurrent = new AlertCurrentEntity();
+ dnCurrent.setAlertHistory(dnHistory);
+ dnCurrent.setLatestText(dnHistory.getAlertText());
+ dnCurrent.setMaintenanceState(MaintenanceState.OFF);
+ dnCurrent.setOriginalTimestamp(System.currentTimeMillis());
+ dnCurrent.setLatestTimestamp(System.currentTimeMillis());
+ m_dao.create(dnCurrent);
+
+ AlertHistoryEntity aggregateHistory = new AlertHistoryEntity();
+ aggregateHistory.setAlertState(AlertState.CRITICAL);
+ aggregateHistory.setServiceName(aggregate.getServiceName());
+ aggregateHistory.setComponentName(aggregate.getComponentName());
+ aggregateHistory.setClusterId(cluster.getClusterId());
+ aggregateHistory.setAlertDefinition(aggregate);
+ aggregateHistory.setAlertLabel(aggregate.getDefinitionName());
+ aggregateHistory.setAlertText(aggregate.getDefinitionName());
+ aggregateHistory.setAlertTimestamp(calendar.getTimeInMillis());
+ m_dao.create(aggregateHistory);
+
+ AlertCurrentEntity aggregateCurrent = new AlertCurrentEntity();
+ aggregateCurrent.setAlertHistory(aggregateHistory);
+ aggregateCurrent.setLatestText(aggregateHistory.getAlertText());
+ aggregateCurrent.setMaintenanceState(MaintenanceState.OFF);
+ aggregateCurrent.setOriginalTimestamp(System.currentTimeMillis());
+ aggregateCurrent.setLatestTimestamp(System.currentTimeMillis());
+ m_dao.create(aggregateCurrent);
+
+ currents = m_dao.findCurrent();
+ assertEquals(3, currents.size());
+
+ for (AlertCurrentEntity current : currents) {
+ assertEquals(MaintenanceState.OFF, current.getMaintenanceState());
+ }
+
+ // turn on HDFS MM
+ Service hdfs = m_clusters.getClusterById(cluster.getClusterId()).getService(
+ "HDFS");
+
+ hdfs.setMaintenanceState(MaintenanceState.ON);
+
+ currents = m_dao.findCurrent();
+ assertEquals(3, currents.size());
+ for (AlertCurrentEntity current : currents) {
+ assertEquals(MaintenanceState.ON, current.getMaintenanceState());
+ }
+
+ // turn HDFS MM off
+ hdfs.setMaintenanceState(MaintenanceState.OFF);
+
+ currents = m_dao.findCurrent();
+ assertEquals(3, currents.size());
+ for (AlertCurrentEntity current : currents) {
+ assertEquals(MaintenanceState.OFF, current.getMaintenanceState());
+ }
+
+ // turn on host MM
+ Host host = m_clusters.getHost(HOSTNAME);
+ host.setMaintenanceState(cluster.getClusterId(), MaintenanceState.ON);
+
+ // only NAMENODE and DATANODE should be in MM; the aggregate should not
+ // since the host is in MM
+ currents = m_dao.findCurrent();
+ assertEquals(3, currents.size());
+ for (AlertCurrentEntity current : currents) {
+ if (current.getAlertHistory().getComponentName() != null) {
+ assertEquals(MaintenanceState.ON, current.getMaintenanceState());
+ } else {
+ assertEquals(MaintenanceState.OFF, current.getMaintenanceState());
+ }
+ }
+
+ // turn host MM off
+ host.setMaintenanceState(cluster.getClusterId(), MaintenanceState.OFF);
+
+ currents = m_dao.findCurrent();
+ assertEquals(3, currents.size());
+ for (AlertCurrentEntity current : currents) {
+ assertEquals(MaintenanceState.OFF, current.getMaintenanceState());
+ }
+
+ // turn a component MM on
+ ServiceComponentHost nnComponent = null;
+ List<ServiceComponentHost> schs = cluster.getServiceComponentHosts(HOSTNAME);
+ for (ServiceComponentHost sch : schs) {
+ if ("NAMENODE".equals(sch.getServiceComponentName())) {
+ sch.setMaintenanceState(MaintenanceState.ON);
+ nnComponent = sch;
+ }
+ }
+
+ assertNotNull(nnComponent);
+
+ currents = m_dao.findCurrent();
+ assertEquals(3, currents.size());
+ for (AlertCurrentEntity current : currents) {
+ if ("NAMENODE".equals(current.getAlertHistory().getComponentName())) {
+ assertEquals(MaintenanceState.ON, current.getMaintenanceState());
+ } else {
+ assertEquals(MaintenanceState.OFF, current.getMaintenanceState());
+ }
+ }
+
+ }
+
+ private Cluster initializeNewCluster() throws Exception {
+ String clusterName = "cluster-" + System.currentTimeMillis();
+ m_clusters.addCluster(clusterName);
+
+ Cluster cluster = m_clusters.getCluster(clusterName);
+ cluster.setDesiredStackVersion(new StackId("HDP", "2.0.6"));
+
+ addHost();
+ m_clusters.mapHostToCluster(HOSTNAME, cluster.getClusterName());
+
+ installHdfsService(cluster);
+ return cluster;
+ }
+
+ /**
+ * @throws Exception
+ */
+ private void addHost() throws Exception {
+ m_clusters.addHost(HOSTNAME);
+
+ Host host = m_clusters.getHost(HOSTNAME);
+ Map<String, String> hostAttributes = new HashMap<String, String>();
+ hostAttributes.put("os_family", "redhat");
+ hostAttributes.put("os_release_version", "6.4");
+ host.setHostAttributes(hostAttributes);
+ host.setState(HostState.HEALTHY);
+ host.persist();
+ }
+
+ /**
+ * Calls {@link Service#persist()} to mock a service install along with
+ * creating a single {@link Host} and {@link ServiceComponentHost}.
+ */
+ private void installHdfsService(Cluster cluster) throws Exception {
+ String serviceName = "HDFS";
+ Service service = m_serviceFactory.createNew(cluster, serviceName);
+ cluster.addService(service);
+ service.persist();
+ service = cluster.getService(serviceName);
+ Assert.assertNotNull(service);
+
+ ServiceComponent datanode = m_componentFactory.createNew(service,
+ "DATANODE");
+
+ service.addServiceComponent(datanode);
+ datanode.setDesiredState(State.INSTALLED);
+ datanode.persist();
+
+ ServiceComponentHost sch = m_schFactory.createNew(datanode, HOSTNAME);
+
+ datanode.addServiceComponentHost(sch);
+ sch.setDesiredState(State.INSTALLED);
+ sch.setState(State.INSTALLED);
+ sch.setDesiredStackVersion(new StackId("HDP-2.0.6"));
+ sch.setStackVersion(new StackId("HDP-2.0.6"));
+
+ sch.persist();
+
+ ServiceComponent namenode = m_componentFactory.createNew(service,
+ "NAMENODE");
+
+ service.addServiceComponent(namenode);
+ namenode.setDesiredState(State.INSTALLED);
+ namenode.persist();
+
+ sch = m_schFactory.createNew(namenode, HOSTNAME);
+ namenode.addServiceComponentHost(sch);
+ sch.setDesiredState(State.INSTALLED);
+ sch.setState(State.INSTALLED);
+ sch.setDesiredStackVersion(new StackId("HDP-2.0.6"));
+ sch.setStackVersion(new StackId("HDP-2.0.6"));
+
+ sch.persist();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
index 502c3b9..f2c4053 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
@@ -50,6 +50,7 @@ import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.alert.AggregateDefinitionMapping;
import org.apache.ambari.server.state.alert.AggregateSource;
import org.apache.ambari.server.state.alert.AlertDefinition;
@@ -250,6 +251,13 @@ public class AlertDataManagerTest {
List<AlertHistoryEntity> histories = dao.findAll(clusterId);
assertEquals(1, histories.size());
+ AlertCurrentEntity currentAlert = new AlertCurrentEntity();
+ currentAlert.setAlertHistory(histories.get(0));
+ currentAlert.setMaintenanceState(MaintenanceState.OFF);
+ currentAlert.setOriginalTimestamp(System.currentTimeMillis());
+ currentAlert.setLatestTimestamp(System.currentTimeMillis());
+ dao.create(currentAlert);
+
AlertTargetEntity target = helper.createAlertTarget();
Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
targets.add(target);
@@ -262,7 +270,7 @@ public class AlertDataManagerTest {
AlertState.OK);
AlertStateChangeEvent event = new AlertStateChangeEvent(clusterId, alert1,
- histories.get(0), AlertState.CRITICAL);
+ currentAlert, AlertState.CRITICAL);
AlertStateChangedListener listener = injector.getInstance(AlertStateChangedListener.class);
listener.onAlertEvent(event);
[04/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Conflicts:
ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
ambari-server/src/test/java/org/apache/ambari/server/utils/TestStageUtils.java
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ae8f1e77
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ae8f1e77
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ae8f1e77
Branch: refs/heads/trunk
Commit: ae8f1e77eafe32c2ad8bded7da24a2cef07b605f
Parents: 4a4644b a826334
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Aug 27 10:04:14 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Aug 27 10:04:14 2014 -0400
----------------------------------------------------------------------
ambari-agent/conf/unix/install-helper.sh | 7 -
ambari-agent/pom.xml | 11 +-
ambari-server/conf/unix/install-helper.sh | 3 -
.../server/actionmanager/ActionScheduler.java | 33 ++
.../ambari/server/actionmanager/Stage.java | 32 +-
.../server/actionmanager/StageFactory.java | 4 +-
.../ambari/server/agent/ExecutionCommand.java | 2 +-
.../resources/RequestResourceDefinition.java | 12 +-
.../ServiceConfigVersionResourceDefinition.java | 10 +-
.../server/api/services/AmbariMetaInfo.java | 18 +
.../stackadvisor/StackAdvisorHelper.java | 14 +-
.../stackadvisor/StackAdvisorHelper.java.orig | 116 ----
.../stackadvisor/StackAdvisorResponse.java | 73 +++
...GetComponentLayoutRecommnedationCommand.java | 5 +-
.../GetComponentLayoutValidationCommand.java | 5 +-
.../GetConfigurationRecommnedationCommand.java | 18 +-
.../GetConfigurationValidationCommand.java | 5 +-
.../commands/StackAdvisorCommand.java | 30 +-
.../recommendations/RecommendationResponse.java | 38 +-
.../validations/ValidationResponse.java | 15 +-
.../server/api/util/StackExtensionHelper.java | 9 +
.../controller/AmbariActionExecutionHelper.java | 9 +-
.../AmbariCustomCommandExecutionHelper.java | 34 +-
.../AmbariManagementControllerImpl.java | 184 ++++---
.../server/controller/ClusterRequest.java | 28 +-
.../server/controller/ClusterResponse.java | 9 +-
.../server/controller/ConfigGroupRequest.java | 9 +
.../ambari/server/controller/HostRequest.java | 11 +-
.../controller/ServiceConfigVersionRequest.java | 23 +
.../ServiceConfigVersionResponse.java | 13 +-
.../StackServiceComponentResponse.java | 33 +-
.../server/controller/StackServiceResponse.java | 16 +-
.../internal/AbstractResourceProvider.java | 92 ++--
.../internal/BaseBlueprintProcessor.java | 37 +-
.../BlueprintConfigurationProcessor.java | 5 +-
.../internal/ClusterResourceProvider.java | 126 +++--
.../internal/ConfigGroupResourceProvider.java | 4 +
.../internal/HostResourceProvider.java | 54 +-
.../RecommendationResourceProvider.java | 4 +-
.../ServiceConfigVersionResourceProvider.java | 12 +-
.../StackServiceComponentResourceProvider.java | 22 +-
.../internal/StackServiceResourceProvider.java | 22 +-
.../internal/ValidationResourceProvider.java | 4 +-
.../internal/ViewInstanceResourceProvider.java | 9 +-
.../internal/ViewVersionResourceProvider.java | 3 +
.../ambari/server/orm/dao/ServiceConfigDAO.java | 41 +-
.../server/orm/entities/AlertGroupEntity.java | 74 ++-
.../ambari/server/orm/entities/StageEntity.java | 28 +
.../ambari/server/orm/entities/ViewEntity.java | 39 +-
.../ambari/server/stageplanner/RoleGraph.java | 3 +-
.../org/apache/ambari/server/state/Cluster.java | 15 +-
.../ambari/server/state/ComponentInfo.java | 14 +-
.../ambari/server/state/ConfigHelper.java | 15 +-
.../apache/ambari/server/state/ServiceInfo.java | 9 +
.../server/state/cluster/ClusterImpl.java | 119 +++-
.../server/upgrade/AbstractUpgradeCatalog.java | 3 +-
.../server/upgrade/UpgradeCatalog170.java | 19 +-
.../apache/ambari/server/utils/StageUtils.java | 13 +-
.../apache/ambari/server/view/ViewRegistry.java | 15 +
.../server/view/configuration/ViewConfig.java | 14 +
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 5 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 5 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 5 +-
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 5 +-
.../main/resources/custom_actions/check_host.py | 7 +-
.../src/main/resources/properties.json | 7 +-
.../src/main/resources/scripts/stack_advisor.py | 5 +-
.../1.3.2/hooks/before-ANY/scripts/params.py | 3 +-
.../hooks/before-INSTALL/scripts/params.py | 2 +-
.../HDP/1.3.2/services/GANGLIA/metainfo.xml | 3 +
.../HDP/1.3.2/services/HBASE/metainfo.xml | 4 +
.../stacks/HDP/1.3.2/services/HDFS/metainfo.xml | 5 +
.../stacks/HDP/1.3.2/services/HIVE/metainfo.xml | 11 +-
.../services/HIVE/package/scripts/params.py | 2 +-
.../HDP/1.3.2/services/MAPREDUCE/metainfo.xml | 5 +
.../HDP/1.3.2/services/NAGIOS/metainfo.xml | 2 +
.../HDP/1.3.2/services/OOZIE/metainfo.xml | 3 +
.../stacks/HDP/1.3.2/services/PIG/metainfo.xml | 2 +
.../HDP/1.3.2/services/SQOOP/metainfo.xml | 2 +
.../HDP/1.3.2/services/WEBHCAT/metainfo.xml | 4 +-
.../HDP/1.3.2/services/ZOOKEEPER/metainfo.xml | 3 +
.../stacks/HDP/1.3.2/services/stack_advisor.py | 519 ++++++++++++++++++
.../stacks/HDP/1.3.3/services/stack_advisor.py | 25 +
.../stacks/HDP/1.3/services/stack_advisor.py | 25 +
.../2.0.6/hooks/before-ANY/scripts/params.py | 3 +-
.../hooks/before-INSTALL/scripts/params.py | 2 +-
.../HDP/2.0.6/services/FLUME/metainfo.xml | 2 +
.../HDP/2.0.6/services/GANGLIA/metainfo.xml | 3 +
.../HDP/2.0.6/services/HBASE/metainfo.xml | 4 +
.../stacks/HDP/2.0.6/services/HDFS/metainfo.xml | 7 +
.../stacks/HDP/2.0.6/services/HIVE/metainfo.xml | 11 +-
.../services/HIVE/package/scripts/params.py | 2 +-
.../HDP/2.0.6/services/NAGIOS/metainfo.xml | 2 +
.../HDP/2.0.6/services/OOZIE/metainfo.xml | 3 +
.../stacks/HDP/2.0.6/services/PIG/metainfo.xml | 2 +
.../HDP/2.0.6/services/SQOOP/metainfo.xml | 2 +
.../HDP/2.0.6/services/WEBHCAT/metainfo.xml | 4 +-
.../stacks/HDP/2.0.6/services/YARN/metainfo.xml | 7 +
.../HDP/2.0.6/services/ZOOKEEPER/metainfo.xml | 2 +
.../FALCON/configuration/falcon-env.xml | 63 +++
.../2.1.GlusterFS/services/FALCON/metainfo.xml | 2 +-
.../services/FALCON/package/scripts/params.py | 32 +-
.../FALCON/package/scripts/status_params.py | 2 +-
.../GLUSTERFS/configuration/core-site.xml | 26 -
.../GLUSTERFS/configuration/hadoop-env.xml | 207 +++++++
.../services/GLUSTERFS/metainfo.xml | 7 +-
.../2.1.GlusterFS/services/OOZIE/metainfo.xml | 2 +-
.../services/STORM/configuration/storm-env.xml | 39 ++
.../2.1.GlusterFS/services/STORM/metainfo.xml | 2 +-
.../services/STORM/package/scripts/params.py | 12 +-
.../STORM/package/scripts/status_params.py | 2 +-
.../services/TEZ/configuration/tez-env.xml | 29 +
.../HDP/2.1.GlusterFS/services/TEZ/metainfo.xml | 2 +-
.../services/TEZ/package/scripts/params.py | 4 +-
.../services/YARN/configuration/global.xml | 64 ---
.../services/YARN/configuration/yarn-env.xml | 181 +++++++
.../2.1.GlusterFS/services/YARN/metainfo.xml | 3 +-
.../services/YARN/package/scripts/params.py | 41 +-
.../YARN/package/scripts/status_params.py | 8 +-
.../stacks/HDP/2.1/services/FALCON/metainfo.xml | 3 +
.../stacks/HDP/2.1/services/STORM/metainfo.xml | 6 +
.../stacks/HDP/2.1/services/TEZ/metainfo.xml | 2 +
.../stacks/HDP/2.1/services/YARN/metainfo.xml | 2 +
.../stacks/HDP/2.1/services/stack_advisor.py | 7 -
.../ExecutionCommandWrapperTest.java | 2 +-
.../actionmanager/TestActionDBAccessorImpl.java | 20 +-
.../server/actionmanager/TestActionManager.java | 31 +-
.../actionmanager/TestActionScheduler.java | 33 +-
.../ambari/server/actionmanager/TestStage.java | 4 +-
.../server/agent/TestHeartbeatHandler.java | 15 +-
.../server/agent/TestHeartbeatMonitor.java | 4 +-
.../server/api/services/AmbariMetaInfoTest.java | 9 +
.../stackadvisor/StackAdvisorHelperTest.java | 22 +-
...tConfigurationRecommnedationCommandTest.java | 103 ++++
.../commands/StackAdvisorCommandTest.java | 86 ++-
.../api/util/StackExtensionHelperTest.java | 2 +
.../AmbariManagementControllerTest.java | 164 +++---
...hYarnCapacitySchedulerReleaseConfigTest.java | 4 +-
.../internal/ClusterResourceProviderTest.java | 537 ++++++++++++++++++-
.../internal/JMXHostProviderTest.java | 10 +-
.../RecommendationResourceProviderTest.java | 31 ++
.../ValidationResourceProviderTest.java | 70 +++
.../ViewInstanceResourceProviderTest.java | 89 ++-
.../server/stageplanner/TestStagePlanner.java | 6 +-
.../ambari/server/state/ConfigHelperTest.java | 6 +-
.../server/state/cluster/ClusterTest.java | 66 ++-
.../server/state/cluster/ClustersTest.java | 3 +-
.../svccomphost/ServiceComponentHostTest.java | 3 +-
.../server/upgrade/UpgradeCatalog170Test.java | 41 +-
.../server/upgrade/UpgradeCatalogTest.java | 2 +-
.../ambari/server/utils/TestStageUtils.java | 6 +-
.../view/configuration/ViewConfigTest.java | 7 +
ambari-server/src/test/python/TestCheckHost.py | 29 +-
.../stacks/1.3.2/HIVE/test_hive_metastore.py | 4 +-
.../stacks/1.3.2/HIVE/test_hive_server.py | 4 +-
.../1.3.2/hooks/before-ANY/test_before_any.py | 6 +-
.../hooks/before-INSTALL/test_before_install.py | 4 +-
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 4 +-
.../stacks/2.0.6/HIVE/test_hive_server.py | 4 +-
.../2.0.6/hooks/before-ANY/test_before_any.py | 6 +-
.../hooks/before-INSTALL/test_before_install.py | 4 +-
.../stacks/2.1/HIVE/test_hive_metastore.py | 4 +-
.../HDP/2.0.6/services/NAGIOS/metainfo.xml | 2 +
.../HDP/2.0.6/services/WEBHCAT/metainfo.xml | 1 +
.../stacks/HDP/2.0.6/services/YARN/metainfo.xml | 4 +
.../HDP/2.0.7/services/HBASE/metainfo.xml | 4 +
.../stacks/HDP/2.0.7/services/HDFS/metainfo.xml | 7 +
.../stacks/HDP/2.0.7/services/HIVE/metainfo.xml | 5 +
.../HDP/2.0.7/services/ZOOKEEPER/metainfo.xml | 3 +
.../HDP/2.0.8/services/SQOOP/metainfo.xml | 1 +
.../HDP/2.1.1/services/STORM/metainfo.xml | 4 +
.../org/apache/ambari/view/ViewDefinition.java | 7 +
.../data/configurations/service_version.json | 7 +-
.../data/configurations/service_versions.json | 77 +--
ambari-web/app/assets/test/tests.js | 2 +
ambari-web/app/config.js | 2 +-
.../main/dashboard/config_history_controller.js | 4 +-
.../controllers/main/service/info/configs.js | 8 +-
.../app/controllers/wizard/step3_controller.js | 1 -
ambari-web/app/data/HDP2/secure_properties.js | 1 +
ambari-web/app/data/HDP2/site_properties.js | 178 +++---
ambari-web/app/data/site_properties.js | 160 +++---
ambari-web/app/mappers.js | 1 +
.../mappers/service_config_version_mapper.js | 3 +-
ambari-web/app/mappers/stack_service_mapper.js | 2 +
ambari-web/app/messages.js | 5 +-
ambari-web/app/mixins.js | 1 -
ambari-web/app/mixins/common/serverValidator.js | 19 +-
ambari-web/app/mixins/models/service_mixin.js | 30 --
ambari-web/app/models/host_component.js | 28 +-
ambari-web/app/models/service.js | 7 +-
ambari-web/app/models/service_config_version.js | 12 +-
ambari-web/app/models/stack_service.js | 13 +-
.../app/models/stack_service_component.js | 10 +-
ambari-web/app/styles/application.less | 58 +-
.../common/configs/config_history_flow.hbs | 42 +-
.../templates/main/dashboard/config_history.hbs | 11 +-
ambari-web/app/utils/ajax/ajax.js | 2 +-
ambari-web/app/utils/config.js | 2 +-
ambari-web/app/utils/helper.js | 15 +-
.../views/common/configs/config_history_flow.js | 67 ++-
.../common/configs/overriddenProperty_view.js | 1 +
.../app/views/common/configs/services_config.js | 3 +-
.../views/main/dashboard/config_history_view.js | 12 +-
ambari-web/test/app_test.js | 54 +-
.../dashboard/config_history_controller_test.js | 25 +-
ambari-web/test/models/host_component_test.js | 212 +++++++-
ambari-web/test/models/host_test.js | 357 +++++++++++-
ambari-web/test/models/service_test.js | 59 +-
ambari-web/test/models/stack_service_test.js | 343 ++++++++++++
ambari-web/test/service_components.js | 61 +++
ambari-web/test/utils/blueprint_test.js | 1 -
ambari-web/test/utils/date_test.js | 4 +-
.../common/configs/config_history_flow_test.js | 26 +-
.../src/main/resources/ui/app/styles/main.less | 7 +-
docs/pom.xml | 18 +-
216 files changed, 5151 insertions(+), 1390 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-agent/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index 0600f27,33c5af4..75ba178
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@@ -42,53 -42,23 +42,53 @@@ public class ExecutionCommand extends A
super(AgentCommandType.EXECUTION_COMMAND);
}
+ @SerializedName("clusterName")
private String clusterName;
+
+ @SerializedName("taskId")
private long taskId;
+
+ @SerializedName("commandId")
private String commandId;
+
+ @SerializedName("hostname")
private String hostname;
+
+ @SerializedName("role")
private String role;
+
+ @SerializedName("hostLevelParams")
private Map<String, String> hostLevelParams = new HashMap<String, String>();
+
+ @SerializedName("roleParams")
private Map<String, String> roleParams = null;
+
+ @SerializedName("roleCommand")
private RoleCommand roleCommand;
- private Map<String, Set<String>> clusterHostInfo =
+
+ @SerializedName("clusterHostInfo")
+ private Map<String, Set<String>> clusterHostInfo =
new HashMap<String, Set<String>>();
+
+ @SerializedName("configurations")
private Map<String, Map<String, String>> configurations;
+
@SerializedName("configuration_attributes")
private Map<String, Map<String, Map<String, String>>> configurationAttributes;
+
+ @SerializedName("configurationTags")
private Map<String, Map<String, String>> configurationTags;
+
+ @SerializedName("forceRefreshConfigTags")
private Set<String> forceRefreshConfigTags = new HashSet<String>();
+
+ @SerializedName("commandParams")
- private Map<String, String> commandParams;
+ private Map<String, String> commandParams = new HashMap<String, String>();
+
+ @SerializedName("serviceName")
private String serviceName;
+
+ @SerializedName("componentName")
private String componentName;
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index 5d904ef,c3b6a86..b181399
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@@ -1370,10 -1338,9 +1370,10 @@@ public class ClusterImpl implements Clu
}
@Override
- public ServiceConfigVersionResponse addDesiredConfig(String user, Config config, String serviceConfigVersionNote) {
+ public ServiceConfigVersionResponse addDesiredConfig(String user, Set<Config> configs, String serviceConfigVersionNote) {
- if (null == user)
+ if (null == user) {
throw new NullPointerException("User must be specified.");
+ }
clusterGlobalLock.readLock().lock();
try {
@@@ -1525,10 -1505,9 +1538,10 @@@
}
@Override
- public boolean setServiceConfigVersion(String serviceName, Long version, String user, String note) throws AmbariException {
+ public ServiceConfigVersionResponse setServiceConfigVersion(String serviceName, Long version, String user, String note) throws AmbariException {
- if (null == user)
+ if (null == user) {
throw new NullPointerException("User must be specified.");
+ }
clusterGlobalLock.writeLock().lock();
try {
@@@ -1644,9 -1653,18 +1687,18 @@@
serviceConfigVersionResponse.setClusterName(getClusterName());
serviceConfigVersionResponse.setServiceName(serviceConfigEntity.getServiceName());
serviceConfigVersionResponse.setVersion(serviceConfigEntity.getVersion());
- serviceConfigVersionResponse.setCreateTime(serviceConfigEntity.getCreateTimestamp());
+ serviceConfigVersionResponse.setCreateTime(serviceConfigEntity.getCreateTimestamp());
serviceConfigVersionResponse.setUserName(serviceConfigEntity.getUser());
serviceConfigVersionResponse.setNote(serviceConfigEntity.getNote());
+ if (clusterConfigGroups != null) {
+ ConfigGroup configGroup = clusterConfigGroups.get(serviceConfigEntity.getGroupId());
+ if (configGroup != null) {
+ serviceConfigVersionResponse.setGroupId(configGroup.getId());
+ serviceConfigVersionResponse.setGroupName(configGroup.getName());
+ }
+ }
+
+
return serviceConfigVersionResponse;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
index 0acd61b,0ac9da7..0884c50
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
@@@ -73,8 -73,6 +73,7 @@@ import org.apache.ambari.server.state.C
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.alert.Scope;
- import org.apache.ambari.server.view.configuration.InstanceConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/java/org/apache/ambari/server/utils/StageUtils.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
----------------------------------------------------------------------
diff --cc ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
index d7c8c54,5d85b0d..79ae350
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
@@@ -1045,9 -1042,9 +1046,9 @@@ public class ServiceComponentHostTest
config.setTag(tag);
config.persist();
cluster.addConfig(config);
- cluster.addDesiredConfig("user", config);
+ cluster.addDesiredConfig("user", Collections.singleton(config));
}
-
+
@Test
public void testMaintenance() throws Exception {
String stackVersion="HDP-2.0.6";
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae8f1e77/ambari-server/src/test/java/org/apache/ambari/server/utils/TestStageUtils.java
----------------------------------------------------------------------
diff --cc ambari-server/src/test/java/org/apache/ambari/server/utils/TestStageUtils.java
index d3f0e37,988c67b..8b134c4
--- a/ambari-server/src/test/java/org/apache/ambari/server/utils/TestStageUtils.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/utils/TestStageUtils.java
@@@ -152,8 -147,8 +152,8 @@@ public class TestStageUtils
@Ignore
public void testJasonToExecutionCommand() throws JsonGenerationException,
JsonMappingException, JAXBException, IOException {
- Stage s = StageUtils.getATestStage(1, 2, "host1", "clusterHostInfo");
+ Stage s = StageUtils.getATestStage(1, 2, "host1", "clusterHostInfo", "hostParamsStage");
- ExecutionCommand cmd = s.getExecutionCommands("host1").get(0).getExecutionCommand();
+ ExecutionCommand cmd = s.getExecutionCommands("host1").get(0).getExecutionCommand();
HashMap<String, Map<String,String>> configTags = new HashMap<String, Map<String,String>>();
Map<String, String> globalTag = new HashMap<String, String>();
globalTag.put("tag", "version1");
[05/50] [abbrv] git commit: AMBARI-7051 - Alerts: Expose Creation and
Updating of Group Targets & Definitions (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7051 - Alerts: Expose Creation and Updating of Group Targets & Definitions (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/76fc94ec
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/76fc94ec
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/76fc94ec
Branch: refs/heads/trunk
Commit: 76fc94ec1ab6ee904e0efa254c19521a201c06d4
Parents: ae8f1e7
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Aug 27 21:07:43 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Aug 28 09:38:28 2014 -0400
----------------------------------------------------------------------
.../python/ambari_agent/alerts/base_alert.py | 45 ++-
.../python/ambari_agent/alerts/port_alert.py | 42 +--
.../server/api/services/AlertGroupService.java | 10 +
.../controller/AlertDefinitionResponse.java | 143 +++++++++
.../internal/AlertGroupResourceProvider.java | 144 ++++++++-
.../server/orm/dao/AlertDefinitionDAO.java | 16 +
.../ambari/server/orm/dao/AlertDispatchDAO.java | 18 +-
.../orm/entities/AlertDefinitionEntity.java | 37 ++-
.../server/orm/entities/AlertGroupEntity.java | 56 +++-
.../server/orm/entities/AlertTargetEntity.java | 3 +-
.../ambari/server/state/alert/AlertTarget.java | 37 ++-
.../AlertGroupResourceProviderTest.java | 295 +++++++++++++++----
.../AlertTargetResourceProviderTest.java | 2 +-
.../server/orm/dao/AlertDefinitionDAOTest.java | 18 +-
.../server/orm/dao/AlertDispatchDAOTest.java | 53 ++--
15 files changed, 773 insertions(+), 146 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index 88c7f92..bf8ada6 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -34,7 +34,7 @@ class BaseAlert(object):
self.alert_meta = alert_meta
self.alert_source_meta = alert_source_meta
self.cluster = ''
- self.hostName = ''
+ self.host_name = ''
self._lookup_keys = []
@@ -54,7 +54,7 @@ class BaseAlert(object):
def set_cluster(self, cluster, host):
''' sets cluster information for the alert '''
self.cluster = cluster
- self.hostName = host
+ self.host_name = host
def collect(self):
''' method used for collection. defers to _collect() '''
@@ -123,4 +123,43 @@ class BaseAlert(object):
res[0] = the result code
res[1] = the list of arguments supplied to the reporting text for the result code
'''
- raise NotImplementedError
\ No newline at end of file
+ raise NotImplementedError
+
+ '''
+ See RFC3986, Appendix B
+ Tested on the following cases:
+ "192.168.54.1"
+ "192.168.54.2:7661
+ "hdfs://192.168.54.3/foo/bar"
+ "ftp://192.168.54.4:7842/foo/bar"
+
+ Returns None if only a port is passsed in
+ '''
+ @staticmethod
+ def get_host_from_url(uri):
+ # RFC3986, Appendix B
+ parts = re.findall('^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?', uri)
+
+ # index of parts
+ # scheme = 1
+ # authority = 3
+ # path = 4
+ # query = 6
+ # fragment = 8
+
+ host_and_port = uri
+ if 0 == len(parts[0][1]):
+ host_and_port = parts[0][4]
+ elif 0 == len(parts[0][2]):
+ host_and_port = parts[0][1]
+ elif parts[0][2].startswith("//"):
+ host_and_port = parts[0][3]
+
+ if -1 == host_and_port.find(':'):
+ # if no : then it might only be a port; if it's a port, return this host
+ if host_and_port.isdigit():
+ return None
+
+ return host_and_port
+ else:
+ return host_and_port.split(':')[0]
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py
index eaf744a..1d34410 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py
@@ -39,9 +39,11 @@ class PortAlert(BaseAlert):
def _collect(self):
urivalue = self._lookup_property_value(self.uri)
- host = get_host_from_url(self, urivalue)
port = self.port
-
+ host = BaseAlert.get_host_from_url(urivalue)
+ if host is None:
+ host = self.host_name
+
try:
port = int(get_port_from_url(urivalue))
except:
@@ -67,39 +69,3 @@ class PortAlert(BaseAlert):
except:
pass
-'''
-See RFC3986, Appendix B
-Tested on the following cases:
- "192.168.54.1"
- "192.168.54.2:7661
- "hdfs://192.168.54.3/foo/bar"
- "ftp://192.168.54.4:7842/foo/bar"
-'''
-def get_host_from_url(self, uri):
- # RFC3986, Appendix B
- parts = re.findall('^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?', uri)
-
- # index of parts
- # scheme = 1
- # authority = 3
- # path = 4
- # query = 6
- # fragment = 8
-
- host_and_port = uri
- if 0 == len(parts[0][1]):
- host_and_port = parts[0][4]
- elif 0 == len(parts[0][2]):
- host_and_port = parts[0][1]
- elif parts[0][2].startswith("//"):
- host_and_port = parts[0][3]
-
- if -1 == host_and_port.find(':'):
- # if no : then it might only be a port; if it's a port, return this host
- if host_and_port.isdigit():
- return self.hostName
-
- return host_and_port
- else:
- return host_and_port.split(':')[0]
-
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java
index c2e5048..12cdb70 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java
@@ -23,6 +23,7 @@ import java.util.Map;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -80,6 +81,15 @@ public class AlertGroupService extends BaseService {
createAlertGroupResource(m_clusterName, null));
}
+ @PUT
+ @Produces("text/plain")
+ @Path("{groupId}")
+ public Response updateGroup(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui, @PathParam("groupId") Long groupId) {
+ return handleRequest(headers, body, ui, Request.Type.PUT,
+ createAlertGroupResource(m_clusterName, groupId));
+ }
+
@DELETE
@Produces("text/plain")
@Path("{groupId}")
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java
new file mode 100644
index 0000000..26e2f24
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertDefinitionResponse.java
@@ -0,0 +1,143 @@
+/**
+® * 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.ambari.server.controller;
+
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+
+/**
+ * The {@link AlertDefinitionResponse} encapsulates the definition information
+ * that should be serialized and returned in REST requests for alerts, groups,
+ * and targets.
+ */
+public class AlertDefinitionResponse {
+
+ private String serviceName = null;
+ private String componentName = null;
+ private String name = null;
+ private String label = null;
+ private Long definitionId;
+
+ /**
+ * @return the definitionId
+ */
+ @JsonProperty("id")
+ public Long getDefinitionId() {
+ return definitionId;
+ }
+
+ /**
+ * @param definitionId
+ * the definitionId to set
+ */
+ public void setDefinitionId(Long definitionId) {
+ this.definitionId = definitionId;
+ }
+
+ /**
+ * @return the service name
+ */
+ @JsonProperty("service_name")
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ /**
+ * @param name the service name
+ */
+ public void setServiceName(String name) {
+ serviceName = name;
+ }
+
+ /**
+ * @return the component name
+ */
+ @JsonProperty("component_name")
+ public String getComponentName() {
+ return componentName;
+ }
+
+ /**
+ *
+ * @param name the component name
+ */
+ public void setComponentName(String name) {
+ componentName = name;
+ }
+
+ /**
+ * @return the name
+ */
+ @JsonProperty("name")
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @param definitionName
+ * the definition name.
+ */
+ public void setName(String definitionName) {
+ name = definitionName;
+ }
+
+ /**
+ * @return the label for the definition or {@code null} if none.
+ */
+ @JsonProperty("label")
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * Sets the label for this definition.
+ *
+ * @param definitionLabel
+ */
+ public void setLabel(String definitionLabel) {
+ label = definitionLabel;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ /**
+ * Gets an {@link AlertDefinitionResponse} from the supplied entity.
+ *
+ * @param entity
+ * the entity (not {@code null}).
+ * @return the response.
+ */
+ public static AlertDefinitionResponse coerce(AlertDefinitionEntity entity) {
+ if (null == entity) {
+ return null;
+ }
+
+ AlertDefinitionResponse response = new AlertDefinitionResponse();
+ response.setDefinitionId(entity.getDefinitionId());
+ response.setComponentName(entity.getComponentName());
+ response.setLabel(entity.getLabel());
+ response.setName(entity.getDefinitionName());
+ response.setServiceName(entity.getServiceName());
+
+ return response;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
index f14e76f..fc51ddd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
@@ -17,14 +17,17 @@
*/
package org.apache.ambari.server.controller.internal;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AlertDefinitionResponse;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -36,11 +39,14 @@ import org.apache.ambari.server.controller.spi.Resource.Type;
import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertGroupEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.alert.AlertGroup;
+import org.apache.ambari.server.state.alert.AlertTarget;
import org.apache.commons.lang.StringUtils;
import com.google.inject.Inject;
@@ -66,12 +72,16 @@ public class AlertGroupResourceProvider extends
Arrays.asList(ALERT_GROUP_ID, ALERT_GROUP_CLUSTER_NAME));
/**
- * Group DAO
+ * Group/Target DAO
*/
- @Inject
private static AlertDispatchDAO s_dao;
/**
+ * Definitions DAO
+ */
+ private static AlertDefinitionDAO s_definitionDao;
+
+ /**
* Initializes the injectable members of this class with the specified
* injector.
*
@@ -81,6 +91,7 @@ public class AlertGroupResourceProvider extends
@Inject
public static void init(Injector injector) {
s_dao = injector.getInstance(AlertDispatchDAO.class);
+ s_definitionDao = injector.getInstance(AlertDefinitionDAO.class);
}
/**
@@ -156,11 +167,21 @@ public class AlertGroupResourceProvider extends
}
@Override
- public RequestStatus updateResources(Request request, Predicate predicate)
+ public RequestStatus updateResources(final Request request,
+ Predicate predicate)
throws SystemException, UnsupportedPropertyException,
NoSuchResourceException, NoSuchParentResourceException {
- throw new UnsupportedOperationException();
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ updateAlertGroups(request.getProperties());
+ return null;
+ }
+ });
+
+ notifyUpdate(Resource.Type.AlertGroup, request, predicate);
+ return getRequestStatus(null);
}
@Override
@@ -207,6 +228,7 @@ public class AlertGroupResourceProvider extends
* @param requestMaps
* @throws AmbariException
*/
+ @SuppressWarnings("unchecked")
private void createAlertGroups(Set<Map<String, Object>> requestMaps)
throws AmbariException {
@@ -231,9 +253,27 @@ public class AlertGroupResourceProvider extends
clusterName);
entity.setClusterId(cluster.getClusterId());
- entity.setDefault(false);
entity.setGroupName(name);
+ // groups created through the provider are not default service groups
+ entity.setDefault(false);
+
+ // targets are not required on creation
+ if (requestMap.containsKey(ALERT_GROUP_TARGETS)) {
+ List<Long> targetIds = (List<Long>) requestMap.get(ALERT_GROUP_TARGETS);
+ Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
+ targets.addAll(s_dao.findTargetsById(targetIds));
+ entity.setAlertTargets(targets);
+ }
+
+ // definitions are not required on creation
+ if (requestMap.containsKey(ALERT_GROUP_DEFINITIONS)) {
+ List<Long> definitionIds = (List<Long>) requestMap.get(ALERT_GROUP_DEFINITIONS);
+ Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
+ definitions.addAll(s_definitionDao.findByIds(definitionIds));
+ entity.setAlertDefinitions(definitions);
+ }
+
entities.add(entity);
}
@@ -241,6 +281,74 @@ public class AlertGroupResourceProvider extends
}
/**
+ * Updates existing {@link AlertGroupEntity}s with the specified properties.
+ *
+ * @param requestMaps
+ * a set of property maps, one map for each entity.
+ * @throws AmbariException
+ * if the entity could not be found.
+ */
+ @SuppressWarnings("unchecked")
+ private void updateAlertGroups(Set<Map<String, Object>> requestMaps)
+ throws AmbariException {
+
+ for (Map<String, Object> requestMap : requestMaps) {
+ String stringId = (String) requestMap.get(ALERT_GROUP_ID);
+
+ if( StringUtils.isEmpty(stringId)){
+ throw new IllegalArgumentException("The ID of the alert group is required when updating an existing group");
+ }
+
+ long id = Long.parseLong(stringId);
+ AlertGroupEntity entity = s_dao.findGroupById(id);
+
+ if( null == entity ){
+ String message = MessageFormat.format("The alert group with ID {0} could not be found", id);
+ throw new AmbariException(message);
+ }
+
+ String name = (String) requestMap.get(ALERT_GROUP_NAME);
+
+ // empty arrays are deserialized as HashSet while populated arrays
+ // are deserialized as ArrayList; use Collection for safety
+ Collection<Long> targetIds = (Collection<Long>) requestMap.get(ALERT_GROUP_TARGETS);
+ Collection<Long> definitionIds = (Collection<Long>) requestMap.get(ALERT_GROUP_DEFINITIONS);
+
+ if (!StringUtils.isBlank(name)) {
+ entity.setGroupName(name);
+ }
+
+ // if targets were supplied, replace existing
+ Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
+ if (null != targetIds && targetIds.size() > 0) {
+ List<Long> ids = new ArrayList<Long>(targetIds.size());
+ ids.addAll(targetIds);
+ targets.addAll(s_dao.findTargetsById(ids));
+
+ entity.setAlertTargets(targets);
+ } else if (targetIds.size() == 0) {
+ // empty array supplied, clear out existing targets
+ entity.setAlertTargets(targets);
+ }
+
+ // if definitions were supplied, replace existing
+ Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
+ if (null != definitionIds && definitionIds.size() > 0) {
+ List<Long> ids = new ArrayList<Long>(definitionIds.size());
+ ids.addAll(definitionIds);
+ definitions.addAll(s_definitionDao.findByIds(ids));
+
+ entity.setAlertDefinitions(definitions);
+ } else if (definitionIds.size() == 0) {
+ // empty array supplied, clear out existing definitions
+ entity.setAlertDefinitions(definitions);
+ }
+
+ s_dao.merge(entity);
+ }
+ }
+
+ /**
* Convert the given {@link AlertGroupEntity} to a {@link Resource}.
*
* @param isCollection
@@ -259,9 +367,31 @@ public class AlertGroupResourceProvider extends
resource.setProperty(ALERT_GROUP_ID, entity.getGroupId());
resource.setProperty(ALERT_GROUP_NAME, entity.getGroupName());
resource.setProperty(ALERT_GROUP_CLUSTER_NAME, clusterName);
+ resource.setProperty(ALERT_GROUP_DEFAULT, entity.isDefault());
+
+ if( !isCollection ){
+ Set<AlertTargetEntity> targetEntities = entity.getAlertTargets();
+ Set<AlertDefinitionEntity> definitions = entity.getAlertDefinitions();
+
+ List<AlertTarget> targets = new ArrayList<AlertTarget>(
+ targetEntities.size());
- setResourceProperty(resource, ALERT_GROUP_DEFAULT,
- entity.isDefault(), requestedIds);
+ List<AlertDefinitionResponse> definitionList = new ArrayList<AlertDefinitionResponse>(
+ definitions.size());
+
+ for (AlertTargetEntity targetEntity : targetEntities) {
+ AlertTarget target = AlertTarget.coerce(targetEntity);
+ targets.add(target);
+ }
+
+ for (AlertDefinitionEntity definition : definitions) {
+ AlertDefinitionResponse response = AlertDefinitionResponse.coerce(definition);
+ definitionList.add(response);
+ }
+
+ resource.setProperty(ALERT_GROUP_DEFINITIONS, definitionList);
+ resource.setProperty(ALERT_GROUP_TARGETS, targets);
+ }
return resource;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
index 4a8fe12..f410c39 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
@@ -124,6 +124,22 @@ public class AlertDefinitionDAO {
}
/**
+ * Gets all of the alert definitions for the list of IDs given.
+ *
+ * @param definitionIds
+ * the IDs of the definitions to retrieve.
+ * @return the definition or an empty list (never {@code null}).
+ */
+ public List<AlertDefinitionEntity> findByIds(List<Long> definitionIds) {
+ TypedQuery<AlertDefinitionEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertDefinitionEntity.findByIds", AlertDefinitionEntity.class);
+
+ query.setParameter("definitionIds", definitionIds);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
* Gets all alert definitions for the given service in the specified cluster.
*
* @param clusterId
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
index dfbe747..e08c948 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
@@ -72,6 +72,22 @@ public class AlertDispatchDAO {
}
/**
+ * Gets all of the alert targets for the list of IDs given.
+ *
+ * @param targetIds
+ * the IDs of the targets to retrieve.
+ * @return the targets or an empty list (never {@code null}).
+ */
+ public List<AlertTargetEntity> findTargetsById(List<Long> targetIds) {
+ TypedQuery<AlertTargetEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertTargetEntity.findByIds", AlertTargetEntity.class);
+
+ query.setParameter("targetIds", targetIds);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
* Gets a notification with the specified ID.
*
* @param noticeId
@@ -207,7 +223,7 @@ public class AlertDispatchDAO {
/**
* Persists a new alert group.
- *
+ *
* @param alertGroup
* the group to persist (not {@code null}).
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
index 299467c..b4b8a44 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.server.orm.entities;
+import java.util.HashSet;
import java.util.Set;
import javax.persistence.Basic;
@@ -58,7 +59,8 @@ import org.apache.ambari.server.state.alert.Scope;
@NamedQuery(name = "AlertDefinitionEntity.findByName", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.definitionName = :definitionName AND ad.clusterId = :clusterId"),
@NamedQuery(name = "AlertDefinitionEntity.findByService", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName = :serviceName AND ad.clusterId = :clusterId"),
@NamedQuery(name = "AlertDefinitionEntity.findByServiceAndComponent", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName = :serviceName AND ad.componentName = :componentName AND ad.clusterId = :clusterId"),
- @NamedQuery(name = "AlertDefinitionEntity.findByServiceMaster", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName IN :services AND ad.scope = :scope AND ad.clusterId = :clusterId") })
+ @NamedQuery(name = "AlertDefinitionEntity.findByServiceMaster", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName IN :services AND ad.scope = :scope AND ad.clusterId = :clusterId"),
+ @NamedQuery(name = "AlertDefinitionEntity.findByIds", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.definitionId IN :definitionIds") })
public class AlertDefinitionEntity {
@Id
@@ -394,6 +396,34 @@ public class AlertDefinitionEntity {
}
/**
+ * Adds the specified alert group to the groups that this definition is
+ * associated with. This is used to complement the JPA bidirectional
+ * association.
+ *
+ * @param alertGroup
+ */
+ protected void addAlertGroup(AlertGroupEntity alertGroup) {
+ if (null == alertGroups) {
+ alertGroups = new HashSet<AlertGroupEntity>();
+ }
+
+ alertGroups.add(alertGroup);
+ }
+
+ /**
+ * Removes the specified alert group to the groups that this definition is
+ * associated with. This is used to complement the JPA bidirectional
+ * association.
+ *
+ * @param alertGroup
+ */
+ protected void removeAlertGroup(AlertGroupEntity alertGroup) {
+ if (null != alertGroups) {
+ alertGroups.remove(alertGroup);
+ }
+ }
+
+ /**
* Called before {@link EntityManager#remove(Object)} for this entity, removes
* the non-owning relationship between definitions and groups.
*/
@@ -405,10 +435,7 @@ public class AlertDefinitionEntity {
}
for (AlertGroupEntity group : groups) {
- Set<AlertDefinitionEntity> definitions = group.getAlertDefinitions();
- if (null != definitions) {
- definitions.remove(this);
- }
+ group.removeAlertDefinition(this);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
index 1ca592c..f97a0eb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
@@ -177,7 +177,7 @@ public class AlertGroupEntity {
/**
* Set the service name. This is only applicable when {@link #isDefault()} is
* {@code true}.
- *
+ *
* @param serviceName
* the service that this is the default group for, or {@code null} if
* this is not a default group.
@@ -189,10 +189,14 @@ public class AlertGroupEntity {
/**
* Gets all of the alert definitions that are a part of this grouping.
*
- * @return the alert definitions or {@code null} if none.
+ * @return the alert definitions or an empty set if none (never {@code null).
*/
public Set<AlertDefinitionEntity> getAlertDefinitions() {
- return alertDefinitions;
+ if (null == alertDefinitions) {
+ alertDefinitions = new HashSet<AlertDefinitionEntity>();
+ }
+
+ return Collections.unmodifiableSet(alertDefinitions);
}
/**
@@ -202,14 +206,58 @@ public class AlertGroupEntity {
* the definitions, or {@code null} for none.
*/
public void setAlertDefinitions(Set<AlertDefinitionEntity> alertDefinitions) {
+ if (null != this.alertDefinitions) {
+ for (AlertDefinitionEntity definition : this.alertDefinitions) {
+ definition.removeAlertGroup(this);
+ }
+ }
+
this.alertDefinitions = alertDefinitions;
+
+ if (null != alertDefinitions) {
+ for (AlertDefinitionEntity definition : alertDefinitions) {
+ definition.addAlertGroup(this);
+ }
+ }
+ }
+
+ /**
+ * Adds the specified definition to the definitions that this group will
+ * dispatch to.
+ *
+ * @param definition
+ * the definition to add (not {@code null}).
+ */
+ public void addAlertDefinition(AlertDefinitionEntity definition) {
+ if (null == alertDefinitions) {
+ alertDefinitions = new HashSet<AlertDefinitionEntity>();
+ }
+
+ alertDefinitions.add(definition);
+ definition.addAlertGroup(this);
+ }
+
+ /**
+ * Removes the specified definition from the definitions that this group will
+ * dispatch to.
+ *
+ * @param definition
+ * the definition to remove (not {@code null}).
+ */
+ public void removeAlertDefinition(AlertDefinitionEntity definition) {
+ if (null != alertDefinitions) {
+ alertDefinitions.remove(definition);
+ }
+
+ definition.removeAlertGroup(this);
}
/**
* Gets an immutable set of the targets that will receive notifications for
* alert definitions in this group.
*
- * @return the targets, or {@code null} if there are none.
+ * @return the targets that will be dispatch to for alerts in this group, or
+ * an empty set if there are none (never {@code null}).
*/
public Set<AlertTargetEntity> getAlertTargets() {
if( null == alertTargets ) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
index 89728e5..12c394d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
@@ -46,7 +46,8 @@ import javax.persistence.TableGenerator;
@TableGenerator(name = "alert_target_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "alert_target_id_seq", initialValue = 0, allocationSize = 1)
@NamedQueries({
@NamedQuery(name = "AlertTargetEntity.findAll", query = "SELECT alertTarget FROM AlertTargetEntity alertTarget"),
- @NamedQuery(name = "AlertTargetEntity.findByName", query = "SELECT alertTarget FROM AlertTargetEntity alertTarget WHERE alertTarget.targetName = :targetName"), })
+ @NamedQuery(name = "AlertTargetEntity.findByName", query = "SELECT alertTarget FROM AlertTargetEntity alertTarget WHERE alertTarget.targetName = :targetName"),
+ @NamedQuery(name = "AlertTargetEntity.findByIds", query = "SELECT alertTarget FROM AlertTargetEntity alertTarget WHERE alertTarget.targetId IN :targetIds") })
public class AlertTargetEntity {
@Id
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
index 21e83d9..f495787 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
@@ -17,24 +17,27 @@
*/
package org.apache.ambari.server.state.alert;
-import java.util.List;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.codehaus.jackson.annotate.JsonProperty;
+
/**
* The {@link AlertTarget} class represents a dispatch mechanism and audience
* that will receive information about alerts int he system.
*/
public class AlertTarget {
- private String m_id;
+
+ private Long m_id;
private String m_name;
private String m_description;
private String m_notificationType;
private String m_properties;
- private List<AlertGroup> m_groups;
/**
* @return the id
*/
- public String getId() {
+ @JsonProperty("id")
+ public Long getId() {
return m_id;
}
@@ -42,13 +45,14 @@ public class AlertTarget {
* @param id
* the id to set
*/
- public void setId(String id) {
+ public void setId(Long id) {
m_id = id;
}
/**
* @return the name
*/
+ @JsonProperty("name")
public String getName() {
return m_name;
}
@@ -64,6 +68,7 @@ public class AlertTarget {
/**
* @return the description
*/
+ @JsonProperty("description")
public String getDescription() {
return m_description;
}
@@ -79,6 +84,7 @@ public class AlertTarget {
/**
* @return the notificationType
*/
+ @JsonProperty("notification_type")
public String getNotificationType() {
return m_notificationType;
}
@@ -94,6 +100,7 @@ public class AlertTarget {
/**
* @return the properties
*/
+ @JsonProperty("properties")
public String getProperties() {
return m_properties;
}
@@ -107,17 +114,17 @@ public class AlertTarget {
}
/**
- * @return the groups
+ * @param entity
+ * @return
*/
- public List<AlertGroup> getGroups() {
- return m_groups;
- }
+ public static AlertTarget coerce(AlertTargetEntity entity) {
+ AlertTarget target = new AlertTarget();
+ target.setId(entity.getTargetId());
+ target.setDescription(entity.getDescription());
+ target.setName(entity.getTargetName());
+ target.setNotificationType(entity.getNotificationType());
+ target.setProperties(entity.getProperties());
- /**
- * @param groups
- * the groups to set
- */
- public void setGroups(List<AlertGroup> groups) {
- m_groups = groups;
+ return target;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
index c9428b7..ddfc75a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
@@ -17,24 +17,30 @@
*/
package org.apache.ambari.server.controller.internal;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.resetToStrict;
import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.UUID;
+import org.apache.ambari.server.controller.AlertDefinitionResponse;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.Request;
@@ -43,13 +49,18 @@ import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.alert.AlertTarget;
+import org.apache.ambari.server.state.alert.SourceType;
+import org.apache.ambari.server.state.alert.TargetType;
import org.easymock.Capture;
import org.easymock.EasyMock;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@@ -69,17 +80,42 @@ public class AlertGroupResourceProviderTest {
private static final long ALERT_GROUP_CLUSTER_ID = 1L;
private static final String ALERT_GROUP_CLUSTER_NAME = "c1";
+ private static final Long ALERT_TARGET_ID = Long.valueOf(28);
+ private static final String ALERT_TARGET_NAME = "The Administrators";
+ private static final String ALERT_TARGET_DESC = "Admins and Others";
+ private static final String ALERT_TARGET_TYPE = TargetType.EMAIL.name();
+
+ private static final Long ALERT_DEF_ID = Long.valueOf(10);
+ private static final String ALERT_DEF_NAME = "Mock Definition";
+ private static final String ALERT_DEF_LABEL = "Mock Label";
+
+ private static String DEFINITION_UUID = UUID.randomUUID().toString();
+
private AlertDispatchDAO m_dao;
+ private AlertDefinitionDAO m_definitionDao;
private Injector m_injector;
+ private AmbariManagementController m_amc;
+ private Clusters m_clusters;
+ private Cluster m_cluster;
+
@Before
- public void before() {
- m_dao = createStrictMock(AlertDispatchDAO.class);
+ public void before() throws Exception {
+ m_dao = createMock(AlertDispatchDAO.class);
+ m_definitionDao = createMock(AlertDefinitionDAO.class);
+
+ m_amc = createMock(AmbariManagementController.class);
+ m_clusters = createMock(Clusters.class);
+ m_cluster = createMock(Cluster.class);
m_injector = Guice.createInjector(Modules.override(
new InMemoryDefaultTestModule()).with(new MockModule()));
AlertGroupResourceProvider.init(m_injector);
+
+ expect(m_amc.getClusters()).andReturn(m_clusters).atLeastOnce();
+ expect(m_clusters.getCluster((String) anyObject())).andReturn(m_cluster).atLeastOnce();
+ expect(m_cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
}
/**
@@ -108,44 +144,41 @@ public class AlertGroupResourceProviderTest {
AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME,
AlertGroupResourceProvider.ALERT_GROUP_DEFAULT);
- AmbariManagementController amc = createMock(AmbariManagementController.class);
- Clusters clusters = createMock(Clusters.class);
- Cluster cluster = createMock(Cluster.class);
- expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
- expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce();
- expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
-
Predicate predicate = new PredicateBuilder().property(
AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals("c1").toPredicate();
expect(m_dao.findAllGroups(ALERT_GROUP_CLUSTER_ID)).andReturn(
getMockEntities());
- replay(amc, clusters, cluster, m_dao);
+ replay(m_amc, m_clusters, m_cluster, m_dao);
- AlertGroupResourceProvider provider = createProvider(amc);
+ AlertGroupResourceProvider provider = createProvider(m_amc);
Set<Resource> results = provider.getResources(request, predicate);
assertEquals(1, results.size());
Resource r = results.iterator().next();
- Assert.assertEquals(ALERT_GROUP_NAME,
+ assertEquals(ALERT_GROUP_NAME,
r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_NAME));
- Assert.assertEquals(ALERT_GROUP_ID,
+ assertEquals(ALERT_GROUP_ID,
r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_ID));
- Assert.assertEquals(ALERT_GROUP_CLUSTER_NAME,
+ assertEquals(ALERT_GROUP_CLUSTER_NAME,
r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME));
- verify(amc, clusters, cluster, m_dao);
+ // verify definitions do not come back in collections
+ assertNull(r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS));
+
+ verify(m_amc, m_clusters, m_cluster, m_dao);
}
/**
* @throws Exception
*/
@Test
+ @SuppressWarnings("unchecked")
public void testGetSingleResource() throws Exception {
Request request = PropertyHelper.getReadRequest(
AlertGroupResourceProvider.ALERT_GROUP_ID,
@@ -173,15 +206,28 @@ public class AlertGroupResourceProviderTest {
Resource r = results.iterator().next();
- Assert.assertEquals(ALERT_GROUP_NAME,
+ assertEquals(ALERT_GROUP_NAME,
r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_NAME));
- Assert.assertEquals(ALERT_GROUP_ID,
+ assertEquals(ALERT_GROUP_ID,
r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_ID));
- Assert.assertEquals(ALERT_GROUP_CLUSTER_NAME,
+ assertEquals(ALERT_GROUP_CLUSTER_NAME,
r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME));
+ // verify definitions and targets are returned on single instances
+ List<AlertDefinitionResponse> definitions = (List<AlertDefinitionResponse>) r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS);
+ List<AlertTarget> targets = (List<AlertTarget>) r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_TARGETS);
+
+ assertNotNull(definitions);
+ assertNotNull(targets);
+
+ assertEquals(1, definitions.size());
+ assertEquals(ALERT_DEF_NAME, definitions.get(0).getName());
+
+ assertEquals(1, targets.size());
+ assertEquals(ALERT_TARGET_NAME, targets.get(0).getName());
+
verify(amc, m_dao);
}
@@ -190,21 +236,40 @@ public class AlertGroupResourceProviderTest {
*/
@Test
public void testCreateResources() throws Exception {
- AmbariManagementController amc = createMock(AmbariManagementController.class);
- Clusters clusters = createMock(Clusters.class);
- Cluster cluster = createMock(Cluster.class);
- expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
- expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce();
- expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
-
Capture<List<AlertGroupEntity>> listCapture = new Capture<List<AlertGroupEntity>>();
+ // the definition IDs to associate with the group
+ List<Long> definitionIds = new ArrayList<Long>();
+ definitionIds.add(ALERT_DEF_ID);
+
+ // the target IDs to associate with the group
+ List<Long> targetIds = new ArrayList<Long>();
+ targetIds.add(ALERT_TARGET_ID);
+
+ // definition entities to return from DAO
+ List<AlertDefinitionEntity> definitionEntities = new ArrayList<AlertDefinitionEntity>();
+ definitionEntities.addAll(getMockDefinitions());
+
+ // target entities to return from DAO
+ List<AlertTargetEntity> targetEntities = new ArrayList<AlertTargetEntity>();
+ targetEntities.addAll(getMockTargets());
+
+ // expect create group
m_dao.createGroups(capture(listCapture));
- expectLastCall();
+ expectLastCall().once();
- replay(amc, clusters, cluster, m_dao);
+ // expect target entity lookup for association
+ expect(m_dao.findTargetsById(EasyMock.eq(targetIds))).andReturn(
+ targetEntities).times(1);
+
+ // expect definition entity lookup for association
+ expect(m_definitionDao.findByIds(definitionIds)).andReturn(
+ definitionEntities).times(1);
+
+ replay(m_amc, m_clusters, m_cluster, m_dao, m_definitionDao);
+
+ AlertGroupResourceProvider provider = createProvider(m_amc);
- AlertGroupResourceProvider provider = createProvider(amc);
Map<String, Object> requestProps = new HashMap<String, Object>();
requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME,
ALERT_GROUP_NAME);
@@ -212,25 +277,109 @@ public class AlertGroupResourceProviderTest {
requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME,
ALERT_GROUP_CLUSTER_NAME);
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS,
+ definitionIds);
+
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_TARGETS, targetIds);
+
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
provider.createResources(request);
- Assert.assertTrue(listCapture.hasCaptured());
+ assertTrue(listCapture.hasCaptured());
AlertGroupEntity entity = listCapture.getValue().get(0);
- Assert.assertNotNull(entity);
+ assertNotNull(entity);
- Assert.assertEquals(ALERT_GROUP_NAME, entity.getGroupName());
- Assert.assertEquals(ALERT_GROUP_CLUSTER_ID,
+ assertEquals(ALERT_GROUP_NAME, entity.getGroupName());
+ assertEquals(ALERT_GROUP_CLUSTER_ID,
entity.getClusterId().longValue());
- verify(amc, clusters, cluster, m_dao);
+ verify(m_amc, m_clusters, m_cluster, m_dao, m_definitionDao);
}
/**
* @throws Exception
*/
@Test
+ @SuppressWarnings("unchecked")
public void testUpdateResources() throws Exception {
+ Capture<AlertGroupEntity> entityCapture = new Capture<AlertGroupEntity>();
+
+ // the definition IDs to associate with the group
+ List<Long> definitionIds = new ArrayList<Long>();
+ definitionIds.add(ALERT_DEF_ID);
+
+ // the target IDs to associate with the group
+ List<Long> targetIds = new ArrayList<Long>();
+ targetIds.add(ALERT_TARGET_ID);
+
+ // definition entities to return from DAO
+ List<AlertDefinitionEntity> definitionEntities = new ArrayList<AlertDefinitionEntity>();
+ definitionEntities.addAll(getMockDefinitions());
+
+ // target entities to return from DAO
+ List<AlertTargetEntity> targetEntities = new ArrayList<AlertTargetEntity>();
+ targetEntities.addAll(getMockTargets());
+
+ m_dao.createGroups(EasyMock.anyObject(List.class));
+ expectLastCall().times(1);
+
+ AlertGroupEntity group = new AlertGroupEntity();
+ expect(m_dao.findGroupById(ALERT_GROUP_ID)).andReturn(
+ group).times(1);
+
+ expect(m_dao.merge(capture(entityCapture))).andReturn(group).once();
+
+ // expect target entity lookup for association
+ expect(m_dao.findTargetsById(EasyMock.eq(targetIds))).andReturn(
+ targetEntities).once();
+
+ // expect definition entity lookup for association
+ expect(m_definitionDao.findByIds(definitionIds)).andReturn(
+ definitionEntities).once();
+
+ replay(m_amc, m_clusters, m_cluster, m_dao, m_definitionDao);
+
+ AlertGroupResourceProvider provider = createProvider(m_amc);
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME,
+ ALERT_GROUP_NAME);
+
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME,
+ ALERT_GROUP_CLUSTER_NAME);
+
+ Request request = PropertyHelper.getCreateRequest(
+ Collections.singleton(requestProps), null);
+
+ provider.createResources(request);
+
+ // create new properties, and include the ID since we're not going through
+ // a service layer which would add it for us automatically
+ requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_ID,
+ ALERT_GROUP_ID.toString());
+
+ String newName = ALERT_GROUP_NAME + " Foo";
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME, newName);
+
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS,
+ definitionIds);
+
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_TARGETS, targetIds);
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals(
+ ALERT_GROUP_CLUSTER_NAME).and().property(
+ AlertGroupResourceProvider.ALERT_GROUP_ID).equals(
+ ALERT_GROUP_ID.toString()).toPredicate();
+
+ request = PropertyHelper.getUpdateRequest(requestProps, null);
+ provider.updateResources(request, predicate);
+
+ assertTrue(entityCapture.hasCaptured());
+
+ AlertGroupEntity entity = entityCapture.getValue();
+ assertEquals(newName, entity.getGroupName());
+ verify(m_amc, m_clusters, m_cluster, m_dao, m_definitionDao);
}
/**
@@ -238,22 +387,15 @@ public class AlertGroupResourceProviderTest {
*/
@Test
public void testDeleteResources() throws Exception {
- AmbariManagementController amc = createMock(AmbariManagementController.class);
- Clusters clusters = createMock(Clusters.class);
- Cluster cluster = createMock(Cluster.class);
- expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
- expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce();
- expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
-
Capture<AlertGroupEntity> entityCapture = new Capture<AlertGroupEntity>();
Capture<List<AlertGroupEntity>> listCapture = new Capture<List<AlertGroupEntity>>();
m_dao.createGroups(capture(listCapture));
expectLastCall();
- replay(amc, clusters, cluster, m_dao);
+ replay(m_amc, m_clusters, m_cluster, m_dao);
- AlertGroupResourceProvider provider = createProvider(amc);
+ AlertGroupResourceProvider provider = createProvider(m_amc);
Map<String, Object> requestProps = new HashMap<String, Object>();
requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME,
@@ -265,9 +407,9 @@ public class AlertGroupResourceProviderTest {
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
provider.createResources(request);
- Assert.assertTrue(listCapture.hasCaptured());
+ assertTrue(listCapture.hasCaptured());
AlertGroupEntity entity = listCapture.getValue().get(0);
- Assert.assertNotNull(entity);
+ assertNotNull(entity);
Predicate predicate = new PredicateBuilder().property(
AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals(
@@ -287,9 +429,9 @@ public class AlertGroupResourceProviderTest {
provider.deleteResources(predicate);
AlertGroupEntity entity1 = entityCapture.getValue();
- Assert.assertEquals(ALERT_GROUP_ID, entity1.getGroupId());
+ assertEquals(ALERT_GROUP_ID, entity1.getGroupId());
- verify(amc, clusters, cluster, m_dao);
+ verify(m_amc, m_clusters, m_cluster, m_dao);
}
/**
@@ -298,6 +440,7 @@ public class AlertGroupResourceProviderTest {
*/
private AlertGroupResourceProvider createProvider(
AmbariManagementController amc) {
+
return new AlertGroupResourceProvider(
PropertyHelper.getPropertyIds(Resource.Type.AlertGroup),
PropertyHelper.getKeyPropertyIds(Resource.Type.AlertGroup), amc);
@@ -312,10 +455,57 @@ public class AlertGroupResourceProviderTest {
entity.setGroupName(ALERT_GROUP_NAME);
entity.setClusterId(ALERT_GROUP_CLUSTER_ID);
entity.setDefault(false);
+
+ entity.setAlertTargets(getMockTargets());
+ entity.setAlertDefinitions(getMockDefinitions());
return Arrays.asList(entity);
}
/**
+ * Gets some mock {@link AlertDefinitionEntity} instances.
+ *
+ * @return
+ * @throws Exception
+ */
+ private Set<AlertDefinitionEntity> getMockDefinitions() throws Exception {
+ AlertDefinitionEntity entity = new AlertDefinitionEntity();
+ entity.setClusterId(Long.valueOf(1L));
+ entity.setComponentName(null);
+ entity.setDefinitionId(ALERT_DEF_ID);
+ entity.setDefinitionName(ALERT_DEF_NAME);
+ entity.setLabel(ALERT_DEF_LABEL);
+ entity.setEnabled(true);
+ entity.setHash(DEFINITION_UUID);
+ entity.setScheduleInterval(Integer.valueOf(2));
+ entity.setServiceName(null);
+ entity.setSourceType(SourceType.METRIC.name());
+ entity.setSource(null);
+
+ Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
+ definitions.add(entity);
+
+ return definitions;
+ }
+
+ /**
+ * Gets some mock {@link AlertTargetEntity} instances.
+ *
+ * @return
+ */
+ private Set<AlertTargetEntity> getMockTargets() throws Exception {
+ AlertTargetEntity entity = new AlertTargetEntity();
+ entity.setTargetId(ALERT_TARGET_ID);
+ entity.setDescription(ALERT_TARGET_DESC);
+ entity.setTargetName(ALERT_TARGET_NAME);
+ entity.setNotificationType(ALERT_TARGET_TYPE);
+
+ Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
+ targets.add(entity);
+
+ return targets;
+ }
+
+ /**
*
*/
private class MockModule implements Module {
@@ -325,10 +515,9 @@ public class AlertGroupResourceProviderTest {
@Override
public void configure(Binder binder) {
binder.bind(AlertDispatchDAO.class).toInstance(m_dao);
- binder.bind(Clusters.class).toInstance(
- EasyMock.createNiceMock(Clusters.class));
- binder.bind(Cluster.class).toInstance(
- EasyMock.createNiceMock(Cluster.class));
+ binder.bind(AlertDefinitionDAO.class).toInstance(m_definitionDao);
+ binder.bind(Clusters.class).toInstance(m_clusters);
+ binder.bind(Cluster.class).toInstance(m_cluster);
binder.bind(ActionMetadata.class);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
index 982dd4b..6ca2035 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
@@ -266,7 +266,7 @@ public class AlertTargetResourceProviderTest {
entity.setTargetId(ALERT_TARGET_ID);
entity.setDescription(ALERT_TARGET_DESC);
entity.setTargetName(ALERT_TARGET_NAME);
- entity.setNotificationType(TargetType.EMAIL.name());
+ entity.setNotificationType(ALERT_TARGET_TYPE);
return Arrays.asList(entity);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index a7ef513..a7cc066 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
@@ -193,6 +194,21 @@ public class AlertDefinitionDAOTest {
}
/**
+ *
+ */
+ @Test
+ public void testFindByIds() {
+ List<AlertDefinitionEntity> definitions = dao.findAll();
+ List<Long> ids = new ArrayList<Long>();
+ ids.add(definitions.get(0).getDefinitionId());
+ ids.add(definitions.get(1).getDefinitionId());
+ ids.add(99999L);
+
+ definitions = dao.findByIds(ids);
+ assertEquals(2, definitions.size());
+ }
+
+ /**
*
*/
@Test
@@ -260,7 +276,7 @@ public class AlertDefinitionDAOTest {
AlertDefinitionEntity definition = helper.createAlertDefinition(clusterId);
AlertGroupEntity group = helper.createAlertGroup(clusterId, null);
- group.getAlertDefinitions().add(definition);
+ group.addAlertDefinition(definition);
dispatchDao.merge(group);
AlertHistoryEntity history = new AlertHistoryEntity();
http://git-wip-us.apache.org/repos/asf/ambari/blob/76fc94ec/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
index 894f2c2..8451c9b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -56,7 +57,7 @@ public class AlertDispatchDAOTest {
OrmTestHelper helper;
/**
- *
+ *
*/
@Before
public void setup() throws Exception {
@@ -92,7 +93,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testFindAllTargets() throws Exception {
@@ -102,7 +103,24 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ * @throws Exception
+ */
+ public void testFindTargetsByIds() throws Exception {
+ List<AlertTargetEntity> targets = dao.findAllTargets();
+ assertNotNull(targets);
+ assertEquals(5, targets.size());
+
+ List<Long> ids = new ArrayList<Long>();
+ ids.add(targets.get(0).getTargetId());
+ ids.add(targets.get(1).getTargetId());
+ ids.add(99999L);
+
+ targets = dao.findTargetsById(ids);
+ assertEquals(2, targets.size());
+ }
+
+ /**
+ *
*/
@Test
public void testFindTargetByName() throws Exception {
@@ -115,7 +133,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testFindAllGroups() throws Exception {
@@ -125,7 +143,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testFindGroupByName() throws Exception {
@@ -140,7 +158,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testCreateGroup() throws Exception {
@@ -159,7 +177,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testGroupDefinitions() throws Exception {
@@ -170,7 +188,10 @@ public class AlertDispatchDAOTest {
group = dao.findGroupById(group.getGroupId());
assertNotNull(group);
- group.getAlertDefinitions().addAll(definitions);
+ for (AlertDefinitionEntity definition : definitions) {
+ group.addAlertDefinition(definition);
+ }
+
dao.merge(group);
group = dao.findGroupByName(group.getGroupName());
@@ -193,7 +214,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testCreateTarget() throws Exception {
@@ -222,12 +243,12 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testDeleteGroup() throws Exception {
- int targetCount = dao.findAllTargets().size();
-
+ int targetCount = dao.findAllTargets().size();
+
AlertGroupEntity group = helper.createAlertGroup(clusterId, null);
AlertTargetEntity target = helper.createAlertTarget();
assertEquals(targetCount + 1, dao.findAllTargets().size());
@@ -255,7 +276,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testDeleteTarget() throws Exception {
@@ -270,7 +291,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testDeleteAssociatedTarget() throws Exception {
@@ -298,7 +319,7 @@ public class AlertDispatchDAOTest {
}
/**
- *
+ *
*/
@Test
public void testUpdateGroup() throws Exception {
@@ -319,8 +340,6 @@ public class AlertDispatchDAOTest {
assertEquals(groupName + "FOO", group.getGroupName());
assertEquals(true, group.isDefault());
- assertNotNull(group.getAlertDefinitions());
- assertNotNull(group.getAlertTargets());
assertEquals(0, group.getAlertDefinitions().size());
assertEquals(0, group.getAlertTargets().size());
[14/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e508fe5a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e508fe5a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e508fe5a
Branch: refs/heads/trunk
Commit: e508fe5a331c2fb8a98c55ccddbcee42ec77f2b6
Parents: 91ae5f2 637d521
Author: Nate Cole <nc...@hortonworks.com>
Authored: Sun Sep 7 05:44:24 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Sun Sep 7 05:44:24 2014 -0400
----------------------------------------------------------------------
.../app/scripts/controllers/NavbarCtrl.js | 41 +++-
.../admin-web/app/scripts/services/Cluster.js | 14 +-
.../resources/ui/admin-web/app/styles/main.css | 18 ++
.../ui/admin-web/app/views/leftNavbar.html | 39 +++-
ambari-agent/conf/unix/install-helper.sh | 6 +
ambari-agent/pom.xml | 2 +-
.../src/main/package/rpm/posttrans_agent.sh | 7 +
.../resources/blueprints/hdp-multinode-default | 5 +-
.../resources/blueprints/hdp-singlenode-default | 2 +-
.../resources/blueprints/lambda-architecture | 12 +-
.../resources/blueprints/multi-node-hdfs-yarn | 6 +-
.../resources/blueprints/single-node-hdfs-yarn | 2 +-
.../src/main/resources/blueprints/warmup | 8 +-
ambari-server/conf/unix/install-helper.sh | 6 +
ambari-server/pom.xml | 25 ++
.../server/api/util/StackExtensionHelper.java | 8 +-
.../server/configuration/Configuration.java | 36 +++
.../AmbariManagementControllerImpl.java | 24 +-
.../ambari/server/controller/AmbariServer.java | 10 +-
.../internal/ClientConfigResourceProvider.java | 5 +
.../internal/ViewVersionResourceProvider.java | 22 +-
.../nagios/NagiosPropertyProvider.java | 8 +-
.../ambari/server/orm/entities/ViewEntity.java | 55 ++++-
.../AmbariLdapAuthoritiesPopulator.java | 18 +-
.../AmbariLocalUserDetailsService.java | 4 +-
.../apache/ambari/server/view/ViewRegistry.java | 200 ++++++++++------
.../src/main/package/rpm/posttrans_server.sh | 7 +
.../HDP/1.3.2/configuration/cluster-env.xml | 5 +
.../1.3.2/hooks/after-INSTALL/scripts/params.py | 5 +-
.../1.3.2/hooks/before-ANY/scripts/params.py | 3 +-
.../hooks/before-INSTALL/scripts/params.py | 11 +-
.../1.3.2/hooks/before-START/scripts/params.py | 16 +-
.../scripts/shared_initialization.py | 121 +++++-----
.../services/GANGLIA/package/scripts/params.py | 2 +-
.../services/HBASE/package/scripts/params.py | 11 +-
.../services/HDFS/configuration/hadoop-env.xml | 32 +--
.../services/HDFS/package/scripts/params.py | 9 +-
.../1.3.2/services/HIVE/package/scripts/hive.py | 31 ++-
.../services/HIVE/package/scripts/params.py | 9 +-
.../MAPREDUCE/package/scripts/params.py | 9 +-
.../services/NAGIOS/package/scripts/params.py | 5 +-
.../services/OOZIE/package/scripts/params.py | 9 +-
.../services/PIG/package/scripts/params.py | 9 +-
.../services/SQOOP/package/scripts/params.py | 11 +-
.../services/WEBHCAT/package/scripts/params.py | 9 +-
.../ZOOKEEPER/package/scripts/params.py | 9 +-
.../HDP/2.0.6/configuration/cluster-env.xml | 5 +
.../2.0.6/hooks/after-INSTALL/scripts/params.py | 8 +-
.../scripts/shared_initialization.py | 48 ++--
.../2.0.6/hooks/before-ANY/scripts/params.py | 3 +-
.../hooks/before-INSTALL/scripts/params.py | 11 +-
.../2.0.6/hooks/before-START/scripts/params.py | 12 +-
.../scripts/shared_initialization.py | 124 +++++-----
.../services/FLUME/package/scripts/params.py | 2 +-
.../services/GANGLIA/package/scripts/params.py | 2 +-
.../services/HBASE/package/scripts/params.py | 10 +-
.../services/HDFS/configuration/hadoop-env.xml | 27 ---
.../services/HDFS/package/scripts/params.py | 9 +-
.../2.0.6/services/HIVE/package/scripts/hive.py | 42 +++-
.../services/HIVE/package/scripts/params.py | 9 +-
.../services/NAGIOS/package/scripts/params.py | 62 ++---
.../services/OOZIE/package/scripts/params.py | 9 +-
.../services/PIG/package/scripts/params.py | 9 +-
.../services/SQOOP/package/scripts/params.py | 10 +-
.../services/WEBHCAT/package/scripts/params.py | 9 +-
.../YARN/configuration-mapred/mapred-site.xml | 2 +-
.../scripts/application_timeline_server.py | 4 +-
.../YARN/package/scripts/historyserver.py | 4 +-
.../services/YARN/package/scripts/params.py | 18 +-
.../services/YARN/package/scripts/service.py | 30 ++-
.../YARN/package/scripts/status_params.py | 2 +-
.../HDP/2.0.6/services/ZOOKEEPER/metainfo.xml | 1 +
.../ZOOKEEPER/package/scripts/params.py | 9 +-
.../stacks/HDP/2.0.6/services/stack_advisor.py | 19 +-
.../blueprints/multinode-default.json | 7 +-
.../blueprints/singlenode-default.json | 4 +-
.../services/FALCON/package/scripts/params.py | 9 +-
.../services/STORM/package/scripts/params.py | 7 +-
.../services/TEZ/package/scripts/params.py | 2 +-
.../services/YARN/package/scripts/params.py | 9 +-
.../HDP/2.1/blueprints/multinode-default.json | 7 +-
.../HDP/2.1/blueprints/singlenode-default.json | 4 +-
.../services/FALCON/package/scripts/params.py | 9 +-
.../services/STORM/package/scripts/params.py | 7 +-
.../2.1/services/TEZ/configuration/tez-site.xml | 2 +-
.../2.1/services/TEZ/package/scripts/params.py | 2 +-
.../stacks/HDP/2.2.1/services/YARN/metainfo.xml | 8 +
.../api/util/StackExtensionHelperTest.java | 27 +++
.../server/configuration/ConfigurationTest.java | 19 +-
.../AmbariManagementControllerImplTest.java | 86 +++++++
.../AmbariPrivilegeResourceProviderTest.java | 6 +-
.../ClientConfigResourceProviderTest.java | 175 +++++++++++++-
.../ViewPrivilegeResourceProviderTest.java | 6 +-
.../nagios/NagiosPropertyProviderTest.java | 2 +
.../server/orm/entities/ViewEntityTest.java | 30 ++-
...ariAuthorizationProviderDisableUserTest.java | 97 ++++++++
.../TestAmbariLdapAuthoritiesPopulator.java | 2 +
.../ambari/server/view/ViewRegistryTest.java | 52 ++++-
.../stacks/1.3.2/HIVE/test_hive_client.py | 36 +++
.../stacks/1.3.2/HIVE/test_hive_metastore.py | 36 +++
.../stacks/1.3.2/HIVE/test_hive_server.py | 36 +++
.../1.3.2/configs/default.hbasedecom.json | 24 +-
.../python/stacks/1.3.2/configs/default.json | 25 +-
.../1.3.2/configs/default.non_gmetad_host.json | 22 +-
.../stacks/1.3.2/configs/default_client.json | 24 +-
.../python/stacks/1.3.2/configs/secured.json | 24 +-
.../stacks/1.3.2/configs/secured_client.json | 25 +-
.../hooks/before-START/test_before_start.py | 3 +-
.../stacks/2.0.6/HIVE/test_hive_client.py | 52 +++++
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 52 +++++
.../stacks/2.0.6/HIVE/test_hive_server.py | 52 +++++
.../stacks/2.0.6/YARN/test_historyserver.py | 104 ++++-----
.../stacks/2.0.6/YARN/test_nodemanager.py | 103 ++++----
.../stacks/2.0.6/YARN/test_resourcemanager.py | 102 ++++----
.../stacks/2.0.6/common/test_stack_advisor.py | 54 ++++-
.../2.0.6/configs/default.hbasedecom.json | 24 +-
.../python/stacks/2.0.6/configs/default.json | 23 +-
.../2.0.6/configs/default.non_gmetad_host.json | 24 +-
.../stacks/2.0.6/configs/default_client.json | 24 +-
.../python/stacks/2.0.6/configs/ha_default.json | 24 +-
.../python/stacks/2.0.6/configs/ha_secured.json | 35 +--
.../2.0.6/configs/rebalancehdfs_default.json | 24 +-
.../python/stacks/2.0.6/configs/secured.json | 29 ++-
.../stacks/2.0.6/configs/secured_client.json | 25 +-
.../stacks/2.1/HIVE/test_hive_metastore.py | 52 +++++
.../stacks/2.1/YARN/test_apptimelineserver.py | 54 +++--
.../test/python/stacks/2.1/configs/default.json | 22 +-
.../test/python/stacks/2.1/configs/secured.json | 25 +-
.../HDP/2.0.5/services/ZOOKEEPER/metainfo.xml | 12 +
.../HDP/2.0.7/services/ZOOKEEPER/metainfo.xml | 12 +
.../org/apache/ambari/view/ViewDefinition.java | 27 +++
ambari-web/app/app.js | 13 ++
ambari-web/app/controllers/login_controller.js | 10 +-
.../app/controllers/main/admin/security.js | 43 ++--
.../security/add/addSecurity_controller.js | 7 +-
.../main/admin/security/add/step1.js | 11 +-
.../main/admin/security/add/step2.js | 1 +
.../main/admin/security/add/step3.js | 35 ++-
.../main/admin/security/add/step4.js | 9 +-
.../controllers/main/admin/security/disable.js | 4 +-
.../security/security_progress_controller.js | 20 +-
ambari-web/app/controllers/main/host/details.js | 18 +-
.../controllers/main/service/add_controller.js | 23 +-
.../controllers/main/service/info/configs.js | 5 +-
.../service/manage_config_groups_controller.js | 5 +-
.../main/service/reassign_controller.js | 6 +-
ambari-web/app/controllers/wizard.js | 66 +++---
.../app/controllers/wizard/step3_controller.js | 3 +-
.../app/controllers/wizard/step5_controller.js | 8 +-
.../app/controllers/wizard/step6_controller.js | 55 ++++-
.../app/controllers/wizard/step8_controller.js | 16 +-
ambari-web/app/data/HDP2/secure_configs.js | 32 ++-
ambari-web/app/data/HDP2/secure_mapping.js | 45 ++++
ambari-web/app/data/HDP2/secure_properties.js | 91 ++++++--
ambari-web/app/data/HDP2/site_properties.js | 41 ++--
ambari-web/app/data/secure_configs.js | 10 +-
ambari-web/app/data/secure_properties.js | 23 +-
ambari-web/app/data/service_configs.js | 1 +
ambari-web/app/data/site_properties.js | 43 ++--
ambari-web/app/messages.js | 11 +-
ambari-web/app/mixins/common/blueprint.js | 6 +-
ambari-web/app/router.js | 25 +-
ambari-web/app/routes/add_security.js | 6 +-
ambari-web/app/routes/main.js | 5 +-
ambari-web/app/styles/application.less | 71 +++---
.../common/configs/config_history_flow.hbs | 22 +-
.../templates/main/admin/security/add/step1.hbs | 2 +-
ambari-web/app/utils/ajax/ajax.js | 4 +
ambari-web/app/utils/blueprint.js | 8 +-
ambari-web/app/utils/config.js | 83 +++++--
.../app/views/common/configs/services_config.js | 3 +-
.../app/views/common/quick_view_link_view.js | 234 +++++++++++--------
.../app/views/main/admin/security/add/step1.js | 6 +-
ambari-web/app/views/wizard/controls_view.js | 4 +
.../main/admin/security/add/step1_test.js | 10 +-
.../main/admin/security/disable_test.js | 6 +-
.../controllers/main/admin/security_test.js | 18 +-
.../test/controllers/wizard/step6_test.js | 96 ++++++++
ambari-web/test/models/dataset_job_test.js | 2 +-
ambari-web/test/utils/blueprint_test.js | 2 +-
.../test/views/common/quick_link_view_test.js | 56 +++++
.../slider-core/0.41.0/slider-core-0.41.0.jar | Bin 0 -> 1125710 bytes
.../slider-core/0.41.0/slider-core-0.41.0.pom | 25 ++
.../slider/slider-core/maven-metadata-local.xml | 28 +++
.../slider/slider/0.30.0/slider-0.30.0.jar | Bin 1125710 -> 0 bytes
.../slider/slider/0.30.0/slider-0.30.0.pom | 25 --
.../slider/slider/maven-metadata-local.xml | 28 ---
contrib/views/slider/pom.xml | 5 +-
188 files changed, 3187 insertions(+), 1443 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e508fe5a/ambari-agent/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e508fe5a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
[16/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0b406cbe
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0b406cbe
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0b406cbe
Branch: refs/heads/trunk
Commit: 0b406cbefdbfc8f53b25d203319c964fcf3f93c7
Parents: 84c16c5 42a07f9
Author: Nate Cole <nc...@hortonworks.com>
Authored: Sun Sep 7 16:53:49 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Sun Sep 7 16:53:49 2014 -0400
----------------------------------------------------------------------
.../java/org/apache/ambari/server/orm/entities/ViewEntity.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
[39/50] [abbrv] git commit: AMBARI-7534 - Alerts: Disabling an Alert
Should Propagate to Agent (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7534 - Alerts: Disabling an Alert Should Propagate to Agent (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/10f1f73b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/10f1f73b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/10f1f73b
Branch: refs/heads/trunk
Commit: 10f1f73b810e2c84d5818314ff9d1743c644a3bf
Parents: 7324374
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Sat Sep 27 09:33:43 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Sat Sep 27 09:33:43 2014 -0400
----------------------------------------------------------------------
.../ambari_agent/AlertSchedulerHandler.py | 27 ++++++--
.../python/ambari_agent/alerts/base_alert.py | 12 +++-
.../src/test/python/ambari_agent/TestAlerts.py | 68 +++++++++++++++++++-
.../ambari_agent/dummy_files/definitions.json | 1 +
4 files changed, 101 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/10f1f73b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
index 8dcce50..c645cba 100644
--- a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
+++ b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
@@ -125,7 +125,7 @@ class AlertSchedulerHandler():
uuid_valid = False
for definition in definitions:
- definition_uuid = definition.definition_uuid()
+ definition_uuid = definition.get_uuid()
if scheduled_job.name == definition_uuid:
uuid_valid = True
break
@@ -141,7 +141,7 @@ class AlertSchedulerHandler():
for definition in definitions:
definition_scheduled = False
for scheduled_job in scheduled_jobs:
- definition_uuid = definition.definition_uuid()
+ definition_uuid = definition.get_uuid()
if definition_uuid == scheduled_job.name:
definition_scheduled = True
break
@@ -264,7 +264,16 @@ class AlertSchedulerHandler():
'''
Schedule a definition (callable). Scheduled jobs are given the UUID
as their name so that they can be identified later on.
+ <p/>
+ This function can be called with a definition that is disabled; it will
+ simply NOOP.
'''
+ # NOOP if the definition is disabled; don't schedule it
+ if definition.is_enabled() == False:
+ logger.info("The alert {0} with UUID {1} is disabled and will not be scheduled".format(
+ definition.get_name(),definition.get_uuid()))
+ return
+
job = None
if self.__in_minutes:
@@ -277,10 +286,20 @@ class AlertSchedulerHandler():
# although the documentation states that Job(kwargs) takes a name
# key/value pair, it does not actually set the name; do it manually
if job is not None:
- job.name = definition.definition_uuid()
+ job.name = definition.get_uuid()
logger.info("Scheduling {0} with UUID {1}".format(
- definition.definition_name(), definition.definition_uuid()))
+ definition.get_name(), definition.get_uuid()))
+
+ def get_job_count(self):
+ '''
+ Gets the number of jobs currently scheduled. This is mainly used for
+ test verification of scheduling
+ '''
+ if self.__scheduler is None:
+ return 0
+
+ return len(self.__scheduler.get_jobs())
def main():
args = list(sys.argv)
http://git-wip-us.apache.org/repos/asf/ambari/blob/10f1f73b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index 10dcff8..a3eb404 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -48,14 +48,21 @@ class BaseAlert(object):
return 1 if interval < 1 else interval
- def definition_name(self):
+ def is_enabled(self):
+ '''
+ gets whether the definition is enabled
+ '''
+ return self.alert_meta['enabled']
+
+
+ def get_name(self):
'''
gets the unique name of the alert definition
'''
return self.alert_meta['name']
- def definition_uuid(self):
+ def get_uuid(self):
'''
gets the unique has of the alert definition
'''
@@ -101,6 +108,7 @@ class BaseAlert(object):
data['component'] = self._find_value('componentName')
data['timestamp'] = long(time.time() * 1000)
data['uuid'] = self._find_value('uuid')
+ data['enabled'] = self._find_value('enabled')
if logger.isEnabledFor(logging.DEBUG):
logger.debug("debug alert text: {0}".format(data['text']))
http://git-wip-us.apache.org/repos/asf/ambari/blob/10f1f73b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
index 662d8ee..f9c2ab4 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
@@ -34,9 +34,11 @@ class TestAlerts(TestCase):
def setUp(self):
pass
+
def tearDown(self):
sys.stdout == sys.__stdout__
+
@patch.object(Scheduler, "add_interval_job")
@patch.object(Scheduler, "start")
def test_start(self, aps_add_interval_job_mock, aps_start_mock):
@@ -49,6 +51,7 @@ class TestAlerts(TestCase):
self.assertTrue(aps_add_interval_job_mock.called)
self.assertTrue(aps_start_mock.called)
+
def test_port_alert(self):
json = { "name": "namenode_process",
"service": "HDFS",
@@ -56,6 +59,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "enabled": True,
"uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "PORT",
@@ -80,6 +84,7 @@ class TestAlerts(TestCase):
res = pa.collect()
+
def test_port_alert_no_sub(self):
json = { "name": "namenode_process",
"service": "HDFS",
@@ -87,6 +92,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "enabled": True,
"uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "PORT",
@@ -109,6 +115,7 @@ class TestAlerts(TestCase):
res = pa.collect()
+
def test_script_alert(self):
json = {
"name": "namenode_process",
@@ -117,6 +124,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "enabled": True,
"uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "SCRIPT",
@@ -145,7 +153,8 @@ class TestAlerts(TestCase):
self.assertEquals('WARNING', collector.alerts()[0]['state'])
self.assertEquals('all is not well', collector.alerts()[0]['text'])
-
+
+
@patch.object(MetricAlert, "_load_jmx")
def test_metric_alert(self, ma_load_jmx_mock):
json = {
@@ -155,6 +164,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "enabled": True,
"uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "METRIC",
@@ -201,13 +211,17 @@ class TestAlerts(TestCase):
self.assertEquals('OK', collector.alerts()[0]['state'])
self.assertEquals('ok_arr: 1 3 None', collector.alerts()[0]['text'])
+
def test_reschedule(self):
test_file_path = os.path.join('ambari_agent', 'dummy_files')
test_stack_path = os.path.join('ambari_agent', 'dummy_files')
ash = AlertSchedulerHandler(test_file_path, test_stack_path)
ash.start()
+
+ self.assertEquals(1, ash.get_job_count())
ash.reschedule()
+ self.assertEquals(1, ash.get_job_count())
def test_alert_collector_purge(self):
@@ -217,6 +231,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "enabled": True,
"uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "PORT",
@@ -247,3 +262,54 @@ class TestAlerts(TestCase):
collector.remove_by_uuid('c1f73191-4481-4435-8dae-fd380e4c0be1')
self.assertEquals(0,len(collector.alerts()))
+
+ def test_disabled_definitions(self):
+ test_file_path = os.path.join('ambari_agent', 'dummy_files')
+ test_stack_path = os.path.join('ambari_agent', 'dummy_files')
+
+ ash = AlertSchedulerHandler(test_file_path, test_stack_path)
+ ash.start()
+
+ self.assertEquals(1, ash.get_job_count())
+
+ json = { "name": "namenode_process",
+ "service": "HDFS",
+ "component": "NAMENODE",
+ "label": "NameNode process",
+ "interval": 6,
+ "scope": "host",
+ "enabled": True,
+ "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
+ "source": {
+ "type": "PORT",
+ "uri": "{{hdfs-site/my-key}}",
+ "default_port": 50070,
+ "reporting": {
+ "ok": {
+ "text": "TCP OK - {0:.4f} response time on port {1}"
+ },
+ "critical": {
+ "text": "Could not load process info: {0}"
+ }
+ }
+ }
+ }
+
+ pa = PortAlert(json, json['source'])
+ ash.schedule_definition(pa)
+
+ self.assertEquals(2, ash.get_job_count())
+
+ json['enabled'] = False
+ pa = PortAlert(json, json['source'])
+ ash.schedule_definition(pa)
+
+ # verify disabled alert not scheduled
+ self.assertEquals(2, ash.get_job_count())
+
+ json['enabled'] = True
+ pa = PortAlert(json, json['source'])
+ ash.schedule_definition(pa)
+
+ # verify enabled alert was scheduled
+ self.assertEquals(3, ash.get_job_count())
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/10f1f73b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
index 30973c2..8e01833 100644
--- a/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
+++ b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
@@ -17,6 +17,7 @@
"interval": 6,
"scope": "host",
"uuid": "3f82ae27-fa6a-465b-b77d-67963ac55d2f",
+ "enabled": true,
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.namenode.http-address}}",
[43/50] [abbrv] git commit: AMBARI-7568 - Alerts: An Alert Definition
On Demand Execution (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7568 - Alerts: An Alert Definition On Demand Execution (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/054745d0
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/054745d0
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/054745d0
Branch: refs/heads/trunk
Commit: 054745d06472ef74430f47f09e1c8881f9f9780a
Parents: b9cca71
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Sep 30 17:08:55 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Sep 30 23:12:48 2014 -0400
----------------------------------------------------------------------
.../ambari_agent/AlertSchedulerHandler.py | 62 +++++++++++---
.../src/main/python/ambari_agent/Controller.py | 4 +
.../python/ambari_agent/alerts/collector.py | 12 ++-
.../src/test/python/ambari_agent/TestAlerts.py | 44 +++++++++-
.../ambari/server/agent/AgentCommand.java | 12 ++-
.../server/agent/AlertExecutionCommand.java | 74 +++++++++++++++++
.../ambari/server/agent/HeartBeatHandler.java | 4 +
.../ambari/server/agent/HeartBeatResponse.java | 17 ++++
.../AlertDefinitionResourceProvider.java | 87 ++++++++++++++++++--
.../server/state/alert/AlertDefinitionHash.java | 63 ++++++++++----
.../src/main/resources/properties.json | 3 +-
.../state/alerts/AlertDefinitionHashTest.java | 47 ++++++++++-
.../svccomphost/ServiceComponentHostTest.java | 2 +-
13 files changed, 389 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
index c645cba..5863b23 100644
--- a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
+++ b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
@@ -33,9 +33,9 @@ from alerts.metric_alert import MetricAlert
from alerts.port_alert import PortAlert
from alerts.script_alert import ScriptAlert
-
logger = logging.getLogger()
+
class AlertSchedulerHandler():
make_cachedir = True
@@ -50,6 +50,7 @@ class AlertSchedulerHandler():
'standalone': False
}
+
def __init__(self, cachedir, stacks_dir, in_minutes=True):
self.cachedir = cachedir
self.stacks_dir = stacks_dir
@@ -66,7 +67,7 @@ class AlertSchedulerHandler():
self.__in_minutes = in_minutes
self.__config_maps = {}
-
+
def update_definitions(self, alert_commands, reschedule_jobs=False):
''' updates the persisted definitions and restarts the scheduler '''
@@ -76,11 +77,11 @@ class AlertSchedulerHandler():
if reschedule_jobs:
self.reschedule()
-
+
def __make_function(self, alert_def):
return lambda: alert_def.collect()
-
+
def start(self):
''' loads definitions from file and starts the scheduler '''
@@ -102,7 +103,7 @@ class AlertSchedulerHandler():
self.__scheduler.start()
-
+
def stop(self):
if not self.__scheduler is None:
self.__scheduler.shutdown(wait=False)
@@ -159,7 +160,7 @@ class AlertSchedulerHandler():
''' gets the collector for reporting to the server '''
return self._collector
-
+
def __load_definitions(self):
''' loads all alert commands from the file. all clusters are stored in one file '''
definitions = []
@@ -184,13 +185,11 @@ class AlertSchedulerHandler():
configmap = command_json['configurations']
for definition in command_json['alertDefinitions']:
- obj = self.__json_to_callable(definition)
+ obj = self.__json_to_callable(clusterName, hostName, definition)
if obj is None:
continue
- obj.set_cluster(clusterName, hostName)
-
# get the config values for the alerts 'lookup keys',
# eg: hdfs-site/dfs.namenode.http-address : host_and_port
vals = self.__find_config_values(configmap, obj.get_lookup_keys())
@@ -202,7 +201,8 @@ class AlertSchedulerHandler():
return definitions
- def __json_to_callable(self, json_definition):
+
+ def __json_to_callable(self, clusterName, hostName, json_definition):
'''
converts the json that represents all aspects of a definition
and makes an object that extends BaseAlert that is used for individual
@@ -223,8 +223,12 @@ class AlertSchedulerHandler():
source['stacks_dir'] = self.stacks_dir
alert = ScriptAlert(json_definition, source)
+ if alert is not None:
+ alert.set_cluster(clusterName, hostName)
+
return alert
-
+
+
def __find_config_values(self, configmap, obj_keylist):
''' finds templated values in the configuration map provided by the server '''
if configmap is None:
@@ -242,7 +246,8 @@ class AlertSchedulerHandler():
pass
return result
-
+
+
def update_configurations(self, commands):
'''
when an execution command comes in, update any necessary values.
@@ -291,6 +296,7 @@ class AlertSchedulerHandler():
logger.info("Scheduling {0} with UUID {1}".format(
definition.get_name(), definition.get_uuid()))
+
def get_job_count(self):
'''
Gets the number of jobs currently scheduled. This is mainly used for
@@ -299,7 +305,37 @@ class AlertSchedulerHandler():
if self.__scheduler is None:
return 0
- return len(self.__scheduler.get_jobs())
+ return len(self.__scheduler.get_jobs())
+
+
+ def execute_alert(self, execution_commands):
+ '''
+ Executes an alert immediately, ignoring any scheduled jobs. The existing
+ jobs remain untouched. The result of this is stored in the alert
+ collector for tranmission during the next heartbeat
+ '''
+ if self.__scheduler is None or execution_commands is None:
+ return
+
+ for execution_command in execution_commands:
+ try:
+ alert_definition = execution_command['alertDefinition']
+
+ clusterName = '' if not 'clusterName' in execution_command else execution_command['clusterName']
+ hostName = '' if not 'hostName' in execution_command else execution_command['hostName']
+
+ alert = self.__json_to_callable(clusterName, hostName, alert_definition)
+
+ if alert is None:
+ continue
+
+ logger.info("Executing on-demand alert {0} ({1})".format(alert.get_name(),
+ alert.get_uuid()))
+
+ alert.set_helpers(self._collector, self.__config_maps[clusterName])
+ alert.collect()
+ except:
+ logger.exception("Unable to execute the alert outside of the job scheduler")
def main():
args = list(sys.argv)
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-agent/src/main/python/ambari_agent/Controller.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/Controller.py b/ambari-agent/src/main/python/ambari_agent/Controller.py
index 18df06e..1f9471d 100644
--- a/ambari-agent/src/main/python/ambari_agent/Controller.py
+++ b/ambari-agent/src/main/python/ambari_agent/Controller.py
@@ -262,6 +262,10 @@ class Controller(threading.Thread):
if 'alertDefinitionCommands' in response.keys():
self.alert_scheduler_handler.update_definitions(response['alertDefinitionCommands'], True)
pass
+
+ if 'alertExecutionCommands' in response.keys():
+ self.alert_scheduler_handler.execute_alert(response['alertExecutionCommands'])
+ pass
if "true" == response['restartAgent']:
logger.error("Received the restartAgent command")
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-agent/src/main/python/ambari_agent/alerts/collector.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/collector.py b/ambari-agent/src/main/python/ambari_agent/alerts/collector.py
index 9943211..f2c4f72 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/collector.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/collector.py
@@ -28,13 +28,15 @@ class AlertCollector():
'''
def __init__(self):
self.__buckets = {}
-
+
+
def put(self, cluster, alert):
if not cluster in self.__buckets:
self.__buckets[cluster] = {}
self.__buckets[cluster][alert['name']] = alert
-
+
+
def remove(self, cluster, alert_name):
'''
Removes the alert with the specified name if it exists in the dictionary
@@ -43,7 +45,8 @@ class AlertCollector():
return
del self.__buckets[cluster][alert_name]
-
+
+
def remove_by_uuid(self, alert_uuid):
'''
Removes the alert with the specified uuid if it exists in the dictionary
@@ -53,7 +56,8 @@ class AlertCollector():
alert = alert_map[alert_name]
if alert['uuid'] == alert_uuid:
self.remove(cluster, alert_name)
-
+
+
def alerts(self):
alerts = []
for clustermap in self.__buckets.values()[:]:
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
index f9c2ab4..1bacf24 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
@@ -312,4 +312,46 @@ class TestAlerts(TestCase):
ash.schedule_definition(pa)
# verify enabled alert was scheduled
- self.assertEquals(3, ash.get_job_count())
\ No newline at end of file
+ self.assertEquals(3, ash.get_job_count())
+
+ def test_immediate_alert(self):
+ test_file_path = os.path.join('ambari_agent', 'dummy_files')
+ test_stack_path = os.path.join('ambari_agent', 'dummy_files')
+
+ ash = AlertSchedulerHandler(test_file_path, test_stack_path)
+ ash.start()
+
+ self.assertEquals(1, ash.get_job_count())
+ self.assertEquals(0, len(ash._collector.alerts()))
+
+ execution_commands = [ {
+ "clusterName": "c1",
+ "hostName": "c6401.ambari.apache.org",
+ "alertDefinition": {
+ "name": "namenode_process",
+ "service": "HDFS",
+ "component": "NAMENODE",
+ "label": "NameNode process",
+ "interval": 6,
+ "scope": "host",
+ "enabled": True,
+ "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
+ "source": {
+ "type": "PORT",
+ "uri": "{{hdfs-site/my-key}}",
+ "default_port": 50070,
+ "reporting": {
+ "ok": {
+ "text": "TCP OK - {0:.4f} response time on port {1}"
+ },
+ "critical": {
+ "text": "Could not load process info: {0}"
+ }
+ }
+ }
+ }
+ } ]
+
+ # execute the alert immediately and verify that the collector has the result
+ ash.execute_alert(execution_commands)
+ self.assertEquals(1, len(ash._collector.alerts()))
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentCommand.java
index 6e8aab1..e2f013d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentCommand.java
@@ -53,7 +53,17 @@ public abstract class AgentCommand {
STATUS_COMMAND,
CANCEL_COMMAND,
REGISTRATION_COMMAND,
- ALERT_DEFINITION_COMMAND
+
+ /**
+ * Sends alert definitions to an agent which will refresh all alerts running
+ * on that host.
+ */
+ ALERT_DEFINITION_COMMAND,
+
+ /**
+ * A single alert that should be run immediately.
+ */
+ ALERT_EXECUTION_COMMAND
}
public AgentCommandType getCommandType() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertExecutionCommand.java
new file mode 100644
index 0000000..b0781da
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertExecutionCommand.java
@@ -0,0 +1,74 @@
+/**
+ * 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.ambari.server.agent;
+
+import org.apache.ambari.server.state.alert.AlertDefinition;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * The {@link AlertExecutionCommand} is used to instruct an agent to run an
+ * alert immediately and return the result in the next heartbeat. This does not
+ * affect any existing jobs and does cause the job for the executed alert to
+ * reset its interval.
+ */
+public class AlertExecutionCommand extends AgentCommand {
+
+ /**
+ * The name of the cluster.
+ */
+ @SerializedName("clusterName")
+ private final String m_clusterName;
+
+ /**
+ * The agent hostname.
+ */
+ @SerializedName("hostName")
+ private final String m_hostName;
+
+ /**
+ * The definition to run.
+ */
+ @SerializedName("alertDefinition")
+ private final AlertDefinition m_definition;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterName
+ * the name of the cluster (not {@code null}).
+ * @param hostName
+ * the name of the host (not {@code null}).
+ * @param definition
+ * the definition to run (not {@code null}).
+ */
+ public AlertExecutionCommand(String clusterName, String hostName, AlertDefinition definition) {
+ super(AgentCommandType.ALERT_EXECUTION_COMMAND);
+ m_clusterName = clusterName;
+ m_hostName = hostName;
+ m_definition = definition;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AgentCommandType getCommandType() {
+ return AgentCommandType.ALERT_EXECUTION_COMMAND;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index c826153..f735fc5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -621,6 +621,10 @@ public class HeartBeatHandler {
response.addAlertDefinitionCommand((AlertDefinitionCommand) ac);
break;
}
+ case ALERT_EXECUTION_COMMAND: {
+ response.addAlertExecutionCommand((AlertExecutionCommand) ac);
+ break;
+ }
default:
LOG.error("There is no action for agent command ="
+ ac.getCommandType().name());
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatResponse.java
index 1e9dc12..56b4f18 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatResponse.java
@@ -50,6 +50,13 @@ public class HeartBeatResponse {
@SerializedName("alertDefinitionCommands")
private List<AlertDefinitionCommand> alertDefinitionCommands = null;
+ /**
+ * {@link AlertExecutionCommand}s are used to execute an alert job
+ * immediately.
+ */
+ @SerializedName("alertExecutionCommands")
+ private List<AlertExecutionCommand> alertExecutionCommands = null;
+
@SerializedName("registrationCommand")
private RegistrationCommand registrationCommand;
@@ -159,6 +166,16 @@ public class HeartBeatResponse {
alertDefinitionCommands.add(command);
}
+ public void addAlertExecutionCommand(AlertExecutionCommand command) {
+ // commands are added here when they are taken off the queue; there should
+ // be no thread contention and thus no worry about locks for the null check
+ if (null == alertExecutionCommands) {
+ alertExecutionCommands = new ArrayList<AlertExecutionCommand>();
+ }
+
+ alertExecutionCommands.add(command);
+ }
+
@Override
public String toString() {
StringBuilder buffer = new StringBuilder("HeartBeatResponse{");
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
index e2d2837..e4aa222 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
@@ -28,6 +28,8 @@ import java.util.Set;
import java.util.UUID;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.agent.ActionQueue;
+import org.apache.ambari.server.agent.AlertExecutionCommand;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -43,6 +45,8 @@ import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
import org.apache.ambari.server.state.alert.AlertDefinitionHash;
import org.apache.ambari.server.state.alert.Scope;
import org.apache.ambari.server.state.alert.SourceType;
@@ -77,6 +81,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
protected static final String ALERT_DEF_SOURCE_REPORTING_WARNING = "AlertDefinition/source/reporting/warning";
protected static final String ALERT_DEF_SOURCE_REPORTING_CRITICAL = "AlertDefinition/source/reporting/critical";
+ protected static final String ALERT_DEF_ACTION_RUN_NOW = "AlertDefinition/run_now";
private static Set<String> pkPropertyIds = new HashSet<String>(
Arrays.asList(ALERT_DEF_ID, ALERT_DEF_NAME));
@@ -88,12 +93,26 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
private static AlertDefinitionHash alertDefinitionHash;
/**
+ * Used for coercing an {@link AlertDefinitionEntity} to an
+ * {@link AlertDefinition}.
+ */
+ private static AlertDefinitionFactory definitionFactory;
+
+ /**
+ * Used to enqueue commands to send to the agents when running an alert
+ * on-demand.
+ */
+ private static ActionQueue actionQueue;
+
+ /**
* @param instance
*/
@Inject
public static void init(Injector injector) {
alertDefinitionDAO = injector.getInstance(AlertDefinitionDAO.class);
alertDefinitionHash = injector.getInstance(AlertDefinitionHash.class);
+ definitionFactory = injector.getInstance(AlertDefinitionFactory.class);
+ actionQueue = injector.getInstance(ActionQueue.class);
}
AlertDefinitionResourceProvider(Set<String> propertyIds,
@@ -199,9 +218,24 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
NoSuchResourceException, NoSuchParentResourceException {
String clusterName = null;
- Set<String> invalidatedHosts = new HashSet<String>();
Clusters clusters = getManagementController().getClusters();
+ // check the predicate to see if there is a reques to run
+ // the alert definition immediately
+ if( null != predicate ){
+ Set<Map<String,Object>> predicateMaps = getPropertyMaps(predicate);
+ for (Map<String, Object> propertyMap : predicateMaps) {
+ String runNow = (String) propertyMap.get(ALERT_DEF_ACTION_RUN_NOW);
+ if (null != runNow) {
+ if (Boolean.valueOf(runNow) == Boolean.TRUE) {
+ scheduleImmediateAlert(propertyMap);
+ }
+ }
+ }
+ }
+
+ // if an AlertDefinition property body was specified, perform the update\
+ Set<String> invalidatedHosts = new HashSet<String>();
for (Map<String, Object> requestPropMap : request.getProperties()) {
for (Map<String, Object> propertyMap : getPropertyMaps(requestPropMap, predicate)) {
String stringId = (String) propertyMap.get(ALERT_DEF_ID);
@@ -234,10 +268,13 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
}
}
- // build alert definition commands for all agent hosts affected
- alertDefinitionHash.enqueueAgentCommands(clusterName, invalidatedHosts);
-
- notifyUpdate(Resource.Type.AlertDefinition, request, predicate);
+ // build alert definition commands for all agent hosts affected; only
+ // update agents and broadcast update event if there are actual invalidated
+ // hosts
+ if (invalidatedHosts.size() > 0) {
+ alertDefinitionHash.enqueueAgentCommands(clusterName, invalidatedHosts);
+ notifyUpdate(Resource.Type.AlertDefinition, request, predicate);
+ }
return getRequestStatus(null);
}
@@ -501,4 +538,44 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
return resource;
}
+
+ /**
+ * Extracts an {@link AlertDefinitionEntity} from the property map and
+ * enqueues an {@link AlertExecutionCommand} for every host that should re-run
+ * the specified definition.
+ *
+ * @param propertyMap
+ */
+ private void scheduleImmediateAlert(Map<String, Object> propertyMap) {
+ Clusters clusters = getManagementController().getClusters();
+ String stringId = (String) propertyMap.get(ALERT_DEF_ID);
+ long id = Long.parseLong(stringId);
+
+ AlertDefinitionEntity entity = alertDefinitionDAO.findById(id);
+ if (null == entity) {
+ LOG.error("Unable to lookup alert definition with ID {}", id);
+ return;
+ }
+
+ Cluster cluster = null;
+ try {
+ cluster = clusters.getClusterById(entity.getClusterId());
+ } catch (AmbariException ambariException) {
+ LOG.error("Unable to lookup cluster with ID {}", entity.getClusterId(),
+ ambariException);
+ return;
+ }
+
+ Set<String> hostNames = alertDefinitionHash.getAssociatedHosts(cluster,
+ entity.getDefinitionName(), entity.getServiceName(),
+ entity.getComponentName());
+
+ for (String hostName : hostNames) {
+ AlertDefinition definition = definitionFactory.coerce(entity);
+ AlertExecutionCommand command = new AlertExecutionCommand(
+ cluster.getClusterName(), hostName, definition);
+
+ actionQueue.enqueue(hostName, command);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
index 35d7742..10cd54a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
@@ -309,16 +309,13 @@ public class AlertDefinitionHash {
*/
public Set<String> invalidateHosts(long clusterId, String definitionName,
String definitionServiceName, String definitionComponentName) {
- Set<String> invalidatedHosts = new HashSet<String>();
Cluster cluster = null;
- Map<String, Host> hosts = null;
String clusterName = null;
try {
cluster = m_clusters.getClusterById(clusterId);
if (null != cluster) {
clusterName = cluster.getClusterName();
- hosts = m_clusters.getHostsForCluster(clusterName);
}
if (null == cluster) {
@@ -329,16 +326,55 @@ public class AlertDefinitionHash {
}
if (null == cluster) {
- return invalidatedHosts;
+ return Collections.emptySet();
+ }
+
+ // determine which hosts in the cluster would be affected by a change
+ // to the specified definition
+ Set<String> affectedHosts = getAssociatedHosts(cluster, definitionName,
+ definitionServiceName, definitionComponentName);
+
+ // invalidate all returned hosts
+ for (String hostName : affectedHosts) {
+ invalidate(clusterName, hostName);
+ }
+
+ return affectedHosts;
+ }
+
+ /**
+ * Gets the hosts that are associated with the specified definition. Each host
+ * returned is expected to be capable of running the alert. A change to the
+ * definition would entail contacting each returned host and invalidating
+ * their current alert definitions.
+ *
+ * @param cluster
+ * @param definitionName
+ * @param definitionServiceName
+ * @param definitionComponentName
+ * @return a set of all associated hosts or an empty set, never {@code null}.
+ */
+ public Set<String> getAssociatedHosts(Cluster cluster, String definitionName,
+ String definitionServiceName, String definitionComponentName) {
+
+ Map<String, Host> hosts = null;
+ String clusterName = cluster.getClusterName();
+ Set<String> affectedHosts = new HashSet<String>();
+
+ try {
+ hosts = m_clusters.getHostsForCluster(clusterName);
+ } catch (AmbariException ambariException) {
+ LOG.error("Unable to lookup hosts for cluster named {}", clusterName,
+ ambariException);
+
+ return affectedHosts;
}
// intercept host agent alerts; they affect all hosts
if (Services.AMBARI.equals(definitionServiceName)
&& Components.AMBARI_AGENT.equals(definitionComponentName)) {
-
- invalidateAll();
- invalidatedHosts.addAll(hosts.keySet());
- return invalidatedHosts;
+ affectedHosts.addAll(hosts.keySet());
+ return affectedHosts;
}
// find all hosts that have the matching service and component
@@ -354,8 +390,7 @@ public class AlertDefinitionHash {
String componentName = component.getServiceComponentName();
if (serviceName.equals(definitionServiceName)
&& componentName.equals(definitionComponentName)) {
- invalidate(clusterName, hostName);
- invalidatedHosts.add(hostName);
+ affectedHosts.add(hostName);
}
}
}
@@ -367,7 +402,7 @@ public class AlertDefinitionHash {
LOG.warn("The alert definition {} has an unknown service of {}",
definitionName, definitionServiceName);
- return invalidatedHosts;
+ return affectedHosts;
}
// get all master components of the definition's service; any hosts that
@@ -379,15 +414,14 @@ public class AlertDefinitionHash {
Map<String, ServiceComponentHost> componentHosts = component.getValue().getServiceComponentHosts();
if (null != componentHosts) {
for (String componentHost : componentHosts.keySet()) {
- invalidate(clusterName, componentHost);
- invalidatedHosts.add(componentHost);
+ affectedHosts.add(componentHost);
}
}
}
}
}
- return invalidatedHosts;
+ return affectedHosts;
}
/**
@@ -462,6 +496,7 @@ public class AlertDefinitionHash {
// before the next heartbeat, there would be several commands that would
// force the agents to reschedule their alerts more than once
m_actionQueue.dequeue(hostName, AgentCommandType.ALERT_DEFINITION_COMMAND);
+ m_actionQueue.dequeue(hostName, AgentCommandType.ALERT_EXECUTION_COMMAND);
m_actionQueue.enqueue(hostName, command);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index 3893f39..96f44c4 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -447,7 +447,8 @@
"AlertDefinition/interval",
"AlertDefinition/enabled",
"AlertDefinition/scope",
- "AlertDefinition/source"
+ "AlertDefinition/source",
+ "AlertDefinition/run_now"
],
"AlertGroup": [
"AlertGroup/id",
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionHashTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionHashTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionHashTest.java
index 1cb6eac..412b4d3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionHashTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionHashTest.java
@@ -25,6 +25,7 @@ import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -32,11 +33,16 @@ import java.util.UUID;
import junit.framework.TestCase;
+import org.apache.ambari.server.agent.ActionQueue;
+import org.apache.ambari.server.agent.AlertDefinitionCommand;
+import org.apache.ambari.server.agent.AlertExecutionCommand;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponent;
@@ -344,6 +350,35 @@ public class AlertDefinitionHashTest extends TestCase {
assertEquals(expected, m_hash.getHash(CLUSTERNAME, HOSTNAME));
}
+ @Test
+ public void testActionQueueInvalidation() throws Exception{
+ ActionQueue actionQueue = m_injector.getInstance(ActionQueue.class);
+
+ AlertDefinitionCommand definitionCommand1 = new AlertDefinitionCommand(
+ CLUSTERNAME, HOSTNAME, "12345", null);
+
+ AlertDefinitionCommand definitionCommand2 = new AlertDefinitionCommand(
+ CLUSTERNAME, "anotherHost", "67890", null);
+
+ AlertExecutionCommand executionCommand = new AlertExecutionCommand(
+ CLUSTERNAME, HOSTNAME, null);
+
+ actionQueue.enqueue(HOSTNAME, definitionCommand1);
+ actionQueue.enqueue(HOSTNAME, executionCommand);
+ actionQueue.enqueue("anotherHost", definitionCommand2);
+
+ assertEquals(2, actionQueue.size(HOSTNAME));
+ assertEquals(1, actionQueue.size("anotherHost"));
+
+ Set<String> hosts = new HashSet<String>();
+ hosts.add(HOSTNAME);
+
+ // should invalidate both alert commands, and add a new definition command
+ m_hash.enqueueAgentCommands(CLUSTERNAME, hosts);
+ assertEquals(1, actionQueue.size(HOSTNAME));
+ assertEquals(1, actionQueue.size("anotherHost"));
+ }
+
/**
*
*/
@@ -353,12 +388,20 @@ public class AlertDefinitionHashTest extends TestCase {
*/
@Override
public void configure(Binder binder) {
+ Cluster cluster = EasyMock.createNiceMock(Cluster.class);
+ EasyMock.expect(cluster.getAllConfigs()).andReturn(
+ new ArrayList<Config>()).anyTimes();
+
binder.bind(Clusters.class).toInstance(
EasyMock.createNiceMock(Clusters.class));
- binder.bind(Cluster.class).toInstance(
- EasyMock.createNiceMock(Cluster.class));
+
+ binder.bind(Cluster.class).toInstance(cluster);
+
binder.bind(AlertDefinitionDAO.class).toInstance(
EasyMock.createNiceMock(AlertDefinitionDAO.class));
+
+ binder.bind(ConfigHelper.class).toInstance(
+ EasyMock.createNiceMock(ConfigHelper.class));
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/054745d0/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
index 79ae350..5410ee3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
@@ -125,7 +125,7 @@ public class ServiceComponentHostTest {
String svcComponent,
String hostName, boolean isClient) throws AmbariException{
Cluster c = clusters.getCluster("C1");
-
+ Assert.assertNotNull(c.getConfigGroups());
return createNewServiceComponentHost(c, svc, svcComponent, hostName);
}
[12/50] [abbrv] git commit: AMBARI-7118. Alerts: populate incoming
alert data to history and current (ncole)
Posted by jo...@apache.org.
AMBARI-7118. Alerts: populate incoming alert data to history and current (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/0de98b02
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/0de98b02
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/0de98b02
Branch: refs/heads/trunk
Commit: 0de98b0207b48007f39610f8dc8c0d13de6e7d92
Parents: 03a5be1
Author: Nate Cole <nc...@hortonworks.com>
Authored: Tue Sep 2 16:24:51 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Wed Sep 3 07:59:40 2014 -0400
----------------------------------------------------------------------
.../ambari_agent/AlertSchedulerHandler.py | 2 -
.../python/ambari_agent/alerts/base_alert.py | 2 +
.../ambari/server/agent/HeartBeatHandler.java | 13 ++
.../apache/ambari/server/orm/dao/AlertsDAO.java | 14 ++
.../server/orm/entities/AlertCurrentEntity.java | 4 +-
.../org/apache/ambari/server/state/Alert.java | 21 ++-
.../server/state/cluster/AlertDataManager.java | 110 +++++++++++
.../server/orm/dao/AlertDefinitionDAOTest.java | 2 +-
.../ambari/server/orm/dao/AlertsDAOTest.java | 14 ++
.../state/cluster/AlertDataManagerTest.java | 181 +++++++++++++++++++
10 files changed, 358 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
index cc5be92..e987dae 100644
--- a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
+++ b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
@@ -57,8 +57,6 @@ class AlertSchedulerHandler():
except:
logger.critical("Could not create the cache directory {0}".format(cachedir))
pass
-
-
self.__scheduler = Scheduler(AlertSchedulerHandler.APS_CONFIG)
self.__in_minutes = in_minutes
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index bf8ada6..adb872a 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -20,6 +20,7 @@ limitations under the License.
import logging
import re
+import time
import traceback
logger = logging.getLogger()
@@ -78,6 +79,7 @@ class BaseAlert(object):
data['cluster'] = self.cluster
data['service'] = self._find_value('serviceName')
data['component'] = self._find_value('componentName')
+ data['timestamp'] = long(time.time() * 1000)
self.collector.put(self.cluster, data)
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index d0d5a13..492d832 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -60,6 +60,7 @@ import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.AlertDefinitionHash;
+import org.apache.ambari.server.state.cluster.AlertDataManager;
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
import org.apache.ambari.server.state.host.HostHealthyHeartbeatEvent;
import org.apache.ambari.server.state.host.HostRegistrationRequestEvent;
@@ -114,6 +115,9 @@ public class HeartBeatHandler {
@Inject
private AlertDefinitionHash alertDefinitionHash;
+
+ @Inject
+ private AlertDataManager alertManager;
private Map<String, Long> hostResponseIds = new ConcurrentHashMap<String, Long>();
@@ -232,6 +236,15 @@ public class HeartBeatHandler {
if (null == hostname || null == heartbeat) {
return;
}
+
+ if (null != heartbeat.getAlerts()) {
+ for (Alert alert : heartbeat.getAlerts()) {
+ if (null == alert.getHost())
+ alert.setHost(hostname);
+ Cluster cluster = clusterFsm.getCluster(alert.getCluster());
+ alertManager.add(cluster.getClusterId(), alert);
+ }
+ }
for (Cluster cluster : clusterFsm.getClustersForHost(hostname)) {
cluster.addAlerts(heartbeat.getNodeStatus().getAlerts());
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index f2a5886..b43b5b1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -239,6 +239,20 @@ public class AlertsDAO {
return daoUtils.selectList(query);
}
+
+ @RequiresSession
+ public AlertCurrentEntity findCurrentByHostAndName(long clusterId, String hostName,
+ String alertName) {
+
+ TypedQuery<AlertCurrentEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertCurrentEntity.findByHostAndName", AlertCurrentEntity.class);
+
+ query.setParameter("clusterId", Long.valueOf(clusterId));
+ query.setParameter("hostName", hostName);
+ query.setParameter("definitionName", alertName);
+
+ return daoUtils.selectOne(query);
+ }
/**
* Removes alert history and current alerts for the specified alert defintiion
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
index cde61f2..31b1673 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.server.orm.entities;
+import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
@@ -48,6 +49,7 @@ import org.apache.ambari.server.state.MaintenanceState;
@NamedQuery(name = "AlertCurrentEntity.findAll", query = "SELECT alert FROM AlertCurrentEntity alert"),
@NamedQuery(name = "AlertCurrentEntity.findByService", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.serviceName = :serviceName"),
@NamedQuery(name = "AlertCurrentEntity.findByHost", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.hostName = :hostName"),
+ @NamedQuery(name = "AlertCurrentEntity.findByHostAndName", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.alertDefinition.definitionName = :definitionName AND history.hostName = :hostName"),
@NamedQuery(name = "AlertCurrentEntity.removeByHistoryId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.alertId = :historyId"),
@NamedQuery(name = "AlertCurrentEntity.removeByDefinitionId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertDefinition.definitionId = :definitionId") })
public class AlertCurrentEntity {
@@ -70,7 +72,7 @@ public class AlertCurrentEntity {
/**
* Unidirectional one-to-one association to {@link AlertHistoryEntity}
*/
- @OneToOne
+ @OneToOne(cascade = { CascadeType.PERSIST })
@JoinColumn(name = "history_id", unique = true, nullable = false)
private AlertHistoryEntity alertHistory;
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
index e39b900..7b8aabd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
@@ -22,6 +22,7 @@ import org.codehaus.jackson.annotate.JsonProperty;
* An alert represents a problem or notice for a cluster.
*/
public class Alert {
+ private String cluster = null;
private String name = null;
private String instance = null;
private String service = null;
@@ -30,6 +31,7 @@ public class Alert {
private AlertState state = AlertState.UNKNOWN;
private String label = null;
private String text = null;
+ private long timestamp = 0L;
/**
@@ -162,7 +164,23 @@ public class Alert {
public void setState(AlertState state) {
this.state = state;
}
-
+
+ @JsonProperty("timestamp")
+ public void setTimestamp(long ts) {
+ timestamp = ts;
+ }
+
+ @JsonProperty("timestamp")
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ /**
+ * @return
+ */
+ public String getCluster() {
+ return cluster;
+ }
@Override
public int hashCode() {
@@ -224,6 +242,7 @@ public class Alert {
sb.append('}');
return sb.toString();
}
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
new file mode 100644
index 0000000..4670d3b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
@@ -0,0 +1,110 @@
+/**
+ * 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.ambari.server.state.cluster;
+
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.state.Alert;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * The AlertManager is reponsible for tracking all alerts generated for a cluster.
+ */
+@Singleton
+public class AlertDataManager {
+
+ @Inject
+ private AlertsDAO m_alertsDao;
+ @Inject
+ private AlertDefinitionDAO m_definitionDao;
+
+
+ AlertDataManager() {
+ }
+
+ /**
+ * Adds an alert. Checks for a new state before creating a new history record.
+ *
+ * @param clusterId the id for the cluster
+ * @param alert the alert to add
+ */
+ public void add(long clusterId, Alert alert) {
+
+ AlertCurrentEntity current = m_alertsDao.findCurrentByHostAndName(clusterId,
+ alert.getHost(), alert.getName());
+
+ if (null == current) {
+ AlertDefinitionEntity definition = m_definitionDao.findByName(clusterId,
+ alert.getName());
+
+ AlertHistoryEntity history = createHistory(clusterId, definition, alert);
+
+ current = new AlertCurrentEntity();
+ current.setAlertHistory(history);
+ current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
+ current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
+
+ m_alertsDao.create(current);
+
+ } else if (alert.getState() == current.getAlertHistory().getAlertState()) {
+ current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
+
+ m_alertsDao.merge(current);
+ } else {
+ // insert history, update current
+ AlertHistoryEntity history = createHistory(clusterId,
+ current.getAlertHistory().getAlertDefinition(), alert);
+
+ current.setAlertHistory(history);
+ current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
+ current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
+
+ m_alertsDao.merge(current);
+ }
+
+ }
+ /**
+ * Convenience to create a new alert.
+ * @param clusterId the cluster id
+ * @param definition the definition
+ * @param alert the alert data
+ * @return the new history record
+ */
+ private AlertHistoryEntity createHistory(long clusterId, AlertDefinitionEntity definition, Alert alert) {
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setAlertDefinition(definition);
+ history.setAlertInstance(alert.getInstance());
+ history.setAlertLabel(alert.getLabel());
+ history.setAlertState(alert.getState());
+ history.setAlertText(alert.getText());
+ history.setAlertTimestamp(Long.valueOf(alert.getTimestamp()));
+ history.setClusterId(Long.valueOf(clusterId));
+ history.setComponentName(alert.getComponent());
+ history.setHostName(alert.getHost());
+ history.setServiceName(alert.getService());
+
+ return history;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index a7cc066..b8af7c1 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -287,7 +287,7 @@ public class AlertDefinitionDAOTest {
history.setAlertState(AlertState.OK);
history.setAlertText("Alert Text");
history.setAlertTimestamp(calendar.getTimeInMillis());
- alertsDao.create(history);
+// alertsDao.create(history);
AlertCurrentEntity current = new AlertCurrentEntity();
current.setAlertHistory(history);
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index caeada1..4500c1c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -21,6 +21,7 @@ package org.apache.ambari.server.orm.dao;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import java.util.ArrayList;
import java.util.Calendar;
@@ -104,6 +105,7 @@ public class AlertsDAOTest {
history.setAlertLabel(definition.getDefinitionName() + " " + i);
history.setAlertText(definition.getDefinitionName() + " " + i);
history.setAlertTimestamp(calendar.getTimeInMillis());
+ history.setHostName("h1");
history.setAlertState(AlertState.OK);
if (i == 0 || i == 5) {
@@ -261,4 +263,16 @@ public class AlertsDAOTest {
assertNotNull(history);
assertEquals(0, history.size());
}
+
+ @Test
+ public void testFindCurrentByHostAndName() throws Exception {
+ AlertCurrentEntity entity = dao.findCurrentByHostAndName(clusterId.longValue(), "h2", "Alert Definition 1");
+ assertNull(entity);
+
+ entity = dao.findCurrentByHostAndName(clusterId.longValue(), "h1", "Alert Definition 1");
+
+ assertNotNull(entity);
+ assertNotNull(entity.getAlertHistory());
+ assertNotNull(entity.getAlertHistory().getAlertDefinition());
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/0de98b02/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
new file mode 100644
index 0000000..eae1de6
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
@@ -0,0 +1,181 @@
+/**
+ * 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.ambari.server.state.cluster;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.OrmTestHelper;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.alert.Scope;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+
+/**
+ * Tests the alert manager.
+ */
+public class AlertDataManagerTest {
+
+ private static final String ALERT_DEFINITION = "Alert Definition 1";
+ private static final String SERVICE = "service1";
+ private static final String COMPONENT = "component1";
+ private static final String HOST1 = "h1";
+ private static final String HOST2 = "h2";
+ private static final String ALERT_LABEL = "My Label";
+
+ private Long clusterId;
+ private Injector injector;
+ private OrmTestHelper helper;
+ private AlertsDAO dao;
+
+ @Before
+ public void setup() throws Exception {
+ injector = Guice.createInjector(new InMemoryDefaultTestModule());
+ injector.getInstance(GuiceJpaInitializer.class);
+ helper = injector.getInstance(OrmTestHelper.class);
+ clusterId = helper.createCluster();
+ dao = injector.getInstance(AlertsDAO.class);
+ AlertDefinitionDAO definitionDao = injector.getInstance(AlertDefinitionDAO.class);
+
+ // create 5 definitions
+ for (int i = 0; i < 5; i++) {
+ AlertDefinitionEntity definition = new AlertDefinitionEntity();
+ definition.setDefinitionName("Alert Definition " + i);
+ definition.setServiceName("Service " + i);
+ definition.setComponentName(null);
+ definition.setClusterId(clusterId);
+ definition.setHash(UUID.randomUUID().toString());
+ definition.setScheduleInterval(Integer.valueOf(60));
+ definition.setScope(Scope.SERVICE);
+ definition.setSource("Source " + i);
+ definition.setSourceType("SCRIPT");
+ definitionDao.create(definition);
+ }
+
+ }
+
+ @After
+ public void teardown() {
+ injector.getInstance(PersistService.class).stop();
+ injector = null;
+ }
+
+ @Test
+ public void testAlertRecords() {
+
+ Alert alert1 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST1, AlertState.OK);
+ alert1.setLabel(ALERT_LABEL);
+ alert1.setText("Component component1 is OK");
+ alert1.setTimestamp(1L);
+
+ Alert alert2 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST2, AlertState.CRITICAL);
+ alert2.setLabel(ALERT_LABEL);
+ alert2.setText("Component component2 is not OK");
+
+ AlertDataManager am = injector.getInstance(AlertDataManager.class);
+
+ am.add(clusterId.longValue(), alert1);
+ am.add(clusterId.longValue(), alert2);
+
+ List<AlertCurrentEntity> allCurrent = dao.findCurrentByService(clusterId.longValue(), SERVICE);
+ assertEquals(2, allCurrent.size());
+
+ List<AlertHistoryEntity> allHistory = dao.findAll(clusterId.longValue());
+ assertEquals(2, allHistory.size());
+
+ AlertCurrentEntity current = dao.findCurrentByHostAndName(clusterId.longValue(), HOST1, ALERT_DEFINITION);
+ assertNotNull(current);
+ assertEquals(HOST1, current.getAlertHistory().getHostName());
+ assertEquals(ALERT_DEFINITION, current.getAlertHistory().getAlertDefinition().getDefinitionName());
+ assertEquals(ALERT_LABEL, current.getAlertHistory().getAlertLabel());
+ assertEquals("Component component1 is OK", current.getAlertHistory().getAlertText());
+ assertEquals(current.getAlertHistory().getAlertState(), AlertState.OK);
+ assertEquals(1L, current.getOriginalTimestamp().longValue());
+ assertEquals(1L, current.getLatestTimestamp().longValue());
+
+ Long currentId = current.getAlertId();
+ Long historyId = current.getAlertHistory().getAlertId();
+
+ // no new history since the state is the same
+ Alert alert3 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST1, AlertState.OK);
+ alert3.setLabel(ALERT_LABEL);
+ alert3.setText("Component component1 is OK");
+ alert3.setTimestamp(2L);
+ am.add(clusterId.longValue(), alert3);
+
+ current = dao.findCurrentByHostAndName(clusterId.longValue(), HOST1, ALERT_DEFINITION);
+ assertNotNull(current);
+ assertEquals(currentId, current.getAlertId());
+ assertEquals(historyId, current.getAlertHistory().getAlertId());
+ assertEquals(HOST1, current.getAlertHistory().getHostName());
+ assertEquals(ALERT_DEFINITION, current.getAlertHistory().getAlertDefinition().getDefinitionName());
+ assertEquals(ALERT_LABEL, current.getAlertHistory().getAlertLabel());
+ assertEquals("Component component1 is OK", current.getAlertHistory().getAlertText());
+ assertEquals(current.getAlertHistory().getAlertState(), AlertState.OK);
+ assertEquals(1L, current.getOriginalTimestamp().longValue());
+ assertEquals(2L, current.getLatestTimestamp().longValue());
+
+ allCurrent = dao.findCurrentByService(clusterId.longValue(), SERVICE);
+ assertEquals(2, allCurrent.size());
+
+ allHistory = dao.findAll(clusterId.longValue());
+ assertEquals(2, allHistory.size());
+
+ // change to warning
+ Alert alert4 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST1, AlertState.WARNING);
+ alert4.setLabel(ALERT_LABEL);
+ alert4.setText("Component component1 is about to go down");
+ alert4.setTimestamp(3L);
+ am.add(clusterId.longValue(), alert4);
+
+ current = dao.findCurrentByHostAndName(clusterId.longValue(), HOST1, ALERT_DEFINITION);
+ assertNotNull(current);
+ assertEquals(current.getAlertId(), currentId);
+ assertFalse(historyId.equals(current.getAlertHistory().getAlertId()));
+ assertEquals(HOST1, current.getAlertHistory().getHostName());
+ assertEquals(ALERT_DEFINITION, current.getAlertHistory().getAlertDefinition().getDefinitionName());
+ assertEquals(ALERT_LABEL, current.getAlertHistory().getAlertLabel());
+ assertEquals("Component component1 is about to go down", current.getAlertHistory().getAlertText());
+ assertEquals(current.getAlertHistory().getAlertState(), AlertState.WARNING);
+ assertEquals(3L, current.getOriginalTimestamp().longValue());
+ assertEquals(3L, current.getLatestTimestamp().longValue());
+
+ allCurrent = dao.findCurrentByService(clusterId.longValue(), SERVICE);
+ assertEquals(2, allCurrent.size());
+
+ allHistory = dao.findAll(clusterId.longValue());
+ assertEquals(3, allHistory.size());
+ }
+}
[30/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e2e79668
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e2e79668
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e2e79668
Branch: refs/heads/trunk
Commit: e2e79668ed94266487fe9d1d2ccba2003922e883
Parents: 179290e d7ed431
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Sep 19 13:18:45 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Sep 19 13:18:45 2014 -0400
----------------------------------------------------------------------
.../clusters/ClustersManageAccessCtrl.js | 2 +-
.../app/scripts/directives/editableList.js | 18 +-
.../resources/ui/admin-web/app/styles/main.css | 14 +-
.../app/views/directives/editableList.html | 2 +-
.../ui/admin-web/app/views/groups/list.html | 2 +-
.../ui/admin-web/app/views/leftNavbar.html | 9 +-
.../resources/ui/admin-web/app/views/main.html | 3 +-
.../ui/admin-web/app/views/users/list.html | 2 +-
.../test/python/ambari_agent/TestController.py | 4 +-
.../TestCustomServiceOrchestrator.py | 3 +-
.../resource_management/TestCopyFromLocal.py | 8 +-
.../TestExecuteHadoopResource.py | 12 +-
.../resource_management/TestExecuteResource.py | 3 +-
.../core/providers/system.py | 12 +-
.../python/resource_management/core/shell.py | 24 +-
.../libraries/providers/copy_from_local.py | 4 +
.../libraries/providers/execute_hadoop.py | 6 +-
.../libraries/providers/hdfs_directory.py | 6 +-
.../libraries/resources/copy_from_local.py | 1 +
ambari-server/pom.xml | 8 +
.../server/api/util/StackExtensionHelper.java | 122 +-
.../controller/MaintenanceStateHelper.java | 2 +-
.../server/upgrade/UpgradeCatalog170.java | 43 +-
.../src/main/resources/properties.json | 1 +
.../1.3.2/hooks/before-START/scripts/params.py | 2 +-
.../services/HIVE/configuration/hcat-env.xml | 57 +
.../stacks/HDP/1.3.2/services/HIVE/metainfo.xml | 19 +-
.../1.3.2/services/HIVE/package/scripts/hcat.py | 13 +-
.../services/HIVE/package/scripts/params.py | 2 +
.../HIVE/package/templates/hcat-env.sh.j2 | 44 -
.../configuration/capacity-scheduler.xml | 2 +-
.../2.0.6/hooks/after-INSTALL/scripts/params.py | 11 +-
.../scripts/shared_initialization.py | 4 +
.../2.0.6/hooks/before-START/scripts/params.py | 13 +-
.../services/FLUME/package/scripts/flume.py | 2 +-
.../services/FLUME/package/scripts/params.py | 6 +-
.../GANGLIA/configuration/ganglia-env.xml | 2 +-
.../services/GANGLIA/package/scripts/params.py | 8 +-
.../services/HBASE/package/scripts/params.py | 16 +-
.../services/HDFS/package/scripts/params.py | 18 +-
.../HDFS/package/scripts/service_check.py | 2 +-
.../services/HIVE/configuration/hcat-env.xml | 57 +
.../stacks/HDP/2.0.6/services/HIVE/metainfo.xml | 19 +-
.../2.0.6/services/HIVE/package/scripts/hcat.py | 15 +-
.../HIVE/package/scripts/hcat_service_check.py | 10 +-
.../HIVE/package/scripts/install_jars.py | 2 +
.../services/HIVE/package/scripts/params.py | 71 +-
.../services/HIVE/package/scripts/webhcat.py | 4 +
.../HIVE/package/templates/hcat-env.sh.j2 | 43 -
.../services/PIG/package/scripts/params.py | 12 +-
.../2.0.6/services/PIG/package/scripts/pig.py | 1 +
.../services/SQOOP/package/scripts/params.py | 11 +-
.../YARN/configuration/capacity-scheduler.xml | 2 +-
.../package/scripts/mapred_service_check.py | 4 +
.../services/YARN/package/scripts/params.py | 24 +-
.../YARN/package/scripts/service_check.py | 2 +-
.../ZOOKEEPER/package/scripts/params.py | 7 +-
.../services/FALCON/package/scripts/params.py | 12 +-
.../services/STORM/package/scripts/params.py | 11 +-
.../stacks/HDP/2.2/services/FALCON/metainfo.xml | 2 +-
.../stacks/HDP/2.2/services/FLUME/metainfo.xml | 2 +-
.../stacks/HDP/2.2/services/HBASE/metainfo.xml | 2 +-
.../services/HDFS/configuration/hadoop-env.xml | 2 +-
.../services/HDFS/configuration/hdfs-site.xml | 34 -
.../stacks/HDP/2.2/services/HDFS/metainfo.xml | 4 +-
.../HIVE/configuration/webhcat-site.xml | 14 +-
.../stacks/HDP/2.2/services/HIVE/metainfo.xml | 6 +-
.../services/OOZIE/configuration/oozie-site.xml | 13 -
.../stacks/HDP/2.2/services/OOZIE/metainfo.xml | 6 +-
.../stacks/HDP/2.2/services/PIG/metainfo.xml | 2 +-
.../services/SLIDER/package/scripts/params.py | 4 +-
.../stacks/HDP/2.2/services/SQOOP/metainfo.xml | 2 +-
.../services/STORM/configuration/storm-env.xml | 29 -
.../services/STORM/configuration/storm-site.xml | 6 +-
.../stacks/HDP/2.2/services/STORM/metainfo.xml | 2 +-
.../stacks/HDP/2.2/services/TEZ/metainfo.xml | 2 +-
.../HDP/2.2/services/WEBHCAT/metainfo.xml | 43 -
.../YARN/configuration-mapred/mapred-site.xml | 11 +-
.../services/YARN/configuration/yarn-site.xml | 11 +-
.../stacks/HDP/2.2/services/YARN/metainfo.xml | 6 +-
.../HDP/2.2/services/ZOOKEEPER/metainfo.xml | 2 +-
.../api/util/StackExtensionHelperTest.java | 40 +-
.../stacks/1.3.2/HDFS/test_service_check.py | 2 +-
.../stacks/1.3.2/HIVE/test_hcat_client.py | 20 +-
.../python/stacks/1.3.2/configs/default.json | 5 +-
.../python/stacks/1.3.2/configs/secured.json | 5 +-
.../python/stacks/2.0.6/FLUME/test_flume.py | 4 +-
.../stacks/2.0.6/HDFS/test_service_check.py | 2 +-
.../stacks/2.0.6/HIVE/test_hcat_client.py | 22 +-
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 9 +-
.../stacks/2.0.6/HIVE/test_hive_server.py | 12 +-
.../2.0.6/HIVE/test_hive_service_check.py | 17 +-
.../stacks/2.0.6/HIVE/test_webhcat_server.py | 8 +
.../python/stacks/2.0.6/PIG/test_pig_client.py | 2 +
.../2.0.6/YARN/test_mapreduce2_service_check.py | 8 +
.../2.0.6/YARN/test_yarn_service_check.py | 4 +-
.../python/stacks/2.0.6/configs/default.json | 5 +-
.../python/stacks/2.0.6/configs/secured.json | 5 +-
.../stacks/2.1/HIVE/test_hive_metastore.py | 8 +-
.../services/YARN/configuration/yarn-site.xml | 2 +-
ambari-web/app/data/HDP2/site_properties.js | 24 +
ambari-web/app/data/site_properties.js | 24 +
ambari-web/app/messages.js | 1 +
ambari-web/app/mixins/common/serverValidator.js | 11 +-
ambari-web/app/models/service_config_version.js | 7 +-
ambari-web/app/styles/application.less | 51 +-
.../common/configs/config_history_flow.hbs | 20 +-
.../common/configs/service_version_box.hbs | 17 +-
.../templates/main/dashboard/config_history.hbs | 6 +-
ambari-web/app/utils/config.js | 2 +-
.../views/common/configs/config_history_flow.js | 19 +-
ambari-web/app/views/common/filter_view.js | 8 +-
.../views/main/dashboard/config_history_view.js | 4 +-
contrib/views/slider/pom.xml | 9 +-
.../ambari/view/slider/GangliaMetric.java | 257 +++
.../ambari/view/slider/MetricsHolder.java | 44 +
.../apache/ambari/view/slider/SliderApp.java | 16 +-
.../ambari/view/slider/SliderAppType.java | 32 +-
.../slider/SliderAppsViewControllerImpl.java | 87 +-
.../apache/ambari/view/slider/TemporalInfo.java | 48 +
.../rest/client/SliderAppGangliaHelper.java | 196 +++
.../rest/client/SliderAppMasterClient.java | 127 +-
.../app/assets/data/resource/cluster_name.json | 12 -
.../assets/data/resource/components_hosts.json | 16 -
.../ui/app/assets/data/resource/empty_json.json | 1 +
.../assets/data/resource/service_configs.json | 38 -
.../assets/data/resource/service_status.json | 95 --
.../assets/data/resource/slider-properties.json | 7 +-
.../ui-bg_flat_0_aaaaaa_40x100.png | Bin 0 -> 180 bytes
.../ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 120 bytes
.../ui-bg_glass_65_ffffff_1x400.png | Bin 0 -> 105 bytes
.../ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 111 bytes
.../ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 110 bytes
.../ui-bg_glass_75_ffffff_1x400.png | Bin 0 -> 107 bytes
.../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 101 bytes
.../ui-bg_inset-soft_95_fef1ec_1x100.png | Bin 0 -> 123 bytes
.../ui-icons_222222_256x240.png | Bin 0 -> 4369 bytes
.../ui-icons_2e83ff_256x240.png | Bin 0 -> 4369 bytes
.../ui-icons_454545_256x240.png | Bin 0 -> 4369 bytes
.../ui-icons_888888_256x240.png | Bin 0 -> 4369 bytes
.../ui-icons_cd0a0a_256x240.png | Bin 0 -> 4369 bytes
.../ui-icons_f6cf3b_256x240.png | Bin 0 -> 8884 bytes
.../createAppWizard/step1_controller.js | 90 +-
.../createAppWizard/step4_controller.js | 10 +-
.../ui/app/controllers/slider_app_controller.js | 35 +-
.../ui/app/controllers/slider_controller.js | 305 +---
.../src/main/resources/ui/app/helpers/ajax.js | 133 +-
.../src/main/resources/ui/app/initialize.js | 11 +-
.../ui/app/mappers/application_type.js | 2 +-
.../ui/app/mappers/slider_apps_mapper.js | 41 +-
.../ui/app/mixins/ajax_error_handler.js | 84 +
.../main/resources/ui/app/models/slider_app.js | 5 +
.../resources/ui/app/models/slider_config.js | 51 +
.../src/main/resources/ui/app/routes/main.js | 16 +
.../resources/ui/app/styles/application.less | 80 +-
.../resources/ui/app/templates/application.hbs | 17 +-
.../ui/app/templates/common/ajax_error.hbs | 24 +
.../resources/ui/app/templates/slider_app.hbs | 26 +-
.../ui/app/templates/slider_app/configs.hbs | 2 +-
.../resources/ui/app/templates/slider_apps.hbs | 10 +-
.../ui/app/templates/slider_title_tooltip.hbs | 6 +-
.../src/main/resources/ui/app/translations.js | 22 +-
.../resources/ui/app/views/application_view.js | 18 +-
.../views/slider_app/metrics/app_metric_view.js | 71 +
.../ui/app/views/slider_app/summary_view.js | 71 +-
.../slider/src/main/resources/ui/config.js | 1 +
.../resources/ui/vendor/scripts/common/tv4.js | 1605 ++++++++++++++++++
.../views/slider/src/main/resources/view.xml | 21 +-
168 files changed, 3721 insertions(+), 1439 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e2e79668/ambari-agent/src/test/python/ambari_agent/TestController.py
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e2e79668/ambari-server/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e2e79668/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e2e79668/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
[13/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/91ae5f27
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/91ae5f27
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/91ae5f27
Branch: refs/heads/trunk
Commit: 91ae5f27e98ec4d81c7299480b8adb3619e31c5b
Parents: 0de98b0 ad983de
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Sep 4 18:35:01 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Thu Sep 4 18:35:01 2014 -0400
----------------------------------------------------------------------
.../src/main/resources/ui/admin-web/gulpfile.js | 51 -
.../main/resources/ui/admin-web/package.json | 9 -
ambari-agent/pom.xml | 12 +-
.../src/main/python/ambari_agent/HostInfo.py | 2 +-
.../test/python/ambari_agent/TestHardware.py | 4 +-
.../resource_management/TestContentSources.py | 2 +-
.../resource_management/TestPackageResource.py | 8 +-
.../TestRepositoryResource.py | 16 +-
.../src/main/python/ambari_commons/os_check.py | 8 +-
.../src/main/python/ambari_jinja2/AUTHORS | 31 +
.../src/main/python/ambari_jinja2/CHANGES | 235 +++
.../src/main/python/ambari_jinja2/LICENSE | 31 +
.../src/main/python/ambari_jinja2/MANIFEST.in | 12 +
.../src/main/python/ambari_jinja2/Makefile | 4 +
.../ambari_jinja2/ambari_jinja2/__init__.py | 73 +
.../ambari_jinja2/ambari_jinja2/_debugsupport.c | 78 +
.../ambari_jinja2/_markupsafe/__init__.py | 225 +++
.../ambari_jinja2/_markupsafe/_bundle.py | 49 +
.../ambari_jinja2/_markupsafe/_constants.py | 267 +++
.../ambari_jinja2/_markupsafe/_native.py | 45 +
.../ambari_jinja2/_markupsafe/tests.py | 80 +
.../ambari_jinja2/ambari_jinja2/_stringdefs.py | 130 ++
.../ambari_jinja2/ambari_jinja2/bccache.py | 280 +++
.../ambari_jinja2/ambari_jinja2/compiler.py | 1640 ++++++++++++++++++
.../ambari_jinja2/ambari_jinja2/constants.py | 32 +
.../python/ambari_jinja2/ambari_jinja2/debug.py | 308 ++++
.../ambari_jinja2/ambari_jinja2/defaults.py | 40 +
.../ambari_jinja2/ambari_jinja2/environment.py | 1118 ++++++++++++
.../ambari_jinja2/ambari_jinja2/exceptions.py | 143 ++
.../python/ambari_jinja2/ambari_jinja2/ext.py | 610 +++++++
.../ambari_jinja2/ambari_jinja2/filters.py | 719 ++++++++
.../python/ambari_jinja2/ambari_jinja2/lexer.py | 681 ++++++++
.../ambari_jinja2/ambari_jinja2/loaders.py | 449 +++++
.../python/ambari_jinja2/ambari_jinja2/meta.py | 102 ++
.../python/ambari_jinja2/ambari_jinja2/nodes.py | 901 ++++++++++
.../ambari_jinja2/ambari_jinja2/optimizer.py | 68 +
.../ambari_jinja2/ambari_jinja2/parser.py | 896 ++++++++++
.../ambari_jinja2/ambari_jinja2/runtime.py | 544 ++++++
.../ambari_jinja2/ambari_jinja2/sandbox.py | 271 +++
.../python/ambari_jinja2/ambari_jinja2/tests.py | 146 ++
.../ambari_jinja2/testsuite/__init__.py | 95 +
.../ambari_jinja2/testsuite/api.py | 240 +++
.../ambari_jinja2/testsuite/core_tags.py | 286 +++
.../ambari_jinja2/testsuite/debug.py | 60 +
.../ambari_jinja2/testsuite/doctests.py | 29 +
.../ambari_jinja2/testsuite/ext.py | 455 +++++
.../ambari_jinja2/testsuite/filters.py | 291 ++++
.../ambari_jinja2/testsuite/imports.py | 144 ++
.../ambari_jinja2/testsuite/inheritance.py | 208 +++
.../ambari_jinja2/testsuite/lexnparse.py | 390 +++++
.../ambari_jinja2/testsuite/loader.py | 191 ++
.../ambari_jinja2/testsuite/regression.py | 258 +++
.../testsuite/res/templates/broken.html | 3 +
.../testsuite/res/templates/foo/test.html | 1 +
.../testsuite/res/templates/syntaxerror.html | 4 +
.../testsuite/res/templates/test.html | 1 +
.../ambari_jinja2/testsuite/security.py | 134 ++
.../ambari_jinja2/testsuite/tests.py | 87 +
.../ambari_jinja2/testsuite/utils.py | 85 +
.../python/ambari_jinja2/ambari_jinja2/utils.py | 601 +++++++
.../ambari_jinja2/ambari_jinja2/visitor.py | 87 +
.../python/ambari_jinja2/artwork/jinjalogo.svg | 132 ++
.../custom_fixers/fix_alt_unicode.py | 13 +
.../custom_fixers/fix_broken_reraising.py | 21 +
.../ambari_jinja2/custom_fixers/fix_xrange2.py | 11 +
.../src/main/python/ambari_jinja2/docs/Makefile | 75 +
.../python/ambari_jinja2/docs/_static/jinja.js | 26 +
.../python/ambari_jinja2/docs/_static/print.css | 5 +
.../python/ambari_jinja2/docs/_static/style.css | 390 +++++
.../ambari_jinja2/docs/_templates/genindex.html | 36 +
.../ambari_jinja2/docs/_templates/layout.html | 77 +
.../docs/_templates/opensearch.xml | 9 +
.../ambari_jinja2/docs/_templates/page.html | 4 +
.../ambari_jinja2/docs/_templates/search.html | 35 +
.../src/main/python/ambari_jinja2/docs/api.rst | 787 +++++++++
.../ambari_jinja2/docs/cache_extension.py | 56 +
.../python/ambari_jinja2/docs/changelog.rst | 3 +
.../src/main/python/ambari_jinja2/docs/conf.py | 141 ++
.../python/ambari_jinja2/docs/extensions.rst | 347 ++++
.../src/main/python/ambari_jinja2/docs/faq.rst | 191 ++
.../main/python/ambari_jinja2/docs/index.rst | 27 +
.../python/ambari_jinja2/docs/integration.rst | 88 +
.../main/python/ambari_jinja2/docs/intro.rst | 168 ++
.../main/python/ambari_jinja2/docs/jinjaext.py | 192 ++
.../main/python/ambari_jinja2/docs/sandbox.rst | 46 +
.../python/ambari_jinja2/docs/switching.rst | 242 +++
.../python/ambari_jinja2/docs/templates.rst | 1365 +++++++++++++++
.../main/python/ambari_jinja2/docs/tricks.rst | 100 ++
.../ambari_jinja2/examples/basic/cycle.py | 13 +
.../ambari_jinja2/examples/basic/debugger.py | 7 +
.../ambari_jinja2/examples/basic/inheritance.py | 12 +
.../examples/basic/templates/broken.html | 6 +
.../examples/basic/templates/subbroken.html | 3 +
.../python/ambari_jinja2/examples/basic/test.py | 27 +
.../basic/test_filter_and_linestatements.py | 25 +
.../examples/basic/test_loop_filter.py | 12 +
.../ambari_jinja2/examples/basic/translate.py | 6 +
.../main/python/ambari_jinja2/examples/bench.py | 433 +++++
.../python/ambari_jinja2/examples/profile.py | 52 +
.../examples/rwbench/django/_form.html | 1 +
.../examples/rwbench/django/_input_field.html | 1 +
.../examples/rwbench/django/_textarea.html | 1 +
.../examples/rwbench/django/index.html | 29 +
.../examples/rwbench/django/layout.html | 29 +
.../ambari_jinja2/examples/rwbench/djangoext.py | 135 ++
.../examples/rwbench/genshi/helpers.html | 12 +
.../examples/rwbench/genshi/index.html | 41 +
.../examples/rwbench/genshi/layout.html | 30 +
.../examples/rwbench/jinja/helpers.html | 12 +
.../examples/rwbench/jinja/index.html | 29 +
.../examples/rwbench/jinja/layout.html | 29 +
.../examples/rwbench/mako/helpers.html | 11 +
.../examples/rwbench/mako/index.html | 31 +
.../examples/rwbench/mako/layout.html | 30 +
.../ambari_jinja2/examples/rwbench/rwbench.py | 112 ++
.../python/ambari_jinja2/ext/Vim/htmljinja.vim | 27 +
.../main/python/ambari_jinja2/ext/Vim/jinja.vim | 113 ++
.../ext/django2jinja/django2jinja.py | 768 ++++++++
.../ambari_jinja2/ext/django2jinja/example.py | 7 +
.../ext/django2jinja/templates/index.html | 58 +
.../ext/django2jinja/templates/layout.html | 4 +
.../ext/django2jinja/templates/subtemplate.html | 1 +
.../python/ambari_jinja2/ext/djangojinja2.py | 86 +
.../python/ambari_jinja2/ext/inlinegettext.py | 78 +
.../src/main/python/ambari_jinja2/ext/jinja.el | 213 +++
.../main/python/ambari_jinja2/jinja2-debug.py | 40 +
.../main/python/ambari_jinja2/scripts/pylintrc | 301 ++++
.../src/main/python/ambari_jinja2/setup.cfg | 6 +
.../src/main/python/ambari_jinja2/setup.py | 110 ++
ambari-common/src/main/python/jinja2/AUTHORS | 31 -
ambari-common/src/main/python/jinja2/CHANGES | 235 ---
ambari-common/src/main/python/jinja2/LICENSE | 31 -
.../src/main/python/jinja2/MANIFEST.in | 12 -
ambari-common/src/main/python/jinja2/Makefile | 4 -
.../main/python/jinja2/artwork/jinjalogo.svg | 132 --
.../python/jinja2/custom_fixers/__init__.py | 0
.../jinja2/custom_fixers/fix_alt_unicode.py | 13 -
.../custom_fixers/fix_broken_reraising.py | 21 -
.../python/jinja2/custom_fixers/fix_xrange2.py | 11 -
.../src/main/python/jinja2/docs/Makefile | 75 -
.../src/main/python/jinja2/docs/_build/.ignore | 0
.../src/main/python/jinja2/docs/_static/.ignore | 0
.../main/python/jinja2/docs/_static/jinja.js | 26 -
.../main/python/jinja2/docs/_static/print.css | 5 -
.../main/python/jinja2/docs/_static/style.css | 390 -----
.../main/python/jinja2/docs/_templates/.ignore | 0
.../python/jinja2/docs/_templates/genindex.html | 36 -
.../python/jinja2/docs/_templates/layout.html | 77 -
.../jinja2/docs/_templates/opensearch.xml | 9 -
.../python/jinja2/docs/_templates/page.html | 4 -
.../python/jinja2/docs/_templates/search.html | 35 -
.../src/main/python/jinja2/docs/api.rst | 787 ---------
.../main/python/jinja2/docs/cache_extension.py | 56 -
.../src/main/python/jinja2/docs/changelog.rst | 3 -
.../src/main/python/jinja2/docs/conf.py | 141 --
.../src/main/python/jinja2/docs/extensions.rst | 347 ----
.../src/main/python/jinja2/docs/faq.rst | 191 --
.../src/main/python/jinja2/docs/index.rst | 27 -
.../src/main/python/jinja2/docs/integration.rst | 88 -
.../src/main/python/jinja2/docs/intro.rst | 168 --
.../src/main/python/jinja2/docs/jinjaext.py | 192 --
.../src/main/python/jinja2/docs/sandbox.rst | 46 -
.../src/main/python/jinja2/docs/switching.rst | 242 ---
.../src/main/python/jinja2/docs/templates.rst | 1365 ---------------
.../src/main/python/jinja2/docs/tricks.rst | 100 --
.../main/python/jinja2/examples/basic/cycle.py | 13 -
.../python/jinja2/examples/basic/debugger.py | 7 -
.../python/jinja2/examples/basic/inheritance.py | 12 -
.../jinja2/examples/basic/templates/broken.html | 6 -
.../examples/basic/templates/subbroken.html | 3 -
.../main/python/jinja2/examples/basic/test.py | 27 -
.../basic/test_filter_and_linestatements.py | 25 -
.../jinja2/examples/basic/test_loop_filter.py | 12 -
.../python/jinja2/examples/basic/translate.py | 6 -
.../src/main/python/jinja2/examples/bench.py | 433 -----
.../src/main/python/jinja2/examples/profile.py | 52 -
.../jinja2/examples/rwbench/django/_form.html | 1 -
.../examples/rwbench/django/_input_field.html | 1 -
.../examples/rwbench/django/_textarea.html | 1 -
.../jinja2/examples/rwbench/django/index.html | 29 -
.../jinja2/examples/rwbench/django/layout.html | 29 -
.../python/jinja2/examples/rwbench/djangoext.py | 135 --
.../jinja2/examples/rwbench/genshi/helpers.html | 12 -
.../jinja2/examples/rwbench/genshi/index.html | 41 -
.../jinja2/examples/rwbench/genshi/layout.html | 30 -
.../jinja2/examples/rwbench/jinja/helpers.html | 12 -
.../jinja2/examples/rwbench/jinja/index.html | 29 -
.../jinja2/examples/rwbench/jinja/layout.html | 29 -
.../jinja2/examples/rwbench/mako/helpers.html | 11 -
.../jinja2/examples/rwbench/mako/index.html | 31 -
.../jinja2/examples/rwbench/mako/layout.html | 30 -
.../python/jinja2/examples/rwbench/rwbench.py | 112 --
.../main/python/jinja2/ext/Vim/htmljinja.vim | 27 -
.../src/main/python/jinja2/ext/Vim/jinja.vim | 113 --
.../jinja2/ext/django2jinja/django2jinja.py | 768 --------
.../python/jinja2/ext/django2jinja/example.py | 7 -
.../ext/django2jinja/templates/index.html | 58 -
.../ext/django2jinja/templates/layout.html | 4 -
.../ext/django2jinja/templates/subtemplate.html | 1 -
.../src/main/python/jinja2/ext/djangojinja2.py | 86 -
.../src/main/python/jinja2/ext/inlinegettext.py | 78 -
.../src/main/python/jinja2/ext/jinja.el | 213 ---
.../src/main/python/jinja2/jinja2-debug.py | 40 -
.../src/main/python/jinja2/jinja2/__init__.py | 73 -
.../main/python/jinja2/jinja2/_debugsupport.c | 78 -
.../jinja2/jinja2/_markupsafe/__init__.py | 225 ---
.../python/jinja2/jinja2/_markupsafe/_bundle.py | 49 -
.../jinja2/jinja2/_markupsafe/_constants.py | 267 ---
.../python/jinja2/jinja2/_markupsafe/_native.py | 45 -
.../python/jinja2/jinja2/_markupsafe/tests.py | 80 -
.../main/python/jinja2/jinja2/_stringdefs.py | 130 --
.../src/main/python/jinja2/jinja2/bccache.py | 280 ---
.../src/main/python/jinja2/jinja2/compiler.py | 1640 ------------------
.../src/main/python/jinja2/jinja2/constants.py | 32 -
.../src/main/python/jinja2/jinja2/debug.py | 308 ----
.../src/main/python/jinja2/jinja2/defaults.py | 40 -
.../main/python/jinja2/jinja2/environment.py | 1118 ------------
.../src/main/python/jinja2/jinja2/exceptions.py | 143 --
.../src/main/python/jinja2/jinja2/ext.py | 610 -------
.../src/main/python/jinja2/jinja2/filters.py | 719 --------
.../src/main/python/jinja2/jinja2/lexer.py | 681 --------
.../src/main/python/jinja2/jinja2/loaders.py | 449 -----
.../src/main/python/jinja2/jinja2/meta.py | 102 --
.../src/main/python/jinja2/jinja2/nodes.py | 901 ----------
.../src/main/python/jinja2/jinja2/optimizer.py | 68 -
.../src/main/python/jinja2/jinja2/parser.py | 896 ----------
.../src/main/python/jinja2/jinja2/runtime.py | 544 ------
.../src/main/python/jinja2/jinja2/sandbox.py | 271 ---
.../src/main/python/jinja2/jinja2/tests.py | 146 --
.../python/jinja2/jinja2/testsuite/__init__.py | 95 -
.../main/python/jinja2/jinja2/testsuite/api.py | 240 ---
.../python/jinja2/jinja2/testsuite/core_tags.py | 286 ---
.../python/jinja2/jinja2/testsuite/debug.py | 60 -
.../python/jinja2/jinja2/testsuite/doctests.py | 29 -
.../main/python/jinja2/jinja2/testsuite/ext.py | 455 -----
.../python/jinja2/jinja2/testsuite/filters.py | 291 ----
.../python/jinja2/jinja2/testsuite/imports.py | 144 --
.../jinja2/jinja2/testsuite/inheritance.py | 208 ---
.../python/jinja2/jinja2/testsuite/lexnparse.py | 390 -----
.../python/jinja2/jinja2/testsuite/loader.py | 191 --
.../jinja2/jinja2/testsuite/regression.py | 258 ---
.../jinja2/jinja2/testsuite/res/__init__.py | 0
.../jinja2/testsuite/res/templates/broken.html | 3 -
.../testsuite/res/templates/foo/test.html | 1 -
.../testsuite/res/templates/syntaxerror.html | 4 -
.../jinja2/testsuite/res/templates/test.html | 1 -
.../python/jinja2/jinja2/testsuite/security.py | 134 --
.../python/jinja2/jinja2/testsuite/tests.py | 87 -
.../python/jinja2/jinja2/testsuite/utils.py | 85 -
.../src/main/python/jinja2/jinja2/utils.py | 601 -------
.../src/main/python/jinja2/jinja2/visitor.py | 87 -
.../src/main/python/jinja2/scripts/pylintrc | 301 ----
ambari-common/src/main/python/jinja2/setup.cfg | 6 -
ambari-common/src/main/python/jinja2/setup.py | 110 --
.../core/providers/__init__.py | 2 +-
.../python/resource_management/core/source.py | 2 +-
.../python/resource_management/core/system.py | 4 +-
.../libraries/providers/__init__.py | 4 +-
.../libraries/providers/monitor_webserver.py | 2 +-
.../libraries/providers/repository.py | 2 +-
ambari-server/pom.xml | 4 +-
.../server/api/services/AmbariMetaInfo.java | 2 +-
.../server/configuration/Configuration.java | 8 +-
.../apache/ambari/server/orm/dao/GroupDAO.java | 1 +
.../apache/ambari/server/orm/dao/UserDAO.java | 1 +
.../authorization/AmbariLdapDataPopulator.java | 5 +-
.../org/apache/ambari/server/state/Host.java | 2 +-
.../server/state/stack/LatestRepoCallable.java | 2 +-
.../ambari/server/state/stack/OsFamily.java | 6 +-
.../server/upgrade/UpgradeCatalog161.java | 22 +
ambari-server/src/main/python/ambari-server.py | 2 +
.../src/main/python/ambari_server/utils.py | 12 +-
ambari-server/src/main/python/bootstrap.py | 14 +-
ambari-server/src/main/python/setupAgent.py | 8 +-
ambari-server/src/main/resources/os_family.json | 2 +-
.../main/resources/scripts/kerberos-setup.sh | 4 +-
.../src/main/resources/scripts/stack_advisor.py | 19 +-
.../scripts/repo_initialization.py | 2 +-
.../before-INSTALL/templates/repo_debian.j2 | 1 -
.../before-INSTALL/templates/repo_ubuntu.j2 | 1 +
.../HBASE/package/scripts/hbase_decommission.py | 62 +-
.../services/HBASE/package/scripts/params.py | 1 +
.../stacks/HDP/1.3.2/services/stack_advisor.py | 377 +---
.../stacks/HDP/1.3.3/services/stack_advisor.py | 4 -
.../stacks/HDP/1.3/services/stack_advisor.py | 4 -
.../scripts/repo_initialization.py | 2 +-
.../before-INSTALL/templates/repo_debian.j2 | 1 -
.../before-INSTALL/templates/repo_ubuntu.j2 | 1 +
.../HDP/2.0.6/services/GANGLIA/metainfo.xml | 2 +-
.../GANGLIA/package/scripts/functions.py | 4 +-
.../GANGLIA/package/scripts/ganglia_server.py | 2 +-
.../services/GANGLIA/package/scripts/params.py | 4 +-
.../HBASE/package/scripts/hbase_decommission.py | 62 +-
.../services/HBASE/package/scripts/params.py | 1 +
.../stacks/HDP/2.0.6/services/HDFS/metainfo.xml | 2 +-
.../stacks/HDP/2.0.6/services/HIVE/metainfo.xml | 2 +-
.../services/HIVE/package/scripts/params.py | 2 +-
.../HIVE/package/scripts/status_params.py | 2 +-
.../HDP/2.0.6/services/NAGIOS/metainfo.xml | 2 +-
.../services/NAGIOS/package/scripts/nagios.py | 8 +-
.../services/NAGIOS/package/scripts/params.py | 10 +-
.../NAGIOS/package/templates/nagios.conf.j2 | 2 +-
.../HDP/2.0.6/services/OOZIE/metainfo.xml | 2 +-
.../services/OOZIE/package/files/oozieSmoke2.sh | 2 +-
.../stacks/HDP/2.0.6/services/stack_advisor.py | 316 +---
.../2.1.GlusterFS/services/FLUME/metainfo.xml | 31 +
.../2.1.GlusterFS/services/HBASE/metainfo.xml | 5 +
.../2.1.GlusterFS/services/OOZIE/metainfo.xml | 4 +-
.../2.1.GlusterFS/services/SQOOP/metainfo.xml | 3 +
.../2.1.GlusterFS/services/YARN/metainfo.xml | 10 +-
.../resources/stacks/HDP/2.1/repos/repoinfo.xml | 2 +-
.../stacks/HDP/2.1/services/OOZIE/metainfo.xml | 2 +-
.../stacks/HDP/2.1/services/SQOOP/metainfo.xml | 4 -
.../stacks/HDP/2.1/services/stack_advisor.py | 64 +-
.../resources/stacks/HDP/2.2.1/metainfo.xml | 23 +
.../stacks/HDP/2.2.1/repos/repoinfo.xml | 67 +
.../stacks/HDP/2.2.1/role_command_order.json | 85 +
.../HDP/2.2.1/services/FALCON/metainfo.xml | 26 +
.../HDP/2.2.1/services/FLUME/metainfo.xml | 26 +
.../HDP/2.2.1/services/HBASE/metainfo.xml | 26 +
.../stacks/HDP/2.2.1/services/HDFS/metainfo.xml | 27 +
.../stacks/HDP/2.2.1/services/HIVE/metainfo.xml | 31 +
.../HDP/2.2.1/services/OOZIE/metainfo.xml | 26 +
.../stacks/HDP/2.2.1/services/PIG/metainfo.xml | 26 +
.../HDP/2.2.1/services/SQOOP/metainfo.xml | 26 +
.../HDP/2.2.1/services/STORM/metainfo.xml | 27 +
.../stacks/HDP/2.2.1/services/TEZ/metainfo.xml | 26 +
.../HDP/2.2.1/services/WEBHCAT/metainfo.xml | 26 +
.../stacks/HDP/2.2.1/services/YARN/metainfo.xml | 31 +
.../HDP/2.2.1/services/ZOOKEEPER/metainfo.xml | 26 +
.../src/main/resources/stacks/stack_advisor.py | 271 +++
.../server/api/services/AmbariMetaInfoTest.java | 1 -
.../AmbariManagementControllerTest.java | 4 +-
.../AmbariLdapDataPopulatorTest.java | 22 +-
.../server/upgrade/UpgradeCatalog161Test.java | 24 +
.../src/test/python/TestAmbariServer.py | 11 +-
ambari-server/src/test/python/TestBootstrap.py | 6 +-
ambari-server/src/test/python/TestOSCheck.py | 12 +-
ambari-server/src/test/python/TestSetupAgent.py | 64 +-
.../src/test/python/TestStackAdvisor.py | 323 +++-
ambari-server/src/test/python/TestUtils.py | 6 +-
.../stacks/1.3.2/HBASE/test_hbase_master.py | 6 +-
.../python/stacks/1.3.2/configs/default.json | 4 +-
.../hooks/before-INSTALL/test_before_install.py | 83 +-
.../stacks/2.0.6/HBASE/test_hbase_master.py | 6 +-
.../stacks/2.0.6/common/test_stack_advisor.py | 6 +-
.../python/stacks/2.0.6/configs/default.json | 5 +-
.../hooks/before-INSTALL/test_before_install.py | 98 +-
ambari-server/src/test/python/unitTests.py | 2 +-
.../HDP/2.0.1/services/GANGLIA/metainfo.xml | 2 +-
.../stacks/HDP/2.0.1/services/HDFS/metainfo.xml | 2 +-
.../stacks/HDP/2.0.1/services/HIVE/metainfo.xml | 2 +-
.../HDP/2.0.1/services/OOZIE/metainfo.xml | 2 +-
.../HDP/2.0.5/services/GANGLIA/metainfo.xml | 2 +-
.../stacks/HDP/2.0.5/services/HDFS/metainfo.xml | 2 +-
.../stacks/HDP/2.0.5/services/HIVE/metainfo.xml | 2 +-
.../HDP/2.0.5/services/OOZIE/metainfo.xml | 2 +-
.../stacks/HDP/2.0.7/services/HIVE/metainfo.xml | 2 +-
.../assets/data/wizard/stack/HDP_versions.json | 10 +-
ambari-web/app/assets/test/tests.js | 1 +
ambari-web/app/controllers/application.js | 4 +
.../controllers/global/cluster_controller.js | 6 +-
ambari-web/app/controllers/installer.js | 2 +-
.../app/controllers/main/admin/repositories.js | 2 +-
.../main/admin/security/add/step4.js | 3 +
.../security/security_progress_controller.js | 6 +-
ambari-web/app/controllers/main/host/details.js | 11 +-
.../controllers/main/service/info/configs.js | 56 +-
.../app/controllers/wizard/step3_controller.js | 2 +-
.../app/controllers/wizard/step7_controller.js | 8 +
.../app/controllers/wizard/step8_controller.js | 2 +-
.../mappers/service_config_version_mapper.js | 1 +
ambari-web/app/messages.js | 1 +
ambari-web/app/models/service_config.js | 8 +-
ambari-web/app/models/service_config_version.js | 9 +-
ambari-web/app/router.js | 2 +-
ambari-web/app/routes/main.js | 19 +-
ambari-web/app/styles/application.less | 40 +-
ambari-web/app/templates/application.hbs | 22 +-
.../common/configs/config_history_flow.hbs | 16 +-
.../templates/main/dashboard/config_history.hbs | 4 +-
ambari-web/app/utils/blueprint.js | 6 +-
.../views/common/configs/config_history_flow.js | 42 +-
.../app/views/common/configs/services_config.js | 2 +-
.../app/views/common/filter_combo_cleanable.js | 1 +
ambari-web/app/views/main/menu.js | 37 +-
ambari-web/app/views/main/service/menu.js | 2 +-
.../views/common/filter_combo_cleanable_test.js | 42 +
ambari-web/vendor/scripts/jquery.timeago.js | 6 +-
.../jobs/src/main/resources/ui/Gruntfile.js | 13 -
.../jobs/src/main/resources/ui/package.json | 1 -
pom.xml | 2 +
392 files changed, 23368 insertions(+), 22538 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/91ae5f27/ambari-agent/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/91ae5f27/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/91ae5f27/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/91ae5f27/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
[42/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b9cca713
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b9cca713
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b9cca713
Branch: refs/heads/trunk
Commit: b9cca7137540a6233a016ccf8ff3eba4c119b2b6
Parents: a42b727 753fe29
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Sep 30 16:47:50 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Sep 30 16:47:50 2014 -0400
----------------------------------------------------------------------
.../controllers/ambariViews/ViewsListCtrl.js | 36 ++++++
.../ui/admin-web/app/scripts/services/View.js | 18 +++
.../resources/ui/admin-web/app/styles/main.css | 18 ++-
.../ui/admin-web/app/views/leftNavbar.html | 6 +-
.../src/main/python/ambari_agent/ActionQueue.py | 4 +-
.../src/main/python/ambari_agent/Controller.py | 6 +-
ambari-server/conf/unix/ambari.properties | 2 +-
.../AmbariCustomCommandExecutionHelper.java | 12 ++
.../security/ldap/AmbariLdapDataPopulator.java | 109 ++++++++++++-----
ambari-server/src/main/python/ambari-server.py | 2 +-
.../1.3.2/hooks/after-INSTALL/scripts/hook.py | 1 -
.../1.3.2/hooks/after-INSTALL/scripts/params.py | 5 +-
.../scripts/shared_initialization.py | 37 ++----
.../hooks/before-ANY/files/changeToSecureUid.sh | 50 ++++++++
.../HDP/1.3.2/hooks/before-ANY/scripts/hook.py | 3 +
.../1.3.2/hooks/before-ANY/scripts/params.py | 102 ++++++++++++++++
.../before-ANY/scripts/shared_initialization.py | 58 +++++++++
.../before-INSTALL/files/changeToSecureUid.sh | 50 --------
.../1.3.2/hooks/before-INSTALL/scripts/hook.py | 1 -
.../scripts/shared_initialization.py | 35 ------
.../1.3.2/hooks/before-START/scripts/hook.py | 1 -
.../2.0.6/hooks/after-INSTALL/scripts/hook.py | 2 +-
.../2.0.6/hooks/after-INSTALL/scripts/params.py | 5 +-
.../scripts/shared_initialization.py | 28 +----
.../hooks/before-ANY/files/changeToSecureUid.sh | 50 ++++++++
.../HDP/2.0.6/hooks/before-ANY/scripts/hook.py | 2 +
.../2.0.6/hooks/before-ANY/scripts/params.py | 108 ++++++++++++++++-
.../before-ANY/scripts/shared_initialization.py | 56 +++++++++
.../before-INSTALL/files/changeToSecureUid.sh | 50 --------
.../2.0.6/hooks/before-INSTALL/scripts/hook.py | 1 -
.../scripts/shared_initialization.py | 35 ------
.../2.0.6/hooks/before-START/scripts/hook.py | 1 -
.../2.0.6/hooks/before-START/scripts/params.py | 4 +-
.../services/FLUME/package/scripts/params.py | 4 +-
.../services/HBASE/package/scripts/params.py | 9 +-
.../services/HDFS/package/scripts/params.py | 4 +-
.../services/HIVE/package/scripts/params.py | 6 +-
.../services/HIVE/package/scripts/webhcat.py | 32 +++--
.../services/OOZIE/package/scripts/params.py | 4 +-
.../services/PIG/package/scripts/params.py | 4 +-
.../services/SQOOP/package/scripts/params.py | 4 +-
.../services/YARN/package/scripts/params.py | 4 +-
.../ZOOKEEPER/package/scripts/params.py | 4 +-
.../services/FALCON/package/scripts/params.py | 4 +-
.../services/STORM/package/scripts/params.py | 4 +-
.../HDP/2.2/configuration/cluster-env.xml | 29 +++++
.../services/HDFS/configuration/hadoop-env.xml | 29 -----
.../HIVE/configuration/webhcat-site.xml | 11 ++
.../services/SLIDER/package/scripts/params.py | 4 +-
.../ldap/AmbariLdapDataPopulatorTest.java | 32 +++++
.../1.3.2/configs/default.hbasedecom.json | 2 +-
.../python/stacks/1.3.2/configs/default.json | 2 +-
.../1.3.2/configs/default.non_gmetad_host.json | 2 +-
.../stacks/1.3.2/configs/default_client.json | 2 +-
.../python/stacks/1.3.2/configs/secured.json | 2 +-
.../stacks/1.3.2/configs/secured_client.json | 2 +-
.../1.3.2/configs/secured_no_jce_name.json | 2 +-
.../hooks/after-INSTALL/test_after_install.py | 13 --
.../1.3.2/hooks/before-ANY/test_before_any.py | 119 +++++++++++++++++++
.../hooks/before-INSTALL/test_before_install.py | 110 +----------------
.../stacks/2.0.6/HIVE/test_webhcat_server.py | 20 ++++
.../2.0.6/configs/default.hbasedecom.json | 2 +-
.../python/stacks/2.0.6/configs/default.json | 2 +-
.../2.0.6/configs/default.non_gmetad_host.json | 2 +-
.../stacks/2.0.6/configs/default_client.json | 2 +-
.../stacks/2.0.6/configs/flume_target.json | 2 +-
.../python/stacks/2.0.6/configs/ha_default.json | 2 +-
.../python/stacks/2.0.6/configs/ha_secured.json | 2 +-
.../python/stacks/2.0.6/configs/secured.json | 2 +-
.../stacks/2.0.6/configs/secured_client.json | 2 +-
.../2.0.6/configs/secured_no_jce_name.json | 2 +-
.../hooks/after-INSTALL/test_after_install.py | 13 --
.../2.0.6/hooks/before-ANY/test_before_any.py | 119 +++++++++++++++++++
.../hooks/before-INSTALL/test_before_install.py | 110 +----------------
.../test/python/stacks/2.1/configs/default.json | 2 +-
.../test/python/stacks/2.1/configs/secured.json | 2 +-
.../test/python/stacks/2.2/configs/default.json | 2 +-
.../test/python/stacks/2.2/configs/secured.json | 2 +-
ambari-web/app/app.js | 2 +
.../data/requests/host_check/jdk_name.json | 2 +-
ambari-web/app/controllers/application.js | 4 +-
.../controllers/global/cluster_controller.js | 22 ++++
ambari-web/app/controllers/main.js | 4 +-
ambari-web/app/controllers/main/host.js | 24 ----
.../app/controllers/main/host/add_controller.js | 1 +
ambari-web/app/controllers/main/host/details.js | 6 +-
.../controllers/main/service/info/configs.js | 10 +-
.../app/controllers/main/views_controller.js | 4 -
.../app/controllers/wizard/step3_controller.js | 8 +-
.../app/controllers/wizard/step7_controller.js | 4 +-
.../app/controllers/wizard/step8_controller.js | 2 +-
ambari-web/app/data/HDP2/site_properties.js | 14 ++-
.../mappers/service_config_version_mapper.js | 1 +
ambari-web/app/mappers/stack_service_mapper.js | 7 +-
ambari-web/app/messages.js | 2 +-
ambari-web/app/mixins/common/serverValidator.js | 61 ++--------
ambari-web/app/models/repository.js | 2 +-
ambari-web/app/models/service_config_version.js | 23 +++-
ambari-web/app/routes/installer.js | 3 +-
ambari-web/app/routes/main.js | 3 +-
.../templates/main/host/component_filter.hbs | 6 +-
ambari-web/app/utils/ajax/ajax.js | 4 +-
ambari-web/app/utils/components.js | 33 ++++-
ambari-web/app/utils/helper.js | 15 +++
.../views/common/configs/config_history_flow.js | 19 ++-
ambari-web/app/views/main/host.js | 36 +++++-
ambari-web/app/views/main/views/details.js | 54 +++++++++
ambari-web/test/utils/date_test.js | 7 +-
.../main/dashboard/config_history_view_test.js | 24 ++--
.../slider-core/0.51.0/slider-core-0.51.0.jar | Bin 1146908 -> 1155217 bytes
.../slider/SliderAppsViewControllerImpl.java | 98 +++++++++------
.../createAppWizard/step3_controller.js | 20 ++--
.../createAppWizard/step4_controller.js | 59 +++++++--
.../src/main/resources/ui/app/helpers/ajax.js | 2 +-
.../ui/app/mappers/slider_apps_mapper.js | 1 +
.../ui/app/mixins/ajax_error_handler.js | 2 +-
.../main/resources/ui/app/styles/common.less | 3 +
.../main/resources/ui/app/styles/wizard.less | 44 +++----
.../resources/ui/app/templates/application.hbs | 2 +-
.../ui/app/templates/createAppWizard/step1.hbs | 10 +-
.../ui/app/templates/createAppWizard/step2.hbs | 8 +-
.../src/main/resources/ui/app/translations.js | 11 +-
.../resources/ui/app/views/application_view.js | 11 +-
.../ui/app/views/common/config_set_view.js | 7 +-
.../ui/app/views/create_app_wizard_view.js | 6 +-
dev-support/test-patch.sh | 62 ----------
pom.xml | 2 +-
127 files changed, 1477 insertions(+), 910 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b9cca713/ambari-agent/src/main/python/ambari_agent/Controller.py
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b9cca713/ambari-web/app/controllers/main/host.js
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b9cca713/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
[37/50] [abbrv] git commit: AMBARI-7508 - Alerts: Reschedule
Individual Alerts on Agents (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7508 - Alerts: Reschedule Individual Alerts on Agents (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7db82c92
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7db82c92
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7db82c92
Branch: refs/heads/trunk
Commit: 7db82c923c2903a2e2fab3d302fb9337423da08b
Parents: 2448352
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Sep 25 22:19:49 2014 -0700
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Sep 26 09:38:10 2014 -0700
----------------------------------------------------------------------
.../ambari_agent/AlertSchedulerHandler.py | 98 ++++++-
.../python/ambari_agent/alerts/base_alert.py | 37 ++-
.../python/ambari_agent/alerts/collector.py | 21 +-
.../src/test/python/ambari_agent/TestAlerts.py | 50 ++++
.../ambari_agent/dummy_files/definitions.json | 1 +
ambari-project/pom.xml | 7 +-
ambari-server/pom.xml | 12 +-
.../internal/AlertGroupResourceProvider.java | 33 ++-
.../events/AlertDefinitionDeleteEvent.java | 55 ++++
.../ambari/server/events/AmbariEvent.java | 7 +-
.../listeners/AlertLifecycleListener.java | 54 +++-
.../events/listeners/AlertReceivedListener.java | 8 +
.../server/orm/dao/AlertDefinitionDAO.java | 13 +
.../apache/ambari/server/orm/dao/AlertsDAO.java | 1 +
.../orm/entities/AlertDefinitionEntity.java | 15 +-
.../server/orm/entities/AlertGroupEntity.java | 5 +-
.../state/alert/AggregateDefinitionMapping.java | 31 +-
.../server/state/alert/AlertDefinition.java | 19 ++
.../state/alert/AlertDefinitionFactory.java | 1 +
.../server/state/alert/AlertDefinitionHash.java | 293 +++++++++++--------
.../AlertGroupResourceProviderTest.java | 87 ++++++
.../server/orm/dao/AlertDefinitionDAOTest.java | 6 +-
.../alerts/AlertDefinitionEqualityTest.java | 1 +
.../state/alerts/AlertEventPublisherTest.java | 68 ++++-
.../alerts/AlertStateChangedEventTest.java | 12 +-
.../state/cluster/AlertDataManagerTest.java | 2 +-
26 files changed, 755 insertions(+), 182 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
index 7cce533..8dcce50 100644
--- a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
+++ b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
@@ -61,22 +61,25 @@ class AlertSchedulerHandler():
logger.critical("Could not create the cache directory {0}".format(cachedir))
pass
+ self._collector = AlertCollector()
self.__scheduler = Scheduler(AlertSchedulerHandler.APS_CONFIG)
self.__in_minutes = in_minutes
- self.__collector = AlertCollector()
self.__config_maps = {}
+
- def update_definitions(self, alert_commands, refresh_jobs=False):
+ def update_definitions(self, alert_commands, reschedule_jobs=False):
''' updates the persisted definitions and restarts the scheduler '''
with open(os.path.join(self.cachedir, self.FILENAME), 'w') as f:
json.dump(alert_commands, f, indent=2)
- if refresh_jobs:
- self.start()
+ if reschedule_jobs:
+ self.reschedule()
+
def __make_function(self, alert_def):
return lambda: alert_def.collect()
+
def start(self):
''' loads definitions from file and starts the scheduler '''
@@ -90,26 +93,72 @@ class AlertSchedulerHandler():
alert_callables = self.__load_definitions()
+ # schedule each definition
for _callable in alert_callables:
- if self.__in_minutes:
- self.__scheduler.add_interval_job(self.__make_function(_callable),
- minutes=_callable.interval())
- else:
- self.__scheduler.add_interval_job(self.__make_function(_callable),
- seconds=_callable.interval())
+ self.schedule_definition(_callable)
logger.debug("Starting scheduler {0}; currently running: {1}".format(
str(self.__scheduler), str(self.__scheduler.running)))
+
self.__scheduler.start()
+
def stop(self):
if not self.__scheduler is None:
self.__scheduler.shutdown(wait=False)
self.__scheduler = Scheduler(AlertSchedulerHandler.APS_CONFIG)
+
+
+ def reschedule(self):
+ '''
+ Removes jobs that are scheduled where their UUID no longer is valid.
+ Schedules jobs where the definition UUID is not currently scheduled.
+ '''
+ jobs_scheduled = 0
+ jobs_removed = 0
+
+ definitions = self.__load_definitions()
+ scheduled_jobs = self.__scheduler.get_jobs()
+
+ # for every scheduled job, see if its UUID is still valid
+ for scheduled_job in scheduled_jobs:
+ uuid_valid = False
+
+ for definition in definitions:
+ definition_uuid = definition.definition_uuid()
+ if scheduled_job.name == definition_uuid:
+ uuid_valid = True
+ break
+
+ # jobs without valid UUIDs should be unscheduled
+ if uuid_valid == False:
+ jobs_removed += 1
+ logger.info("Unscheduling {0}".format(scheduled_job.name))
+ self._collector.remove_by_uuid(scheduled_job.name)
+ self.__scheduler.unschedule_job(scheduled_job)
+ # for every definition, determine if there is a scheduled job
+ for definition in definitions:
+ definition_scheduled = False
+ for scheduled_job in scheduled_jobs:
+ definition_uuid = definition.definition_uuid()
+ if definition_uuid == scheduled_job.name:
+ definition_scheduled = True
+ break
+
+ # if no jobs are found with the definitions UUID, schedule it
+ if definition_scheduled == False:
+ jobs_scheduled += 1
+ self.schedule_definition(definition)
+
+ logger.info("Alert Reschedule Summary: {0} rescheduled, {1} unscheduled".format(
+ str(jobs_scheduled), str(jobs_removed)))
+
+
def collector(self):
''' gets the collector for reporting to the server '''
- return self.__collector
+ return self._collector
+
def __load_definitions(self):
''' loads all alert commands from the file. all clusters are stored in one file '''
@@ -147,7 +196,7 @@ class AlertSchedulerHandler():
vals = self.__find_config_values(configmap, obj.get_lookup_keys())
self.__config_maps[clusterName].update(vals)
- obj.set_helpers(self.__collector, self.__config_maps[clusterName])
+ obj.set_helpers(self._collector, self.__config_maps[clusterName])
definitions.append(obj)
@@ -208,7 +257,30 @@ class AlertSchedulerHandler():
configmap = command['configurations']
keylist = self.__config_maps[clusterName].keys()
vals = self.__find_config_values(configmap, keylist)
- self.__config_maps[clusterName].update(vals)
+ self.__config_maps[clusterName].update(vals)
+
+
+ def schedule_definition(self,definition):
+ '''
+ Schedule a definition (callable). Scheduled jobs are given the UUID
+ as their name so that they can be identified later on.
+ '''
+ job = None
+
+ if self.__in_minutes:
+ job = self.__scheduler.add_interval_job(self.__make_function(definition),
+ minutes=definition.interval())
+ else:
+ job = self.__scheduler.add_interval_job(self.__make_function(definition),
+ seconds=definition.interval())
+
+ # although the documentation states that Job(kwargs) takes a name
+ # key/value pair, it does not actually set the name; do it manually
+ if job is not None:
+ job.name = definition.definition_uuid()
+
+ logger.info("Scheduling {0} with UUID {1}".format(
+ definition.definition_name(), definition.definition_uuid()))
def main():
args = list(sys.argv)
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index b22938d..10dcff8 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -46,17 +46,34 @@ class BaseAlert(object):
else:
interval = self.alert_meta['interval']
return 1 if interval < 1 else interval
-
+
+
+ def definition_name(self):
+ '''
+ gets the unique name of the alert definition
+ '''
+ return self.alert_meta['name']
+
+
+ def definition_uuid(self):
+ '''
+ gets the unique has of the alert definition
+ '''
+ return self.alert_meta['uuid']
+
+
def set_helpers(self, collector, value_dict):
''' sets helper objects for alerts without having to use them in a constructor '''
self.collector = collector
self.config_value_dict = value_dict
-
+
+
def set_cluster(self, cluster, host):
''' sets cluster information for the alert '''
self.cluster = cluster
self.host_name = host
-
+
+
def collect(self):
''' method used for collection. defers to _collect() '''
@@ -83,12 +100,14 @@ class BaseAlert(object):
data['service'] = self._find_value('serviceName')
data['component'] = self._find_value('componentName')
data['timestamp'] = long(time.time() * 1000)
+ data['uuid'] = self._find_value('uuid')
if logger.isEnabledFor(logging.DEBUG):
logger.debug("debug alert text: {0}".format(data['text']))
self.collector.put(self.cluster, data)
-
+
+
def _find_value(self, meta_key):
''' safe way to get a value when outputting result json. will not throw an exception '''
if self.alert_meta.has_key(meta_key):
@@ -96,10 +115,12 @@ class BaseAlert(object):
else:
return None
+
def get_lookup_keys(self):
''' returns a list of lookup keys found for this alert '''
return self._lookup_keys
-
+
+
def _find_lookup_property(self, key):
'''
check if the supplied key is parameterized
@@ -112,7 +133,8 @@ class BaseAlert(object):
return keys[0]
return key
-
+
+
def _lookup_property_value(self, key):
'''
in the case of specifying a configuration path, lookup that path's value
@@ -124,7 +146,8 @@ class BaseAlert(object):
return self.config_value_dict[key]
else:
return None
-
+
+
def _collect(self):
'''
Low level function to collect alert data. The result is a tuple as:
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-agent/src/main/python/ambari_agent/alerts/collector.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/collector.py b/ambari-agent/src/main/python/ambari_agent/alerts/collector.py
index 7249449..9943211 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/collector.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/collector.py
@@ -33,8 +33,27 @@ class AlertCollector():
if not cluster in self.__buckets:
self.__buckets[cluster] = {}
- self.__buckets[cluster][alert['name']] = alert
+ self.__buckets[cluster][alert['name']] = alert
+ def remove(self, cluster, alert_name):
+ '''
+ Removes the alert with the specified name if it exists in the dictionary
+ '''
+ if not cluster in self.__buckets:
+ return
+
+ del self.__buckets[cluster][alert_name]
+
+ def remove_by_uuid(self, alert_uuid):
+ '''
+ Removes the alert with the specified uuid if it exists in the dictionary
+ '''
+ for cluster,alert_map in self.__buckets.iteritems():
+ for alert_name in alert_map.keys():
+ alert = alert_map[alert_name]
+ if alert['uuid'] == alert_uuid:
+ self.remove(cluster, alert_name)
+
def alerts(self):
alerts = []
for clustermap in self.__buckets.values()[:]:
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
index 5dc45b5..662d8ee 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
@@ -56,6 +56,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "PORT",
"uri": "{{hdfs-site/my-key}}",
@@ -86,6 +87,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "PORT",
"uri": "http://c6401.ambari.apache.org",
@@ -115,6 +117,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "SCRIPT",
"path": "test_script.py",
@@ -152,6 +155,7 @@ class TestAlerts(TestCase):
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
"source": {
"type": "METRIC",
"uri": "http://myurl:8633",
@@ -197,3 +201,49 @@ class TestAlerts(TestCase):
self.assertEquals('OK', collector.alerts()[0]['state'])
self.assertEquals('ok_arr: 1 3 None', collector.alerts()[0]['text'])
+ def test_reschedule(self):
+ test_file_path = os.path.join('ambari_agent', 'dummy_files')
+ test_stack_path = os.path.join('ambari_agent', 'dummy_files')
+
+ ash = AlertSchedulerHandler(test_file_path, test_stack_path)
+ ash.start()
+ ash.reschedule()
+
+
+ def test_alert_collector_purge(self):
+ json = { "name": "namenode_process",
+ "service": "HDFS",
+ "component": "NAMENODE",
+ "label": "NameNode process",
+ "interval": 6,
+ "scope": "host",
+ "uuid": "c1f73191-4481-4435-8dae-fd380e4c0be1",
+ "source": {
+ "type": "PORT",
+ "uri": "{{hdfs-site/my-key}}",
+ "default_port": 50070,
+ "reporting": {
+ "ok": {
+ "text": "TCP OK - {0:.4f} response time on port {1}"
+ },
+ "critical": {
+ "text": "Could not load process info: {0}"
+ }
+ }
+ }
+ }
+
+ collector = AlertCollector()
+
+ pa = PortAlert(json, json['source'])
+ pa.set_helpers(collector, {'hdfs-site/my-key': 'value1'})
+ self.assertEquals(6, pa.interval())
+
+ res = pa.collect()
+
+ self.assertIsNotNone(collector.alerts()[0])
+ self.assertEquals('CRITICAL', collector.alerts()[0]['state'])
+
+ collector.remove_by_uuid('c1f73191-4481-4435-8dae-fd380e4c0be1')
+ self.assertEquals(0,len(collector.alerts()))
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
index ad52abc..30973c2 100644
--- a/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
+++ b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
@@ -16,6 +16,7 @@
"label": "NameNode process",
"interval": 6,
"scope": "host",
+ "uuid": "3f82ae27-fa6a-465b-b77d-67963ac55d2f",
"source": {
"type": "PORT",
"uri": "{{hdfs-site/dfs.namenode.http-address}}",
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-project/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml
index 58e2e8f..edba1dc 100644
--- a/ambari-project/pom.xml
+++ b/ambari-project/pom.xml
@@ -55,8 +55,9 @@
</pluginRepositories>
<repositories>
<repository>
- <id>EclipseLink</id>
- <url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
+ <id>oss.sonatype.org</id>
+ <name>OSS Sonatype Staging</name>
+ <url>https://oss.sonatype.org/content/groups/staging</url>
</repository>
<repository>
<id>spring-milestones</id>
@@ -211,7 +212,7 @@
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
- <version>2.4.0</version>
+ <version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index 5ac76f9..f37a177 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -191,7 +191,7 @@
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
- <version>2.4.0</version>
+ <version>2.4.2</version>
</dependency>
</dependencies>
</plugin>
@@ -1451,14 +1451,12 @@
<version>1.5.2</version>
</dependency>
</dependencies>
- <!--<reporting> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId> <version>2.5.2</version> </plugin>
- </plugins> </reporting> -->
-
+
<pluginRepositories>
<pluginRepository>
- <id>EclipseLink</id>
- <url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
+ <id>oss.sonatype.org</id>
+ <name>OSS Sonatype Staging</name>
+ <url>https://oss.sonatype.org/content/groups/staging</url>
</pluginRepository>
</pluginRepositories>
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
index fc51ddd..8c55aa7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
@@ -314,10 +314,6 @@ public class AlertGroupResourceProvider extends
Collection<Long> targetIds = (Collection<Long>) requestMap.get(ALERT_GROUP_TARGETS);
Collection<Long> definitionIds = (Collection<Long>) requestMap.get(ALERT_GROUP_DEFINITIONS);
- if (!StringUtils.isBlank(name)) {
- entity.setGroupName(name);
- }
-
// if targets were supplied, replace existing
Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
if (null != targetIds && targetIds.size() > 0) {
@@ -331,17 +327,26 @@ public class AlertGroupResourceProvider extends
entity.setAlertTargets(targets);
}
- // if definitions were supplied, replace existing
- Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
- if (null != definitionIds && definitionIds.size() > 0) {
- List<Long> ids = new ArrayList<Long>(definitionIds.size());
- ids.addAll(definitionIds);
- definitions.addAll(s_definitionDao.findByIds(ids));
+ // only the targets should be updatable on default groups; everything
+ // else is valid only on regular groups
+ if (!entity.isDefault()) {
+ // set the name if supplied
+ if (!StringUtils.isBlank(name)) {
+ entity.setGroupName(name);
+ }
- entity.setAlertDefinitions(definitions);
- } else if (definitionIds.size() == 0) {
- // empty array supplied, clear out existing definitions
- entity.setAlertDefinitions(definitions);
+ // if definitions were supplied, replace existing
+ Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
+ if (null != definitionIds && definitionIds.size() > 0) {
+ List<Long> ids = new ArrayList<Long>(definitionIds.size());
+ ids.addAll(definitionIds);
+ definitions.addAll(s_definitionDao.findByIds(ids));
+
+ entity.setAlertDefinitions(definitions);
+ } else {
+ // empty array supplied, clear out existing definitions
+ entity.setAlertDefinitions(definitions);
+ }
}
s_dao.merge(entity);
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionDeleteEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionDeleteEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionDeleteEvent.java
new file mode 100644
index 0000000..c8fd36b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionDeleteEvent.java
@@ -0,0 +1,55 @@
+/**
+ * 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.ambari.server.events;
+
+import org.apache.ambari.server.state.alert.AlertDefinition;
+
+/**
+ * The {@link AlertDefinitionDeleteEvent} is used to represent that an
+ * {@link AlertDefinition} has been removed from the system.
+ */
+public class AlertDefinitionDeleteEvent extends ClusterEvent {
+
+ /**
+ * The removed alert defintiion
+ */
+ private final AlertDefinition m_definition;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterId
+ * the ID of the cluster that the definition is in.
+ * @param definition
+ * the alert definition being registered.
+ */
+ public AlertDefinitionDeleteEvent(
+ long clusterId, AlertDefinition definition) {
+ super(AmbariEventType.ALERT_DEFINITION_REMOVAL, clusterId);
+ m_definition = definition;
+ }
+
+ /**
+ * Get the registered alert definition.
+ *
+ * @return the alert definition (not {@code null}).
+ */
+ public AlertDefinition getDefinition() {
+ return m_definition;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
index 6cf752e..3dae676 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
@@ -35,7 +35,12 @@ public abstract class AmbariEvent {
/**
* An alert definition is registered with the system.
*/
- ALERT_DEFINITION_REGISTRATION;
+ ALERT_DEFINITION_REGISTRATION,
+
+ /**
+ * An alert definition is removed from the system.
+ */
+ ALERT_DEFINITION_REMOVAL;
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
index 43d4b35..9d2f4c6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
@@ -17,15 +17,22 @@
*/
package org.apache.ambari.server.events.listeners;
+import java.util.Set;
+
+import org.apache.ambari.server.events.AlertDefinitionDeleteEvent;
import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.state.alert.AggregateDefinitionMapping;
import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.AlertDefinitionHash;
import org.apache.ambari.server.state.alert.SourceType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import com.google.inject.Singleton;
/**
@@ -34,6 +41,10 @@ import com.google.inject.Singleton;
*/
@Singleton
public class AlertLifecycleListener {
+ /**
+ * Logger.
+ */
+ private static Logger LOG = LoggerFactory.getLogger(AlertLifecycleListener.class);
/**
* Used for quick lookups of aggregate alerts.
@@ -42,6 +53,13 @@ public class AlertLifecycleListener {
private AggregateDefinitionMapping m_aggregateMapping;
/**
+ * Invalidates hosts so that they can receive updated alert definition
+ * commands.
+ */
+ @Inject
+ private Provider<AlertDefinitionHash> m_alertDefinitionHash;
+
+ /**
* Constructor.
*
* @param publisher
@@ -66,8 +84,42 @@ public class AlertLifecycleListener {
public void onAmbariEvent(AlertDefinitionRegistrationEvent event) {
AlertDefinition definition = event.getDefinition();
+ LOG.debug("Registering alert definition {}", definition);
+
if (definition.getSource().getType() == SourceType.AGGREGATE) {
- m_aggregateMapping.addAggregateType(event.getClusterId(), definition);
+ m_aggregateMapping.registerAggregate(event.getClusterId(), definition);
+ }
+ }
+
+ /**
+ * Handles {@link AlertDefinitionDeleteEvent} by performing the following
+ * tasks:
+ * <ul>
+ * <li>Removal from with {@link AggregateDefinitionMapping}</li>
+ * <li>{@link AlertDefinitionHash} invalidation</li>
+ * </ul>
+ *
+ * @param event
+ * the event being handled.
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ public void onAmbariEvent(AlertDefinitionDeleteEvent event) {
+ AlertDefinition definition = event.getDefinition();
+
+ LOG.debug("Removing alert definition {}", definition);
+
+ if (null == definition) {
+ return;
}
+
+ m_aggregateMapping.removeAssociatedAggregate(event.getClusterId(),
+ definition.getName());
+
+ AlertDefinitionHash hashHelper = m_alertDefinitionHash.get();
+ Set<String> invalidatedHosts = hashHelper.invalidateHosts(definition);
+
+ hashHelper.enqueueAgentCommands(definition.getClusterId(),
+ invalidatedHosts);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
index e87ba7d..78d8e66 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
@@ -101,6 +101,14 @@ public class AlertReceivedListener {
AlertDefinitionEntity definition = m_definitionDao.findByName(clusterId,
alert.getName());
+ if (null == definition) {
+ LOG.warn(
+ "Received an alert for {} which is a definition that does not exist anymore",
+ alert.getName());
+
+ return;
+ }
+
AlertHistoryEntity history = createHistory(clusterId, definition, alert);
current = new AlertCurrentEntity();
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
index 075ee04..8e8c808 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
@@ -25,6 +25,7 @@ import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.apache.ambari.server.controller.RootServiceResponseFactory;
+import org.apache.ambari.server.events.AlertDefinitionDeleteEvent;
import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
@@ -364,6 +365,18 @@ public class AlertDefinitionDAO {
if (null != alertDefinition) {
entityManager.remove(alertDefinition);
}
+
+ // publish the alert definition removal
+ AlertDefinition coerced = alertDefinitionFactory.coerce(alertDefinition);
+ if (null != coerced) {
+ AlertDefinitionDeleteEvent event = new AlertDefinitionDeleteEvent(
+ alertDefinition.getClusterId(), coerced);
+
+ eventPublisher.publish(event);
+ } else {
+ LOG.warn("Unable to broadcast alert removal event for {}",
+ alertDefinition.getDefinitionName());
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index a28b448..f2161f3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -515,6 +515,7 @@ public class AlertsDAO {
query.setParameter("clusterId", Long.valueOf(clusterId));
query.setParameter("definitionName", alertName);
+ query = setQueryRefreshHint(query);
return daoUtils.selectOne(query);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
index 8548fda..4ab2c80 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
@@ -17,7 +17,9 @@
*/
package org.apache.ambari.server.orm.entities;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.Set;
import javax.persistence.Basic;
@@ -363,7 +365,7 @@ public class AlertDefinitionEntity {
* @return the groups, or {@code null} if none.
*/
public Set<AlertGroupEntity> getAlertGroups() {
- return alertGroups;
+ return Collections.unmodifiableSet(alertGroups);
}
/**
@@ -418,7 +420,7 @@ public class AlertDefinitionEntity {
* @param alertGroup
*/
protected void removeAlertGroup(AlertGroupEntity alertGroup) {
- if (null != alertGroups) {
+ if (null != alertGroups && alertGroups.contains(alertGroup)) {
alertGroups.remove(alertGroup);
}
}
@@ -429,12 +431,15 @@ public class AlertDefinitionEntity {
*/
@PreRemove
public void preRemove() {
- Set<AlertGroupEntity> groups = getAlertGroups();
- if (null == groups || groups.size() == 0) {
+ if (null == alertGroups || alertGroups.size() == 0) {
return;
}
- for (AlertGroupEntity group : groups) {
+ Iterator<AlertGroupEntity> iterator = alertGroups.iterator();
+ while (iterator.hasNext()) {
+ AlertGroupEntity group = iterator.next();
+ iterator.remove();
+
group.removeAlertDefinition(this);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
index 1cc9bcc..ac3586d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
+import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -73,14 +74,14 @@ public class AlertGroupEntity {
/**
* Bi-directional many-to-many association to {@link AlertDefinitionEntity}
*/
- @ManyToMany
+ @ManyToMany(cascade = CascadeType.MERGE)
@JoinTable(name = "alert_grouping", joinColumns = { @JoinColumn(name = "group_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "definition_id", nullable = false) })
private Set<AlertDefinitionEntity> alertDefinitions;
/**
* Unidirectional many-to-many association to {@link AlertTargetEntity}
*/
- @ManyToMany
+ @ManyToMany(cascade = CascadeType.MERGE)
@JoinTable(name = "alert_group_target", joinColumns = { @JoinColumn(name = "group_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "target_id", nullable = false) })
private Set<AlertTargetEntity> alertTargets;
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
index 04f20f9..c63c0d4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
@@ -19,6 +19,7 @@ package org.apache.ambari.server.state.alert;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import com.google.inject.Singleton;
@@ -33,7 +34,8 @@ public final class AggregateDefinitionMapping {
* In-memory mapping of cluster ID to definition name / aggregate definition.
* This is used for fast lookups when receiving events.
*/
- private Map<Long, Map<String, AlertDefinition>> m_aggregateMap = new HashMap<Long, Map<String, AlertDefinition>>();
+ private Map<Long, Map<String, AlertDefinition>> m_aggregateMap =
+ new ConcurrentHashMap<Long, Map<String, AlertDefinition>>();
/**
* Constructor.
@@ -69,10 +71,10 @@ public final class AggregateDefinitionMapping {
*
* @param clusterId
* the ID of the cluster that the definition is bound to.
- * @param name
- * the unique name of the definition.
+ * @param definition
+ * the aggregate definition to register (not {@code null}).
*/
- public void addAggregateType(long clusterId, AlertDefinition definition) {
+ public void registerAggregate(long clusterId, AlertDefinition definition) {
Long id = Long.valueOf(clusterId);
if (!m_aggregateMap.containsKey(id)) {
@@ -85,4 +87,25 @@ public final class AggregateDefinitionMapping {
map.put(as.getAlertName(), definition);
}
+
+ /**
+ * Removes the associated aggregate for the specified aggregated definition.
+ *
+ * @param clusterId
+ * the ID of the cluster that the definition is bound to.
+ * @param name
+ * the unique name of the definition for which aggregates should be
+ * unassociated (not {@code null}).
+ */
+ public void removeAssociatedAggregate(long clusterId,
+ String aggregatedDefinitonName) {
+ Long id = Long.valueOf(clusterId);
+
+ if (!m_aggregateMap.containsKey(id)) {
+ return;
+ }
+
+ Map<String, AlertDefinition> map = m_aggregateMap.get(id);
+ map.remove(aggregatedDefinitonName);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
index 5058e91..961fb66 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
@@ -34,6 +34,7 @@ import java.util.HashSet;
*/
public class AlertDefinition {
+ private long clusterId;
private String serviceName = null;
private String componentName = null;
@@ -46,6 +47,24 @@ public class AlertDefinition {
private String uuid = null;
/**
+ * Gets the cluster ID for this definition.
+ *
+ * @return
+ */
+ public long getClusterId() {
+ return clusterId;
+ }
+
+ /**
+ * Sets the cluster ID for this definition.
+ *
+ * @param clusterId
+ */
+ public void setClusterId(long clusterId) {
+ this.clusterId = clusterId;
+ }
+
+ /**
* @return the service name
*/
public String getServiceName() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
index 4f6a9a3..9c72b6a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
@@ -125,6 +125,7 @@ public class AlertDefinitionFactory {
}
AlertDefinition definition = new AlertDefinition();
+ definition.setClusterId(entity.getClusterId());
definition.setComponentName(entity.getComponentName());
definition.setEnabled(entity.getEnabled());
definition.setInterval(entity.getScheduleInterval());
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
index 9ea039c..35d7742 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
@@ -262,85 +262,19 @@ public class AlertDefinitionHash {
/**
- * Gets the alert definition entities for the specified host. This will include the
- * following types of alert definitions:
- * <ul>
- * <li>Service/Component alerts</li>
- * <li>Service alerts where the host is a MASTER</li>
- * <li>Host alerts that are not bound to a service</li>
- * </ul>
+ * Invalidate the hashes of any host that would be affected by the specified
+ * definition.
*
- * @param clusterName
- * the cluster name (not {@code null}).
- * @param hostName
- * the host name (not {@code null}).
- * @return the alert definitions for the host, or an empty set (never
+ * @param definition
+ * the definition to use to find the hosts to invlidate (not
+ * {@code null}).
+ * @return the hosts that were invalidated, or an empty set (never
* {@code null}).
*/
- private Set<AlertDefinitionEntity> getAlertDefinitionEntities(
- String clusterName,
- String hostName) {
- Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
-
- try {
- Cluster cluster = m_clusters.getCluster(clusterName);
- if (null == cluster) {
- LOG.warn("Unable to get alert definitions for the missing cluster {}",
- clusterName);
-
- return Collections.emptySet();
- }
-
- long clusterId = cluster.getClusterId();
- List<ServiceComponentHost> serviceComponents = cluster.getServiceComponentHosts(hostName);
- if (null == serviceComponents || serviceComponents.size() == 0) {
- LOG.warn(
- "Unable to get alert definitions for {} since there are no service components defined",
- hostName);
-
- return Collections.emptySet();
- }
-
- for (ServiceComponentHost serviceComponent : serviceComponents) {
- String serviceName = serviceComponent.getServiceName();
- String componentName = serviceComponent.getServiceComponentName();
-
- // add all alerts for this service/component pair
- definitions.addAll(m_definitionDao.findByServiceComponent(
- clusterId, serviceName, componentName));
- }
-
- // for every service, get the master components and see if the host
- // is a master
- Set<String> services = new HashSet<String>();
- for (Entry<String, Service> entry : cluster.getServices().entrySet()) {
- Service service = entry.getValue();
- Map<String, ServiceComponent> components = service.getServiceComponents();
- for (Entry<String, ServiceComponent> component : components.entrySet()) {
- if (component.getValue().isMasterComponent()) {
- Map<String, ServiceComponentHost> hosts = component.getValue().getServiceComponentHosts();
-
- if( hosts.containsKey( hostName ) ){
- services.add(service.getName());
- }
- }
- }
- }
-
- // add all service scoped alerts
- if( services.size() > 0 ){
- definitions.addAll(m_definitionDao.findByServiceMaster(clusterId,
- services));
- }
-
- // add any alerts not bound to a service (host level alerts)
- definitions.addAll(m_definitionDao.findAgentScoped(clusterId));
- } catch (AmbariException ambariException) {
- LOG.error("Unable to get alert definitions", ambariException);
- return Collections.emptySet();
- }
-
- return definitions;
+ public Set<String> invalidateHosts(AlertDefinitionEntity definition) {
+ return invalidateHosts(definition.getClusterId(),
+ definition.getDefinitionName(), definition.getServiceName(),
+ definition.getComponentName());
}
/**
@@ -353,8 +287,28 @@ public class AlertDefinitionHash {
* @return the hosts that were invalidated, or an empty set (never
* {@code null}).
*/
- public Set<String> invalidateHosts(AlertDefinitionEntity definition) {
- long clusterId = definition.getClusterId();
+ public Set<String> invalidateHosts(AlertDefinition definition) {
+ return invalidateHosts(definition.getClusterId(), definition.getName(),
+ definition.getServiceName(), definition.getComponentName());
+ }
+
+ /**
+ * Invalidate the hashes of any host that would be affected by the specified
+ * definition.
+ *
+ * @param clusterId
+ * the cluster ID
+ * @param definitionName
+ * the definition unique name.
+ * @param definitionServiceName
+ * the definition's service name.
+ * @param definitionComponentName
+ * the definition's component name.
+ * @return the hosts that were invalidated, or an empty set (never
+ * {@code null}).
+ */
+ public Set<String> invalidateHosts(long clusterId, String definitionName,
+ String definitionServiceName, String definitionComponentName) {
Set<String> invalidatedHosts = new HashSet<String>();
Cluster cluster = null;
@@ -379,8 +333,6 @@ public class AlertDefinitionHash {
}
// intercept host agent alerts; they affect all hosts
- String definitionServiceName = definition.getServiceName();
- String definitionComponentName = definition.getComponentName();
if (Services.AMBARI.equals(definitionServiceName)
&& Components.AMBARI_AGENT.equals(definitionComponentName)) {
@@ -413,7 +365,7 @@ public class AlertDefinitionHash {
Service service = services.get(definitionServiceName);
if (null == service) {
LOG.warn("The alert definition {} has an unknown service of {}",
- definition.getDefinitionName(), definitionServiceName);
+ definitionName, definitionServiceName);
return invalidatedHosts;
}
@@ -439,6 +391,82 @@ public class AlertDefinitionHash {
}
/**
+ * Enqueue {@link AlertDefinitionCommand}s for every host specified so that
+ * they will receive a payload of alert definitions that they should be
+ * running.
+ * <p/>
+ * This method is typically called after
+ * {@link #invalidateHosts(AlertDefinitionEntity)} has caused a cache
+ * invalidation of the alert definition hash.
+ *
+ * @param clusterName
+ * the name of the cluster (not {@code null}).
+ * @param hosts
+ * the hosts to push {@link AlertDefinitionCommand}s for.
+ */
+ public void enqueueAgentCommands(long clusterId, Set<String> hosts) {
+ String clusterName = null;
+
+ try {
+ Cluster cluster = m_clusters.getClusterById(clusterId);
+ clusterName = cluster.getClusterName();
+ } catch (AmbariException ae) {
+ LOG.error("Unable to lookup cluster for alert definition commands", ae);
+ }
+
+ enqueueAgentCommands(clusterName, hosts);
+ }
+
+ /**
+ * Enqueue {@link AlertDefinitionCommand}s for every host specified so that
+ * they will receive a payload of alert definitions that they should be
+ * running.
+ * <p/>
+ * This method is typically called after
+ * {@link #invalidateHosts(AlertDefinitionEntity)} has caused a cache
+ * invalidation of the alert definition hash.
+ *
+ * @param clusterName
+ * the name of the cluster (not {@code null}).
+ * @param hosts
+ * the hosts to push {@link AlertDefinitionCommand}s for.
+ */
+ public void enqueueAgentCommands(String clusterName, Set<String> hosts) {
+ if (null == clusterName) {
+ LOG.warn("Unable to create alert definition agent commands because of a null cluster name");
+ return;
+ }
+
+ if (null == hosts || hosts.size() == 0) {
+ return;
+ }
+
+ for (String hostName : hosts) {
+ List<AlertDefinition> definitions = getAlertDefinitions(clusterName,
+ hostName);
+
+ String hash = getHash(clusterName, hostName);
+
+ AlertDefinitionCommand command = new AlertDefinitionCommand(clusterName,
+ hostName, hash, definitions);
+
+ try {
+ Cluster cluster = m_clusters.getCluster(clusterName);
+ command.addConfigs(m_configHelper.get(), cluster);
+ } catch (AmbariException ae) {
+ LOG.warn("Unable to add configurations to alert definition command", ae);
+ }
+
+ // unlike other commands, the alert definitions commands are really
+ // designed to be 1:1 per change; if multiple invalidations happened
+ // before the next heartbeat, there would be several commands that would
+ // force the agents to reschedule their alerts more than once
+ m_actionQueue.dequeue(hostName, AgentCommandType.ALERT_DEFINITION_COMMAND);
+ m_actionQueue.enqueue(hostName, command);
+ }
+ }
+
+ /**
* Calculates a unique hash value representing all of the alert definitions
* that should be scheduled to run on a given host. Alerts of type
* {@link SourceType#AGGREGATE} are not included in the hash since they are
@@ -492,51 +520,84 @@ public class AlertDefinitionHash {
}
/**
- * Enqueue {@link AlertDefinitionCommand}s for every host specified so that
- * they will receive a payload of alert definitions that they should be
- * running.
- * <p/>
- * This method is typically called after
- * {@link #invalidateHosts(AlertDefinitionEntity)} has caused a cache
- * invalidation of the alert definition hash.
+ * Gets the alert definition entities for the specified host. This will include the
+ * following types of alert definitions:
+ * <ul>
+ * <li>Service/Component alerts</li>
+ * <li>Service alerts where the host is a MASTER</li>
+ * <li>Host alerts that are not bound to a service</li>
+ * </ul>
*
* @param clusterName
- * the name of the cluster (not {@code null}).
- * @param hosts
- * the hosts to push {@link AlertDefinitionCommand}s for.
+ * the cluster name (not {@code null}).
+ * @param hostName
+ * the host name (not {@code null}).
+ * @return the alert definitions for the host, or an empty set (never
+ * {@code null}).
*/
- public void enqueueAgentCommands(String clusterName, Set<String> hosts) {
- if (null == clusterName) {
- LOG.warn("Unable to create alert definition agent commands because of a null cluster name");
- return;
- }
+ private Set<AlertDefinitionEntity> getAlertDefinitionEntities(
+ String clusterName,
+ String hostName) {
+ Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
- if (null == hosts || hosts.size() == 0) {
- return;
- }
+ try {
+ Cluster cluster = m_clusters.getCluster(clusterName);
+ if (null == cluster) {
+ LOG.warn("Unable to get alert definitions for the missing cluster {}",
+ clusterName);
- for (String hostName : hosts) {
- List<AlertDefinition> definitions = getAlertDefinitions(clusterName,
- hostName);
+ return Collections.emptySet();
+ }
- String hash = getHash(clusterName, hostName);
+ long clusterId = cluster.getClusterId();
+ List<ServiceComponentHost> serviceComponents = cluster.getServiceComponentHosts(hostName);
+ if (null == serviceComponents || serviceComponents.size() == 0) {
+ LOG.warn(
+ "Unable to get alert definitions for {} since there are no service components defined",
+ hostName);
- AlertDefinitionCommand command = new AlertDefinitionCommand(clusterName,
- hostName, hash, definitions);
+ return Collections.emptySet();
+ }
- try {
- Cluster cluster = m_clusters.getCluster(clusterName);
- command.addConfigs(m_configHelper.get(), cluster);
- } catch (AmbariException ae) {
- LOG.warn("Unable to add configurations to alert definition command", ae);
+ for (ServiceComponentHost serviceComponent : serviceComponents) {
+ String serviceName = serviceComponent.getServiceName();
+ String componentName = serviceComponent.getServiceComponentName();
+
+ // add all alerts for this service/component pair
+ definitions.addAll(m_definitionDao.findByServiceComponent(
+ clusterId, serviceName, componentName));
}
- // unlike other commands, the alert definitions commands are really
- // designed to be 1:1 per change; if multiple invalidations happened
- // before the next heartbeat, there would be several commands that would
- // force the agents to reschedule their alerts more than once
- m_actionQueue.dequeue(hostName, AgentCommandType.ALERT_DEFINITION_COMMAND);
- m_actionQueue.enqueue(hostName, command);
+ // for every service, get the master components and see if the host
+ // is a master
+ Set<String> services = new HashSet<String>();
+ for (Entry<String, Service> entry : cluster.getServices().entrySet()) {
+ Service service = entry.getValue();
+ Map<String, ServiceComponent> components = service.getServiceComponents();
+ for (Entry<String, ServiceComponent> component : components.entrySet()) {
+ if (component.getValue().isMasterComponent()) {
+ Map<String, ServiceComponentHost> hosts = component.getValue().getServiceComponentHosts();
+
+ if( hosts.containsKey( hostName ) ){
+ services.add(service.getName());
+ }
+ }
+ }
+ }
+
+ // add all service scoped alerts
+ if( services.size() > 0 ){
+ definitions.addAll(m_definitionDao.findByServiceMaster(clusterId,
+ services));
+ }
+
+ // add any alerts not bound to a service (host level alerts)
+ definitions.addAll(m_definitionDao.findAgentScoped(clusterId));
+ } catch (AmbariException ambariException) {
+ LOG.error("Unable to get alert definitions", ambariException);
+ return Collections.emptySet();
}
+
+ return definitions;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
index 5583617..771bf8a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
@@ -383,6 +383,93 @@ public class AlertGroupResourceProviderTest {
}
/**
+ * Tests that updating a default group doesn't change read-only properties
+ *
+ * @throws Exception
+ */
+ @Test
+ @SuppressWarnings("unchecked")
+ public void testUpdateDefaultGroup() throws Exception {
+ Capture<AlertGroupEntity> entityCapture = new Capture<AlertGroupEntity>();
+
+ // the definition IDs to associate with the group
+ List<Long> definitionIds = new ArrayList<Long>();
+ definitionIds.add(ALERT_DEF_ID);
+
+ // the target IDs to associate with the group
+ List<Long> targetIds = new ArrayList<Long>();
+ targetIds.add(ALERT_TARGET_ID);
+
+ // definition entities to return from DAO
+ List<AlertDefinitionEntity> definitionEntities = new ArrayList<AlertDefinitionEntity>();
+ definitionEntities.addAll(getMockDefinitions());
+
+ // target entities to return from DAO
+ List<AlertTargetEntity> newTargetEntities = new ArrayList<AlertTargetEntity>();
+ newTargetEntities.addAll(getMockTargets());
+
+ Set<AlertTargetEntity> mockTargets2 = getMockTargets();
+ AlertTargetEntity target2 = mockTargets2.iterator().next();
+ target2.setTargetId(29L);
+
+ newTargetEntities.add(target2);
+
+ AlertGroupEntity group = new AlertGroupEntity();
+ group.setDefault(true);
+ group.setGroupName(ALERT_GROUP_NAME);
+ group.setAlertDefinitions(getMockDefinitions());
+ group.setAlertTargets(getMockTargets());
+
+ expect(m_dao.findGroupById(ALERT_GROUP_ID)).andReturn(group).times(1);
+ expect(m_dao.merge(capture(entityCapture))).andReturn(group).once();
+
+ // expect target entity lookup for association
+ List<Long> newTargets = Arrays.asList(28L, 29L);
+ expect(m_dao.findTargetsById(EasyMock.eq(newTargets))).andReturn(
+ newTargetEntities).once();
+
+ replay(m_dao, m_definitionDao);
+
+ AlertGroupResourceProvider provider = createProvider(m_amc);
+
+ // create new properties, and include the ID since we're not going through
+ // a service layer which would add it for us automatically
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_ID,
+ ALERT_GROUP_ID.toString());
+
+ // try to change the name (it should not work)
+ String newName = ALERT_GROUP_NAME + " Foo";
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME, newName);
+
+ // try to change the definitions (it should not work)
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_DEFINITIONS,
+ new ArrayList<Long>());
+
+ // try to change the targets (it should work)
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_TARGETS,
+ newTargets);
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals(
+ ALERT_GROUP_CLUSTER_NAME).and().property(
+ AlertGroupResourceProvider.ALERT_GROUP_ID).equals(
+ ALERT_GROUP_ID.toString()).toPredicate();
+
+ Request request = PropertyHelper.getUpdateRequest(requestProps, null);
+ provider.updateResources(request, predicate);
+
+ assertTrue(entityCapture.hasCaptured());
+
+ AlertGroupEntity entity = entityCapture.getValue();
+ assertEquals(ALERT_GROUP_NAME, entity.getGroupName());
+ assertEquals(2, entity.getAlertTargets().size());
+ assertEquals(1, entity.getAlertDefinitions().size());
+
+ verify(m_dao, m_definitionDao);
+ }
+
+ /**
* @throws Exception
*/
@Test
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index 4d182cc..a1cd063 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -118,7 +118,7 @@ public class AlertDefinitionDAOTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
- definition.setSource("Source " + i);
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
dao.create(definition);
}
@@ -133,7 +133,7 @@ public class AlertDefinitionDAOTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(60);
definition.setScope(Scope.HOST);
- definition.setSource("Source " + i);
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
dao.create(definition);
}
@@ -148,7 +148,7 @@ public class AlertDefinitionDAOTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(60);
definition.setScope(Scope.HOST);
- definition.setSource("Source " + i);
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
dao.create(definition);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionEqualityTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionEqualityTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionEqualityTest.java
index fd18134..1ee1224 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionEqualityTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertDefinitionEqualityTest.java
@@ -72,6 +72,7 @@ public class AlertDefinitionEqualityTest extends TestCase {
*/
private AlertDefinition getAlertDefinition(SourceType sourceType) {
AlertDefinition definition = new AlertDefinition();
+ definition.setClusterId(1);
definition.setComponentName("component");
definition.setEnabled(true);
definition.setInterval(1);
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java
index 482b5ef..7309851 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertEventPublisherTest.java
@@ -17,13 +17,20 @@
*/
package org.apache.ambari.server.state.alerts;
+import java.lang.reflect.Field;
+
import junit.framework.Assert;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.events.AlertDefinitionDeleteEvent;
import org.apache.ambari.server.events.AmbariEvent;
+import org.apache.ambari.server.events.listeners.AlertLifecycleListener;
import org.apache.ambari.server.events.listeners.AlertServiceStateListener;
+import org.apache.ambari.server.events.listeners.AlertStateChangedListener;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.OrmTestHelper;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
@@ -33,10 +40,15 @@ import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceFactory;
import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.alert.AggregateDefinitionMapping;
+import org.apache.ambari.server.state.alert.AggregateSource;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.Scope;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import com.google.common.eventbus.EventBus;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.persist.PersistService;
@@ -55,6 +67,9 @@ public class AlertEventPublisherTest {
private Injector injector;
private ServiceFactory serviceFactory;
private AmbariMetaInfo metaInfo;
+ private OrmTestHelper ormHelper;
+ private AggregateDefinitionMapping aggregateMapping;
+ private AmbariEventPublisher eventPublisher;
/**
*
@@ -64,13 +79,25 @@ public class AlertEventPublisherTest {
injector = Guice.createInjector(new InMemoryDefaultTestModule());
injector.getInstance(GuiceJpaInitializer.class);
+ eventPublisher = injector.getInstance(AmbariEventPublisher.class);
+ EventBus synchronizedBus = new EventBus();
+
// force singleton init via Guice so the listener registers with the bus
- injector.getInstance(AlertServiceStateListener.class);
+ synchronizedBus.register(injector.getInstance(AlertLifecycleListener.class));
+ synchronizedBus.register(injector.getInstance(AlertStateChangedListener.class));
+ synchronizedBus.register(injector.getInstance(AlertServiceStateListener.class));
+
+ // !!! need a synchronous op for testing
+ Field field = AmbariEventPublisher.class.getDeclaredField("m_eventBus");
+ field.setAccessible(true);
+ field.set(eventPublisher, synchronizedBus);
dispatchDao = injector.getInstance(AlertDispatchDAO.class);
definitionDao = injector.getInstance(AlertDefinitionDAO.class);
clusters = injector.getInstance(Clusters.class);
serviceFactory = injector.getInstance(ServiceFactory.class);
+ ormHelper = injector.getInstance(OrmTestHelper.class);
+ aggregateMapping = injector.getInstance(AggregateDefinitionMapping.class);
metaInfo = injector.getInstance(AmbariMetaInfo.class);
metaInfo.init();
@@ -107,7 +134,7 @@ public class AlertEventPublisherTest {
/**
* Tests that all {@link AlertDefinitionEntity} instances are created for the
* installed service.
- *
+ *
* @throws Exception
*/
@Test
@@ -118,6 +145,43 @@ public class AlertEventPublisherTest {
}
/**
+ * Tests that {@link AlertDefinitionDeleteEvent} instances are fired when a
+ * definition is removed.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testAlertDefinitionRemoval() throws Exception {
+ Assert.assertEquals(0, definitionDao.findAll().size());
+ AlertDefinitionEntity definition = ormHelper.createAlertDefinition(1L);
+ Assert.assertEquals(1, definitionDao.findAll().size());
+
+ AggregateSource source = new AggregateSource();
+ source.setAlertName(definition.getDefinitionName());
+
+ AlertDefinition aggregate = new AlertDefinition();
+ aggregate.setClusterId(1L);
+ aggregate.setComponentName("DATANODE");
+ aggregate.setEnabled(true);
+ aggregate.setInterval(1);
+ aggregate.setLabel("DataNode Aggregate");
+ aggregate.setName("datanode_aggregate");
+ aggregate.setScope(Scope.ANY);
+ aggregate.setServiceName("HDFS");
+ aggregate.setSource(source);
+ aggregate.setUuid("uuid");
+
+ aggregateMapping.registerAggregate(1L, aggregate);
+ Assert.assertNotNull(aggregateMapping.getAggregateDefinition(1L,
+ source.getAlertName()));
+
+ definitionDao.remove(definition);
+
+ Assert.assertNull(aggregateMapping.getAggregateDefinition(1L,
+ source.getAlertName()));
+ }
+
+ /**
* Calls {@link Service#persist()} to mock a service install.
*/
private void installHdfsService() throws Exception {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
index 312f297..18b4123 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.server.state.alerts;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
@@ -39,6 +40,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import com.google.common.eventbus.EventBus;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Injector;
@@ -72,6 +74,14 @@ public class AlertStateChangedEventTest {
dispatchDao = injector.getInstance(AlertDispatchDAO.class);
eventPublisher = injector.getInstance(AlertEventPublisher.class);
+
+ EventBus synchronizedBus = new EventBus();
+ synchronizedBus.register(injector.getInstance(AlertStateChangedListener.class));
+
+ // !!! need a synchronous op for testing
+ Field field = AlertEventPublisher.class.getDeclaredField("m_eventBus");
+ field.setAccessible(true);
+ field.set(eventPublisher, synchronizedBus);
}
/**
@@ -99,8 +109,6 @@ public class AlertStateChangedEventTest {
// async publishing
eventPublisher.publish(event);
- Thread.sleep(2000);
-
EasyMock.verify(dispatchDao, history, event);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7db82c92/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
index 85a6e9b..502c3b9 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
@@ -373,7 +373,7 @@ public class AlertDataManagerTest {
AggregateDefinitionMapping aggregateMapping = injector.getInstance(AggregateDefinitionMapping.class);
AlertDefinition aggregateDefinition = factory.coerce(aggDef);
- aggregateMapping.addAggregateType(clusterId.longValue(),
+ aggregateMapping.registerAggregate(clusterId.longValue(),
aggregateDefinition );
AggregateSource as = (AggregateSource) aggregateDefinition.getSource();
[32/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e6cc0587
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e6cc0587
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e6cc0587
Branch: refs/heads/trunk
Commit: e6cc05872462d53f9b420837f129921d0e2e0b24
Parents: 7f86e75 802df76
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Sep 22 10:47:55 2014 -0700
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Sep 22 10:47:55 2014 -0700
----------------------------------------------------------------------
ambari-server/pom.xml | 22 ++++
.../internal/ClientConfigResourceProvider.java | 33 ++++-
.../internal/ConfigGroupResourceProvider.java | 15 ++-
.../server/upgrade/UpgradeCatalog170.java | 68 +++++-----
.../main/resources/slider_resources/README.txt | 17 +++
.../services/GANGLIA/package/scripts/params.py | 5 +-
.../services/GANGLIA/package/scripts/params.py | 6 +-
.../services/OOZIE/package/scripts/oozie.py | 10 +-
.../services/OOZIE/package/scripts/params.py | 13 +-
.../services/SQOOP/package/scripts/params.py | 2 +
.../SQOOP/package/scripts/service_check.py | 1 +
.../services/FALCON/package/scripts/falcon.py | 4 +
.../services/STORM/configuration/storm-site.xml | 6 +-
.../services/SLIDER/package/scripts/slider.py | 3 +-
.../services/STORM/configuration/storm-site.xml | 6 +-
.../ClientConfigResourceProviderTest.java | 9 +-
.../ConfigGroupResourceProviderTest.java | 37 +++++-
.../server/upgrade/UpgradeCatalog170Test.java | 125 ++++++++++++-------
.../stacks/2.0.6/OOZIE/test_oozie_client.py | 18 +--
.../stacks/2.0.6/OOZIE/test_oozie_server.py | 18 +--
.../stacks/2.0.6/SQOOP/test_service_check.py | 2 +
.../stacks/2.1/FALCON/test_falcon_client.py | 4 +
.../stacks/2.1/FALCON/test_falcon_server.py | 4 +
.../stacks/2.2/SLIDER/test_slider_client.py | 4 +-
.../main/dashboard/config_history_controller.js | 1 +
ambari-web/app/controllers/main/service/item.js | 28 ++++-
ambari-web/app/templates/main/host/details.hbs | 2 +-
ambari-web/app/templates/main/service/item.hbs | 13 +-
ambari-web/app/views/common/filter_view.js | 74 ++++++++++-
.../views/main/dashboard/config_history_view.js | 10 +-
ambari-web/app/views/main/service/item.js | 6 +-
contrib/views/slider/docs/index.md | 63 ++++++++++
.../view/slider/SliderAppsViewController.java | 8 ++
.../slider/SliderAppsViewControllerImpl.java | 69 +++++-----
.../assets/data/resource/slider-properties.json | 7 +-
.../ui/app/controllers/slider_controller.js | 20 ++-
.../src/main/resources/ui/app/helpers/ajax.js | 7 +-
.../resources/ui/app/models/slider_config.js | 8 +-
.../src/main/resources/ui/app/routes/main.js | 7 +-
.../src/main/resources/ui/app/translations.js | 1 +
.../views/slider/src/main/resources/view.xml | 25 ++++
41 files changed, 596 insertions(+), 185 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e6cc0587/ambari-server/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e6cc0587/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
[36/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/24483521
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/24483521
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/24483521
Branch: refs/heads/trunk
Commit: 24483521f96f395b61b786e12c444901c90073c7
Parents: ae9bf4c 7d6731b
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Sep 24 13:50:41 2014 -0700
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Sep 24 13:50:41 2014 -0700
----------------------------------------------------------------------
.../TestExecuteHadoopResource.py | 14 +-
.../libraries/resources/execute_hadoop.py | 2 +-
.../server/configuration/Configuration.java | 14 +-
.../BlueprintConfigurationProcessor.java | 28 +-
.../ambari/server/orm/dao/PermissionDAO.java | 25 +-
.../server/security/authorization/Users.java | 24 +-
.../server/upgrade/UpgradeCatalog170.java | 33 +
ambari-server/src/main/python/ambari-server.py | 14 +-
.../services/HBASE/package/scripts/params.py | 3 +-
.../HBASE/package/scripts/service_check.py | 4 +-
.../stacks/HDP/1.3.2/services/HIVE/metainfo.xml | 2 +-
.../OOZIE/configuration/oozie-log4j.xml | 2 +-
.../stacks/HDP/2.0.6.GlusterFS/metainfo.xml | 6 +-
.../HDP/2.0.6.GlusterFS/repos/repoinfo.xml | 39 +
.../HDP/2.0.6.GlusterFS/role_command_order.json | 30 +-
.../GLUSTERFS/configuration/core-site.xml | 272 +-
.../services/GLUSTERFS/configuration/global.xml | 35 -
.../GLUSTERFS/configuration/hadoop-env.xml | 209 +
.../services/GLUSTERFS/metainfo.xml | 36 +-
.../services/HBASE/configuration/hbase-site.xml | 370 +
.../2.0.6.GlusterFS/services/HBASE/metainfo.xml | 34 +
.../2.0.6.GlusterFS/services/HDFS/metainfo.xml | 46 +-
.../2.0.6.GlusterFS/services/HDFS/metrics.json | 7840 ------------------
.../services/HIVE/configuration/hive-site.xml | 502 ++
.../HIVE/etc/hive-schema-0.13.0.mysql.sql | 889 ++
.../HIVE/etc/hive-schema-0.13.0.oracle.sql | 835 ++
.../HIVE/etc/hive-schema-0.13.0.postgres.sql | 1538 ++++
.../etc/upgrade-0.12.0-to-0.13.0.oracle.sql | 165 +
.../services/HIVE/etc/upgrade-0.13.0.oracle.sql | 38 +
.../2.0.6.GlusterFS/services/HIVE/metainfo.xml | 100 +
.../services/OOZIE/configuration/oozie-site.xml | 313 +
.../2.0.6.GlusterFS/services/OOZIE/metainfo.xml | 78 +
.../PIG/configuration/pig-properties.xml | 91 +
.../2.0.6.GlusterFS/services/PIG/metainfo.xml | 27 +
.../2.0.6.GlusterFS/services/SQOOP/metainfo.xml | 32 +
.../YARN/configuration-mapred/core-site.xml.2 | 20 +
.../YARN/configuration-mapred/mapred-site.xml | 88 +
.../YARN/configuration-mapred/mapred-site.xml.2 | 68 +
.../YARN/configuration/capacity-scheduler.xml | 124 +
.../YARN/configuration/mapred-site.xml.2 | 68 +
.../services/YARN/configuration/yarn-env.xml | 181 +
.../services/YARN/configuration/yarn-site.xml | 413 +
.../2.0.6.GlusterFS/services/YARN/metainfo.xml | 143 +
.../2.0.6.GlusterFS/services/YARN/metrics.json | 2534 ++++++
.../files/validateYarnComponentStatus.py | 170 +
.../services/YARN/package/scripts/__init__.py | 20 +
.../scripts/application_timeline_server.py | 55 +
.../YARN/package/scripts/historyserver.py | 53 +
.../package/scripts/mapred_service_check.py | 73 +
.../YARN/package/scripts/mapreduce2_client.py | 42 +
.../YARN/package/scripts/nodemanager.py | 59 +
.../services/YARN/package/scripts/params.py | 143 +
.../YARN/package/scripts/resourcemanager.py | 90 +
.../services/YARN/package/scripts/service.py | 62 +
.../YARN/package/scripts/service_check.py | 67 +
.../YARN/package/scripts/status_params.py | 35 +
.../services/YARN/package/scripts/yarn.py | 163 +
.../YARN/package/scripts/yarn_client.py | 42 +
.../package/templates/container-executor.cfg.j2 | 22 +
.../YARN/package/templates/mapreduce.conf.j2 | 17 +
.../YARN/package/templates/yarn-env.sh.j2 | 128 +
.../YARN/package/templates/yarn.conf.j2 | 17 +
.../services/ZOOKEEPER/metainfo.xml | 28 +
.../services/HBASE/package/scripts/params.py | 3 +-
.../stacks/HDP/2.0.6/services/HIVE/metainfo.xml | 2 +-
.../NAGIOS/package/files/nagios_alerts.php | 2 +-
.../OOZIE/configuration/oozie-log4j.xml | 2 +-
.../package/templates/oozie-log4j.properties.j2 | 2 +-
.../scripts/application_timeline_server.py | 2 +-
.../services/STORM/package/scripts/params.py | 5 +-
.../services/STORM/package/scripts/service.py | 10 +-
.../STORM/package/scripts/service_check.py | 6 +-
.../services/STORM/configuration/storm-site.xml | 12 +-
.../src/main/resources/stacks/stack_advisor.py | 270 +-
.../BlueprintConfigurationProcessorTest.java | 54 +-
.../security/authorization/TestUsers.java | 112 +-
.../server/upgrade/UpgradeCatalog170Test.java | 2 +
.../src/test/python/TestAmbariServer.py | 3 +-
ambari-server/src/test/python/ldap-password.dat | 1 +
.../python/stacks/1.3.2/HDFS/test_namenode.py | 37 +
.../stacks/1.3.2/HDFS/test_service_check.py | 75 +-
.../python/stacks/1.3.2/configs/secured.json | 5 +-
.../python/stacks/2.0.6/HDFS/test_namenode.py | 25 +-
.../stacks/2.0.6/YARN/test_resourcemanager.py | 36 +
.../python/stacks/2.0.6/configs/default.json | 1 +
.../python/stacks/2.0.6/configs/secured.json | 6 +-
.../stacks/2.1/STORM/test_service_check.py | 5 +-
.../stacks/2.1/STORM/test_storm_drpc_server.py | 8 +-
.../stacks/2.1/STORM/test_storm_nimbus.py | 8 +-
.../2.1/STORM/test_storm_rest_api_service.py | 8 +-
.../stacks/2.1/STORM/test_storm_supervisor.py | 16 +-
.../2.1/STORM/test_storm_supervisor_prod.py | 8 +-
.../stacks/2.1/STORM/test_storm_ui_server.py | 8 +-
.../stacks/2.1/YARN/test_apptimelineserver.py | 14 +
ambari-web/app/controllers/installer.js | 20 +-
.../security/security_progress_controller.js | 27 -
.../main/mirroring/jobs_controller.js | 2 +-
.../controllers/main/service/info/configs.js | 21 +-
.../app/controllers/wizard/step7_controller.js | 8 +-
.../app/controllers/wizard/step8_controller.js | 24 +-
ambari-web/app/data/HDP2/secure_properties.js | 1 +
ambari-web/app/data/secure_properties.js | 1 +
ambari-web/app/mappers/users_mapper.js | 12 +
ambari-web/app/models/user.js | 1 +
ambari-web/app/router.js | 14 +-
ambari-web/app/utils/config.js | 107 +-
ambari-web/app/utils/helper.js | 2 +-
ambari-web/app/views/wizard/controls_view.js | 21 +-
.../security_progress_controller_test.js | 71 -
.../main/service/info/config_test.js | 9 +-
.../test/controllers/wizard/step8_test.js | 34 +-
ambari-web/test/utils/config_test.js | 38 +-
.../slider-agent/0.51.0/slider-agent-0.51.0.pom | 25 +
.../0.51.0/slider-agent-0.51.0.tar.gz | Bin 0 -> 472393 bytes
.../slider-agent/maven-metadata-local.xml | 28 +
.../slider-core/0.51.0/slider-core-0.51.0.jar | Bin 1144236 -> 1146908 bytes
.../slider/slider-core/maven-metadata-local.xml | 2 +-
contrib/views/slider/lib/slider-agent.tar.gz | Bin 480985 -> 0 bytes
contrib/views/slider/pom.xml | 29 +-
.../slider/SliderAppsViewControllerImpl.java | 27 +-
.../resources/ui/app/assets/data/apps/apps.json | 475 ++
.../createAppWizard/step1_controller.js | 37 +-
.../createAppWizard/step3_controller.js | 1 +
.../ui/app/controllers/slider_controller.js | 36 +
.../main/resources/ui/app/models/slider_app.js | 11 +-
.../resources/ui/app/styles/application.less | 37 +-
.../ui/app/templates/common/app_tooltip.hbs | 12 +-
.../ui/app/templates/createAppWizard/step1.hbs | 41 +-
.../ui/app/templates/slider_app/summary.hbs | 95 +-
.../ui/app/templates/slider_title_tooltip.hbs | 3 -
.../src/main/resources/ui/app/translations.js | 8 +-
.../resources/ui/app/views/application_view.js | 11 +-
.../resources/ui/app/views/common/chart_view.js | 6 +-
.../views/slider_app/metrics/app_metric_view.js | 2 +-
.../ui/app/views/slider_app/summary_view.js | 68 +-
.../resources/ui/app/views/slider_apps_view.js | 1 +
...test-patch-find-new-patch-available-jiras.sh | 126 +
dev-support/test-patch.sh | 1077 +++
138 files changed, 13120 insertions(+), 8814 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/24483521/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
[03/50] [abbrv] git commit: AMBARI-7021 - Alerts: Create Group and
Target REST Endpoints (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7021 - Alerts: Create Group and Target REST Endpoints (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4a4644b8
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4a4644b8
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4a4644b8
Branch: refs/heads/trunk
Commit: 4a4644b882c9a0d39b249db5a106f7075cb0c93d
Parents: 6ba11a2
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Aug 26 14:21:31 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Aug 27 08:51:49 2014 -0400
----------------------------------------------------------------------
.../python/ambari_agent/alerts/base_alert.py | 4 +-
.../python/ambari_agent/alerts/port_alert.py | 11 +-
.../ambari/server/agent/HeartBeatHandler.java | 16 +-
.../resources/AlertGroupResourceDefinition.java | 50 +++
.../AlertTargetResourceDefinition.java | 50 +++
.../resources/ResourceInstanceFactoryImpl.java | 8 +
.../server/api/services/AlertGroupService.java | 111 ++++++
.../server/api/services/AlertTargetService.java | 96 ++++++
.../server/api/services/ClusterService.java | 66 +++-
.../ambari/server/controller/AmbariServer.java | 4 +
.../AbstractControllerResourceProvider.java | 10 +-
.../internal/AlertGroupResourceProvider.java | 268 +++++++++++++++
.../internal/AlertTargetResourceProvider.java | 258 ++++++++++++++
.../ambari/server/controller/spi/Resource.java | 13 +-
.../ambari/server/orm/dao/AlertDispatchDAO.java | 78 +++--
.../ambari/server/state/alert/AlertGroup.java | 124 +++++++
.../ambari/server/state/alert/AlertTarget.java | 123 +++++++
.../ambari/server/state/alert/TargetType.java | 37 ++
.../svccomphost/ServiceComponentHostImpl.java | 2 +
.../src/main/resources/key_properties.json | 7 +
.../src/main/resources/properties.json | 18 +-
.../AlertGroupResourceProviderTest.java | 335 +++++++++++++++++++
.../AlertTargetResourceProviderTest.java | 290 ++++++++++++++++
.../svccomphost/ServiceComponentHostTest.java | 242 +++++++-------
24 files changed, 2045 insertions(+), 176 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index 07987d9..88c7f92 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -34,7 +34,7 @@ class BaseAlert(object):
self.alert_meta = alert_meta
self.alert_source_meta = alert_source_meta
self.cluster = ''
- self.hostname = ''
+ self.hostName = ''
self._lookup_keys = []
@@ -54,7 +54,7 @@ class BaseAlert(object):
def set_cluster(self, cluster, host):
''' sets cluster information for the alert '''
self.cluster = cluster
- self.hostname = host
+ self.hostName = host
def collect(self):
''' method used for collection. defers to _collect() '''
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py
index d06d1f4..eaf744a 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/port_alert.py
@@ -22,7 +22,6 @@ import logging
import re
import socket
import time
-import traceback
from alerts.base_alert import BaseAlert
from resource_management.libraries.functions.get_port_from_url import get_port_from_url
@@ -40,7 +39,7 @@ class PortAlert(BaseAlert):
def _collect(self):
urivalue = self._lookup_property_value(self.uri)
- host = get_host_from_url(urivalue)
+ host = get_host_from_url(self, urivalue)
port = self.port
try:
@@ -76,9 +75,9 @@ Tested on the following cases:
"hdfs://192.168.54.3/foo/bar"
"ftp://192.168.54.4:7842/foo/bar"
'''
-def get_host_from_url(uri):
+def get_host_from_url(self, uri):
# RFC3986, Appendix B
- parts = re.findall('^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?' , uri)
+ parts = re.findall('^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?', uri)
# index of parts
# scheme = 1
@@ -96,6 +95,10 @@ def get_host_from_url(uri):
host_and_port = parts[0][3]
if -1 == host_and_port.find(':'):
+ # if no : then it might only be a port; if it's a port, return this host
+ if host_and_port.isdigit():
+ return self.hostName
+
return host_and_port
else:
return host_and_port.split(':')[0]
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index dca3bd9..d0d5a13 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -229,11 +229,13 @@ public class HeartBeatHandler {
protected void calculateHostAlerts(HeartBeat heartbeat, String hostname)
throws AmbariException {
- if (heartbeat != null && hostname != null) {
- for (Cluster cluster : clusterFsm.getClustersForHost(hostname)) {
- cluster.addAlerts(heartbeat.getNodeStatus().getAlerts());
- }
- }
+ if (null == hostname || null == heartbeat) {
+ return;
+ }
+
+ for (Cluster cluster : clusterFsm.getClustersForHost(hostname)) {
+ cluster.addAlerts(heartbeat.getNodeStatus().getAlerts());
+ }
}
protected void processHostStatus(HeartBeat heartbeat, String hostname) throws AmbariException {
@@ -710,7 +712,7 @@ public class HeartBeatHandler {
response.setResponseStatus(RegistrationStatus.OK);
// force the registering agent host to receive its list of alert definitions
- List<AlertDefinitionCommand> alertDefinitionCommands = getAlertDefinitionCommands(hostname);
+ List<AlertDefinitionCommand> alertDefinitionCommands = getRegistrationAlertDefinitionCommands(hostname);
response.setAlertDefinitionCommands(alertDefinitionCommands);
Long requestId = 0L;
@@ -787,7 +789,7 @@ public class HeartBeatHandler {
* @return
* @throws AmbariException
*/
- private List<AlertDefinitionCommand> getAlertDefinitionCommands(
+ private List<AlertDefinitionCommand> getRegistrationAlertDefinitionCommands(
String hostname) throws AmbariException {
Set<Cluster> hostClusters = clusterFsm.getClustersForHost(hostname);
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertGroupResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertGroupResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertGroupResourceDefinition.java
new file mode 100644
index 0000000..67e5d60
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertGroupResourceDefinition.java
@@ -0,0 +1,50 @@
+/**
+ * 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.ambari.server.api.resources;
+
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * The {@link AlertGroupResourceDefinition} class is used to register alert
+ * groups to be returned via the REST API.
+ */
+public class AlertGroupResourceDefinition extends BaseResourceDefinition {
+
+ /**
+ * Constructor.
+ */
+ public AlertGroupResourceDefinition() {
+ super(Resource.Type.AlertGroup);
+ }
+
+ /**
+ *
+ */
+ @Override
+ public String getPluralName() {
+ return "alert_groups";
+ }
+
+ /**
+ *
+ */
+ @Override
+ public String getSingularName() {
+ return "alert_group";
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertTargetResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertTargetResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertTargetResourceDefinition.java
new file mode 100644
index 0000000..bc0d81d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertTargetResourceDefinition.java
@@ -0,0 +1,50 @@
+/**
+ * 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.ambari.server.api.resources;
+
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * The {@link AlertTargetResourceDefinition} class is used to register alert
+ * targets to be returned via the REST API.
+ */
+public class AlertTargetResourceDefinition extends BaseResourceDefinition {
+
+ /**
+ * Constructor.
+ */
+ public AlertTargetResourceDefinition() {
+ super(Resource.Type.AlertTarget);
+ }
+
+ /**
+ *
+ */
+ @Override
+ public String getPluralName() {
+ return "alert_targets";
+ }
+
+ /**
+ *
+ */
+ @Override
+ public String getSingularName() {
+ return "alert_target";
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index 13fff1d..7faf365 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -251,6 +251,14 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
resourceDefinition = new AlertDefResourceDefinition();
break;
+ case AlertGroup:
+ resourceDefinition = new AlertGroupResourceDefinition();
+ break;
+
+ case AlertTarget:
+ resourceDefinition = new AlertTargetResourceDefinition();
+ break;
+
case AmbariPrivilege:
resourceDefinition = new PrivilegeResourceDefinition(Resource.Type.AmbariPrivilege);
break;
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java
new file mode 100644
index 0000000..c2e5048
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertGroupService.java
@@ -0,0 +1,111 @@
+/**
+ * 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.ambari.server.api.services;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.state.alert.AlertGroup;
+
+/**
+ * The {@link AlertGroupService} handles CRUD operations for a cluster's alert
+ * groups.
+ */
+public class AlertGroupService extends BaseService {
+
+ /**
+ * Cluster name for cluster-based requests
+ */
+ private String m_clusterName = null;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterName
+ */
+ AlertGroupService(String clusterName) {
+ m_clusterName = clusterName;
+ }
+
+ @GET
+ @Produces("text/plain")
+ public Response getGroups(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createAlertGroupResource(m_clusterName, null));
+ }
+
+ @GET
+ @Produces("text/plain")
+ @Path("{groupId}")
+ public Response getGroup(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui, @PathParam("groupId") Long groupId) {
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createAlertGroupResource(m_clusterName, groupId));
+ }
+
+ @POST
+ @Produces("text/plain")
+ public Response createGroup(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, body, ui, Request.Type.POST,
+ createAlertGroupResource(m_clusterName, null));
+ }
+
+ @DELETE
+ @Produces("text/plain")
+ @Path("{groupId}")
+ public Response deleteGroup(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui, @PathParam("groupId") Long groupId) {
+ return handleRequest(headers, body, ui, Request.Type.DELETE,
+ createAlertGroupResource(m_clusterName, groupId));
+ }
+
+ /**
+ * Create a request capturing the group ID and resource type for an
+ * {@link AlertGroup}.
+ *
+ * @param groupId
+ * the unique ID of the group to create the query for (not
+ * {@code null}).
+ * @return the instance of the query.
+ */
+ private ResourceInstance createAlertGroupResource(String clusterName,
+ Long groupId) {
+
+ Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>();
+ mapIds.put(Resource.Type.Cluster, m_clusterName);
+ mapIds.put(Resource.Type.AlertGroup,
+ null == groupId ? null : groupId.toString());
+
+ return createResource(Resource.Type.AlertGroup, mapIds);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java
new file mode 100644
index 0000000..86281b3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java
@@ -0,0 +1,96 @@
+/**
+ * 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.ambari.server.api.services;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.state.alert.AlertTarget;
+
+/**
+ * The {@link AlertTargetService} handles CRUD operation requests for alert
+ * targets.
+ */
+@Path("/alert_targets/")
+public class AlertTargetService extends BaseService {
+
+ @GET
+ @Produces("text/plain")
+ public Response getTargets(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createAlertTargetResource(null));
+ }
+
+ @GET
+ @Produces("text/plain")
+ @Path("{targetId}")
+ public Response getTargets(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui, @PathParam("targetId") Long targetId) {
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createAlertTargetResource(targetId));
+ }
+
+ @POST
+ @Produces("text/plain")
+ public Response createTarget(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, body, ui, Request.Type.POST,
+ createAlertTargetResource(null));
+ }
+
+ @DELETE
+ @Produces("text/plain")
+ @Path("{targetId}")
+ public Response deleteTarget(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui, @PathParam("targetId") Long targetId) {
+ return handleRequest(headers, body, ui, Request.Type.DELETE,
+ createAlertTargetResource(targetId));
+ }
+
+ /**
+ * Create a request capturing the target ID and resource type for an
+ * {@link AlertTarget}.
+ *
+ * @param targetId
+ * the unique ID of the target to create the query for (not
+ * {@code null}).
+ * @return the instance of the query.
+ */
+ private ResourceInstance createAlertTargetResource(Long targetId) {
+ Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>();
+
+ mapIds.put(Resource.Type.AlertTarget,
+ null == targetId ? null : targetId.toString());
+
+ return createResource(Resource.Type.AlertTarget, mapIds);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
index 8043b3f..3f1ce36 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
@@ -18,15 +18,26 @@
package org.apache.ambari.server.api.services;
+import java.util.Collections;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
import org.apache.ambari.server.api.resources.ResourceInstance;
import org.apache.ambari.server.controller.AmbariServer;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.state.Clusters;
-import javax.ws.rs.*;
-import javax.ws.rs.core.*;
-import java.util.Collections;
-
/**
* Service responsible for cluster resource requests.
@@ -46,7 +57,7 @@ public class ClusterService extends BaseService {
* Construct a ClusterService.
*/
public ClusterService() {
- this.clusters = AmbariServer.getController().getClusters();
+ clusters = AmbariServer.getController().getClusters();
}
/**
@@ -187,7 +198,7 @@ public class ClusterService extends BaseService {
hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new ServiceService(clusterName);
}
-
+
/**
* Gets the configurations sub-resource.
*
@@ -295,7 +306,7 @@ public class ClusterService extends BaseService {
hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new RequestScheduleService(clusterName);
}
-
+
/**
* Gets the alert definition service
*
@@ -313,12 +324,32 @@ public class ClusterService extends BaseService {
}
/**
+ * Gets the alert group service.
+ *
+ * @param request
+ * the request.
+ * @param clusterName
+ * the cluster name.
+ * @return the alert group service.
+ */
+ @Path("{clusterName}/alert_groups")
+ public AlertGroupService getAlertGroups(
+ @Context javax.ws.rs.core.Request request,
+ @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
+ return new AlertGroupService(clusterName);
+ }
+
+ /**
* Gets the privilege service
*
- * @param request the request
- * @param clusterName the cluster name
+ * @param request
+ * the request
+ * @param clusterName
+ * the cluster name
*
- * @return the privileges service
+ * @return the privileges service
*/
@Path("{clusterName}/privileges")
public PrivilegeService getPrivilegeService(@Context javax.ws.rs.core.Request request, @PathParam ("clusterName") String clusterName) {
@@ -343,14 +374,17 @@ public class ClusterService extends BaseService {
}
/**
- * Determine whether or not the access specified by the given request type
- * is permitted for the current user on the cluster resource identified by
- * the given cluster name.
+ * Determine whether or not the access specified by the given request type is
+ * permitted for the current user on the cluster resource identified by the
+ * given cluster name.
*
- * @param requestType the request method type
- * @param clusterName the name of the cluster resource
+ * @param requestType
+ * the request method type
+ * @param clusterName
+ * the name of the cluster resource
*
- * @throws WebApplicationException if access is forbidden
+ * @throws WebApplicationException
+ * if access is forbidden
*/
private void hasPermission(Request.Type requestType, String clusterName) throws WebApplicationException {
if (!clusters.checkPermission(clusterName, requestType == Request.Type.GET)) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 21c9d80..c75a7bb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -46,6 +46,8 @@ import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.internal.AbstractControllerResourceProvider;
import org.apache.ambari.server.controller.internal.AlertDefinitionResourceProvider;
+import org.apache.ambari.server.controller.internal.AlertGroupResourceProvider;
+import org.apache.ambari.server.controller.internal.AlertTargetResourceProvider;
import org.apache.ambari.server.controller.internal.AmbariPrivilegeResourceProvider;
import org.apache.ambari.server.controller.internal.BlueprintResourceProvider;
import org.apache.ambari.server.controller.internal.ClusterPrivilegeResourceProvider;
@@ -538,6 +540,8 @@ public class AmbariServer {
StackDependencyResourceProvider.init(ambariMetaInfo);
ClusterResourceProvider.init(injector.getInstance(BlueprintDAO.class), ambariMetaInfo, injector.getInstance(ConfigHelper.class));
AlertDefinitionResourceProvider.init(injector);
+ AlertGroupResourceProvider.init(injector);
+ AlertTargetResourceProvider.init(injector);
PermissionResourceProvider.init(injector.getInstance(PermissionDAO.class));
ViewPermissionResourceProvider.init(injector.getInstance(PermissionDAO.class));
PrivilegeResourceProvider.init(injector.getInstance(PrivilegeDAO.class), injector.getInstance(UserDAO.class),
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 71ddc8d..c10d300 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -18,15 +18,15 @@
package org.apache.ambari.server.controller.internal;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.ResourceProviderFactory;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
-import java.util.Map;
-import java.util.Set;
-
/**
* Abstract resource provider implementation that maps to an Ambari management controller.
*/
@@ -149,6 +149,10 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc
return new ValidationResourceProvider(propertyIds, keyPropertyIds, managementController);
case AlertDefinition:
return new AlertDefinitionResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case AlertGroup:
+ return new AlertGroupResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case AlertTarget:
+ return new AlertTargetResourceProvider(propertyIds, keyPropertyIds, managementController);
case Controller:
return new ControllerResourceProvider(propertyIds, keyPropertyIds, managementController);
case ClientConfig:
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
new file mode 100644
index 0000000..f14e76f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java
@@ -0,0 +1,268 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.alert.AlertGroup;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+/**
+ * The {@link AlertGroupResourceProvider} class deals with managing the CRUD
+ * operations for {@link AlertGroup}, including property coercion to and from
+ * {@link AlertGroupEntity}.
+ */
+public class AlertGroupResourceProvider extends
+ AbstractControllerResourceProvider {
+
+ protected static final String ALERT_GROUP = "AlertGroup";
+ protected static final String ALERT_GROUP_ID = "AlertGroup/id";
+ protected static final String ALERT_GROUP_CLUSTER_NAME = "AlertGroup/cluster_name";
+ protected static final String ALERT_GROUP_NAME = "AlertGroup/name";
+ protected static final String ALERT_GROUP_DEFAULT = "AlertGroup/default";
+ protected static final String ALERT_GROUP_DEFINITIONS = "AlertGroup/definitions";
+ protected static final String ALERT_GROUP_TARGETS = "AlertGroup/targets";
+
+ private static final Set<String> PK_PROPERTY_IDS = new HashSet<String>(
+ Arrays.asList(ALERT_GROUP_ID, ALERT_GROUP_CLUSTER_NAME));
+
+ /**
+ * Group DAO
+ */
+ @Inject
+ private static AlertDispatchDAO s_dao;
+
+ /**
+ * Initializes the injectable members of this class with the specified
+ * injector.
+ *
+ * @param injector
+ * the injector (not {@code null}).
+ */
+ @Inject
+ public static void init(Injector injector) {
+ s_dao = injector.getInstance(AlertDispatchDAO.class);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param propertyIds
+ * @param keyPropertyIds
+ * @param managementController
+ */
+ AlertGroupResourceProvider(Set<String> propertyIds,
+ Map<Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ public RequestStatus createResources(final Request request)
+ throws SystemException,
+ UnsupportedPropertyException, ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+
+ createResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ createAlertGroups(request.getProperties());
+ return null;
+ }
+ });
+
+ notifyCreate(Resource.Type.AlertGroup, request);
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<Resource> results = new HashSet<Resource>();
+ Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate);
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ String clusterName = (String) propertyMap.get(ALERT_GROUP_CLUSTER_NAME);
+
+ if (null == clusterName || clusterName.isEmpty()) {
+ throw new IllegalArgumentException("The cluster name is required when retrieving alert groups");
+ }
+
+ String id = (String) propertyMap.get(ALERT_GROUP_ID);
+ if (null != id) {
+ AlertGroupEntity entity = s_dao.findGroupById(Long.parseLong(id));
+ if (null != entity) {
+ results.add(toResource(false, clusterName, entity, requestPropertyIds));
+ }
+ } else {
+ Cluster cluster = null;
+
+ try {
+ cluster = getManagementController().getClusters().getCluster(clusterName);
+ } catch (AmbariException ae) {
+ throw new NoSuchResourceException("Parent Cluster resource doesn't exist", ae);
+ }
+
+ List<AlertGroupEntity> entities = s_dao.findAllGroups(cluster.getClusterId());
+
+ for (AlertGroupEntity entity : entities) {
+ results.add(toResource(true, clusterName, entity, requestPropertyIds));
+ }
+ }
+ }
+
+ return results;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<Resource> resources = getResources(new RequestImpl(null, null, null,
+ null), predicate);
+
+ Set<Long> groupIds = new HashSet<Long>();
+
+ for (final Resource resource : resources) {
+ Long id = (Long) resource.getPropertyValue(ALERT_GROUP_ID);
+ groupIds.add(id);
+ }
+
+ for (Long groupId : groupIds) {
+ LOG.info("Deleting alert target {}", groupId);
+
+ final AlertGroupEntity entity = s_dao.findGroupById(groupId.longValue());
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ s_dao.remove(entity);
+ return null;
+ }
+ });
+ }
+
+ notifyDelete(Resource.Type.AlertGroup, predicate);
+ return getRequestStatus(null);
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return PK_PROPERTY_IDS;
+ }
+
+ /**
+ * Create and persist {@link AlertTargetEntity} from the map of properties.
+ *
+ * @param requestMaps
+ * @throws AmbariException
+ */
+ private void createAlertGroups(Set<Map<String, Object>> requestMaps)
+ throws AmbariException {
+
+ List<AlertGroupEntity> entities = new ArrayList<AlertGroupEntity>();
+ for (Map<String, Object> requestMap : requestMaps) {
+ AlertGroupEntity entity = new AlertGroupEntity();
+
+ String name = (String) requestMap.get(ALERT_GROUP_NAME);
+ String clusterName = (String) requestMap.get(ALERT_GROUP_CLUSTER_NAME);
+
+ if (StringUtils.isEmpty(name)) {
+ throw new IllegalArgumentException(
+ "The name of the alert group is required.");
+ }
+
+ if (StringUtils.isEmpty(clusterName)) {
+ throw new IllegalArgumentException(
+ "The name of the cluster is required when creating an alert group.");
+ }
+
+ Cluster cluster = getManagementController().getClusters().getCluster(
+ clusterName);
+
+ entity.setClusterId(cluster.getClusterId());
+ entity.setDefault(false);
+ entity.setGroupName(name);
+
+ entities.add(entity);
+ }
+
+ s_dao.createGroups(entities);
+ }
+
+ /**
+ * Convert the given {@link AlertGroupEntity} to a {@link Resource}.
+ *
+ * @param isCollection
+ * {@code true} if the resource is part of a collection.
+ * @param entity
+ * the entity to convert.
+ * @param requestedIds
+ * the properties that were requested or {@code null} for all.
+ * @return the resource representation of the entity (never {@code null}).
+ */
+ private Resource toResource(boolean isCollection, String clusterName,
+ AlertGroupEntity entity,
+ Set<String> requestedIds) {
+
+ Resource resource = new ResourceImpl(Resource.Type.AlertGroup);
+ resource.setProperty(ALERT_GROUP_ID, entity.getGroupId());
+ resource.setProperty(ALERT_GROUP_NAME, entity.getGroupName());
+ resource.setProperty(ALERT_GROUP_CLUSTER_NAME, clusterName);
+
+ setResourceProperty(resource, ALERT_GROUP_DEFAULT,
+ entity.isDefault(), requestedIds);
+
+ return resource;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
new file mode 100644
index 0000000..e00f60f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
@@ -0,0 +1,258 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.alert.AlertTarget;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+/**
+ * The {@link AlertTargetResourceProvider} class deals with managing the CRUD
+ * operations for {@link AlertTarget}, including property coercion to and from
+ * {@link AlertTargetEntity}.
+ */
+public class AlertTargetResourceProvider extends
+ AbstractControllerResourceProvider {
+
+ protected static final String ALERT_TARGET = "AlertTarget";
+ protected static final String ALERT_TARGET_ID = "AlertTarget/id";
+ protected static final String ALERT_TARGET_NAME = "AlertTarget/name";
+ protected static final String ALERT_TARGET_DESCRIPTION = "AlertTarget/description";
+ protected static final String ALERT_TARGET_NOTIFICATION_TYPE = "AlertTarget/notification_type";
+ protected static final String ALERT_TARGET_PROPERTIES = "AlertTarget/properties";
+ protected static final String ALERT_TARGET_GROUPS = "AlertTarget/groups";
+
+ private static final Set<String> PK_PROPERTY_IDS = new HashSet<String>(
+ Arrays.asList(ALERT_TARGET_ID, ALERT_TARGET_NAME));
+
+ /**
+ * Target DAO
+ */
+ @Inject
+ private static AlertDispatchDAO s_dao;
+
+ /**
+ * Initializes the injectable members of this class with the specified
+ * injector.
+ *
+ * @param injector
+ * the injector (not {@code null}).
+ */
+ @Inject
+ public static void init(Injector injector) {
+ s_dao = injector.getInstance(AlertDispatchDAO.class);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param propertyIds
+ * @param keyPropertyIds
+ * @param managementController
+ */
+ AlertTargetResourceProvider(Set<String> propertyIds,
+ Map<Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ public RequestStatus createResources(final Request request)
+ throws SystemException,
+ UnsupportedPropertyException, ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+
+ createResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ createAlertTargets(request.getProperties());
+ return null;
+ }
+ });
+
+ notifyCreate(Resource.Type.AlertTarget, request);
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<Resource> results = new HashSet<Resource>();
+ Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate);
+
+ if( null == predicate ){
+ List<AlertTargetEntity> entities = s_dao.findAllTargets();
+ for (AlertTargetEntity entity : entities) {
+ results.add(toResource(true, entity, requestPropertyIds));
+ }
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ String id = (String) propertyMap.get(ALERT_TARGET_ID);
+ if (null == id) {
+ continue;
+ }
+
+ AlertTargetEntity entity = s_dao.findTargetById(Long.parseLong(id));
+ if (null != entity) {
+ results.add(toResource(false, entity, requestPropertyIds));
+ }
+ }
+ }
+
+ return results;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<Resource> resources = getResources(new RequestImpl(null, null, null,
+ null), predicate);
+
+ Set<Long> targetIds = new HashSet<Long>();
+
+ for (final Resource resource : resources) {
+ Long id = (Long) resource.getPropertyValue(ALERT_TARGET_ID);
+ targetIds.add(id);
+ }
+
+ for (Long targetId : targetIds) {
+ LOG.info("Deleting alert target {}", targetId);
+
+ final AlertTargetEntity entity = s_dao.findTargetById(targetId.longValue());
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ s_dao.remove(entity);
+ return null;
+ }
+ });
+ }
+
+ notifyDelete(Resource.Type.AlertTarget, predicate);
+ return getRequestStatus(null);
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return PK_PROPERTY_IDS;
+ }
+
+ /**
+ * Create and persist {@link AlertTargetEntity} from the map of properties.
+ *
+ * @param requestMaps
+ * @throws AmbariException
+ */
+ private void createAlertTargets(Set<Map<String, Object>> requestMaps)
+ throws AmbariException {
+ List<AlertTargetEntity> entities = new ArrayList<AlertTargetEntity>();
+ for (Map<String, Object> requestMap : requestMaps) {
+ AlertTargetEntity entity = new AlertTargetEntity();
+
+ String name = (String) requestMap.get(ALERT_TARGET_NAME);
+ String description = (String) requestMap.get(ALERT_TARGET_DESCRIPTION);
+ String notificationType = (String) requestMap.get(ALERT_TARGET_NOTIFICATION_TYPE);
+ String properties = (String) requestMap.get(ALERT_TARGET_PROPERTIES);
+
+ if (StringUtils.isEmpty(name)) {
+ throw new IllegalArgumentException(
+ "The name of the alert target is required.");
+ }
+
+ if (StringUtils.isEmpty(notificationType)) {
+ throw new IllegalArgumentException(
+ "The type of the alert target is required.");
+ }
+
+ entity.setDescription(description);
+ entity.setNotificationType(notificationType);
+ entity.setProperties(properties);
+ entity.setTargetName(name);
+
+ entities.add(entity);
+ }
+
+ s_dao.createTargets(entities);
+ }
+
+ /**
+ * Convert the given {@link AlertTargetEntity} to a {@link Resource}.
+ *
+ * @param isCollection
+ * {@code true} if the resource is part of a collection.
+ * @param entity
+ * the entity to convert.
+ * @param requestedIds
+ * the properties that were requested or {@code null} for all.
+ * @return the resource representation of the entity (never {@code null}).
+ */
+ private Resource toResource(boolean isCollection, AlertTargetEntity entity,
+ Set<String> requestedIds) {
+
+ Resource resource = new ResourceImpl(Resource.Type.AlertTarget);
+ resource.setProperty(ALERT_TARGET_ID, entity.getTargetId());
+ resource.setProperty(ALERT_TARGET_NAME, entity.getTargetName());
+
+ setResourceProperty(resource, ALERT_TARGET_DESCRIPTION,
+ entity.getDescription(), requestedIds);
+
+ setResourceProperty(resource, ALERT_TARGET_NOTIFICATION_TYPE,
+ entity.getNotificationType(), requestedIds);
+
+ setResourceProperty(resource, ALERT_TARGET_PROPERTIES,
+ entity.getProperties(), requestedIds);
+
+ return resource;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index b10b4bc..3114809 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -115,6 +115,8 @@ public interface Resource {
HostComponentProcess,
Permission,
AlertDefinition,
+ AlertGroup,
+ AlertTarget,
AmbariPrivilege,
ClusterPrivilege,
ViewPrivilege,
@@ -196,6 +198,8 @@ public interface Resource {
public static final Type HostComponentProcess = InternalType.HostComponentProcess.getType();
public static final Type Permission = InternalType.Permission.getType();
public static final Type AlertDefinition = InternalType.AlertDefinition.getType();
+ public static final Type AlertGroup = InternalType.AlertGroup.getType();
+ public static final Type AlertTarget = InternalType.AlertTarget.getType();
public static final Type AmbariPrivilege = InternalType.AmbariPrivilege.getType();
public static final Type ClusterPrivilege = InternalType.ClusterPrivilege.getType();
public static final Type ViewPrivilege = InternalType.ViewPrivilege.getType();
@@ -315,8 +319,13 @@ public interface Resource {
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o) {
+ return true;
+ }
+
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
Type type = (Type) o;
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
index 2871e62..dfbe747 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
@@ -51,7 +51,7 @@ public class AlertDispatchDAO {
/**
* Gets an alert group with the specified ID.
- *
+ *
* @param groupId
* the ID of the group to retrieve.
* @return the group or {@code null} if none exists.
@@ -62,7 +62,7 @@ public class AlertDispatchDAO {
/**
* Gets an alert target with the specified ID.
- *
+ *
* @param targetId
* the ID of the target to retrieve.
* @return the target or {@code null} if none exists.
@@ -73,7 +73,7 @@ public class AlertDispatchDAO {
/**
* Gets a notification with the specified ID.
- *
+ *
* @param noticeId
* the ID of the notification to retrieve.
* @return the notification or {@code null} if none exists.
@@ -85,7 +85,7 @@ public class AlertDispatchDAO {
/**
* Gets an alert group with the specified name across all clusters. Alert
* group names are unique within a cluster.
- *
+ *
* @param groupName
* the name of the group (not {@code null}).
* @return the alert group or {@code null} if none exists.
@@ -102,7 +102,7 @@ public class AlertDispatchDAO {
/**
* Gets an alert group with the specified name for the given cluster. Alert
* group names are unique within a cluster.
- *
+ *
* @param clusterId
* the ID of the cluster.
* @param groupName
@@ -122,7 +122,7 @@ public class AlertDispatchDAO {
/**
* Gets an alert target with the specified name. Alert target names are unique
* across all clusters.
- *
+ *
* @param targetName
* the name of the target (not {@code null}).
* @return the alert target or {@code null} if none exists.
@@ -138,7 +138,7 @@ public class AlertDispatchDAO {
/**
* Gets all alert groups stored in the database across all clusters.
- *
+ *
* @return all alert groups or empty list if none exist (never {@code null}).
*/
public List<AlertGroupEntity> findAllGroups() {
@@ -150,7 +150,7 @@ public class AlertDispatchDAO {
/**
* Gets all alert groups stored in the database for the specified cluster.
- *
+ *
* @return all alert groups in the specified cluster or empty list if none
* exist (never {@code null}).
*/
@@ -165,7 +165,7 @@ public class AlertDispatchDAO {
/**
* Gets all alert targets stored in the database.
- *
+ *
* @return all alert targets or empty list if none exist (never {@code null}).
*/
public List<AlertTargetEntity> findAllTargets() {
@@ -177,7 +177,7 @@ public class AlertDispatchDAO {
/**
* Gets all alert notifications stored in the database.
- *
+ *
* @return all alert notifications or empty list if none exist (never
* {@code null}).
*/
@@ -189,6 +189,23 @@ public class AlertDispatchDAO {
}
/**
+ * Persists new alert groups.
+ *
+ * @param entities
+ * the groups to persist (not {@code null}).
+ */
+ @Transactional
+ public void createGroups(List<AlertGroupEntity> entities) {
+ if (null == entities) {
+ return;
+ }
+
+ for (AlertGroupEntity entity : entities) {
+ create(entity);
+ }
+ }
+
+ /**
* Persists a new alert group.
*
* @param alertGroup
@@ -201,7 +218,7 @@ public class AlertDispatchDAO {
/**
* Refresh the state of the alert group from the database.
- *
+ *
* @param alertGroup
* the group to refresh (not {@code null}).
*/
@@ -212,7 +229,7 @@ public class AlertDispatchDAO {
/**
* Merge the speicified alert group with the existing group in the database.
- *
+ *
* @param alertGroup
* the group to merge (not {@code null}).
* @return the updated group with merged content (never {@code null}).
@@ -224,7 +241,7 @@ public class AlertDispatchDAO {
/**
* Removes the specified alert group from the database.
- *
+ *
* @param alertGroup
* the group to remove.
*/
@@ -234,8 +251,25 @@ public class AlertDispatchDAO {
}
/**
+ * Persists new alert targets.
+ *
+ * @param entities
+ * the targets to persist (not {@code null}).
+ */
+ @Transactional
+ public void createTargets(List<AlertTargetEntity> entities) {
+ if (null == entities) {
+ return;
+ }
+
+ for (AlertTargetEntity entity : entities) {
+ create(entity);
+ }
+ }
+
+ /**
* Persists a new alert target.
- *
+ *
* @param alertTarget
* the target to persist (not {@code null}).
*/
@@ -246,7 +280,7 @@ public class AlertDispatchDAO {
/**
* Refresh the state of the alert target from the database.
- *
+ *
* @param alertTarget
* the target to refresh (not {@code null}).
*/
@@ -257,7 +291,7 @@ public class AlertDispatchDAO {
/**
* Merge the speicified alert target with the existing target in the database.
- *
+ *
* @param alertTarget
* the target to merge (not {@code null}).
* @return the updated target with merged content (never {@code null}).
@@ -269,7 +303,7 @@ public class AlertDispatchDAO {
/**
* Removes the specified alert target from the database.
- *
+ *
* @param alertTarget
* the target to remove.
*/
@@ -280,7 +314,7 @@ public class AlertDispatchDAO {
/**
* Persists a new notification.
- *
+ *
* @param alertNotice
* the notification to persist (not {@code null}).
*/
@@ -291,7 +325,7 @@ public class AlertDispatchDAO {
/**
* Refresh the state of the notification from the database.
- *
+ *
* @param alertNotice
* the notification to refresh (not {@code null}).
*/
@@ -302,7 +336,7 @@ public class AlertDispatchDAO {
/**
* Merge the specified notification with the existing target in the database.
- *
+ *
* @param alertNotice
* the notification to merge (not {@code null}).
* @return the updated notification with merged content (never {@code null}).
@@ -314,7 +348,7 @@ public class AlertDispatchDAO {
/**
* Removes the specified notification from the database.
- *
+ *
* @param alertNotice
* the notification to remove.
*/
@@ -327,7 +361,7 @@ public class AlertDispatchDAO {
* Removes notifications for the specified alert definition ID. This will
* invoke {@link EntityManager#clear()} when completed since the JPQL
* statement will remove entries without going through the EM.
- *
+ *
* @param definitionId
* the ID of the definition to remove.
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertGroup.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertGroup.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertGroup.java
new file mode 100644
index 0000000..659efa9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertGroup.java
@@ -0,0 +1,124 @@
+/**
+ * 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.ambari.server.state.alert;
+
+import java.util.List;
+
+/**
+ * The {@link AlertGroup} class represents a grouping of {@link AlertDefinition}
+ * instances as well as the targets that will be invoked when an alert is
+ * triggered.
+ */
+public class AlertGroup {
+ private String m_id;
+ private String m_name;
+ private String m_clusterName;
+ private boolean m_isDefault;
+ private List<AlertDefinition> m_definitions;
+ private List<AlertTarget> m_targets;
+
+ /**
+ * @return the id
+ */
+ public String getId() {
+ return m_id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ m_id = id;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return m_name;
+ }
+
+ /**
+ * @param name
+ * the name to set
+ */
+ public void setName(String name) {
+ m_name = name;
+ }
+
+ /**
+ * @return the clusterName
+ */
+ public String getClusterName() {
+ return m_clusterName;
+ }
+
+ /**
+ * @param clusterName
+ * the clusterName to set
+ */
+ public void setClusterName(String clusterName) {
+ m_clusterName = clusterName;
+ }
+
+ /**
+ * @return the isDefault
+ */
+ public boolean isDefault() {
+ return m_isDefault;
+ }
+
+ /**
+ * @param isDefault
+ * the isDefault to set
+ */
+ public void setDefault(boolean isDefault) {
+ m_isDefault = isDefault;
+ }
+
+ /**
+ * @return the definitions
+ */
+ public List<AlertDefinition> getDefinitions() {
+ return m_definitions;
+ }
+
+ /**
+ * @param definitions
+ * the definitions to set
+ */
+ public void setDefinitions(List<AlertDefinition> definitions) {
+ m_definitions = definitions;
+ }
+
+ /**
+ * @return the targets
+ */
+ public List<AlertTarget> getTargets() {
+ return m_targets;
+ }
+
+ /**
+ * @param targets
+ * the targets to set
+ */
+ public void setTargets(List<AlertTarget> targets) {
+ m_targets = targets;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
new file mode 100644
index 0000000..21e83d9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
@@ -0,0 +1,123 @@
+/**
+ * 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.ambari.server.state.alert;
+
+import java.util.List;
+
+/**
+ * The {@link AlertTarget} class represents a dispatch mechanism and audience
+ * that will receive information about alerts int he system.
+ */
+public class AlertTarget {
+ private String m_id;
+ private String m_name;
+ private String m_description;
+ private String m_notificationType;
+ private String m_properties;
+ private List<AlertGroup> m_groups;
+
+ /**
+ * @return the id
+ */
+ public String getId() {
+ return m_id;
+ }
+
+ /**
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ m_id = id;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return m_name;
+ }
+
+ /**
+ * @param name
+ * the name to set
+ */
+ public void setName(String name) {
+ m_name = name;
+ }
+
+ /**
+ * @return the description
+ */
+ public String getDescription() {
+ return m_description;
+ }
+
+ /**
+ * @param description
+ * the description to set
+ */
+ public void setDescription(String description) {
+ m_description = description;
+ }
+
+ /**
+ * @return the notificationType
+ */
+ public String getNotificationType() {
+ return m_notificationType;
+ }
+
+ /**
+ * @param notificationType
+ * the notificationType to set
+ */
+ public void setNotificationType(String notificationType) {
+ m_notificationType = notificationType;
+ }
+
+ /**
+ * @return the properties
+ */
+ public String getProperties() {
+ return m_properties;
+ }
+
+ /**
+ * @param properties
+ * the properties to set
+ */
+ public void setProperties(String properties) {
+ m_properties = properties;
+ }
+
+ /**
+ * @return the groups
+ */
+ public List<AlertGroup> getGroups() {
+ return m_groups;
+ }
+
+ /**
+ * @param groups
+ * the groups to set
+ */
+ public void setGroups(List<AlertGroup> groups) {
+ m_groups = groups;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java
new file mode 100644
index 0000000..e2564cc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/TargetType.java
@@ -0,0 +1,37 @@
+/**
+ * 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.ambari.server.state.alert;
+
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+
+/**
+ * The {@link TargetType} enumeration is used to represent the built-in target
+ * dispatch mechanisms that are supported internally. {@link AlertTarget}
+ * instances may have other custom target types that are not listed here.
+ */
+public enum TargetType {
+ /**
+ * Alerts will be distributed via email.
+ */
+ EMAIL,
+
+ /**
+ * {@link AlertsDAO} will be distributed via SNMP.
+ */
+ SNMP;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index cc5bb5b..75265b7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -555,6 +555,8 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
impl.alertDefinitionHash.invalidate(impl.getClusterName(), hostName);
impl.alertDefinitionHash.enqueueAgentCommands(impl.getClusterName(),
Collections.singleton(hostName));
+
+ impl.updateLastOpInfo(event.getType(), event.getOpTimestamp());
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/resources/key_properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/key_properties.json b/ambari-server/src/main/resources/key_properties.json
index 06ebb61..3007fee 100644
--- a/ambari-server/src/main/resources/key_properties.json
+++ b/ambari-server/src/main/resources/key_properties.json
@@ -149,6 +149,13 @@
"Cluster": "AlertDefinition/cluster_name",
"AlertDefinition": "AlertDefinition/id"
},
+ "AlertTarget": {
+ "AlertTarget": "AlertTarget/id"
+ },
+ "AlertGroup": {
+ "Cluster": "AlertGroup/cluster_name",
+ "AlertGroup": "AlertGroup/id"
+ },
"Controller": {
"Controller": "Controllers/name"
},
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index bc2ad22..9574aa9 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -425,7 +425,23 @@
"AlertDefinition/enabled",
"AlertDefinition/scope",
"AlertDefinition/source"
- ],
+ ],
+ "AlertGroup": [
+ "AlertGroup/id",
+ "AlertGroup/name",
+ "AlertGroup/cluster_name",
+ "AlertGroup/default",
+ "AlertGroup/definitions",
+ "AlertGroup/targets"
+ ],
+ "AlertTarget": [
+ "AlertTarget/id",
+ "AlertTarget/name",
+ "AlertTarget/description",
+ "AlertTarget/notification_type",
+ "AlertTarget/properties",
+ "AlertTarget/groups"
+ ],
"Controller":[
"Controllers/name",
"LDAP/configured",
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
new file mode 100644
index 0000000..c9428b7
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
@@ -0,0 +1,335 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.resetToStrict;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.metadata.ActionMetadata;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.util.Modules;
+
+/**
+ * {@link AlertGroupResourceProvider} tests.
+ */
+public class AlertGroupResourceProviderTest {
+
+ private static final Long ALERT_GROUP_ID = Long.valueOf(28);
+ private static final String ALERT_GROUP_NAME = "Important Alerts";
+ private static final long ALERT_GROUP_CLUSTER_ID = 1L;
+ private static final String ALERT_GROUP_CLUSTER_NAME = "c1";
+
+ private AlertDispatchDAO m_dao;
+ private Injector m_injector;
+
+ @Before
+ public void before() {
+ m_dao = createStrictMock(AlertDispatchDAO.class);
+
+ m_injector = Guice.createInjector(Modules.override(
+ new InMemoryDefaultTestModule()).with(new MockModule()));
+
+ AlertGroupResourceProvider.init(m_injector);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testGetResourcesNoPredicate() throws Exception {
+ AlertGroupResourceProvider provider = createProvider(null);
+
+ Request request = PropertyHelper.getReadRequest("AlertGroup/cluster_name",
+ "AlertGroup/id");
+
+ Set<Resource> results = provider.getResources(request, null);
+
+ assertEquals(0, results.size());
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testGetResourcesClusterPredicate() throws Exception {
+ Request request = PropertyHelper.getReadRequest(
+ AlertGroupResourceProvider.ALERT_GROUP_ID,
+ AlertGroupResourceProvider.ALERT_GROUP_NAME,
+ AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME,
+ AlertGroupResourceProvider.ALERT_GROUP_DEFAULT);
+
+ AmbariManagementController amc = createMock(AmbariManagementController.class);
+ Clusters clusters = createMock(Clusters.class);
+ Cluster cluster = createMock(Cluster.class);
+ expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
+ expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce();
+ expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals("c1").toPredicate();
+
+ expect(m_dao.findAllGroups(ALERT_GROUP_CLUSTER_ID)).andReturn(
+ getMockEntities());
+
+ replay(amc, clusters, cluster, m_dao);
+
+ AlertGroupResourceProvider provider = createProvider(amc);
+ Set<Resource> results = provider.getResources(request, predicate);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+
+ Assert.assertEquals(ALERT_GROUP_NAME,
+ r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_NAME));
+
+ Assert.assertEquals(ALERT_GROUP_ID,
+ r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_ID));
+
+ Assert.assertEquals(ALERT_GROUP_CLUSTER_NAME,
+ r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME));
+
+ verify(amc, clusters, cluster, m_dao);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testGetSingleResource() throws Exception {
+ Request request = PropertyHelper.getReadRequest(
+ AlertGroupResourceProvider.ALERT_GROUP_ID,
+ AlertGroupResourceProvider.ALERT_GROUP_NAME,
+ AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME,
+ AlertGroupResourceProvider.ALERT_GROUP_DEFAULT);
+
+ AmbariManagementController amc = createMock(AmbariManagementController.class);
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals(
+ ALERT_GROUP_CLUSTER_NAME).and().property(
+ AlertGroupResourceProvider.ALERT_GROUP_ID).equals(
+ ALERT_GROUP_ID.toString()).toPredicate();
+
+ expect(m_dao.findGroupById(ALERT_GROUP_ID.longValue())).andReturn(
+ getMockEntities().get(0));
+
+ replay(amc, m_dao);
+
+ AlertGroupResourceProvider provider = createProvider(amc);
+ Set<Resource> results = provider.getResources(request, predicate);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+
+ Assert.assertEquals(ALERT_GROUP_NAME,
+ r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_NAME));
+
+ Assert.assertEquals(ALERT_GROUP_ID,
+ r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_ID));
+
+ Assert.assertEquals(ALERT_GROUP_CLUSTER_NAME,
+ r.getPropertyValue(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME));
+
+ verify(amc, m_dao);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testCreateResources() throws Exception {
+ AmbariManagementController amc = createMock(AmbariManagementController.class);
+ Clusters clusters = createMock(Clusters.class);
+ Cluster cluster = createMock(Cluster.class);
+ expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
+ expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce();
+ expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
+
+ Capture<List<AlertGroupEntity>> listCapture = new Capture<List<AlertGroupEntity>>();
+
+ m_dao.createGroups(capture(listCapture));
+ expectLastCall();
+
+ replay(amc, clusters, cluster, m_dao);
+
+ AlertGroupResourceProvider provider = createProvider(amc);
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME,
+ ALERT_GROUP_NAME);
+
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME,
+ ALERT_GROUP_CLUSTER_NAME);
+
+ Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
+ provider.createResources(request);
+
+ Assert.assertTrue(listCapture.hasCaptured());
+ AlertGroupEntity entity = listCapture.getValue().get(0);
+ Assert.assertNotNull(entity);
+
+ Assert.assertEquals(ALERT_GROUP_NAME, entity.getGroupName());
+ Assert.assertEquals(ALERT_GROUP_CLUSTER_ID,
+ entity.getClusterId().longValue());
+
+ verify(amc, clusters, cluster, m_dao);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateResources() throws Exception {
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testDeleteResources() throws Exception {
+ AmbariManagementController amc = createMock(AmbariManagementController.class);
+ Clusters clusters = createMock(Clusters.class);
+ Cluster cluster = createMock(Cluster.class);
+ expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
+ expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce();
+ expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
+
+ Capture<AlertGroupEntity> entityCapture = new Capture<AlertGroupEntity>();
+ Capture<List<AlertGroupEntity>> listCapture = new Capture<List<AlertGroupEntity>>();
+
+ m_dao.createGroups(capture(listCapture));
+ expectLastCall();
+
+ replay(amc, clusters, cluster, m_dao);
+
+ AlertGroupResourceProvider provider = createProvider(amc);
+
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_NAME,
+ ALERT_GROUP_NAME);
+
+ requestProps.put(AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME,
+ ALERT_GROUP_CLUSTER_NAME);
+
+ Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
+ provider.createResources(request);
+
+ Assert.assertTrue(listCapture.hasCaptured());
+ AlertGroupEntity entity = listCapture.getValue().get(0);
+ Assert.assertNotNull(entity);
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertGroupResourceProvider.ALERT_GROUP_CLUSTER_NAME).equals(
+ ALERT_GROUP_CLUSTER_NAME).and().property(
+ AlertGroupResourceProvider.ALERT_GROUP_ID).equals(
+ ALERT_GROUP_ID.toString()).toPredicate();
+
+ // everything is mocked, there is no DB
+ entity.setGroupId(ALERT_GROUP_ID);
+
+ resetToStrict(m_dao);
+ expect(m_dao.findGroupById(ALERT_GROUP_ID.longValue())).andReturn(entity).anyTimes();
+ m_dao.remove(capture(entityCapture));
+ expectLastCall();
+ replay(m_dao);
+
+ provider.deleteResources(predicate);
+
+ AlertGroupEntity entity1 = entityCapture.getValue();
+ Assert.assertEquals(ALERT_GROUP_ID, entity1.getGroupId());
+
+ verify(amc, clusters, cluster, m_dao);
+ }
+
+ /**
+ * @param amc
+ * @return
+ */
+ private AlertGroupResourceProvider createProvider(
+ AmbariManagementController amc) {
+ return new AlertGroupResourceProvider(
+ PropertyHelper.getPropertyIds(Resource.Type.AlertGroup),
+ PropertyHelper.getKeyPropertyIds(Resource.Type.AlertGroup), amc);
+ }
+
+ /**
+ * @return
+ */
+ private List<AlertGroupEntity> getMockEntities() throws Exception {
+ AlertGroupEntity entity = new AlertGroupEntity();
+ entity.setGroupId(ALERT_GROUP_ID);
+ entity.setGroupName(ALERT_GROUP_NAME);
+ entity.setClusterId(ALERT_GROUP_CLUSTER_ID);
+ entity.setDefault(false);
+ return Arrays.asList(entity);
+ }
+
+ /**
+ *
+ */
+ private class MockModule implements Module {
+ /**
+ *
+ */
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(AlertDispatchDAO.class).toInstance(m_dao);
+ binder.bind(Clusters.class).toInstance(
+ EasyMock.createNiceMock(Clusters.class));
+ binder.bind(Cluster.class).toInstance(
+ EasyMock.createNiceMock(Cluster.class));
+ binder.bind(ActionMetadata.class);
+ }
+ }
+}
[40/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f923fd88
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f923fd88
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f923fd88
Branch: refs/heads/trunk
Commit: f923fd880b49548bc1cc289e89c18039fc3552b0
Parents: 10f1f73 f1557e8
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Sep 29 08:13:51 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Sep 29 08:13:51 2014 -0400
----------------------------------------------------------------------
.../admin-web/app/scripts/services/Cluster.js | 2 +-
.../resources/ui/admin-web/app/styles/main.css | 15 ++
.../admin-web/app/views/ambariViews/create.html | 2 +-
.../admin-web/app/views/ambariViews/edit.html | 2 +-
.../ui/admin-web/app/views/leftNavbar.html | 3 +-
.../resources/ui/admin-web/app/views/main.html | 4 +-
ambari-agent/pom.xml | 3 +-
ambari-server/pom.xml | 8 +-
ambari-server/src/main/assemblies/server.xml | 3 +-
.../ambari/server/controller/AmbariServer.java | 2 +-
.../server/orm/entities/ViewInstanceEntity.java | 34 +--
.../AmbariAuthorizationFilter.java | 91 ++++++-
.../server/security/authorization/Users.java | 3 +-
.../server/upgrade/UpgradeCatalog170.java | 139 ++++++----
.../apache/ambari/server/view/ViewRegistry.java | 26 +-
.../GANGLIA/configuration/ganglia-env.xml | 2 +-
.../services/GANGLIA/package/scripts/params.py | 7 +-
.../services/OOZIE/configuration/oozie-env.xml | 2 +-
.../services/OOZIE/package/files/oozieSmoke2.sh | 27 +-
.../services/OOZIE/package/scripts/oozie.py | 8 +-
.../OOZIE/package/scripts/oozie_service.py | 17 +-
.../services/OOZIE/package/scripts/params.py | 30 ++-
.../OOZIE/package/scripts/service_check.py | 5 +-
.../stacks/HDP/2.2/services/SLIDER/metainfo.xml | 5 +-
.../services/SLIDER/package/scripts/params.py | 6 +-
.../orm/entities/ViewInstanceEntityTest.java | 19 +-
.../AmbariAuthorizationFilterTest.java | 266 ++++++++++++++++++-
.../security/authorization/TestUsers.java | 1 +
.../server/upgrade/UpgradeCatalog170Test.java | 63 ++++-
.../ambari/server/upgrade/UpgradeTest.java | 11 +-
.../stacks/2.0.6/OOZIE/test_oozie_server.py | 12 +
.../stacks/2.0.6/OOZIE/test_service_check.py | 3 +-
.../service/manage_config_groups_controller.js | 57 +++-
ambari-web/app/controllers/wizard.js | 1 +
.../app/controllers/wizard/step7_controller.js | 14 +-
ambari-web/app/models/config_group.js | 5 +
.../manage_configuration_groups_popup.hbs | 2 +-
contrib/views/jobs/src/main/resources/view.xml | 4 +-
.../slider/SliderAppsViewControllerImpl.java | 4 +-
.../app/controllers/slider_apps_controller.js | 3 +-
.../ui/app/controllers/slider_controller.js | 11 +-
.../ui/app/mappers/slider_apps_mapper.js | 7 +-
.../ui/app/templates/unavailable_apps.hbs | 3 +
.../src/main/resources/ui/app/translations.js | 2 +-
.../views/slider/src/main/resources/view.xml | 2 +-
docs/pom.xml | 16 +-
pom.xml | 1 +
47 files changed, 741 insertions(+), 212 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f923fd88/ambari-agent/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f923fd88/ambari-server/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f923fd88/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f923fd88/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
index 338fede,d86bf35..f8f6f5b
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
@@@ -69,8 -70,8 +70,9 @@@ import org.apache.ambari.server.state.C
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.alert.Scope;
import org.apache.ambari.server.utils.StageUtils;
+ import org.apache.ambari.server.view.ViewRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
[27/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Conflicts:
ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f1018b17
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f1018b17
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f1018b17
Branch: refs/heads/trunk
Commit: f1018b176a64451c2d62fcd3e2f5238e4587ab02
Parents: a4e97aa 5fc5828
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Sep 18 10:43:23 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Sep 18 10:43:23 2014 -0400
----------------------------------------------------------------------
.../ui/admin-web/app/scripts/services/View.js | 19 +--
.../resources/ui/admin-web/app/styles/main.css | 87 ++++++++++
.../app/views/ambariViews/listTable.html | 19 ++-
ambari-admin/src/main/resources/view.xml | 1 +
.../resource_management/TestCopyFromLocal.py | 8 +-
.../ambari/groovy/client/AmbariClient.groovy | 7 +-
.../libraries/providers/copy_from_local.py | 12 +-
.../libraries/resources/copy_from_local.py | 3 +-
.../server/api/util/StackExtensionHelper.java | 9 +-
.../internal/ClientConfigResourceProvider.java | 35 +++-
.../server/orm/entities/AlertNoticeEntity.java | 51 ++++--
.../ambari/server/state/ConfigHelper.java | 21 ++-
.../server/state/cluster/ClusterImpl.java | 3 +-
.../server/upgrade/UpgradeCatalog161.java | 1 -
.../server/upgrade/UpgradeCatalog170.java | 28 +++-
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 7 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 7 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 7 +-
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 7 +-
.../services/HDFS/configuration/hadoop-env.xml | 2 +-
.../GANGLIA/configuration/ganglia-env.xml | 5 +
.../GANGLIA/package/scripts/ganglia_monitor.py | 4 +-
.../services/GANGLIA/package/scripts/params.py | 24 +--
.../HIVE/package/scripts/install_jars.py | 28 ++--
.../services/HIVE/package/scripts/params.py | 11 +-
.../services/NAGIOS/package/files/sys_logger.py | 30 ++--
.../stacks/HDP/2.2.1/role_command_order.json | 2 +-
.../services/TEZ/configuration/tez-site.xml | 29 ++++
.../stacks/HDP/2.2/role_command_order.json | 3 +-
.../SLIDER/configuration/slider-client.xml | 56 +++++++
.../SLIDER/configuration/slider-log4j.xml | 89 ++++++++++
.../stacks/HDP/2.2/services/SLIDER/metainfo.xml | 72 ++++++++
.../SLIDER/package/files/hbaseSmokeVerify.sh | 34 ++++
.../services/SLIDER/package/scripts/__init__.py | 19 +++
.../services/SLIDER/package/scripts/params.py | 45 +++++
.../SLIDER/package/scripts/service_check.py | 45 +++++
.../services/SLIDER/package/scripts/slider.py | 68 ++++++++
.../SLIDER/package/scripts/slider_client.py | 43 +++++
.../SLIDER/package/templates/slider-wrapper.j2 | 42 +++++
.../2.2/services/TEZ/configuration/tez-site.xml | 29 ++++
.../ClientConfigResourceProviderTest.java | 24 ++-
.../server/orm/dao/AlertDefinitionDAOTest.java | 1 +
.../server/upgrade/UpgradeCatalog161Test.java | 4 -
.../server/upgrade/UpgradeCatalog170Test.java | 114 ++++++++++---
.../stacks/2.0.6/HIVE/test_hive_server.py | 3 +-
.../stacks/2.2/SLIDER/test_slider_client.py | 109 +++++++++++++
.../test/python/stacks/2.2/configs/default.json | 115 +++++++++++++
.../test/python/stacks/2.2/configs/secured.json | 79 +++++++++
ambari-shell/ambari-groovy-shell/pom.xml | 11 ++
.../ambari/shell/commands/ConfigCommands.java | 163 +++++++++++++++++++
.../shell/completion/AbstractCompletion.java | 34 ++++
.../ambari/shell/completion/Blueprint.java | 9 +-
.../ambari/shell/completion/ConfigType.java | 29 ++++
.../apache/ambari/shell/completion/Host.java | 9 +-
.../apache/ambari/shell/completion/Service.java | 12 +-
.../configuration/ConverterConfiguration.java | 6 +
.../shell/converter/AbstractConverter.java | 63 +++++++
.../shell/converter/BlueprintConverter.java | 21 +--
.../shell/converter/ConfigTypeConverter.java | 45 +++++
.../ambari/shell/converter/HostConverter.java | 21 +--
.../shell/converter/ServiceConverter.java | 24 +--
.../shell/commands/ConfigCommandsTest.java | 98 +++++++++++
.../src/test/resources/core-site.xml | 13 ++
ambari-web/app/controllers/application.js | 8 +-
ambari-web/app/controllers/main.js | 1 -
.../resourceManager/wizard_controller.js | 1 -
ambari-web/app/controllers/main/host/details.js | 9 +-
.../controllers/main/service/info/configs.js | 42 +++--
.../main/service/reassign/step2_controller.js | 1 +
.../app/controllers/main/views_controller.js | 6 +-
.../app/controllers/wizard/step5_controller.js | 10 +-
.../app/controllers/wizard/step7_controller.js | 5 +
ambari-web/app/messages.js | 3 +-
ambari-web/app/mixins/common/serverValidator.js | 1 +
ambari-web/app/models/service_config_version.js | 2 +-
ambari-web/app/routes/installer.js | 1 +
ambari-web/app/routes/main.js | 1 -
ambari-web/app/routes/reassign_master_routes.js | 124 +++++++-------
.../app/routes/rm_high_availability_routes.js | 12 +-
ambari-web/app/styles/application.less | 22 ++-
ambari-web/app/templates/application.hbs | 27 ++-
.../common/configs/config_history_flow.hbs | 36 +---
.../configs/config_recommendation_popup.hbs | 40 ++++-
.../common/configs/service_version_box.hbs | 53 ++++++
.../app/templates/common/custom_date_popup.hbs | 39 +++++
ambari-web/app/templates/main/host/summary.hbs | 8 +
.../wizard/step6/step6_issues_popup.hbs | 44 ++---
ambari-web/app/utils/ajax/ajax.js | 2 +-
ambari-web/app/utils/config.js | 2 +-
ambari-web/app/views.js | 1 +
.../views/common/configs/config_history_flow.js | 22 +++
.../app/views/common/select_custom_date_view.js | 36 ++++
ambari-web/app/views/main/host/summary.js | 11 ++
.../test/nagios/plugins/test_sys_logger.py | 77 ++++++++-
.../apache/ambari/view/slider/AlertField.java | 62 +++++++
.../apache/ambari/view/slider/AlertState.java | 40 +++++
.../apache/ambari/view/slider/SliderApp.java | 9 +
.../ambari/view/slider/SliderAppsAlerts.java | 126 ++++++++++++++
.../slider/SliderAppsViewControllerImpl.java | 24 ++-
.../rest/client/SliderAppMasterClient.java | 38 +++--
.../assets/data/resource/service_configs.json | 2 +-
.../createAppWizard/step1_controller.js | 2 +-
.../resources/ui/app/models/slider_app_alert.js | 43 ++---
.../ui/app/templates/slider_app/summary.hbs | 2 +-
.../ui/app/views/slider_app/summary_view.js | 2 +-
105 files changed, 2565 insertions(+), 451 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1018b17/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1018b17/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1018b17/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1018b17/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1018b17/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1018b17/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1018b17/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1018b17/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
[50/50] [abbrv] git commit: Merge branch 'branch-alerts-dev' into
trunk
Posted by jo...@apache.org.
Merge branch 'branch-alerts-dev' into trunk
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/80bceaf3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/80bceaf3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/80bceaf3
Branch: refs/heads/trunk
Commit: 80bceaf3abc8028e7d6b9f9d3a7738132ece6b8a
Parents: 0d953b4 cc2d934
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Oct 6 17:02:54 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Oct 6 17:02:54 2014 -0400
----------------------------------------------------------------------
ambari-agent/pom.xml | 1 +
.../ambari_agent/AlertSchedulerHandler.py | 371 ++++++++++
.../src/main/python/ambari_agent/Controller.py | 35 +-
.../src/main/python/ambari_agent/Heartbeat.py | 8 +-
.../main/python/ambari_agent/alerts/__init__.py | 18 +
.../python/ambari_agent/alerts/base_alert.py | 204 ++++++
.../python/ambari_agent/alerts/collector.py | 70 ++
.../python/ambari_agent/alerts/metric_alert.py | 174 +++++
.../python/ambari_agent/alerts/port_alert.py | 71 ++
.../python/ambari_agent/alerts/script_alert.py | 70 ++
.../python/ambari_agent/apscheduler/__init__.py | 3 +
.../python/ambari_agent/apscheduler/events.py | 64 ++
.../main/python/ambari_agent/apscheduler/job.py | 137 ++++
.../apscheduler/jobstores/__init__.py | 0
.../ambari_agent/apscheduler/jobstores/base.py | 25 +
.../apscheduler/jobstores/mongodb_store.py | 84 +++
.../apscheduler/jobstores/ram_store.py | 25 +
.../apscheduler/jobstores/redis_store.py | 91 +++
.../apscheduler/jobstores/shelve_store.py | 74 ++
.../apscheduler/jobstores/sqlalchemy_store.py | 91 +++
.../ambari_agent/apscheduler/scheduler.py | 607 +++++++++++++++++
.../ambari_agent/apscheduler/threadpool.py | 133 ++++
.../apscheduler/triggers/__init__.py | 3 +
.../apscheduler/triggers/cron/__init__.py | 144 ++++
.../apscheduler/triggers/cron/expressions.py | 194 ++++++
.../apscheduler/triggers/cron/fields.py | 100 +++
.../apscheduler/triggers/interval.py | 39 ++
.../ambari_agent/apscheduler/triggers/simple.py | 17 +
.../python/ambari_agent/apscheduler/util.py | 230 +++++++
.../src/test/python/ambari_agent/TestAlerts.py | 357 ++++++++++
.../test/python/ambari_agent/TestController.py | 1 +
.../ambari_agent/dummy_files/definitions.json | 37 +
.../ambari_agent/dummy_files/test_script.py | 3 +
ambari-project/pom.xml | 7 +-
ambari-server/pom.xml | 22 +-
.../apache/ambari/server/EagerSingleton.java | 43 ++
.../apache/ambari/server/agent/ActionQueue.java | 51 +-
.../ambari/server/agent/AgentCommand.java | 37 +-
.../server/agent/AlertDefinitionCommand.java | 168 +++++
.../server/agent/AlertExecutionCommand.java | 74 ++
.../ambari/server/agent/CancelCommand.java | 5 +-
.../ambari/server/agent/ExecutionCommand.java | 109 +--
.../apache/ambari/server/agent/HeartBeat.java | 6 +
.../ambari/server/agent/HeartBeatHandler.java | 174 +++--
.../ambari/server/agent/HeartBeatResponse.java | 119 +++-
.../ambari/server/agent/HeartbeatMonitor.java | 40 +-
.../ambari/server/agent/NagiosAlertCommand.java | 11 +-
.../server/agent/RegistrationResponse.java | 50 +-
.../ambari/server/agent/StatusCommand.java | 43 +-
.../resources/AlertDefResourceDefinition.java | 3 -
.../resources/AlertGroupResourceDefinition.java | 50 ++
.../api/resources/AlertResourceDefinition.java | 41 ++
.../AlertTargetResourceDefinition.java | 50 ++
.../resources/ClusterResourceDefinition.java | 1 +
.../api/resources/HostResourceDefinition.java | 7 +-
.../resources/ResourceInstanceFactoryImpl.java | 12 +
.../resources/ServiceResourceDefinition.java | 5 +-
.../server/api/services/AlertGroupService.java | 121 ++++
.../server/api/services/AlertService.java | 93 +++
.../server/api/services/AlertTargetService.java | 106 +++
.../server/api/services/AmbariMetaInfo.java | 368 +++++++---
.../server/api/services/ClusterService.java | 82 ++-
.../ambari/server/api/services/HostService.java | 11 +
.../server/api/services/ServiceService.java | 9 +
.../services/parsers/JsonRequestBodyParser.java | 14 +-
.../controller/AlertDefinitionResponse.java | 143 ++++
.../ambari/server/controller/AmbariServer.java | 26 +-
.../server/controller/ControllerModule.java | 71 +-
.../AbstractControllerResourceProvider.java | 12 +-
.../internal/AbstractProviderModule.java | 41 +-
.../AlertDefinitionResourceProvider.java | 465 +++++++++----
.../internal/AlertGroupResourceProvider.java | 403 +++++++++++
.../internal/AlertResourceProvider.java | 191 ++++++
.../internal/AlertSummaryPropertyProvider.java | 138 ++++
.../internal/AlertTargetResourceProvider.java | 369 ++++++++++
.../nagios/NagiosPropertyProvider.java | 27 +-
.../ambari/server/controller/spi/Resource.java | 15 +-
.../events/AlertDefinitionDeleteEvent.java | 55 ++
.../AlertDefinitionRegistrationEvent.java | 57 ++
.../apache/ambari/server/events/AlertEvent.java | 58 ++
.../server/events/AlertReceivedEvent.java | 50 ++
.../server/events/AlertStateChangeEvent.java | 101 +++
.../ambari/server/events/AmbariEvent.java | 75 ++
.../ambari/server/events/ClusterEvent.java | 50 ++
.../server/events/MaintenanceModeEvent.java | 175 +++++
.../ambari/server/events/ServiceEvent.java | 75 ++
.../server/events/ServiceInstalledEvent.java | 52 ++
.../listeners/AlertAggregateListener.java | 126 ++++
.../listeners/AlertLifecycleListener.java | 127 ++++
.../listeners/AlertMaintenanceModeListener.java | 199 ++++++
.../events/listeners/AlertReceivedListener.java | 191 ++++++
.../listeners/AlertServiceStateListener.java | 150 ++++
.../listeners/AlertStateChangedListener.java | 113 +++
.../events/publishers/AlertEventPublisher.java | 108 +++
.../events/publishers/AmbariEventPublisher.java | 66 ++
.../server/notifications/DispatchCallback.java | 50 ++
.../notifications/DispatchCredentials.java | 44 ++
.../server/notifications/DispatchFactory.java | 78 +++
.../server/notifications/DispatchRunnable.java | 60 ++
.../server/notifications/Notification.java | 75 ++
.../notifications/NotificationDispatcher.java | 47 ++
.../ambari/server/notifications/Recipient.java | 45 ++
.../dispatchers/EmailDispatcher.java | 179 +++++
.../server/orm/dao/AlertDefinitionDAO.java | 242 ++++++-
.../ambari/server/orm/dao/AlertDispatchDAO.java | 183 ++++-
.../ambari/server/orm/dao/AlertSummaryDTO.java | 70 ++
.../apache/ambari/server/orm/dao/AlertsDAO.java | 206 +++++-
.../server/orm/entities/AlertCurrentEntity.java | 45 +-
.../orm/entities/AlertDefinitionEntity.java | 91 ++-
.../server/orm/entities/AlertGroupEntity.java | 65 +-
.../server/orm/entities/AlertHistoryEntity.java | 55 +-
.../server/orm/entities/AlertNoticeEntity.java | 2 +
.../server/orm/entities/AlertTargetEntity.java | 3 +-
.../server/orm/entities/ClusterEntity.java | 75 +-
.../org/apache/ambari/server/state/Alert.java | 66 +-
.../ambari/server/state/ConfigFactory.java | 2 -
.../apache/ambari/server/state/ServiceImpl.java | 61 +-
.../state/alert/AggregateDefinitionMapping.java | 111 +++
.../server/state/alert/AggregateSource.java | 92 +++
.../server/state/alert/AlertDefinition.java | 221 +++++-
.../state/alert/AlertDefinitionFactory.java | 285 ++++++++
.../server/state/alert/AlertDefinitionHash.java | 638 +++++++++++++++++
.../ambari/server/state/alert/AlertGroup.java | 124 ++++
.../ambari/server/state/alert/AlertTarget.java | 130 ++++
.../ambari/server/state/alert/MetricSource.java | 128 +++-
.../server/state/alert/PercentSource.java | 191 ++++++
.../ambari/server/state/alert/PortSource.java | 113 +++
.../ambari/server/state/alert/Reporting.java | 247 +++++++
.../apache/ambari/server/state/alert/Scope.java | 18 +-
.../ambari/server/state/alert/ScriptSource.java | 81 +++
.../ambari/server/state/alert/Source.java | 71 +-
.../ambari/server/state/alert/SourceType.java | 9 +-
.../ambari/server/state/alert/TargetType.java | 46 ++
.../server/state/cluster/ClusterImpl.java | 109 ++-
.../ambari/server/state/host/HostImpl.java | 133 ++--
.../services/AlertNoticeDispatchService.java | 398 +++++++++++
.../svccomphost/ServiceComponentHostImpl.java | 109 ++-
.../server/upgrade/UpgradeCatalog170.java | 3 +-
.../apache/ambari/server/utils/StageUtils.java | 10 -
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 2 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 2 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 2 +-
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 2 +-
.../src/main/resources/key_properties.json | 13 +
.../src/main/resources/properties.json | 37 +-
.../stacks/HDP/2.0.6/services/HBASE/alerts.json | 24 +
.../stacks/HDP/2.0.6/services/HDFS/alerts.json | 147 ++++
.../ambari/server/agent/TestActionQueue.java | 88 ++-
.../api/query/render/DefaultRendererTest.java | 3 +-
.../api/query/render/MinimalRendererTest.java | 3 +-
.../ClusterResourceDefinitionTest.java | 3 +-
.../server/api/services/AmbariMetaInfoTest.java | 104 ++-
.../AmbariManagementControllerTest.java | 132 +++-
.../AlertDefinitionResourceProviderTest.java | 221 +++++-
.../AlertGroupResourceProviderTest.java | 611 +++++++++++++++++
.../internal/AlertResourceProviderTest.java | 241 +++++++
.../AlertTargetResourceProviderTest.java | 408 +++++++++++
.../nagios/NagiosPropertyProviderTest.java | 80 +--
.../apache/ambari/server/events/EventsTest.java | 188 +++++
.../ambari/server/events/MockEventListener.java | 99 +++
.../notifications/EmailDispatcherTest.java | 117 ++++
.../server/notifications/MockDispatcher.java | 46 ++
.../apache/ambari/server/orm/OrmTestHelper.java | 42 +-
.../server/orm/dao/AlertDefinitionDAOTest.java | 165 ++++-
.../server/orm/dao/AlertDispatchDAOTest.java | 125 +++-
.../ambari/server/orm/dao/AlertsDAOTest.java | 681 +++++++++++++++++--
.../alerts/AlertDefinitionEqualityTest.java | 158 +++++
.../state/alerts/AlertDefinitionHashTest.java | 407 +++++++++++
.../state/alerts/AlertEventPublisherTest.java | 196 ++++++
.../alerts/AlertStateChangedEventTest.java | 147 ++++
.../state/cluster/AlertDataManagerTest.java | 449 ++++++++++++
.../svccomphost/ServiceComponentHostTest.java | 242 +++----
.../ambari/server/utils/TestStageUtils.java | 120 ++--
.../stacks/HDP/2.0.5/services/HDFS/alerts.json | 77 +++
.../app/controllers/global/update_controller.js | 4 +-
.../app/controllers/main/alerts_controller.js | 4 +-
ambari-web/app/controllers/main/host.js | 4 +-
ambari-web/app/mappers/hosts_mapper.js | 2 +-
ambari-web/app/mappers/service_mapper.js | 8 +-
ambari-web/app/utils/ajax/ajax.js | 6 +-
.../controllers/main/alerts_controller_test.js | 28 +-
181 files changed, 18299 insertions(+), 1292 deletions(-)
----------------------------------------------------------------------
[46/50] [abbrv] git commit: AMBARI-7642 - Alerts: Maintenance Mode
Should Prevent Alert Notifications (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7642 - Alerts: Maintenance Mode Should Prevent Alert Notifications (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3e54f956
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3e54f956
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3e54f956
Branch: refs/heads/trunk
Commit: 3e54f95689d7854fc17a31a2734aea080efd7d71
Parents: 6f9398f
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Oct 3 16:23:31 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Oct 3 23:13:44 2014 -0400
----------------------------------------------------------------------
.../apache/ambari/server/EagerSingleton.java | 43 ++
.../server/controller/ControllerModule.java | 56 ++-
.../server/events/AlertStateChangeEvent.java | 26 +-
.../ambari/server/events/AmbariEvent.java | 7 +-
.../server/events/MaintenanceModeEvent.java | 175 +++++++
.../listeners/AlertAggregateListener.java | 2 +
.../listeners/AlertLifecycleListener.java | 2 +
.../listeners/AlertMaintenanceModeListener.java | 199 ++++++++
.../events/listeners/AlertReceivedListener.java | 6 +-
.../listeners/AlertServiceStateListener.java | 2 +
.../listeners/AlertStateChangedListener.java | 11 +
.../apache/ambari/server/state/ServiceImpl.java | 5 +
.../ambari/server/state/host/HostImpl.java | 133 +++---
.../svccomphost/ServiceComponentHostImpl.java | 13 +
.../apache/ambari/server/events/EventsTest.java | 188 ++++++++
.../ambari/server/events/MockEventListener.java | 99 ++++
.../ambari/server/orm/dao/AlertsDAOTest.java | 456 ++++++++++++++++---
.../state/cluster/AlertDataManagerTest.java | 10 +-
18 files changed, 1280 insertions(+), 153 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/EagerSingleton.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/EagerSingleton.java b/ambari-server/src/main/java/org/apache/ambari/server/EagerSingleton.java
new file mode 100644
index 0000000..dde4143
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/EagerSingleton.java
@@ -0,0 +1,43 @@
+/**
+ * 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.ambari.server;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import com.google.inject.Module;
+import com.google.inject.ScopeAnnotation;
+import com.google.inject.Singleton;
+import com.google.inject.binder.AnnotatedBindingBuilder;
+
+/**
+ * The {@link EagerSingleton} annotation is used to mark a {@link Singleton}
+ * class as being needed to be eagerly registered by a {@link Module}.
+ * <p/>
+ * Classes marked with this annotation should also be {@link Singleton}. They
+ * will be discovered on the classpath and then
+ * {@link AnnotatedBindingBuilder#asEagerSingleton()} will be invoked on them.
+ */
+@Target({ ElementType.TYPE })
+@Retention(RUNTIME)
+@ScopeAnnotation
+public @interface EagerSingleton {
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index da78639..535a75e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -39,6 +39,7 @@ import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
+import org.apache.ambari.server.EagerSingleton;
import org.apache.ambari.server.actionmanager.ActionDBAccessor;
import org.apache.ambari.server.actionmanager.ActionDBAccessorImpl;
import org.apache.ambari.server.actionmanager.ExecutionCommandWrapper;
@@ -53,11 +54,6 @@ import org.apache.ambari.server.controller.internal.HostResourceProvider;
import org.apache.ambari.server.controller.internal.MemberResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
import org.apache.ambari.server.controller.spi.ResourceProvider;
-import org.apache.ambari.server.events.listeners.AlertAggregateListener;
-import org.apache.ambari.server.events.listeners.AlertLifecycleListener;
-import org.apache.ambari.server.events.listeners.AlertReceivedListener;
-import org.apache.ambari.server.events.listeners.AlertServiceStateListener;
-import org.apache.ambari.server.events.listeners.AlertStateChangedListener;
import org.apache.ambari.server.orm.DBAccessor;
import org.apache.ambari.server.orm.DBAccessorImpl;
import org.apache.ambari.server.orm.PersistenceType;
@@ -99,8 +95,14 @@ import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.server.session.HashSessionIdManager;
import org.eclipse.jetty.server.session.HashSessionManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.StandardPasswordEncoder;
+import org.springframework.util.ClassUtils;
import org.springframework.web.filter.DelegatingFilterProxy;
import com.google.common.util.concurrent.ServiceManager;
@@ -117,6 +119,7 @@ import com.google.inject.persist.jpa.AmbariJpaPersistModule;
* Used for injection purposes.
*/
public class ControllerModule extends AbstractModule {
+ private static Logger LOG = LoggerFactory.getLogger(ControllerModule.class);
private final Configuration configuration;
private final HostsMap hostsMap;
@@ -317,9 +320,11 @@ public class ControllerModule extends AbstractModule {
* instances and then register them with a singleton {@link ServiceManager}.
*/
private void bindServices() {
- Set<com.google.common.util.concurrent.Service> services = new HashSet<com.google.common.util.concurrent.Service>();
+ Set<com.google.common.util.concurrent.Service> services =
+ new HashSet<com.google.common.util.concurrent.Service>();
- AlertNoticeDispatchService alertNoticeDispatchService = new AlertNoticeDispatchService();
+ AlertNoticeDispatchService alertNoticeDispatchService =
+ new AlertNoticeDispatchService();
bind(AlertNoticeDispatchService.class).toInstance(
alertNoticeDispatchService);
@@ -332,14 +337,35 @@ public class ControllerModule extends AbstractModule {
/**
* Initializes all eager singletons that should be instantiated as soon as
* possible and not wait for injection.
+ * <p/>
+ * An example of where this is needed is with a singleton that is headless; in
+ * other words, it doesn't have any injections but still needs to be part of
+ * the Guice framework.
+ * <p/>
+ * This currently scans {@code org.apache.ambari.server} for any
+ * {@link EagerSingleton} instances.
*/
private void bindEagerSingletons() {
- // alert subscribers are "headless" and have no guice references; created
- // them as eager singletons to have them register with the eventbus
- bind(AlertReceivedListener.class).asEagerSingleton();
- bind(AlertStateChangedListener.class).asEagerSingleton();
- bind(AlertServiceStateListener.class).asEagerSingleton();
- bind(AlertLifecycleListener.class).asEagerSingleton();
- bind(AlertAggregateListener.class).asEagerSingleton();
+ ClassPathScanningCandidateComponentProvider scanner =
+ new ClassPathScanningCandidateComponentProvider(false);
+
+ // match only singletons that are eager listeners
+ scanner.addIncludeFilter(new AnnotationTypeFilter(EagerSingleton.class));
+
+ Set<BeanDefinition> beanDefinitions = scanner.findCandidateComponents("org.apache.ambari.server");
+
+ if (null == beanDefinitions || beanDefinitions.size() == 0) {
+ LOG.warn("No instances of {} found to register", EagerSingleton.class);
+ return;
+ }
+
+ for (BeanDefinition beanDefinition : beanDefinitions) {
+ String className = beanDefinition.getBeanClassName();
+ Class<?> clazz = ClassUtils.resolveClassName(className,
+ ClassUtils.getDefaultClassLoader());
+
+ bind(clazz).asEagerSingleton();
+ LOG.debug("Binding singleton {} eagerly", clazz);
+ }
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
index efb7119..e637709 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.server.events;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.AlertState;
@@ -33,9 +34,14 @@ public class AlertStateChangeEvent extends AlertEvent {
private final AlertState m_fromState;
/**
- * The newly created historical entry.
+ * The current alert, including state and history.
*/
- private final AlertHistoryEntity m_newEntity;
+ private final AlertCurrentEntity m_currentAlert;
+
+ /**
+ * The historical record for this alert state change event.
+ */
+ private final AlertHistoryEntity m_history;
/**
* Constructor.
@@ -44,20 +50,30 @@ public class AlertStateChangeEvent extends AlertEvent {
* @param alert
*/
public AlertStateChangeEvent(long clusterId, Alert alert,
- AlertHistoryEntity newEntity, AlertState fromState) {
+ AlertCurrentEntity currentAlert, AlertState fromState) {
super(clusterId, alert);
- m_newEntity = newEntity;
+ m_currentAlert = currentAlert;
+ m_history = currentAlert.getAlertHistory();
m_fromState = fromState;
}
/**
+ * Gets the current alert.
+ *
+ * @return the current alert.
+ */
+ public AlertCurrentEntity getCurrentAlert() {
+ return m_currentAlert;
+ }
+
+ /**
* Gets the newly created item in alert history.
*
* @return the newly created historical item.
*/
public AlertHistoryEntity getNewHistoricalEntry() {
- return m_newEntity;
+ return m_history;
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
index 3dae676..5f2517e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
@@ -40,7 +40,12 @@ public abstract class AmbariEvent {
/**
* An alert definition is removed from the system.
*/
- ALERT_DEFINITION_REMOVAL;
+ ALERT_DEFINITION_REMOVAL,
+
+ /**
+ * A host/service/component has had a maintenance mode change.
+ */
+ MAINTENANCE_MODE;
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/MaintenanceModeEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/MaintenanceModeEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/MaintenanceModeEvent.java
new file mode 100644
index 0000000..810cab4
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/MaintenanceModeEvent.java
@@ -0,0 +1,175 @@
+/**
+ * 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.ambari.server.events;
+
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponentHost;
+
+/**
+ * The {@link MaintenanceModeEvent} is used to capture a host/service/component
+ * maintenance mode change and broadcast it to the system.
+ * <p/>
+ * Although there are several different states aside from on & off in
+ * {@link MaintenanceState}, this event should handle explicit on or off state
+ * changes. This event should not be used for implied state changes, such as
+ * when a component goes into implied maintenance mode as a result of its host's
+ * maintenance mode being explicitely invoked.
+ */
+public class MaintenanceModeEvent extends AmbariEvent {
+
+ /**
+ * The new maintenance state.
+ */
+ private final MaintenanceState m_state;
+
+ /**
+ * The service whose maintenance state changed, or {@code null}.
+ */
+ private final Service m_service;
+
+ /**
+ * The host whose maintenance state changed, or {@code null}.
+ */
+ private final Host m_host;
+
+ /**
+ * The component whose maintenace state changed, or {@code null}.
+ */
+ private final ServiceComponentHost m_serviceComponentHost;
+
+ /**
+ * Constructor.
+ *
+ * @param state
+ * the new state (not {@code null}).
+ * @param service
+ * the service that changed maintenance state (not {@code null})).
+ */
+ public MaintenanceModeEvent(MaintenanceState state, Service service) {
+ this(state, service, null, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param state
+ * the new state (not {@code null}).
+ * @param host
+ * the host that changed maintenance state (not {@code null})).
+ */
+ public MaintenanceModeEvent(MaintenanceState state, Host host) {
+ this(state, null, host, null);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param state
+ * the new state (not {@code null}).
+ * @param serviceComponentHost
+ * the component that changed maintenance state (not {@code null})).
+ */
+ public MaintenanceModeEvent(MaintenanceState state,
+ ServiceComponentHost serviceComponentHost) {
+ this(state, null, null, serviceComponentHost);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param state
+ * the new state (not {@code null}).
+ * @param service
+ * the service that changed maintenance state, or {@code null}.
+ * @param host
+ * the host that changed maintenance state, or {@code null}.
+ * @param serviceComponentHost
+ * the component that changed maintenance state, or {@code null}.
+ */
+ private MaintenanceModeEvent(MaintenanceState state, Service service,
+ Host host, ServiceComponentHost serviceComponentHost) {
+ super(AmbariEventType.MAINTENANCE_MODE);
+ m_state = state;
+ m_service = service;
+ m_host = host;
+ m_serviceComponentHost = serviceComponentHost;
+ }
+
+ /**
+ * Gets the service that had the direct maintenance mode event, or
+ * {@code null} if the event was not directly on a service.
+ *
+ * @return the service or {@code null}
+ */
+ public Service getService() {
+ return m_service;
+ }
+
+ /**
+ * Gets the host that had the direct maintenance mode event, or {@code null}
+ * if the event was not directly on a host.
+ *
+ * @return the host or {@code null}
+ */
+ public Host getHost() {
+ return m_host;
+ }
+
+ /**
+ * Gets the component that had the direct maintenance mode event, or
+ * {@code null} if the event was not directly on a component.
+ *
+ * @return the component or {@code null}
+ */
+ public ServiceComponentHost getServiceComponentHost() {
+ return m_serviceComponentHost;
+ }
+
+ /**
+ * Gets the new maintenance state for the service/host/component.
+ *
+ * @return the new maintenance state (never {@code null}).
+ */
+ public MaintenanceState getMaintenanceState() {
+ return m_state;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ Object object = null;
+ if (null != m_service) {
+ object = m_service;
+ } else if (null != m_host) {
+ object = m_host;
+ } else {
+ object = m_serviceComponentHost;
+ }
+
+ StringBuilder buffer = new StringBuilder("MaintenanceModeEvent{ ");
+ buffer.append("state=").append(m_state);
+ buffer.append(", object=").append(object);
+ buffer.append(" }");
+
+ return buffer.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
index a0c8e46..5e9dea2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
@@ -19,6 +19,7 @@ package org.apache.ambari.server.events.listeners;
import java.text.MessageFormat;
+import org.apache.ambari.server.EagerSingleton;
import org.apache.ambari.server.events.AlertReceivedEvent;
import org.apache.ambari.server.events.publishers.AlertEventPublisher;
import org.apache.ambari.server.orm.dao.AlertSummaryDTO;
@@ -41,6 +42,7 @@ import com.google.inject.Singleton;
* {@link SourceType#AGGREGATE} alert that needs to run.
*/
@Singleton
+@EagerSingleton
public class AlertAggregateListener {
@Inject
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
index 9d2f4c6..22932ee 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
@@ -19,6 +19,7 @@ package org.apache.ambari.server.events.listeners;
import java.util.Set;
+import org.apache.ambari.server.EagerSingleton;
import org.apache.ambari.server.events.AlertDefinitionDeleteEvent;
import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
@@ -40,6 +41,7 @@ import com.google.inject.Singleton;
* infrastructure lifecycle such as definition registration events.
*/
@Singleton
+@EagerSingleton
public class AlertLifecycleListener {
/**
* Logger.
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertMaintenanceModeListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertMaintenanceModeListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertMaintenanceModeListener.java
new file mode 100644
index 0000000..af008be
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertMaintenanceModeListener.java
@@ -0,0 +1,199 @@
+/**
+ * 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.ambari.server.events.listeners;
+
+import java.util.List;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.EagerSingleton;
+import org.apache.ambari.server.controller.MaintenanceStateHelper;
+import org.apache.ambari.server.events.MaintenanceModeEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.eventbus.AllowConcurrentEvents;
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AlertMaintenanceModeListener} handles events that relate to
+ * Maintenance Mode changes.
+ */
+@Singleton
+@EagerSingleton
+public class AlertMaintenanceModeListener {
+ /**
+ * Logger.
+ */
+ private static Logger LOG = LoggerFactory.getLogger(AlertMaintenanceModeListener.class);
+
+ /**
+ * Used for updating the MM of current alerts.
+ */
+ @Inject
+ private AlertsDAO m_alertsDao = null;
+
+ /**
+ * Used to assist in determining implied maintenance state.
+ */
+ @Inject
+ private Provider<MaintenanceStateHelper> m_maintenanceHelper;
+
+ /**
+ * Used to lookup MM states.
+ */
+ @Inject
+ private Provider<Clusters> m_clusters;
+
+ /**
+ * Constructor.
+ *
+ * @param publisher
+ */
+ @Inject
+ public AlertMaintenanceModeListener(AmbariEventPublisher publisher) {
+ publisher.register(this);
+ }
+
+ /**
+ * Handles {@link MaintenanceModeEvent} by performing the following tasks:
+ * <ul>
+ * <li>Iterates through all {@link AlertNoticeEntity}, updating the MM state</li>
+ * </ul>
+ *
+ * @param event
+ * the event being handled.
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ public void onEvent(MaintenanceModeEvent event) {
+ List<AlertCurrentEntity> currentAlerts = m_alertsDao.findCurrent();
+
+ for( AlertCurrentEntity currentAlert : currentAlerts ){
+ MaintenanceState currentState = currentAlert.getMaintenanceState();
+ AlertHistoryEntity history = currentAlert.getAlertHistory();
+ AlertDefinitionEntity definition = history.getAlertDefinition();
+
+ long clusterId = history.getClusterId();
+ String hostName = history.getHostName();
+ String serviceName = history.getServiceName();
+ String componentName = history.getComponentName();
+
+ try {
+ Cluster cluster = m_clusters.get().getClusterById(clusterId);
+ if (null == cluster) {
+ LOG.warn("Unable to find cluster with ID {}", clusterId);
+ continue;
+ }
+
+ Service service = cluster.getService(serviceName);
+ if (null == service) {
+ LOG.warn("Unable to find service named {} in cluster {}",
+ serviceName, cluster.getClusterName());
+
+ continue;
+ }
+
+ // if this is a service-level alert, then check explicitely against the
+ // service for the MM state
+ if (null == componentName) {
+ MaintenanceState serviceState = service.getMaintenanceState();
+ if (currentState != serviceState) {
+ currentAlert.setMaintenanceState(serviceState);
+ m_alertsDao.merge(currentAlert);
+ }
+ }
+ // the presence of a component name means that it's a component alert
+ // which require a host
+ else {
+ if (hostName == null) {
+ LOG.warn("The alert {} for component {} must have a host",
+ definition.getDefinitionName(), componentName);
+
+ continue;
+ }
+
+ List<ServiceComponentHost> serviceComponentHosts = cluster.getServiceComponentHosts(hostName);
+ if (null == serviceComponentHosts) {
+ LOG.warn(
+ "Unable to find service components on host {} for {} in cluster {}",
+ hostName, serviceName, cluster.getClusterName());
+
+ continue;
+ }
+
+ ServiceComponentHost serviceComponentHost = null;
+ for (ServiceComponentHost sch : serviceComponentHosts) {
+ if (componentName.equals(sch.getServiceComponentName())) {
+ serviceComponentHost = sch;
+ break;
+ }
+ }
+
+ if (null == serviceComponentHost) {
+ LOG.warn("Unable to find component {} of {} on host {}",
+ componentName, serviceName, hostName);
+
+ continue;
+ }
+
+ MaintenanceState effectiveState = m_maintenanceHelper.get().getEffectiveState(
+ serviceComponentHost);
+
+ switch (effectiveState) {
+ case OFF:
+ if (currentState != MaintenanceState.OFF) {
+ currentAlert.setMaintenanceState(MaintenanceState.OFF);
+ m_alertsDao.merge(currentAlert);
+ }
+
+ break;
+ case ON:
+ case IMPLIED_FROM_HOST:
+ case IMPLIED_FROM_SERVICE:
+ case IMPLIED_FROM_SERVICE_AND_HOST:
+ if (currentState == MaintenanceState.OFF) {
+ currentAlert.setMaintenanceState(MaintenanceState.ON);
+ m_alertsDao.merge(currentAlert);
+ }
+
+ break;
+ default:
+ break;
+ }
+ }
+ } catch (AmbariException ambariException) {
+ LOG.error("Unable to put alert '{}' for host {} into maintenance mode",
+ definition.getDefinitionName(), hostName, ambariException);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
index 78d8e66..45d0734 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.server.events.listeners;
+import org.apache.ambari.server.EagerSingleton;
import org.apache.ambari.server.events.AlertEvent;
import org.apache.ambari.server.events.AlertReceivedEvent;
import org.apache.ambari.server.events.AlertStateChangeEvent;
@@ -28,6 +29,7 @@ import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.MaintenanceState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,6 +44,7 @@ import com.google.inject.Singleton;
* {@link AlertStateChangeEvent} when an {@link AlertState} change is detected.
*/
@Singleton
+@EagerSingleton
public class AlertReceivedListener {
/**
* Logger.
@@ -112,6 +115,7 @@ public class AlertReceivedListener {
AlertHistoryEntity history = createHistory(clusterId, definition, alert);
current = new AlertCurrentEntity();
+ current.setMaintenanceState(MaintenanceState.OFF);
current.setAlertHistory(history);
current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
@@ -155,7 +159,7 @@ public class AlertReceivedListener {
// broadcast the alert changed event for other subscribers
AlertStateChangeEvent alertChangedEvent = new AlertStateChangeEvent(
- event.getClusterId(), event.getAlert(), current.getAlertHistory(),
+ event.getClusterId(), event.getAlert(), current,
oldState);
m_alertEventPublisher.publish(alertChangedEvent);
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
index 6215cc1..9a1a68b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
@@ -21,6 +21,7 @@ import java.text.MessageFormat;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.EagerSingleton;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.AmbariServer;
import org.apache.ambari.server.controller.ControllerModule;
@@ -48,6 +49,7 @@ import com.google.inject.Singleton;
* and {@link AlertGroupEntity} instances are correctly populated.
*/
@Singleton
+@EagerSingleton
public class AlertServiceStateListener {
/**
* Logger.
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
index b2f08d7..c42851b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
@@ -21,14 +21,17 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
+import org.apache.ambari.server.EagerSingleton;
import org.apache.ambari.server.events.AlertStateChangeEvent;
import org.apache.ambari.server.events.publishers.AlertEventPublisher;
import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertGroupEntity;
import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.MaintenanceState;
import org.apache.ambari.server.state.NotificationState;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -44,6 +47,7 @@ import com.google.inject.Singleton;
* in the database.
*/
@Singleton
+@EagerSingleton
public class AlertStateChangedListener {
/**
@@ -75,6 +79,13 @@ public class AlertStateChangedListener {
public void onAlertEvent(AlertStateChangeEvent event) {
LOG.debug(event);
+ // don't create any outbound alert notices if in MM
+ AlertCurrentEntity currentAlert = event.getCurrentAlert();
+ if (null != currentAlert
+ && currentAlert.getMaintenanceState() != MaintenanceState.OFF) {
+ return;
+ }
+
AlertHistoryEntity history = event.getNewHistoricalEntry();
AlertDefinitionEntity definition = history.getAlertDefinition();
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
index e6b5921..d7880c4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
@@ -27,6 +27,7 @@ import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ServiceComponentNotFoundException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.ServiceResponse;
+import org.apache.ambari.server.events.MaintenanceModeEvent;
import org.apache.ambari.server.events.ServiceInstalledEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.dao.ClusterDAO;
@@ -675,6 +676,10 @@ public class ServiceImpl implements Service {
readWriteLock.writeLock().lock();
serviceDesiredStateEntity.setMaintenanceState(state);
saveIfPersisted();
+
+ // broadcast the maintenance mode change
+ MaintenanceModeEvent event = new MaintenanceModeEvent(state, this);
+ eventPublisher.publish(event);
} finally {
readWriteLock.writeLock().unlock();
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
index 619859c..53f5f40 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/host/HostImpl.java
@@ -31,6 +31,8 @@ import org.apache.ambari.server.agent.AgentEnv;
import org.apache.ambari.server.agent.DiskInfo;
import org.apache.ambari.server.agent.HostInfo;
import org.apache.ambari.server.controller.HostResponse;
+import org.apache.ambari.server.events.MaintenanceModeEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.cache.HostConfigMapping;
import org.apache.ambari.server.orm.cache.HostConfigMappingImpl;
import org.apache.ambari.server.orm.dao.ClusterDAO;
@@ -89,7 +91,7 @@ public class HostImpl implements Host {
private static final String TIMEZONE = "timezone";
private static final String OS_RELEASE_VERSION = "os_release_version";
-
+
private final Gson gson;
private static final Type hostAttributesType =
@@ -114,18 +116,22 @@ public class HostImpl implements Host {
private List<DiskInfo> disksInfo = new ArrayList<DiskInfo>();
private boolean persisted = false;
private Integer currentPingPort = null;
-
+
private final StateMachine<HostState, HostEventType, HostEvent> stateMachine;
private Map<Long, MaintenanceState> maintMap = null;
-
-
// In-memory status, based on host components states
private String status;
// In-memory prefix of log file paths that is retrieved when the agent registers with the server
private String prefix;
+ /**
+ * Used to publish events relating to host CRUD operations.
+ */
+ @Inject
+ private AmbariEventPublisher eventPublisher;
+
private static final StateMachineFactory
<HostImpl, HostState, HostEventType, HostEvent>
stateMachineFactory
@@ -214,19 +220,19 @@ public class HostImpl implements Host {
@Inject
public HostImpl(@Assisted HostEntity hostEntity,
@Assisted boolean persisted, Injector injector) {
- this.stateMachine = stateMachineFactory.make(this);
+ stateMachine = stateMachineFactory.make(this);
rwLock = new ReentrantReadWriteLock();
- this.readLock = rwLock.readLock();
- this.writeLock = rwLock.writeLock();
+ readLock = rwLock.readLock();
+ writeLock = rwLock.writeLock();
this.hostEntity = hostEntity;
this.persisted = persisted;
- this.hostDAO = injector.getInstance(HostDAO.class);
- this.hostStateDAO = injector.getInstance(HostStateDAO.class);
- this.gson = injector.getInstance(Gson.class);
- this.clusterDAO = injector.getInstance(ClusterDAO.class);
- this.clusters = injector.getInstance(Clusters.class);
- this.hostConfigMappingDAO = injector.getInstance(HostConfigMappingDAO.class);
+ hostDAO = injector.getInstance(HostDAO.class);
+ hostStateDAO = injector.getInstance(HostStateDAO.class);
+ gson = injector.getInstance(Gson.class);
+ clusterDAO = injector.getInstance(ClusterDAO.class);
+ clusters = injector.getInstance(Clusters.class);
+ hostConfigMappingDAO = injector.getInstance(HostConfigMappingDAO.class);
hostStateEntity = hostEntity.getHostStateEntity();
if (hostStateEntity == null) {
@@ -238,7 +244,7 @@ public class HostImpl implements Host {
persist();
}
} else {
- this.stateMachine.setCurrentState(hostStateEntity.getCurrentState());
+ stateMachine.setCurrentState(hostStateEntity.getCurrentState());
}
}
@@ -405,7 +411,7 @@ public class HostImpl implements Host {
}
// FIXME add all other information into host attributes
- this.setAgentVersion(new AgentVersion(
+ setAgentVersion(new AgentVersion(
hostInfo.getAgentUserId()));
Map<String, String> attrs = new HashMap<String, String>();
@@ -462,7 +468,7 @@ public class HostImpl implements Host {
if (hostInfo.getOSRelease() != null) {
attrs.put(OS_RELEASE_VERSION, hostInfo.getOSRelease());
}
-
+
setHostAttributes(attrs);
saveIfPersisted();
@@ -482,7 +488,7 @@ public class HostImpl implements Host {
}
}
-
+
@Override
public AgentEnv getLastAgentEnv() {
readLock.lock();
@@ -533,7 +539,7 @@ public class HostImpl implements Host {
stateMachine.doTransition(event.getType(), event);
} catch (InvalidStateTransitionException e) {
LOG.error("Can't handle Host event at current state"
- + ", host=" + this.getHostName()
+ + ", host=" + getHostName()
+ ", currentState=" + oldState
+ ", eventType=" + event.getType()
+ ", event=" + event);
@@ -546,7 +552,7 @@ public class HostImpl implements Host {
if (oldState != getState()) {
if (LOG.isDebugEnabled()) {
LOG.debug("Host transitioned to a new state"
- + ", host=" + this.getHostName()
+ + ", host=" + getHostName()
+ ", oldState=" + oldState
+ ", currentState=" + getState()
+ ", eventType=" + event.getType().name()
@@ -574,7 +580,7 @@ public class HostImpl implements Host {
writeLock.unlock();
}
}
-
+
@Override
public Integer getCurrentPingPort() {
try {
@@ -608,7 +614,7 @@ public class HostImpl implements Host {
writeLock.unlock();
}
}
-
+
@Override
public String getPublicHostName() {
try {
@@ -703,8 +709,8 @@ public class HostImpl implements Host {
writeLock.unlock();
}
}
-
-
+
+
@Override
public long getTotalMemBytes() {
try {
@@ -811,18 +817,18 @@ public class HostImpl implements Host {
writeLock.unlock();
}
}
-
+
@Override
public String getOsFamily() {
- String majorVersion = this.getHostAttributes().get(OS_RELEASE_VERSION).split("\\.")[0];
- return this.getHostAttributes().get(OSFAMILY) + majorVersion;
+ String majorVersion = getHostAttributes().get(OS_RELEASE_VERSION).split("\\.")[0];
+ return getHostAttributes().get(OSFAMILY) + majorVersion;
}
@Override
public List<DiskInfo> getDisksInfo() {
try {
readLock.lock();
- return this.disksInfo;
+ return disksInfo;
} finally {
readLock.unlock();
}
@@ -854,10 +860,11 @@ public class HostImpl implements Host {
try {
writeLock.lock();
hostStateEntity.setHealthStatus(gson.toJson(healthStatus));
-
- if (healthStatus.getHealthStatus().equals(HealthStatus.UNKNOWN))
+
+ if (healthStatus.getHealthStatus().equals(HealthStatus.UNKNOWN)) {
setStatus(HealthStatus.UNKNOWN.name());
-
+ }
+
saveIfPersisted();
} finally {
writeLock.unlock();
@@ -943,7 +950,7 @@ public class HostImpl implements Host {
public void setLastRegistrationTime(long lastRegistrationTime) {
try {
writeLock.lock();
- this.hostEntity.setLastRegistrationTime(lastRegistrationTime);
+ hostEntity.setLastRegistrationTime(lastRegistrationTime);
saveIfPersisted();
} finally {
writeLock.unlock();
@@ -1012,8 +1019,8 @@ public class HostImpl implements Host {
writeLock.unlock();
}
}
-
-
+
+
@Override
public String getStatus() {
return status;
@@ -1142,13 +1149,14 @@ public class HostImpl implements Host {
hostStateDAO.merge(hostStateEntity);
}
}
-
+
@Override
@Transactional
public boolean addDesiredConfig(long clusterId, boolean selected, String user, Config config) {
- if (null == user)
+ if (null == user) {
throw new NullPointerException("User must be specified.");
-
+ }
+
HostConfigMapping exist = getDesiredConfigEntity(clusterId, config.getType());
if (null != exist && exist.getVersion().equals(config.getTag())) {
if (!selected) {
@@ -1157,9 +1165,9 @@ public class HostImpl implements Host {
}
return false;
}
-
+
writeLock.lock();
-
+
try {
// set all old mappings for this type to empty
for (HostConfigMapping e : hostConfigMappingDAO.findByType(clusterId,
@@ -1167,7 +1175,7 @@ public class HostImpl implements Host {
e.setSelected(0);
hostConfigMappingDAO.merge(e);
}
-
+
HostConfigMapping hostConfigMapping = new HostConfigMappingImpl();
hostConfigMapping.setClusterId(Long.valueOf(clusterId));
hostConfigMapping.setCreateTimestamp(Long.valueOf(System.currentTimeMillis()));
@@ -1176,31 +1184,31 @@ public class HostImpl implements Host {
hostConfigMapping.setUser(user);
hostConfigMapping.setType(config.getType());
hostConfigMapping.setVersion(config.getTag());
-
+
hostConfigMappingDAO.create(hostConfigMapping);
}
finally {
writeLock.unlock();
}
-
+
hostDAO.merge(hostEntity);
-
+
return true;
}
-
+
@Override
public Map<String, DesiredConfig> getDesiredConfigs(long clusterId) {
Map<String, DesiredConfig> map = new HashMap<String, DesiredConfig>();
for (HostConfigMapping e : hostConfigMappingDAO.findSelected(
clusterId, hostEntity.getHostName())) {
-
+
DesiredConfig dc = new DesiredConfig();
dc.setTag(e.getVersion());
dc.setServiceName(e.getServiceName());
dc.setUser(e.getUser());
map.put(e.getType(), dc);
-
+
}
return map;
}
@@ -1221,7 +1229,7 @@ public class HostImpl implements Host {
hostConfigMap.put(desiredConfigEntry.getKey(), hostConfig);
}
- Map<Long, ConfigGroup> configGroups = cluster.getConfigGroupsByHostname(this.getHostName());
+ Map<Long, ConfigGroup> configGroups = cluster.getConfigGroupsByHostname(getHostName());
if (configGroups != null && !configGroups.isEmpty()) {
for (ConfigGroup configGroup : configGroups.values()) {
@@ -1249,11 +1257,11 @@ public class HostImpl implements Host {
private HostConfigMapping getDesiredConfigEntity(long clusterId, String type) {
HostConfigMapping findSelectedByType = hostConfigMappingDAO.findSelectedByType(clusterId,
hostEntity.getHostName(), type);
-
-
+
+
return findSelectedByType;
}
-
+
private void ensureMaintMap() {
if (null == maintMap) {
String entity = hostStateEntity.getMaintenanceState();
@@ -1268,42 +1276,47 @@ public class HostImpl implements Host {
}
}
}
-
+
@Override
public void setMaintenanceState(long clusterId, MaintenanceState state) {
try {
writeLock.lock();
-
+
ensureMaintMap();
-
+
maintMap.put(Long.valueOf(clusterId), state);
String json = gson.toJson(maintMap, maintMapType);
-
+
hostStateEntity.setMaintenanceState(json);
saveIfPersisted();
+
+ // broadcast the maintenance mode change
+ MaintenanceModeEvent event = new MaintenanceModeEvent(state, this);
+ eventPublisher.publish(event);
} finally {
writeLock.unlock();
}
}
-
+
@Override
public MaintenanceState getMaintenanceState(long clusterId) {
try {
readLock.lock();
ensureMaintMap();
-
+
Long id = Long.valueOf(clusterId);
-
- if (!maintMap.containsKey(id))
+
+ if (!maintMap.containsKey(id)) {
maintMap.put(id, MaintenanceState.OFF);
-
+ }
+
return maintMap.get(id);
} finally {
readLock.unlock();
}
}
-
+
}
-
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 75265b7..bc97936 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -31,6 +31,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.agent.AlertDefinitionCommand;
import org.apache.ambari.server.controller.ServiceComponentHostResponse;
+import org.apache.ambari.server.events.MaintenanceModeEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
import org.apache.ambari.server.orm.dao.HostDAO;
@@ -110,6 +112,12 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
@Inject
private AlertDefinitionHash alertDefinitionHash;
+ /**
+ * Used to publish events relating to service CRUD operations.
+ */
+ @Inject
+ private AmbariEventPublisher eventPublisher;
+
private HostComponentStateEntity stateEntity;
private HostComponentDesiredStateEntity desiredStateEntity;
@@ -1431,6 +1439,11 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
try {
desiredStateEntity.setMaintenanceState(state);
saveIfPersisted();
+
+ // broadcast the maintenance mode change
+ MaintenanceModeEvent event = new MaintenanceModeEvent(state, this);
+ eventPublisher.publish(event);
+
} finally {
writeLock.unlock();
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/test/java/org/apache/ambari/server/events/EventsTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/events/EventsTest.java b/ambari-server/src/test/java/org/apache/ambari/server/events/EventsTest.java
new file mode 100644
index 0000000..ec85cbd
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/events/EventsTest.java
@@ -0,0 +1,188 @@
+/**
+ * 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.ambari.server.events;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import junit.framework.Assert;
+
+import org.apache.ambari.server.events.MaintenanceModeEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.MaintenanceState;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentFactory;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.ServiceComponentHostFactory;
+import org.apache.ambari.server.state.ServiceFactory;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.State;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.eventbus.EventBus;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.persist.PersistService;
+
+/**
+ * Tests that {@link EventsTest} instances are fired correctly and
+ * that alert data is bootstrapped into the database.
+ */
+public class EventsTest {
+
+ private static final String HOSTNAME = "c6401.ambari.apache.org";
+
+ private Clusters m_clusters;
+ private Cluster m_cluster;
+ private String m_clusterName;
+ private Injector m_injector;
+ private ServiceFactory m_serviceFactory;
+ private ServiceComponentFactory m_componentFactory;
+ private ServiceComponentHostFactory m_schFactory;
+ private AmbariEventPublisher m_eventPublisher;
+ private MockEventListener m_listener;
+
+ /**
+ *
+ */
+ @Before
+ public void setup() throws Exception {
+ m_injector = Guice.createInjector(new InMemoryDefaultTestModule());
+ m_injector.getInstance(GuiceJpaInitializer.class);
+
+ m_eventPublisher = m_injector.getInstance(AmbariEventPublisher.class);
+ EventBus synchronizedBus = new EventBus();
+
+ // register mock listener
+ m_listener = m_injector.getInstance(MockEventListener.class);
+ synchronizedBus.register(m_listener);
+
+ // !!! need a synchronous op for testing
+ Field field = AmbariEventPublisher.class.getDeclaredField("m_eventBus");
+ field.setAccessible(true);
+ field.set(m_eventPublisher, synchronizedBus);
+
+ m_clusters = m_injector.getInstance(Clusters.class);
+ m_serviceFactory = m_injector.getInstance(ServiceFactory.class);
+ m_componentFactory = m_injector.getInstance(ServiceComponentFactory.class);
+ m_schFactory = m_injector.getInstance(ServiceComponentHostFactory.class);
+
+ m_clusterName = "foo";
+ m_clusters.addCluster(m_clusterName);
+ m_clusters.addHost(HOSTNAME);
+
+ Host host = m_clusters.getHost(HOSTNAME);
+ Map<String, String> hostAttributes = new HashMap<String, String>();
+ hostAttributes.put("os_family", "redhat");
+ hostAttributes.put("os_release_version", "6.4");
+ host.setHostAttributes(hostAttributes);
+ host.setState(HostState.HEALTHY);
+ host.persist();
+
+ m_cluster = m_clusters.getCluster(m_clusterName);
+ m_cluster.setDesiredStackVersion(new StackId("HDP", "2.0.6"));
+ Assert.assertNotNull(m_cluster);
+
+ m_clusters.mapHostToCluster(HOSTNAME, m_clusterName);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @After
+ public void teardown() throws Exception {
+ m_injector.getInstance(PersistService.class).stop();
+ m_injector = null;
+ }
+
+ /**
+ * Tests that {@link MaintenanceModeEvent}s are fired correctly.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testMaintenanceModeEvents() throws Exception {
+ installHdfsService();
+ Service service = m_cluster.getService("HDFS");
+ Class<?> eventClass = MaintenanceModeEvent.class;
+
+ Assert.assertFalse(m_listener.isEventReceived(eventClass));
+ service.setMaintenanceState(MaintenanceState.ON);
+ Assert.assertTrue(m_listener.isEventReceived(eventClass));
+ Assert.assertEquals(1, m_listener.getEventReceivedCount(eventClass));
+
+ m_listener.reset();
+ Assert.assertFalse(m_listener.isEventReceived(eventClass));
+
+ List<ServiceComponentHost> componentHosts = m_cluster.getServiceComponentHosts(HOSTNAME);
+ ServiceComponentHost componentHost = componentHosts.get(0);
+ componentHost.setMaintenanceState(MaintenanceState.OFF);
+
+ Assert.assertTrue(m_listener.isEventReceived(eventClass));
+ Assert.assertEquals(1, m_listener.getEventReceivedCount(eventClass));
+
+ m_listener.reset();
+ Assert.assertFalse(m_listener.isEventReceived(eventClass));
+
+ Host host = m_clusters.getHost(HOSTNAME);
+ host.setMaintenanceState(m_cluster.getClusterId(), MaintenanceState.ON);
+ host.setMaintenanceState(m_cluster.getClusterId(), MaintenanceState.OFF);
+
+ Assert.assertTrue(m_listener.isEventReceived(eventClass));
+ Assert.assertEquals(2, m_listener.getEventReceivedCount(eventClass));
+ }
+
+ /**
+ * Calls {@link Service#persist()} to mock a service install along with
+ * creating a single {@link Host} and {@link ServiceComponentHost}.
+ */
+ private void installHdfsService() throws Exception {
+ String serviceName = "HDFS";
+ Service service = m_serviceFactory.createNew(m_cluster, serviceName);
+ m_cluster.addService(service);
+ service.persist();
+ service = m_cluster.getService(serviceName);
+ Assert.assertNotNull(service);
+
+ ServiceComponent component = m_componentFactory.createNew(service, "DATANODE");
+ service.addServiceComponent(component);
+ component.setDesiredState(State.INSTALLED);
+ component.persist();
+
+ ServiceComponentHost sch = m_schFactory.createNew(component, HOSTNAME);
+
+ component.addServiceComponentHost(sch);
+ sch.setDesiredState(State.INSTALLED);
+ sch.setState(State.INSTALLED);
+ sch.setDesiredStackVersion(new StackId("HDP-2.0.6"));
+ sch.setStackVersion(new StackId("HDP-2.0.6"));
+
+ sch.persist();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3e54f956/ambari-server/src/test/java/org/apache/ambari/server/events/MockEventListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/events/MockEventListener.java b/ambari-server/src/test/java/org/apache/ambari/server/events/MockEventListener.java
new file mode 100644
index 0000000..bf0d535
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/events/MockEventListener.java
@@ -0,0 +1,99 @@
+/**
+ * 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.ambari.server.events;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link MockEventListener} is used to provide a way to capture events
+ * being fired via an {@link EventBus}.
+ */
+@Singleton
+public class MockEventListener {
+
+ /**
+ * When an event is received, its class is captured and the event object is
+ * added to the list.
+ */
+ private final Map<Class<?>, List<Object>> m_receivedEvents = new HashMap<Class<?>, List<Object>>();
+
+ /**
+ * Resets the captured events.
+ */
+ public void reset() {
+ m_receivedEvents.clear();
+ }
+
+ /**
+ * Gets whether an event of the specified class was received.
+ *
+ * @param clazz
+ * @return
+ */
+ public boolean isEventReceived(Class<?> clazz) {
+ if (!m_receivedEvents.containsKey(clazz)) {
+ return false;
+ }
+
+ return m_receivedEvents.get(clazz).size() > 0;
+ }
+
+ /**
+ * Gets the total number of events received for the specified class.
+ *
+ * @param clazz
+ * @return
+ */
+ public int getEventReceivedCount(Class<?> clazz){
+ if (!m_receivedEvents.containsKey(clazz)) {
+ return 0;
+ }
+
+ return m_receivedEvents.get(clazz).size();
+ }
+
+ /**
+ * @param event
+ */
+ @Subscribe
+ public void onEvent(MaintenanceModeEvent event) {
+ handleEvent(event);
+ }
+
+ /**
+ * Inserts the event into the map of class to event invocations.
+ *
+ * @param event
+ */
+ private void handleEvent(Object event) {
+ List<Object> events = m_receivedEvents.get(event.getClass());
+ if (null == events) {
+ events = new ArrayList<Object>();
+ m_receivedEvents.put(event.getClass(), events);
+ }
+
+ events.add(event);
+ }
+}
[17/50] [abbrv] git commit: AMBARI-7191. Alerts: rename old alerts
endpoint for new alerts and provide summary info (ncole)
Posted by jo...@apache.org.
AMBARI-7191. Alerts: rename old alerts endpoint for new alerts and provide summary info (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/1f1059cf
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/1f1059cf
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/1f1059cf
Branch: refs/heads/trunk
Commit: 1f1059cff1ac749e5bdc8fd98febccb7ca346652
Parents: 0b406cb
Author: Nate Cole <nc...@hortonworks.com>
Authored: Sun Sep 7 16:42:35 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Mon Sep 8 10:04:00 2014 -0400
----------------------------------------------------------------------
.../api/resources/AlertResourceDefinition.java | 4 +-
.../server/api/services/AlertService.java | 4 +-
.../server/api/services/ClusterService.java | 2 +-
.../ambari/server/api/services/HostService.java | 2 +-
.../server/api/services/ServiceService.java | 2 +-
.../ambari/server/controller/AmbariServer.java | 2 +
.../internal/AbstractProviderModule.java | 41 ++++--
.../internal/AlertSummaryPropertyProvider.java | 134 +++++++++++++++++++
.../nagios/NagiosPropertyProvider.java | 27 ++--
.../ambari/server/orm/dao/AlertSummaryDTO.java | 70 ++++++++++
.../apache/ambari/server/orm/dao/AlertsDAO.java | 50 +++++++
.../nagios/NagiosPropertyProviderTest.java | 80 +++++------
.../ambari/server/orm/dao/AlertsDAOTest.java | 75 ++++++++++-
.../app/controllers/global/update_controller.js | 4 +-
.../app/controllers/main/alerts_controller.js | 4 +-
ambari-web/app/controllers/main/host.js | 4 +-
ambari-web/app/mappers/hosts_mapper.js | 2 +-
ambari-web/app/mappers/service_mapper.js | 8 +-
ambari-web/app/utils/ajax/ajax.js | 6 +-
.../controllers/main/alerts_controller_test.js | 28 ++--
20 files changed, 450 insertions(+), 99 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java
index afdbcfc..d7aca22 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java
@@ -30,12 +30,12 @@ public class AlertResourceDefinition extends BaseResourceDefinition {
@Override
public String getPluralName() {
- return "alerts_data";
+ return "alerts";
}
@Override
public String getSingularName() {
- return "alert_data";
+ return "alert";
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java
index 8e163c2..a916c4c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java
@@ -52,7 +52,7 @@ public class AlertService extends BaseService {
*/
@GET
@Produces("text/plain")
- public Response getDefinitions(String body,
+ public Response getAlerts(String body,
@Context HttpHeaders headers,
@Context UriInfo ui) {
return handleRequest(headers, body, ui, Request.Type.GET,
@@ -66,7 +66,7 @@ public class AlertService extends BaseService {
@GET
@Path("{alertId}")
@Produces("text/plain")
- public Response getDefinition(String body,
+ public Response getAlert(String body,
@Context HttpHeaders headers,
@Context UriInfo ui,
@PathParam("alertId") Long id) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
index c76acf7..a56bcbf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
@@ -366,7 +366,7 @@ public class ClusterService extends BaseService {
*
* @return the alert definition service
*/
- @Path("{clusterName}/alerts_data")
+ @Path("{clusterName}/alerts")
public AlertService getAlertService(
@Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
index 8cec7e1..7962ee3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
@@ -212,7 +212,7 @@ public class HostService extends BaseService {
* @param hostName host id
* @return the alerts service
*/
- @Path("{hostName}/alerts_data")
+ @Path("{hostName}/alerts")
public AlertService getAlertHandler(@PathParam("hostName") String hostName) {
return new AlertService(m_clusterName, null, hostName);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
index 30f4f2f..7371fad 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
@@ -187,7 +187,7 @@ public class ServiceService extends BaseService {
/**
* Gets the alerts sub-resource.
*/
- @Path("{serviceName}/alerts_data")
+ @Path("{serviceName}/alerts")
public AlertService getAlertHandler(
@PathParam("serviceName") String serviceName) {
return new AlertService(m_clusterName, serviceName, null);
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 73e4013..4cae67e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -48,6 +48,7 @@ import org.apache.ambari.server.controller.internal.AbstractControllerResourcePr
import org.apache.ambari.server.controller.internal.AlertDefinitionResourceProvider;
import org.apache.ambari.server.controller.internal.AlertGroupResourceProvider;
import org.apache.ambari.server.controller.internal.AlertResourceProvider;
+import org.apache.ambari.server.controller.internal.AlertSummaryPropertyProvider;
import org.apache.ambari.server.controller.internal.AlertTargetResourceProvider;
import org.apache.ambari.server.controller.internal.AmbariPrivilegeResourceProvider;
import org.apache.ambari.server.controller.internal.BlueprintResourceProvider;
@@ -535,6 +536,7 @@ public class AmbariServer {
AlertResourceProvider.init(injector);
AlertDefinitionResourceProvider.init(injector);
AlertGroupResourceProvider.init(injector);
+ AlertSummaryPropertyProvider.init(injector);
AlertTargetResourceProvider.init(injector);
PermissionResourceProvider.init(injector.getInstance(PermissionDAO.class));
ViewPermissionResourceProvider.init(injector.getInstance(PermissionDAO.class));
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
index fc60210..f50955c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
@@ -18,9 +18,21 @@
package org.apache.ambari.server.controller.internal;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.Role;
import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
+import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.AmbariServer;
import org.apache.ambari.server.controller.HostRequest;
import org.apache.ambari.server.controller.HostResponse;
@@ -29,30 +41,33 @@ import org.apache.ambari.server.controller.ServiceComponentHostResponse;
import org.apache.ambari.server.controller.ganglia.GangliaComponentPropertyProvider;
import org.apache.ambari.server.controller.ganglia.GangliaHostComponentPropertyProvider;
import org.apache.ambari.server.controller.ganglia.GangliaHostPropertyProvider;
-import org.apache.ambari.server.controller.ganglia.GangliaReportPropertyProvider;
import org.apache.ambari.server.controller.ganglia.GangliaHostProvider;
+import org.apache.ambari.server.controller.ganglia.GangliaReportPropertyProvider;
import org.apache.ambari.server.controller.jmx.JMXHostProvider;
import org.apache.ambari.server.controller.jmx.JMXPropertyProvider;
import org.apache.ambari.server.controller.nagios.NagiosPropertyProvider;
-import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.ProviderModule;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.controller.AmbariManagementController;
-
-import com.google.inject.Inject;
-
import org.apache.ambari.server.controller.utilities.StreamProvider;
+import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.State;
-import org.apache.ambari.server.state.Cluster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.*;
-import java.util.Map.Entry;
-import java.util.concurrent.ConcurrentHashMap;
+import com.google.inject.Inject;
/**
* An abstract provider module implementation.
@@ -422,6 +437,8 @@ public abstract class AbstractProviderModule implements ProviderModule, Resource
configuration),
"Clusters/cluster_name",
"Clusters/version"));
+ providers.add(new AlertSummaryPropertyProvider(type,
+ "Clusters/cluster_name", null));
break;
case Service:
providers.add(new NagiosPropertyProvider(type,
@@ -430,6 +447,8 @@ public abstract class AbstractProviderModule implements ProviderModule, Resource
configuration),
"ServiceInfo/cluster_name",
"ServiceInfo/service_name"));
+ providers.add(new AlertSummaryPropertyProvider(type,
+ "ServiceInfo/cluster_name", "ServiceInfo/service_name"));
break;
case Host:
providers.add(createGangliaHostPropertyProvider(
@@ -446,6 +465,8 @@ public abstract class AbstractProviderModule implements ProviderModule, Resource
configuration),
"Hosts/cluster_name",
"Hosts/host_name"));
+ providers.add(new AlertSummaryPropertyProvider(type,
+ "Hosts/cluster_name", "Hosts/host_name"));
break;
case Component: {
// TODO as we fill out stack metric definitions, these can be phased out
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
new file mode 100644
index 0000000..438d471
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
@@ -0,0 +1,134 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.AlertSummaryDTO;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Injector;
+
+/**
+ * Property provider that adds alert summary information to endpoints.
+ */
+public class AlertSummaryPropertyProvider extends BaseProvider implements PropertyProvider {
+
+ private final static Logger LOG = LoggerFactory.getLogger(AlertSummaryPropertyProvider.class);
+
+ private static Clusters s_clusters = null;
+ private static AlertsDAO s_dao = null;
+
+ private Resource.Type m_resourceType = null;
+ private String m_clusterPropertyId = null;
+ private String m_typeIdPropertyId = null;
+
+ AlertSummaryPropertyProvider(Resource.Type type,
+ String clusterPropertyId, String typeIdPropertyId) {
+ super(Collections.singleton("alerts_summary"));
+ m_resourceType = type;
+ m_clusterPropertyId = clusterPropertyId;
+ m_typeIdPropertyId = typeIdPropertyId;
+ }
+
+ public static void init(Injector injector) {
+ s_clusters = injector.getInstance(Clusters.class);
+ s_dao = injector.getInstance(AlertsDAO.class);
+ }
+
+ @Override
+ public Set<Resource> populateResources(Set<Resource> resources,
+ Request request, Predicate predicate) throws SystemException {
+
+ Set<String> propertyIds = getRequestPropertyIds(request, predicate);
+
+ try {
+ for (Resource res : resources) {
+ populateResource(res, propertyIds);
+ }
+ } catch (AmbariException e) {
+ LOG.error("Could not load built-in alerts - Executor exception ({})",
+ e.getMessage());
+ }
+
+ return resources;
+ }
+
+ private void populateResource(Resource resource, Set<String> requestedIds) throws AmbariException {
+
+ AlertSummaryDTO summary = null;
+
+ String clusterName = (String) resource.getPropertyValue(m_clusterPropertyId);
+ String typeId = null == m_typeIdPropertyId ? null : (String) resource.getPropertyValue(m_typeIdPropertyId);
+ Cluster cluster = s_clusters.getCluster(clusterName);
+
+ switch (m_resourceType.getInternalType()) {
+ case Cluster:
+ summary = s_dao.findCurrentCounts(cluster.getClusterId(), null, null);
+ break;
+ case Service:
+ summary = s_dao.findCurrentCounts(cluster.getClusterId(), typeId, null);
+ break;
+ case Host:
+ summary = s_dao.findCurrentCounts(cluster.getClusterId(), null, typeId);
+ break;
+ default:
+ break;
+ }
+
+ if (null != summary) {
+ Map<AlertState, Integer> map = new HashMap<AlertState, Integer>();
+ map.put(AlertState.OK, Integer.valueOf(summary.getOkCount()));
+ map.put(AlertState.WARNING, Integer.valueOf(summary.getWarningCount()));
+ map.put(AlertState.CRITICAL, Integer.valueOf(summary.getCriticalCount()));
+ map.put(AlertState.UNKNOWN, Integer.valueOf(summary.getUnknownCount()));
+
+ setResourceProperty(resource, "alerts_summary", map, requestedIds);
+ }
+
+ }
+
+ @Override
+ public Set<String> checkPropertyIds(Set<String> propertyIds) {
+ Set<String> rejects = new HashSet<String>();
+
+ for (String id : propertyIds) {
+ if (!id.startsWith("alerts_summary"))
+ rejects.add(id);
+ }
+
+ return rejects;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java
index d2e425f..5b93db8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProvider.java
@@ -17,14 +17,10 @@
*/
package org.apache.ambari.server.controller.nagios;
-import com.google.gson.Gson;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
@@ -42,8 +38,8 @@ import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
import java.util.regex.Pattern;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
import org.apache.ambari.server.configuration.Configuration;
@@ -54,7 +50,6 @@ import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.utilities.StreamProvider;
-import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Service;
@@ -63,20 +58,26 @@ import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
/**
* Used to populate resources that have Nagios alertable properties.
*/
+@Deprecated
public class NagiosPropertyProvider extends BaseProvider implements PropertyProvider {
private static final Logger LOG = LoggerFactory.getLogger(NagiosPropertyProvider.class);
private static final Set<String> NAGIOS_PROPERTY_IDS = new HashSet<String>();
private static final String NAGIOS_TEMPLATE = "http://%s/ambarinagios/nagios/nagios_alerts.php?q1=alerts&alert_type=all";
- private static final String ALERT_DETAIL_PROPERTY_ID = "alerts/detail";
- private static final String ALERT_SUMMARY_OK_PROPERTY_ID = "alerts/summary/OK";
- private static final String ALERT_SUMMARY_WARNING_PROPERTY_ID = "alerts/summary/WARNING";
- private static final String ALERT_SUMMARY_CRITICAL_PROPERTY_ID = "alerts/summary/CRITICAL";
- private static final String ALERT_SUMMARY_PASSIVE_PROPERTY_ID = "alerts/summary/PASSIVE";
+ private static final String ALERT_DETAIL_PROPERTY_ID = "legacy_alerts/detail";
+ private static final String ALERT_SUMMARY_PROPERTY_ID = "legacy_alerts/summary";
+ private static final String ALERT_SUMMARY_OK_PROPERTY_ID = "legacy_alerts/summary/OK";
+ private static final String ALERT_SUMMARY_WARNING_PROPERTY_ID = "legacy_alerts/summary/WARNING";
+ private static final String ALERT_SUMMARY_CRITICAL_PROPERTY_ID = "legacy_alerts/summary/CRITICAL";
+ private static final String ALERT_SUMMARY_PASSIVE_PROPERTY_ID = "legacy_alerts/summary/PASSIVE";
private static final String PASSIVE_TOKEN = "AMBARIPASSIVE=";
private static final List<String> DEFAULT_IGNORABLE_FOR_SERVICES = Collections.unmodifiableList(new ArrayList<String>(
@@ -99,8 +100,8 @@ public class NagiosPropertyProvider extends BaseProvider implements PropertyProv
private static final Set<String> CLUSTER_NAMES = new CopyOnWriteArraySet<String>();
static {
- NAGIOS_PROPERTY_IDS.add("alerts/summary");
- NAGIOS_PROPERTY_IDS.add("alerts/detail");
+ NAGIOS_PROPERTY_IDS.add(ALERT_SUMMARY_PROPERTY_ID);
+ NAGIOS_PROPERTY_IDS.add(ALERT_DETAIL_PROPERTY_ID);
IGNORABLE_FOR_SERVICES = new ArrayList<String>(DEFAULT_IGNORABLE_FOR_SERVICES);
scheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertSummaryDTO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertSummaryDTO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertSummaryDTO.java
new file mode 100644
index 0000000..80fa4e8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertSummaryDTO.java
@@ -0,0 +1,70 @@
+/**
+ * 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.ambari.server.orm.dao;
+
+import org.apache.ambari.server.state.AlertState;
+
+/**
+ * Used to return alert summary data out of the database.
+ */
+public class AlertSummaryDTO {
+
+ private int okCount;
+ private int warningCount;
+ private int criticalCount;
+ private int unknownCount;
+
+ /**
+ * Constructor, used by JPA. JPA invokes this constructor, even if there
+ * are no records in the resultset. In that case, all arguments are {@code null}.
+ */
+ public AlertSummaryDTO(Number ok, Number warning, Number critical, Number unknown) {
+ okCount = null == ok ? 0 : ok.intValue();
+ warningCount = null == warning ? 0 : warning.intValue();
+ criticalCount = null == critical ? 0 : critical.intValue();
+ unknownCount = null == unknown ? 0 : unknown.intValue();
+ }
+
+ /**
+ * @return the count of {@link AlertState#OK} states
+ */
+ public int getOkCount() {
+ return okCount;
+ }
+
+ /**
+ * @return the count of {@link AlertState#WARNING} states
+ */
+ public int getWarningCount() {
+ return warningCount;
+ }
+
+ /**
+ * @return the count of {@link AlertState#CRITICAL} states
+ */
+ public int getCriticalCount() {
+ return criticalCount;
+ }
+
+ /**
+ * @return the count of {@link AlertState#UNKNOWN} states
+ */
+ public int getUnknownCount() {
+ return unknownCount;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index 5fcc1ec..a274089 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -222,6 +222,55 @@ public class AlertsDAO {
return daoUtils.selectList(query);
}
+ /**
+ * Retrieves the summary information for a particular scope. The result is a DTO
+ * since the columns are aggregated and don't fit to an entity.
+ *
+ * @param clusterId the cluster id
+ * @param serviceName the service name. Use {@code null} to not filter on service.
+ * @param hostName the host name. Use {@code null} to not filter on host.
+ * @return the summary DTO
+ */
+ @RequiresSession
+ public AlertSummaryDTO findCurrentCounts(long clusterId, String serviceName, String hostName) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("SELECT NEW %s (");
+ sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END), ");
+ sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END), ");
+ sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END), ");
+ sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END)) ");
+ sb.append("FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId");
+
+ if (null != serviceName) {
+ sb.append(" AND history.serviceName = :serviceName");
+ }
+
+ if (null != hostName) {
+ sb.append(" AND history.hostName = :hostName");
+ }
+
+ String str = String.format(sb.toString(),
+ AlertSummaryDTO.class.getName(),
+ AlertState.class.getName(), AlertState.OK.name(),
+ AlertState.class.getName(), AlertState.WARNING.name(),
+ AlertState.class.getName(), AlertState.CRITICAL.name(),
+ AlertState.class.getName(), AlertState.UNKNOWN.name());
+
+ TypedQuery<AlertSummaryDTO> query = entityManagerProvider.get().createQuery(
+ str, AlertSummaryDTO.class);
+
+ query.setParameter("clusterId", Long.valueOf(clusterId));
+
+ if (null != serviceName) {
+ query.setParameter("serviceName", serviceName);
+ }
+
+ if (null != hostName) {
+ query.setParameter("hostName", hostName);
+ }
+
+ return daoUtils.selectSingle(query);
+ }
/**
* Gets the current alerts for a given service.
@@ -408,4 +457,5 @@ public class AlertsDAO {
public void remove(AlertCurrentEntity alert) {
entityManagerProvider.get().remove(merge(alert));
}
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java
index 4316dc9..8037451 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/nagios/NagiosPropertyProviderTest.java
@@ -124,7 +124,7 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertFalse("Expected no alerts", values.containsKey("alerts"));
+ Assert.assertFalse("Expected no alerts", values.containsKey("legacy_alerts"));
}
@@ -176,9 +176,9 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertTrue(values.containsKey("alerts/summary"));
+ Assert.assertTrue(values.containsKey("legacy_alerts/summary"));
- Map<String, Object> summary = values.get("alerts/summary");
+ Map<String, Object> summary = values.get("legacy_alerts/summary");
Assert.assertEquals(4L, summary.size());
Assert.assertTrue(summary.containsKey("OK"));
Assert.assertTrue(summary.containsKey("WARNING"));
@@ -230,7 +230,7 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertFalse("Expected no alerts", values.containsKey("alerts"));
+ Assert.assertFalse("Expected no alerts", values.containsKey("legacy_alerts"));
}
@Test
@@ -260,12 +260,12 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertTrue(values.containsKey("alerts"));
- Assert.assertTrue(values.containsKey("alerts/summary"));
- Assert.assertTrue(values.get("alerts").containsKey("detail"));
- Assert.assertTrue(List.class.isInstance(values.get("alerts").get("detail")));
+ Assert.assertTrue(values.containsKey("legacy_alerts"));
+ Assert.assertTrue(values.containsKey("legacy_alerts/summary"));
+ Assert.assertTrue(values.get("legacy_alerts").containsKey("detail"));
+ Assert.assertTrue(List.class.isInstance(values.get("legacy_alerts").get("detail")));
- List<?> list = (List<?>) values.get("alerts").get("detail");
+ List<?> list = (List<?>) values.get("legacy_alerts").get("detail");
Assert.assertEquals(Integer.valueOf(3), Integer.valueOf(list.size()));
for (Object o : list) {
Assert.assertTrue(Map.class.isInstance(o));
@@ -275,7 +275,7 @@ public class NagiosPropertyProviderTest {
Assert.assertTrue("expected HBASE", serviceName.equals("HBASE"));
}
- Map<String, Object> summary = values.get("alerts/summary");
+ Map<String, Object> summary = values.get("legacy_alerts/summary");
Assert.assertTrue(summary.containsKey("OK"));
Assert.assertTrue(summary.containsKey("WARNING"));
Assert.assertTrue(summary.containsKey("CRITICAL"));
@@ -311,12 +311,12 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertTrue(values.containsKey("alerts"));
- Assert.assertTrue(values.containsKey("alerts/summary"));
- Assert.assertTrue(values.get("alerts").containsKey("detail"));
- Assert.assertTrue(List.class.isInstance(values.get("alerts").get("detail")));
+ Assert.assertTrue(values.containsKey("legacy_alerts"));
+ Assert.assertTrue(values.containsKey("legacy_alerts/summary"));
+ Assert.assertTrue(values.get("legacy_alerts").containsKey("detail"));
+ Assert.assertTrue(List.class.isInstance(values.get("legacy_alerts").get("detail")));
- List<?> list = (List<?>) values.get("alerts").get("detail");
+ List<?> list = (List<?>) values.get("legacy_alerts").get("detail");
Assert.assertTrue(7 == list.size());
for (Object o : list) {
Assert.assertTrue(Map.class.isInstance(o));
@@ -326,7 +326,7 @@ public class NagiosPropertyProviderTest {
Assert.assertTrue("expected c6403.ambari.apache.org", host.equals("c6403.ambari.apache.org"));
}
- Map<String, Object> summary = values.get("alerts/summary");
+ Map<String, Object> summary = values.get("legacy_alerts/summary");
Assert.assertTrue(summary.containsKey("OK"));
Assert.assertTrue(summary.containsKey("WARNING"));
Assert.assertTrue(summary.containsKey("CRITICAL"));
@@ -362,12 +362,12 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertTrue(values.containsKey("alerts"));
- Assert.assertTrue(values.containsKey("alerts/summary"));
- Assert.assertTrue(values.get("alerts").containsKey("detail"));
- Assert.assertTrue(List.class.isInstance(values.get("alerts").get("detail")));
+ Assert.assertTrue(values.containsKey("legacy_alerts"));
+ Assert.assertTrue(values.containsKey("legacy_alerts/summary"));
+ Assert.assertTrue(values.get("legacy_alerts").containsKey("detail"));
+ Assert.assertTrue(List.class.isInstance(values.get("legacy_alerts").get("detail")));
- List<?> list = (List<?>) values.get("alerts").get("detail");
+ List<?> list = (List<?>) values.get("legacy_alerts").get("detail");
Assert.assertEquals(Integer.valueOf(16), Integer.valueOf(list.size()));
for (Object o : list) {
Assert.assertTrue(Map.class.isInstance(o));
@@ -377,7 +377,7 @@ public class NagiosPropertyProviderTest {
Assert.assertEquals("c6401.ambari.apache.org", host);
}
- Map<String, Object> summary = values.get("alerts/summary");
+ Map<String, Object> summary = values.get("legacy_alerts/summary");
Assert.assertTrue(summary.containsKey("OK"));
Assert.assertTrue(summary.containsKey("WARNING"));
Assert.assertTrue(summary.containsKey("CRITICAL"));
@@ -417,12 +417,12 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertTrue(values.containsKey("alerts"));
- Assert.assertTrue(values.containsKey("alerts/summary"));
- Assert.assertTrue(values.get("alerts").containsKey("detail"));
- Assert.assertTrue(List.class.isInstance(values.get("alerts").get("detail")));
+ Assert.assertTrue(values.containsKey("legacy_alerts"));
+ Assert.assertTrue(values.containsKey("legacy_alerts/summary"));
+ Assert.assertTrue(values.get("legacy_alerts").containsKey("detail"));
+ Assert.assertTrue(List.class.isInstance(values.get("legacy_alerts").get("detail")));
- List<?> list = (List<?>) values.get("alerts").get("detail");
+ List<?> list = (List<?>) values.get("legacy_alerts").get("detail");
// removed an additional one
Assert.assertEquals(Integer.valueOf(2), Integer.valueOf(list.size()));
for (Object o : list) {
@@ -433,7 +433,7 @@ public class NagiosPropertyProviderTest {
Assert.assertTrue("expected HBASE", serviceName.equals("HBASE"));
}
- Map<String, Object> summary = values.get("alerts/summary");
+ Map<String, Object> summary = values.get("legacy_alerts/summary");
Assert.assertTrue(summary.containsKey("OK"));
Assert.assertTrue(summary.containsKey("WARNING"));
Assert.assertTrue(summary.containsKey("CRITICAL"));
@@ -490,12 +490,12 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertTrue(values.containsKey("alerts"));
- Assert.assertTrue(values.containsKey("alerts/summary"));
- Assert.assertTrue(values.get("alerts").containsKey("detail"));
- Assert.assertTrue(List.class.isInstance(values.get("alerts").get("detail")));
+ Assert.assertTrue(values.containsKey("legacy_alerts"));
+ Assert.assertTrue(values.containsKey("legacy_alerts/summary"));
+ Assert.assertTrue(values.get("legacy_alerts").containsKey("detail"));
+ Assert.assertTrue(List.class.isInstance(values.get("legacy_alerts").get("detail")));
- List<?> list = (List<?>) values.get("alerts").get("detail");
+ List<?> list = (List<?>) values.get("legacy_alerts").get("detail");
// removed an additional one
Assert.assertEquals(Integer.valueOf(4), Integer.valueOf(list.size()));
for (Object o : list) {
@@ -506,7 +506,7 @@ public class NagiosPropertyProviderTest {
Assert.assertEquals(serviceName, "GANGLIA");
}
- Map<String, Object> summary = values.get("alerts/summary");
+ Map<String, Object> summary = values.get("legacy_alerts/summary");
Assert.assertTrue(summary.containsKey("OK"));
Assert.assertTrue(summary.containsKey("WARNING"));
Assert.assertTrue(summary.containsKey("CRITICAL"));
@@ -543,12 +543,12 @@ public class NagiosPropertyProviderTest {
Map<String, Map<String, Object>> values = res.getPropertiesMap();
- Assert.assertTrue(values.containsKey("alerts"));
- Assert.assertTrue(values.containsKey("alerts/summary"));
- Assert.assertTrue(values.get("alerts").containsKey("detail"));
- Assert.assertTrue(List.class.isInstance(values.get("alerts").get("detail")));
+ Assert.assertTrue(values.containsKey("legacy_alerts"));
+ Assert.assertTrue(values.containsKey("legacy_alerts/summary"));
+ Assert.assertTrue(values.get("legacy_alerts").containsKey("detail"));
+ Assert.assertTrue(List.class.isInstance(values.get("legacy_alerts").get("detail")));
- List<?> list = (List<?>) values.get("alerts").get("detail");
+ List<?> list = (List<?>) values.get("legacy_alerts").get("detail");
Assert.assertEquals(Integer.valueOf(1), Integer.valueOf(list.size()));
for (Object o : list) {
Assert.assertTrue(Map.class.isInstance(o));
@@ -558,7 +558,7 @@ public class NagiosPropertyProviderTest {
Assert.assertEquals("c6404.ambari.apache.org", host);
}
- Map<String, Object> summary = values.get("alerts/summary");
+ Map<String, Object> summary = values.get("legacy_alerts/summary");
Assert.assertTrue(summary.containsKey("OK"));
Assert.assertTrue(summary.containsKey("WARNING"));
Assert.assertTrue(summary.containsKey("CRITICAL"));
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index 7c206a2..a397da4 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -229,7 +229,6 @@ public class AlertsDAOTest {
current.setAlertHistory(history);
dao.create(current);
-
List<AlertCurrentEntity> currentAlerts = dao.findCurrentByHost(clusterId, history.getHostName());
assertNotNull(currentAlerts);
@@ -323,4 +322,78 @@ public class AlertsDAOTest {
assertNotNull(entity.getAlertHistory());
assertNotNull(entity.getAlertHistory().getAlertDefinition());
}
+
+ /**
+ *
+ */
+ @Test
+ public void testFindCurrentSummary() throws Exception {
+ AlertSummaryDTO summary = dao.findCurrentCounts(clusterId.longValue(), null, null);
+ assertEquals(5, summary.getOkCount());
+
+ AlertHistoryEntity h1 = dao.findCurrentByCluster(clusterId.longValue()).get(2).getAlertHistory();
+ AlertHistoryEntity h2 = dao.findCurrentByCluster(clusterId.longValue()).get(3).getAlertHistory();
+ AlertHistoryEntity h3 = dao.findCurrentByCluster(clusterId.longValue()).get(4).getAlertHistory();
+ h1.setAlertState(AlertState.WARNING);
+ dao.merge(h1);
+ h2.setAlertState(AlertState.CRITICAL);
+ dao.merge(h2);
+ h3.setAlertState(AlertState.UNKNOWN);
+ dao.merge(h3);
+
+ int ok = 0;
+ int warn = 0;
+ int crit = 0;
+ int unk = 0;
+
+ for (AlertCurrentEntity h : dao.findCurrentByCluster(clusterId.longValue())) {
+ switch (h.getAlertHistory().getAlertState()) {
+ case CRITICAL:
+ crit++;
+ break;
+ case OK:
+ ok++;
+ break;
+ case UNKNOWN:
+ unk++;
+ break;
+ default:
+ warn++;
+ break;
+ }
+
+ }
+
+ summary = dao.findCurrentCounts(clusterId.longValue(), null, null);
+ // !!! db-to-db compare
+ assertEquals(ok, summary.getOkCount());
+ assertEquals(warn, summary.getWarningCount());
+ assertEquals(crit, summary.getCriticalCount());
+ assertEquals(unk, summary.getCriticalCount());
+
+ // !!! expected
+ assertEquals(2, summary.getOkCount());
+ assertEquals(1, summary.getWarningCount());
+ assertEquals(1, summary.getCriticalCount());
+ assertEquals(1, summary.getCriticalCount());
+
+ summary = dao.findCurrentCounts(clusterId.longValue(), "Service 0", null);
+ assertEquals(1, summary.getOkCount());
+ assertEquals(0, summary.getWarningCount());
+ assertEquals(0, summary.getCriticalCount());
+ assertEquals(0, summary.getCriticalCount());
+
+ summary = dao.findCurrentCounts(clusterId.longValue(), null, "h1");
+ assertEquals(2, summary.getOkCount());
+ assertEquals(1, summary.getWarningCount());
+ assertEquals(1, summary.getCriticalCount());
+ assertEquals(1, summary.getCriticalCount());
+
+ summary = dao.findCurrentCounts(clusterId.longValue(), "foo", null);
+ assertEquals(0, summary.getOkCount());
+ assertEquals(0, summary.getWarningCount());
+ assertEquals(0, summary.getCriticalCount());
+ assertEquals(0, summary.getCriticalCount());
+
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-web/app/controllers/global/update_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js
index a71f689..35b9e13 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -154,7 +154,7 @@ App.UpdateController = Em.Controller.extend({
var realUrl = '/hosts?<parameters>fields=Hosts/host_name,Hosts/maintenance_state,Hosts/public_host_name,Hosts/cpu_count,Hosts/ph_cpu_count,' +
'Hosts/host_status,Hosts/last_heartbeat_time,Hosts/ip,host_components/HostRoles/state,host_components/HostRoles/maintenance_state,' +
'host_components/HostRoles/stale_configs,host_components/HostRoles/service_name,metrics/disk,metrics/load/load_one,Hosts/total_mem,' +
- 'alerts/summary<hostAuxiliaryInfo>&minimal_response=true';
+ 'legacy_alerts/summary<hostAuxiliaryInfo>&minimal_response=true';
var hostAuxiliaryInfo = ',Hosts/os_arch,Hosts/os_type,metrics/cpu/cpu_system,metrics/cpu/cpu_user,metrics/memory/mem_total,metrics/memory/mem_free';
if (App.router.get('currentState.name') == 'index' && App.router.get('currentState.parentState.name') == 'hosts') {
@@ -423,7 +423,7 @@ App.UpdateController = Em.Controller.extend({
},
updateServices: function (callback) {
var testUrl = '/data/services/HDP2/services.json';
- var componentConfigUrl = this.getUrl(testUrl, '/services?fields=alerts/summary,ServiceInfo/state,ServiceInfo/maintenance_state&minimal_response=true');
+ var componentConfigUrl = this.getUrl(testUrl, '/services?fields=legacy_alerts/summary,ServiceInfo/state,ServiceInfo/maintenance_state&minimal_response=true');
App.HttpClient.get(componentConfigUrl, App.serviceMapper, {
complete: callback
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-web/app/controllers/main/alerts_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/alerts_controller.js b/ambari-web/app/controllers/main/alerts_controller.js
index 0ea7212..2504ca1 100644
--- a/ambari-web/app/controllers/main/alerts_controller.js
+++ b/ambari-web/app/controllers/main/alerts_controller.js
@@ -139,8 +139,8 @@ App.MainAlertsController = Em.Controller.extend({
*/
getAlertsSuccessCallback: function (json) {
var alerts = [];
- if (json && json.alerts && json.alerts.detail) {
- json.alerts.detail.forEach(function (_alert) {
+ if (json && json.legacy_alerts && json.legacy_alerts.detail) {
+ json.legacy_alerts.detail.forEach(function (_alert) {
alerts.pushObject(App.Alert.create({
title: _alert.description,
serviceType: _alert.service_name,
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-web/app/controllers/main/host.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host.js b/ambari-web/app/controllers/main/host.js
index 227a091..ae36158 100644
--- a/ambari-web/app/controllers/main/host.js
+++ b/ambari-web/app/controllers/main/host.js
@@ -122,7 +122,7 @@ App.MainHostController = Em.ArrayController.extend({
},
{
key: 'criticalAlertsCount',
- alias: 'alerts/summary/CRITICAL{0}|alerts/summary/WARNING{1}',
+ alias: 'legacy_alerts/summary/CRITICAL{0}|legacy_alerts/summary/WARNING{1}',
type: 'CUSTOM'
},
{
@@ -368,7 +368,7 @@ App.MainHostController = Em.ArrayController.extend({
'UNHEALTHY': data.Clusters.health_report['Host/host_status/UNHEALTHY'],
'ALERT': data.Clusters.health_report['Host/host_status/ALERT'],
'UNKNOWN': data.Clusters.health_report['Host/host_status/UNKNOWN'],
- 'health-status-WITH-ALERTS': (data.alerts) ? data.alerts.summary.CRITICAL + data.alerts.summary.WARNING : 0,
+ 'health-status-WITH-ALERTS': (data.legacy_alerts) ? data.legacy_alerts.summary.CRITICAL + data.legacy_alerts.summary.WARNING : 0,
'health-status-RESTART': data.Clusters.health_report['Host/stale_config'],
'health-status-PASSIVE_STATE': data.Clusters.health_report['Host/maintenance_state'],
'TOTAL': data.Clusters.total_hosts
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-web/app/mappers/hosts_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/hosts_mapper.js b/ambari-web/app/mappers/hosts_mapper.js
index 05037f2..241ea88 100644
--- a/ambari-web/app/mappers/hosts_mapper.js
+++ b/ambari-web/app/mappers/hosts_mapper.js
@@ -92,7 +92,7 @@ App.hostsMapper = App.QuickDataMapper.create({
}
serviceToHostComponentIdMap[serviceName].push(component.id);
}, this);
- item.critical_alerts_count = (item.alerts) ? item.alerts.summary.CRITICAL + item.alerts.summary.WARNING : 0;
+ item.critical_alerts_count = (item.legacy_alerts) ? item.legacy_alerts.summary.CRITICAL + item.legacy_alerts.summary.WARNING : 0;
item.cluster_id = App.get('clusterName');
item.index = index;
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-web/app/mappers/service_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/service_mapper.js b/ambari-web/app/mappers/service_mapper.js
index 00680a3..12f65f3 100644
--- a/ambari-web/app/mappers/service_mapper.js
+++ b/ambari-web/app/mappers/service_mapper.js
@@ -30,8 +30,8 @@ App.serviceMapper = App.QuickDataMapper.create({
cachedService.ServiceInfo.passive_state = service.ServiceInfo.maintenance_state;
//check whether Nagios installed and started
- if (service.alerts) {
- cachedService.ServiceInfo.critical_alerts_count = service.alerts.summary.CRITICAL + service.alerts.summary.WARNING;
+ if (service.legacy_alerts) {
+ cachedService.ServiceInfo.critical_alerts_count = service.legacy_alerts.summary.CRITICAL + service.legacy_alerts.summary.WARNING;
}
} else {
var serviceData = {
@@ -45,8 +45,8 @@ App.serviceMapper = App.QuickDataMapper.create({
};
//check whether Nagios installed and started
- if (service.alerts) {
- serviceData.ServiceInfo.critical_alerts_count = service.alerts.summary.CRITICAL + service.alerts.summary.WARNING;
+ if (service.legacy_alerts) {
+ serviceData.ServiceInfo.critical_alerts_count = service.legacy_alerts.summary.CRITICAL + service.legacy_alerts.summary.WARNING;
}
App.cache['services'].push(serviceData);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/ajax/ajax.js b/ambari-web/app/utils/ajax/ajax.js
index 3d1fda9..b787a2e 100644
--- a/ambari-web/app/utils/ajax/ajax.js
+++ b/ambari-web/app/utils/ajax/ajax.js
@@ -291,11 +291,11 @@ var urls = {
},
'alerts.get_by_service': {
- 'real': '/clusters/{clusterName}/services/{serviceName}?fields=alerts',
+ 'real': '/clusters/{clusterName}/services/{serviceName}?fields=legacy_alerts',
'mock': '/data/alerts/HDP2/service_alerts.json'
},
'alerts.get_by_host': {
- 'real': '/clusters/{clusterName}/hosts/{hostName}?fields=alerts',
+ 'real': '/clusters/{clusterName}/hosts/{hostName}?fields=legacy_alerts',
'mock': '/data/alerts/HDP2/host_alerts.json'
},
'background_operations.get_most_recent': {
@@ -1747,7 +1747,7 @@ var urls = {
}
},
'host.status.counters': {
- 'real': '/clusters/{clusterName}?fields=alerts,Clusters/health_report,Clusters/total_hosts&minimal_response=true',
+ 'real': '/clusters/{clusterName}?fields=legacy_alerts,Clusters/health_report,Clusters/total_hosts&minimal_response=true',
'mock': '/data/hosts/HDP2/host_status_counters.json'
},
'components.filter_by_status': {
http://git-wip-us.apache.org/repos/asf/ambari/blob/1f1059cf/ambari-web/test/controllers/main/alerts_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/alerts_controller_test.js b/ambari-web/test/controllers/main/alerts_controller_test.js
index 3a3dc7f..aee782a 100644
--- a/ambari-web/test/controllers/main/alerts_controller_test.js
+++ b/ambari-web/test/controllers/main/alerts_controller_test.js
@@ -171,18 +171,18 @@ describe('MainAlertsController', function () {
result: []
},
{
- title: 'data.alerts is null',
- data: {alerts: null},
+ title: 'data.legacy_alerts is null',
+ data: {legacy_alerts: null},
result: []
},
{
- title: 'data.alerts.detail is null',
- data: {alerts: {detail: null}},
+ title: 'data.legacy_alerts.detail is null',
+ data: {legacy_alerts: {detail: null}},
result: []
},
{
- title: 'data.alerts.detail is empty',
- data: {alerts: {detail: []}},
+ title: 'data.legacy_alerts.detail is empty',
+ data: {legacy_alerts: {detail: []}},
result: []
}
];
@@ -195,7 +195,7 @@ describe('MainAlertsController', function () {
});
});
- var data = {alerts: {detail: [
+ var data = {legacy_alerts: {detail: [
{
description: 't1',
service_name: "s1",
@@ -208,27 +208,27 @@ describe('MainAlertsController', function () {
]}};
var testCasesOfStatus = [
{
- title: 'data.alerts.detail is correct, OK status',
+ title: 'data.legacy_alerts.detail is correct, OK status',
status: 'OK',
result: '0'
},
{
- title: 'data.alerts.detail is correct, WARNING status',
+ title: 'data.legacy_alerts.detail is correct, WARNING status',
status: 'WARNING',
result: '1'
},
{
- title: 'data.alerts.detail is correct, CRITICAL status',
+ title: 'data.legacy_alerts.detail is correct, CRITICAL status',
status: 'CRITICAL',
result: '2'
},
{
- title: 'data.alerts.detail is correct, PASSIVE status',
+ title: 'data.legacy_alerts.detail is correct, PASSIVE status',
status: 'PASSIVE',
result: '3'
},
{
- title: 'data.alerts.detail is correct, unknown status',
+ title: 'data.legacy_alerts.detail is correct, unknown status',
status: '',
result: '4'
}
@@ -236,7 +236,7 @@ describe('MainAlertsController', function () {
testCasesOfStatus.forEach(function (test) {
it(test.title, function () {
controller.set('isLoaded', false);
- data.alerts.detail[0].status = test.status;
+ data.legacy_alerts.detail[0].status = test.status;
controller.getAlertsSuccessCallback(data);
expect(controller.get('alerts.length')).to.equal(1);
expect(controller.get('alerts').objectAt(0).get('status')).to.equal(test.result);
@@ -257,4 +257,4 @@ describe('MainAlertsController', function () {
expect(controller.get('isLoaded')).to.be.true;
});
});
-});
\ No newline at end of file
+});
[09/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7a0f5091
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7a0f5091
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7a0f5091
Branch: refs/heads/trunk
Commit: 7a0f5091784d80b3ea3da535534850f8b6be5201
Parents: c13730a b6abb3d
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Sep 2 08:12:12 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Sep 2 08:12:12 2014 -0400
----------------------------------------------------------------------
ambari-agent/conf/unix/install-helper.sh | 6 -
ambari-server/conf/unix/install-helper.sh | 6 -
.../apache/ambari/server/state/ConfigImpl.java | 2 +-
.../state/configgroup/ConfigGroupImpl.java | 3 +-
.../services/HIVE/configuration/hive-env.xml | 2 +-
.../1.3.2/services/HIVE/package/scripts/hive.py | 8 +-
.../services/HIVE/package/scripts/params.py | 4 +
.../services/HIVE/configuration/hive-env.xml | 2 +-
.../2.0.6/services/HIVE/package/scripts/hive.py | 10 +-
.../services/HIVE/package/scripts/params.py | 4 +
.../stacks/HDP/2.0.6/services/YARN/metainfo.xml | 1 -
.../stacks/HDP/2.1/services/FALCON/metainfo.xml | 4 +
.../server/state/cluster/ClusterTest.java | 22 +
.../stacks/1.3.2/HIVE/test_hive_client.py | 8 +-
.../stacks/1.3.2/HIVE/test_hive_metastore.py | 4 +-
.../stacks/1.3.2/HIVE/test_hive_server.py | 4 +-
.../python/stacks/1.3.2/configs/default.json | 4 +-
.../stacks/1.3.2/configs/default_client.json | 600 ++++++++++++++
.../python/stacks/1.3.2/configs/secured.json | 2 +-
.../stacks/1.3.2/configs/secured_client.json | 786 ++++++++++++++++++
.../stacks/2.0.6/HIVE/test_hive_client.py | 8 +-
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 4 +-
.../stacks/2.0.6/HIVE/test_hive_server.py | 4 +-
.../python/stacks/2.0.6/configs/default.json | 4 +-
.../stacks/2.0.6/configs/default_client.json | 797 ++++++++++++++++++
.../python/stacks/2.0.6/configs/secured.json | 4 +-
.../stacks/2.0.6/configs/secured_client.json | 818 +++++++++++++++++++
.../stacks/2.1/HIVE/test_hive_metastore.py | 4 +-
.../test/python/stacks/2.1/configs/default.json | 4 +-
.../test/python/stacks/2.1/configs/secured.json | 4 +-
.../resourceManager/wizard_controller.js | 12 +
.../controllers/main/service/info/configs.js | 53 +-
ambari-web/app/messages.js | 1 +
ambari-web/app/models/service_config.js | 6 +-
.../app/routes/rm_high_availability_routes.js | 20 +-
.../common/configs/config_history_flow.hbs | 8 +-
.../common/configs/save_configuration.hbs | 6 +-
.../views/common/configs/config_history_flow.js | 32 +-
.../main/dashboard/widgets/pie_chart_widget.js | 7 +-
.../resources/ui/app/assets/data/apps/apps.json | 675 ++++++++++++---
.../ui/app/controllers/slider_app_controller.js | 4 +-
.../main/resources/ui/app/models/slider_app.js | 51 +-
.../ui/app/templates/slider_app/configs.hbs | 84 +-
43 files changed, 3788 insertions(+), 304 deletions(-)
----------------------------------------------------------------------
[22/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Conflicts:
ambari-server/conf/unix/ambari.properties
ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/aaf05135
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/aaf05135
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/aaf05135
Branch: refs/heads/trunk
Commit: aaf051357de9493217fd5b2e05daa06c55a13132
Parents: 853497f 3355733
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Sep 12 19:52:41 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Sep 12 19:52:41 2014 -0400
----------------------------------------------------------------------
.../main/resources/ui/admin-web/app/index.html | 7 +-
.../resources/ui/admin-web/app/scripts/app.js | 3 +-
.../controllers/ambariViews/ViewsEditCtrl.js | 7 +-
.../controllers/groups/GroupsEditCtrl.js | 8 +-
.../app/scripts/controllers/mainCtrl.js | 2 +-
.../scripts/controllers/users/UsersShowCtrl.js | 18 +-
.../ui/admin-web/app/scripts/i18n.config.js | 29 ++
.../resources/ui/admin-web/app/styles/main.css | 9 +
.../admin-web/app/views/ambariViews/edit.html | 10 +-
.../app/views/clusters/manageAccess.html | 2 +-
.../ui/admin-web/app/views/groups/edit.html | 4 +-
.../ui/admin-web/app/views/leftNavbar.html | 15 +-
.../ui/admin-web/app/views/users/show.html | 8 +-
.../src/main/resources/ui/admin-web/bower.json | 4 +-
.../libraries/providers/execute_hadoop.py | 9 +-
.../libraries/providers/hdfs_directory.py | 16 +-
.../libraries/resources/execute_hadoop.py | 1 +
.../libraries/resources/hdfs_directory.py | 1 +
ambari-server/conf/unix/ambari.properties | 2 +-
ambari-server/docs/api/v1/clusters-cluster.md | 284 +++++++-----
.../server/configuration/Configuration.java | 5 +-
.../internal/BaseBlueprintProcessor.java | 13 +-
.../ServiceConfigVersionResourceProvider.java | 2 +-
.../internal/StackAdvisorResourceProvider.java | 6 +-
.../server/upgrade/UpgradeCatalog170.java | 2 +
.../ambari/server/view/ViewArchiveUtility.java | 120 ++++++
.../ambari/server/view/ViewExtractor.java | 223 ++++++++++
.../apache/ambari/server/view/ViewRegistry.java | 429 ++++++-------------
ambari-server/src/main/python/ambari-server.py | 100 ++++-
.../src/main/resources/ganglia_properties.json | 40 ++
.../2.0.6/hooks/after-INSTALL/scripts/params.py | 20 +-
.../hooks/before-INSTALL/scripts/params.py | 3 +-
.../hooks/before-START/files/checkForFormat.sh | 3 +
.../2.0.6/hooks/before-START/scripts/params.py | 25 +-
.../services/FLUME/package/scripts/flume.py | 2 +-
.../FLUME/package/scripts/flume_check.py | 2 +-
.../services/FLUME/package/scripts/params.py | 14 +-
.../HBASE/package/files/hbaseSmokeVerify.sh | 3 +-
.../services/HBASE/package/scripts/params.py | 37 +-
.../HBASE/package/scripts/service_check.py | 6 +-
.../HDFS/package/files/checkForFormat.sh | 4 +-
.../HDFS/package/scripts/hdfs_namenode.py | 15 +-
.../services/HDFS/package/scripts/namenode.py | 2 +-
.../services/HDFS/package/scripts/params.py | 34 +-
.../HDFS/package/scripts/service_check.py | 27 +-
.../2.0.6/services/HIVE/package/scripts/hcat.py | 6 +
.../HIVE/package/scripts/hcat_service_check.py | 8 +-
.../2.0.6/services/HIVE/package/scripts/hive.py | 2 +
.../HIVE/package/scripts/hive_service.py | 9 +-
.../HIVE/package/scripts/install_jars.py | 6 +-
.../services/HIVE/package/scripts/params.py | 73 ++--
.../package/templates/startHiveserver2.sh.j2 | 2 +-
.../services/OOZIE/configuration/oozie-env.xml | 2 +-
.../services/OOZIE/package/files/oozieSmoke2.sh | 8 +-
.../OOZIE/package/scripts/oozie_service.py | 4 +-
.../services/OOZIE/package/scripts/params.py | 24 +-
.../services/PIG/package/scripts/params.py | 20 +-
.../PIG/package/scripts/service_check.py | 10 +-
.../services/SQOOP/package/scripts/params.py | 10 +-
.../WEBHCAT/configuration/webhcat-env.xml | 2 +-
.../services/WEBHCAT/package/scripts/params.py | 41 +-
.../services/WEBHCAT/package/scripts/webhcat.py | 11 +-
.../services/YARN/package/scripts/params.py | 45 +-
.../YARN/package/scripts/resourcemanager.py | 5 +-
.../services/YARN/package/scripts/service.py | 2 +-
.../YARN/package/scripts/service_check.py | 3 +-
.../2.0.6/services/YARN/package/scripts/yarn.py | 14 +-
.../ZOOKEEPER/package/scripts/params.py | 17 +-
.../services/FALCON/package/scripts/params.py | 15 +-
.../services/STORM/package/scripts/params.py | 5 +-
.../main/resources/stacks/HDP/2.2/metainfo.xml | 23 +
.../resources/stacks/HDP/2.2/repos/repoinfo.xml | 82 ++++
.../stacks/HDP/2.2/role_command_order.json | 88 ++++
.../stacks/HDP/2.2/services/FALCON/metainfo.xml | 28 ++
.../stacks/HDP/2.2/services/FLUME/metainfo.xml | 40 ++
.../stacks/HDP/2.2/services/HBASE/metainfo.xml | 42 ++
.../services/HDFS/configuration/hadoop-env.xml | 29 ++
.../services/HDFS/configuration/hdfs-site.xml | 34 ++
.../stacks/HDP/2.2/services/HDFS/metainfo.xml | 68 +++
.../stacks/HDP/2.2/services/HIVE/metainfo.xml | 44 ++
.../services/OOZIE/configuration/oozie-site.xml | 45 ++
.../stacks/HDP/2.2/services/OOZIE/metainfo.xml | 28 ++
.../stacks/HDP/2.2/services/PIG/metainfo.xml | 41 ++
.../stacks/HDP/2.2/services/SQOOP/metainfo.xml | 29 ++
.../services/STORM/configuration/storm-env.xml | 29 ++
.../services/STORM/configuration/storm-site.xml | 54 +++
.../stacks/HDP/2.2/services/STORM/metainfo.xml | 29 ++
.../stacks/HDP/2.2/services/TEZ/metainfo.xml | 40 ++
.../WEBHCAT/configuration/webhcat-site.xml | 59 +++
.../HDP/2.2/services/WEBHCAT/metainfo.xml | 44 ++
.../YARN/configuration-mapred/mapred-site.xml | 36 ++
.../services/YARN/configuration/yarn-site.xml | 35 ++
.../stacks/HDP/2.2/services/YARN/metainfo.xml | 71 +++
.../HDP/2.2/services/ZOOKEEPER/metainfo.xml | 40 ++
.../AmbariPrivilegeResourceProviderTest.java | 2 +-
.../internal/BaseBlueprintProcessorTest.java | 413 ++++++++++++++++++
.../StackAdvisorResourceProviderTest.java | 76 ++++
.../ViewPrivilegeResourceProviderTest.java | 2 +-
...mbariLdapAuthenticationProviderBaseTest.java | 50 +++
...uthenticationProviderForDNWithSpaceTest.java | 4 +-
.../AmbariLdapAuthenticationProviderTest.java | 4 +-
.../ambari/server/view/ViewExtractorTest.java | 262 +++++++++++
.../ambari/server/view/ViewRegistryTest.java | 105 +++--
.../src/test/python/TestAmbariServer.py | 60 ++-
.../stacks/1.3.2/HDFS/test_service_check.py | 18 +-
.../stacks/2.0.6/HBASE/test_hbase_master.py | 6 +
.../2.0.6/HBASE/test_hbase_regionserver.py | 6 +
.../2.0.6/HBASE/test_hbase_service_check.py | 10 +-
.../python/stacks/2.0.6/HDFS/test_namenode.py | 36 +-
.../stacks/2.0.6/HDFS/test_service_check.py | 18 +-
.../stacks/2.0.6/HIVE/test_hcat_client.py | 10 +-
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 8 +
.../stacks/2.0.6/HIVE/test_hive_server.py | 18 +
.../2.0.6/HIVE/test_hive_service_check.py | 7 +
.../stacks/2.0.6/OOZIE/test_oozie_server.py | 10 +-
.../stacks/2.0.6/PIG/test_pig_service_check.py | 12 +-
.../stacks/2.0.6/WEBHCAT/test_webhcat_server.py | 12 +
.../stacks/2.0.6/YARN/test_historyserver.py | 12 +
.../stacks/2.0.6/YARN/test_nodemanager.py | 12 +
.../2.0.6/YARN/test_yarn_service_check.py | 9 +-
.../stacks/2.1/FALCON/test_falcon_server.py | 2 +
.../stacks/2.1/HIVE/test_hive_metastore.py | 7 +
ambari-web/app/assets/test/tests.js | 1 +
.../highAvailability/progress_controller.js | 15 +-
.../main/dashboard/config_history_controller.js | 2 +-
.../app/controllers/wizard/step7_controller.js | 8 +-
ambari-web/app/data/HDP2/secure_properties.js | 6 +-
ambari-web/app/data/secure_properties.js | 15 +
ambari-web/app/models/service_config_version.js | 5 +-
ambari-web/app/styles/application.less | 20 +-
.../common/configs/config_history_flow.hbs | 8 +-
.../templates/main/dashboard/config_history.hbs | 14 +-
ambari-web/app/utils/config.js | 14 +-
.../views/main/dashboard/config_history_view.js | 8 +-
.../progress_controller_test.js | 144 +++++++
.../assets/data/resource/slider-properties.json | 64 +++
.../ui/app/components/configSection.js | 2 +-
.../createAppWizard/step1_controller.js | 26 +-
.../createAppWizard/step3_controller.js | 8 +-
.../app/controllers/slider_apps_controller.js | 187 --------
.../ui/app/controllers/slider_controller.js | 294 +++++++++++++
.../src/main/resources/ui/app/helpers/ajax.js | 44 +-
.../src/main/resources/ui/app/initialize.js | 16 +-
.../ui/app/mappers/application_status.js | 52 ++-
.../main/resources/ui/app/models/slider_app.js | 7 +-
.../resources/ui/app/styles/application.less | 49 ++-
.../app/templates/components/configSection.hbs | 3 +-
.../ui/app/templates/createAppWizard/step3.hbs | 2 +-
.../ui/app/templates/slider_app/summary.hbs | 200 ++++-----
.../ui/app/views/createAppWizard/step3_view.js | 3 +-
.../ui/app/views/slider_app/summary_view.js | 4 +-
151 files changed, 4293 insertions(+), 1097 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/aaf05135/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
[21/50] [abbrv] git commit: AMBARI-7282. Add metric- and script-based
alert types (ncole)
Posted by jo...@apache.org.
AMBARI-7282. Add metric- and script-based alert types (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/853497f8
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/853497f8
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/853497f8
Branch: refs/heads/trunk
Commit: 853497f8eda3fa39c2611391c9e2bce32856119e
Parents: 2262400
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Sep 12 10:37:52 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Sep 12 10:37:52 2014 -0400
----------------------------------------------------------------------
.../ambari_agent/AlertSchedulerHandler.py | 21 ++-
.../src/main/python/ambari_agent/Controller.py | 10 +-
.../python/ambari_agent/alerts/base_alert.py | 6 +
.../python/ambari_agent/alerts/metric_alert.py | 174 +++++++++++++++++++
.../python/ambari_agent/alerts/script_alert.py | 70 ++++++++
.../src/test/python/ambari_agent/TestAlerts.py | 102 ++++++++++-
.../ambari_agent/dummy_files/definitions.json | 21 ---
.../ambari_agent/dummy_files/test_script.py | 3 +
.../internal/AlertResourceProvider.java | 2 +-
.../internal/AlertSummaryPropertyProvider.java | 4 +
.../ambari/server/state/alert/MetricSource.java | 23 +--
.../server/state/cluster/AlertDataManager.java | 1 +
.../stacks/HDP/2.0.6/services/HDFS/alerts.json | 32 +++-
13 files changed, 419 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
index e987dae..7cce533 100644
--- a/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
+++ b/ambari-agent/src/main/python/ambari_agent/AlertSchedulerHandler.py
@@ -29,7 +29,9 @@ import time
import traceback
from apscheduler.scheduler import Scheduler
from alerts.collector import AlertCollector
+from alerts.metric_alert import MetricAlert
from alerts.port_alert import PortAlert
+from alerts.script_alert import ScriptAlert
logger = logging.getLogger()
@@ -48,8 +50,9 @@ class AlertSchedulerHandler():
'standalone': False
}
- def __init__(self, cachedir, in_minutes=True):
+ def __init__(self, cachedir, stacks_dir, in_minutes=True):
self.cachedir = cachedir
+ self.stacks_dir = stacks_dir
if not os.path.exists(cachedir) and AlertSchedulerHandler.make_cachedir:
try:
@@ -133,6 +136,7 @@ class AlertSchedulerHandler():
for definition in command_json['alertDefinitions']:
obj = self.__json_to_callable(definition)
+
if obj is None:
continue
@@ -163,11 +167,12 @@ class AlertSchedulerHandler():
alert = None
if source_type == AlertSchedulerHandler.TYPE_METRIC:
- pass
+ alert = MetricAlert(json_definition, source)
elif source_type == AlertSchedulerHandler.TYPE_PORT:
alert = PortAlert(json_definition, source)
- elif type == AlertSchedulerHandler.TYPE_SCRIPT:
- pass
+ elif source_type == AlertSchedulerHandler.TYPE_SCRIPT:
+ source['stacks_dir'] = self.stacks_dir
+ alert = ScriptAlert(json_definition, source)
return alert
@@ -210,11 +215,15 @@ def main():
del args[0]
try:
- logger.setLevel(logger.debug)
+ logger.setLevel(logging.DEBUG)
except TypeError:
logger.setLevel(12)
- ash = AlertSchedulerHandler(args[0], False)
+ ch = logging.StreamHandler()
+ ch.setLevel(logger.level)
+ logger.addHandler(ch)
+
+ ash = AlertSchedulerHandler(args[0], args[1], False)
ash.start()
i = 0
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-agent/src/main/python/ambari_agent/Controller.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/Controller.py b/ambari-agent/src/main/python/ambari_agent/Controller.py
index 0ceeeff..70b4500 100644
--- a/ambari-agent/src/main/python/ambari_agent/Controller.py
+++ b/ambari-agent/src/main/python/ambari_agent/Controller.py
@@ -31,13 +31,14 @@ import pprint
from random import randint
import hostname
+import security
+import ssl
import AmbariConfig
from Heartbeat import Heartbeat
from Register import Register
from ActionQueue import ActionQueue
-import security
+from FileCache import FileCache
from NetUtil import NetUtil
-import ssl
from LiveStatus import LiveStatus
from AlertSchedulerHandler import AlertSchedulerHandler
@@ -78,9 +79,10 @@ class Controller(threading.Thread):
cache_dir = config.get('agent', 'cache_dir')
if cache_dir is None:
cache_dir = '/var/lib/ambari-agent/cache'
-
+
+ stacks_cache_dir = os.path.join(cache_dir, FileCache.STACKS_CACHE_DIRECTORY)
alerts_cache_dir = os.path.join(cache_dir, 'alerts')
- self.alert_scheduler_handler = AlertSchedulerHandler(alerts_cache_dir)
+ self.alert_scheduler_handler = AlertSchedulerHandler(alerts_cache_dir, stacks_cache_dir)
def __del__(self):
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
index adb872a..b22938d 100644
--- a/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/base_alert.py
@@ -70,6 +70,9 @@ class BaseAlert(object):
traceback.print_exc()
res = (BaseAlert.RESULT_UNKNOWN, [str(e)])
res_base_text = "Unknown {0}"
+
+ if logger.isEnabledFor(logging.DEBUG):
+ logger.debug("debug alert result: {0}".format(str(res)))
data = {}
data['name'] = self._find_value('name')
@@ -80,6 +83,9 @@ class BaseAlert(object):
data['service'] = self._find_value('serviceName')
data['component'] = self._find_value('componentName')
data['timestamp'] = long(time.time() * 1000)
+
+ if logger.isEnabledFor(logging.DEBUG):
+ logger.debug("debug alert text: {0}".format(data['text']))
self.collector.put(self.cluster, data)
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
new file mode 100644
index 0000000..5e4ea9e
--- /dev/null
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/metric_alert.py
@@ -0,0 +1,174 @@
+#!/usr/bin/env python
+
+'''
+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.
+'''
+
+import imp
+import json
+import logging
+import re
+import urllib2
+import uuid
+from alerts.base_alert import BaseAlert
+from resource_management.libraries.functions.get_port_from_url import get_port_from_url
+
+logger = logging.getLogger()
+
+class MetricAlert(BaseAlert):
+
+ def __init__(self, alert_meta, alert_source_meta):
+ super(MetricAlert, self).__init__(alert_meta, alert_source_meta)
+
+ self.uri = self._find_lookup_property(alert_source_meta['uri'])
+ self.metric_info = None
+
+ if 'jmx' in alert_source_meta:
+ self.metric_info = JmxMetric(alert_source_meta['jmx'])
+
+ def _collect(self):
+ if self.metric_info is None:
+ raise Exception("Could not determine result. Specific metric collector is not defined.")
+
+ uri = self._lookup_property_value(self.uri)
+
+ host = BaseAlert.get_host_from_url(uri)
+ if host is None:
+ host = self.host_name
+
+ port = 80 # probably not very realistic
+ try:
+ port = int(get_port_from_url(uri))
+ except:
+ pass
+
+ collect_result = None
+ check_value = None
+ value_list = []
+
+ if isinstance(self.metric_info, JmxMetric):
+ value_list.extend(self._load_jmx(False, host, port, self.metric_info))
+ check_value = self.metric_info.calculate(value_list)
+ value_list.append(check_value)
+
+ collect_result = self.__get_result(value_list[0] if check_value is None else check_value)
+
+ logger.debug("Resolved value list is: {0}".format(str(value_list)))
+
+ return ((collect_result, value_list))
+
+ def __get_result(self, value):
+ ok_value = self.__find_threshold('ok')
+ warn_value = self.__find_threshold('warning')
+ crit_value = self.__find_threshold('critical')
+
+ # critical values are higher
+ crit_direction_up = crit_value > warn_value
+
+ if crit_direction_up:
+ # critcal values are higher
+ if value > crit_value:
+ return self.RESULT_CRITICAL
+ elif value > warn_value:
+ return self.RESULT_WARNING
+ else:
+ if ok_value is not None:
+ if value > ok_value and value <= warn_value:
+ return self.RESULT_OK
+ else:
+ return self.RESULT_UNKNOWN
+ else:
+ return self.RESULT_OK
+ else:
+ # critical values are lower
+ if value < crit_value:
+ return self.RESULT_CRITICAL
+ elif value < warn_value:
+ return self.RESULT_WARNING
+ else:
+ if ok_value is not None:
+ if value < ok_value and value >= warn_value:
+ return self.RESULT_OK
+ else:
+ return self.RESULT_UNKNOWN
+ else:
+ return self.RESULT_OK
+
+ return None
+
+ def __find_threshold(self, reporting_type):
+ ''' find the defined thresholds for alert values '''
+
+ if not 'reporting' in self.alert_source_meta:
+ return None
+
+ if not reporting_type in self.alert_source_meta['reporting']:
+ return None
+
+ if not 'value' in self.alert_source_meta['reporting'][reporting_type]:
+ return None
+
+ return self.alert_source_meta['reporting'][reporting_type]['value']
+
+ def _load_jmx(self, ssl, host, port, jmx_metric):
+ ''' creates a JmxMetric object that holds info about jmx-based metrics '''
+
+ logger.debug(str(jmx_metric.property_map))
+
+ value_list = []
+
+ for k, v in jmx_metric.property_map.iteritems():
+ url = "{0}://{1}:{2}/jmx?qry={3}".format(
+ "https" if ssl else "http", host, str(port), k)
+
+ response = urllib2.urlopen(url)
+ json_response = json.loads(response.read())
+ json_data = json_response['beans'][0]
+
+ for attr in v:
+ value_list.append(json_data[attr])
+
+ return value_list
+
+class JmxMetric:
+ def __init__(self, jmx_info):
+ self.custom_module = None
+ self.property_list = jmx_info['property_list']
+ self.property_map = {}
+
+ if 'value' in jmx_info:
+ realcode = re.sub('(\{(\d+)\})', 'args[\g<2>]', jmx_info['value'])
+
+ self.custom_module = imp.new_module(str(uuid.uuid4()))
+ code = 'def f(args):\n return ' + realcode
+ exec code in self.custom_module.__dict__
+
+ for p in self.property_list:
+ parts = p.split('/')
+ if not parts[0] in self.property_map:
+ self.property_map[parts[0]] = []
+ self.property_map[parts[0]].append(parts[1])
+
+ def calculate(self, args):
+ if self.custom_module is not None:
+ return self.custom_module.f(args)
+ return None
+
+
+
+
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-agent/src/main/python/ambari_agent/alerts/script_alert.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/alerts/script_alert.py b/ambari-agent/src/main/python/ambari_agent/alerts/script_alert.py
new file mode 100644
index 0000000..93af917
--- /dev/null
+++ b/ambari-agent/src/main/python/ambari_agent/alerts/script_alert.py
@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+
+'''
+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.
+'''
+
+import imp
+import logging
+import os
+from alerts.base_alert import BaseAlert
+
+logger = logging.getLogger()
+
+class ScriptAlert(BaseAlert):
+ def __init__(self, alert_meta, alert_source_meta):
+ ''' ScriptAlert reporting structure is output from the script itself '''
+
+ alert_source_meta['reporting'] = {
+ 'ok': { 'text': '{0}' },
+ 'warning': { 'text': '{0}' },
+ 'critical': { 'text': '{0}' },
+ 'unknown': { 'text': '{0}' }
+ }
+
+ super(ScriptAlert, self).__init__(alert_meta, alert_source_meta)
+
+ self.path = None
+ if 'path' in alert_source_meta:
+ self.path = alert_source_meta['path']
+
+ if 'stacks_dir' in alert_source_meta:
+ self.stacks_dir = alert_source_meta['stacks_dir']
+
+ def _collect(self):
+ if self.path is None and self.stack_path is None:
+ raise Exception("The attribute 'path' must be specified")
+
+ path_to_script = self.path
+ if not os.path.exists(self.path) and self.stacks_dir is not None:
+ paths = self.path.split('/')
+ path_to_script = os.path.join(self.stacks_dir, *paths)
+
+ if not os.path.exists(path_to_script) or not os.path.isfile(path_to_script):
+ raise Exception(
+ "Resolved script '{0}' does not appear to be a script".format(
+ path_to_script))
+
+ if logger.isEnabledFor(logging.DEBUG):
+ logger.debug("Executing script check {0}".format(path_to_script))
+
+
+ if (path_to_script.endswith('.py')):
+ cmd_module = imp.load_source(self._find_value('name'), path_to_script)
+ return cmd_module.execute()
+ else:
+ return ((self.RESULT_UNKNOWN, ["could not execute script {0}".format(path_to_script)]))
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
index 6674fdf..5dc45b5 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestAlerts.py
@@ -21,9 +21,11 @@ limitations under the License.
import os
import sys
from ambari_agent.AlertSchedulerHandler import AlertSchedulerHandler
-from ambari_agent.apscheduler.scheduler import Scheduler
-from ambari_agent.alerts.port_alert import PortAlert
from ambari_agent.alerts.collector import AlertCollector
+from ambari_agent.alerts.metric_alert import MetricAlert
+from ambari_agent.alerts.port_alert import PortAlert
+from ambari_agent.alerts.script_alert import ScriptAlert
+from ambari_agent.apscheduler.scheduler import Scheduler
from mock.mock import patch
from unittest import TestCase
@@ -39,8 +41,9 @@ class TestAlerts(TestCase):
@patch.object(Scheduler, "start")
def test_start(self, aps_add_interval_job_mock, aps_start_mock):
test_file_path = os.path.join('ambari_agent', 'dummy_files')
+ test_stack_path = os.path.join('ambari_agent', 'dummy_files')
- ash = AlertSchedulerHandler(test_file_path)
+ ash = AlertSchedulerHandler(test_file_path, test_stack_path)
ash.start()
self.assertTrue(aps_add_interval_job_mock.called)
@@ -75,8 +78,6 @@ class TestAlerts(TestCase):
self.assertEquals(6, pa.interval())
res = pa.collect()
-
- pass
def test_port_alert_no_sub(self):
json = { "name": "namenode_process",
@@ -105,5 +106,94 @@ class TestAlerts(TestCase):
self.assertEquals('http://c6401.ambari.apache.org', pa.uri)
res = pa.collect()
+
+ def test_script_alert(self):
+ json = {
+ "name": "namenode_process",
+ "service": "HDFS",
+ "component": "NAMENODE",
+ "label": "NameNode process",
+ "interval": 6,
+ "scope": "host",
+ "source": {
+ "type": "SCRIPT",
+ "path": "test_script.py",
+ "reporting": {
+ "ok": {
+ "text": "TCP OK - {0:.4f} response time on port {1}"
+ },
+ "critical": {
+ "text": "Could not load process info: {0}"
+ }
+ }
+ }
+ }
+
+ # normally set by AlertSchedulerHandler
+ json['source']['stacks_dir'] = os.path.join('ambari_agent', 'dummy_files')
+
+ collector = AlertCollector()
+ sa = ScriptAlert(json, json['source'])
+ sa.set_helpers(collector, '')
+ self.assertEquals(json['source']['path'], sa.path)
+ self.assertEquals(json['source']['stacks_dir'], sa.stacks_dir)
+
+ sa.collect()
+
+ self.assertEquals('WARNING', collector.alerts()[0]['state'])
+ self.assertEquals('all is not well', collector.alerts()[0]['text'])
+
+ @patch.object(MetricAlert, "_load_jmx")
+ def test_metric_alert(self, ma_load_jmx_mock):
+ json = {
+ "name": "cpu_check",
+ "service": "HDFS",
+ "component": "NAMENODE",
+ "label": "NameNode process",
+ "interval": 6,
+ "scope": "host",
+ "source": {
+ "type": "METRIC",
+ "uri": "http://myurl:8633",
+ "jmx": {
+ "property_list": [
+ "someJmxObject/value",
+ "someOtherJmxObject/value"
+ ],
+ "value": "{0} * 100 + 123"
+ },
+ "reporting": {
+ "ok": {
+ "text": "ok_arr: {0} {1} {2}",
+ },
+ "warning": {
+ "text": "",
+ "value": 13
+ },
+ "critical": {
+ "text": "crit_arr: {0} {1} {2}",
+ "value": 72
+ }
+ }
+ }
+ }
+
+ ma_load_jmx_mock.return_value = [1, 3]
+
+ collector = AlertCollector()
+ ma = MetricAlert(json, json['source'])
+ ma.set_helpers(collector, '')
+ ma.collect()
+
+ self.assertEquals('CRITICAL', collector.alerts()[0]['state'])
+ self.assertEquals('crit_arr: 1 3 223', collector.alerts()[0]['text'])
+
+ del json['source']['jmx']['value']
+ collector = AlertCollector()
+ ma = MetricAlert(json, json['source'])
+ ma.set_helpers(collector, '')
+ ma.collect()
+
+ self.assertEquals('OK', collector.alerts()[0]['state'])
+ self.assertEquals('ok_arr: 1 3 None', collector.alerts()[0]['text'])
- pass
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
index 4894b62..ad52abc 100644
--- a/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
+++ b/ambari-agent/src/test/python/ambari_agent/dummy_files/definitions.json
@@ -10,16 +10,6 @@
},
"alertDefinitions": [
{
- "name": "namenode_cpu",
- "label": "NameNode host CPU Utilization",
- "scope": "host",
- "source": {
- "type": "METRIC",
- "jmx": "java.lang:type=OperatingSystem/SystemCpuLoad",
- "host": "{{hdfs-site/dfs.namenode.secondary.http-address}}"
- }
- },
- {
"name": "namenode_process",
"service": "HDFS",
"component": "NAMENODE",
@@ -39,17 +29,6 @@
}
}
}
- },
- {
- "name": "hdfs_last_checkpoint",
- "label": "Last Checkpoint Time",
- "interval": 1,
- "scope": "service",
- "enabled": false,
- "source": {
- "type": "SCRIPT",
- "path": "scripts/alerts/last_checkpoint.py"
- }
}
]
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-agent/src/test/python/ambari_agent/dummy_files/test_script.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/dummy_files/test_script.py b/ambari-agent/src/test/python/ambari_agent/dummy_files/test_script.py
new file mode 100644
index 0000000..211087c
--- /dev/null
+++ b/ambari-agent/src/test/python/ambari_agent/dummy_files/test_script.py
@@ -0,0 +1,3 @@
+
+def execute(params=None):
+ return (('WARNING', ['all is not well', str(params)]))
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
index 639a02f..715d017 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
@@ -167,12 +167,12 @@ public class AlertResourceProvider extends ReadOnlyResourceProvider {
setResourceProperty(resource, ALERT_LATEST_TIMESTAMP, entity.getLatestTimestamp(), requestedIds);
setResourceProperty(resource, ALERT_MAINTENANCE_STATE, entity.getMaintenanceState(), requestedIds);
setResourceProperty(resource, ALERT_ORIGINAL_TIMESTAMP, entity.getOriginalTimestamp(), requestedIds);
+ setResourceProperty(resource, ALERT_TEXT, entity.getLatestText(), requestedIds);
AlertHistoryEntity history = entity.getAlertHistory();
setResourceProperty(resource, ALERT_INSTANCE, history.getAlertInstance(), requestedIds);
setResourceProperty(resource, ALERT_LABEL, history.getAlertLabel(), requestedIds);
setResourceProperty(resource, ALERT_STATE, history.getAlertState(), requestedIds);
- setResourceProperty(resource, ALERT_TEXT, history.getAlertText(), requestedIds);
setResourceProperty(resource, ALERT_COMPONENT, history.getComponentName(), requestedIds);
setResourceProperty(resource, ALERT_HOST, history.getHostName(), requestedIds);
setResourceProperty(resource, ALERT_SERVICE, history.getServiceName(), requestedIds);
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
index 438d471..d952ae7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
@@ -90,6 +90,10 @@ public class AlertSummaryPropertyProvider extends BaseProvider implements Proper
AlertSummaryDTO summary = null;
String clusterName = (String) resource.getPropertyValue(m_clusterPropertyId);
+
+ if (null == clusterName)
+ return;
+
String typeId = null == m_typeIdPropertyId ? null : (String) resource.getPropertyValue(m_typeIdPropertyId);
Cluster cluster = s_clusters.getCluster(clusterName);
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
index 8bdd2ba..530c1bb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricSource.java
@@ -27,10 +27,11 @@ import com.google.gson.annotations.SerializedName;
*/
public class MetricSource extends Source {
- private String host = null;
-
+ @SerializedName("uri")
+ private String m_uri = null;
+
@SerializedName("jmx")
- private String jmxInfo = null;
+ private Object jmxInfo = null;
@SerializedName("ganglia")
private String gangliaInfo = null;
@@ -38,7 +39,7 @@ public class MetricSource extends Source {
/**
* @return the jmx info, if this metric is jmx-based
*/
- public String getJmxInfo() {
+ public Object getJmxInfo() {
return jmxInfo;
}
@@ -50,10 +51,10 @@ public class MetricSource extends Source {
}
/**
- * @return the host info, which may include port information
+ * @return the uri info, which may include port information
*/
- public String getHost() {
- return host;
+ public String getUri() {
+ return m_uri;
}
/**
@@ -65,7 +66,7 @@ public class MetricSource extends Source {
int result = super.hashCode();
result = prime * result
+ ((gangliaInfo == null) ? 0 : gangliaInfo.hashCode());
- result = prime * result + ((host == null) ? 0 : host.hashCode());
+ result = prime * result + ((m_uri == null) ? 0 : m_uri.hashCode());
result = prime * result + ((jmxInfo == null) ? 0 : jmxInfo.hashCode());
return result;
@@ -97,11 +98,11 @@ public class MetricSource extends Source {
return false;
}
- if (host == null) {
- if (other.host != null) {
+ if (m_uri == null) {
+ if (other.m_uri != null) {
return false;
}
- } else if (!host.equals(other.host)) {
+ } else if (!m_uri.equals(other.m_uri)) {
return false;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
index 4670d3b..4a65d5a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
@@ -68,6 +68,7 @@ public class AlertDataManager {
} else if (alert.getState() == current.getAlertHistory().getAlertState()) {
current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
+ current.setLatestText(alert.getText());
m_alertsDao.merge(current);
} else {
http://git-wip-us.apache.org/repos/asf/ambari/blob/853497f8/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
index 7f863a7..00286b1 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
@@ -19,6 +19,36 @@
}
}
}
+ },
+ {
+ "name": "check_cpu",
+ "label": "NameNode host CPU utilization",
+ "interval": 2,
+ "scope": "any",
+ "source": {
+ "type": "METRIC",
+ "uri": "{{hdfs-site/dfs.namenode.http-address}}",
+ "reporting": {
+ "ok": {
+ "text": "{1} CPU, load {0:.1%}"
+ },
+ "warning": {
+ "text": "{1} CPU, load {0:.1%}",
+ "value": 200
+ },
+ "critical": {
+ "text": "{1} CPU, load {0:.1%}",
+ "value": 250
+ }
+ },
+ "jmx": {
+ "property_list": [
+ "java.lang:type=OperatingSystem/SystemCpuLoad",
+ "java.lang:type=OperatingSystem/AvailableProcessors"
+ ],
+ "value": "{0} * 100"
+ }
+ }
}
],
"SECONDARY_NAMENODE": [
@@ -84,4 +114,4 @@
}
}
]
-}
\ No newline at end of file
+}
[44/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6f9398f0
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6f9398f0
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6f9398f0
Branch: refs/heads/trunk
Commit: 6f9398f0ff45da86c001eb86322695a3d76b7232
Parents: 054745d bd851c1
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Oct 1 11:26:26 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Oct 1 11:26:26 2014 -0400
----------------------------------------------------------------------
.../resources/ui/admin-web/app/styles/main.css | 2 +-
.../src/main/python/ambari_agent/ActionQueue.py | 5 +-
.../python/ambari_agent/ActualConfigHandler.py | 5 +-
.../test/python/ambari_agent/TestActionQueue.py | 55 +
.../ambari_agent/TestActualConfigHandler.py | 25 +-
ambari-server/pom.xml | 2 +
ambari-server/sbin/ambari-server | 2 +-
.../ambari/server/agent/ExecutionCommand.java | 1 +
.../server/api/util/StackExtensionHelper.java | 6 +
.../AmbariManagementControllerImpl.java | 28 +
.../ambari/server/state/ComponentInfo.java | 21 +-
.../server/upgrade/UpgradeCatalog170.java | 2 +
ambari-server/src/main/python/ambari-server.py | 162 +-
.../0.8/blueprints/multinode-default.json | 182 +
.../0.8/blueprints/singlenode-default.json | 136 +
.../BIGTOP/0.8/configuration/cluster-env.xml | 56 +
.../0.8/hooks/after-INSTALL/scripts/hook.py | 35 +
.../0.8/hooks/after-INSTALL/scripts/params.py | 68 +
.../scripts/shared_initialization.py | 52 +
.../BIGTOP/0.8/hooks/before-ANY/scripts/hook.py | 33 +
.../0.8/hooks/before-ANY/scripts/params.py | 33 +
.../before-ANY/scripts/shared_initialization.py | 58 +
.../before-INSTALL/files/changeToSecureUid.sh | 50 +
.../0.8/hooks/before-INSTALL/scripts/hook.py | 39 +
.../0.8/hooks/before-INSTALL/scripts/params.py | 118 +
.../scripts/repo_initialization.py | 57 +
.../scripts/shared_initialization.py | 94 +
.../before-INSTALL/templates/repo_suse_rhel.j2 | 7 +
.../before-INSTALL/templates/repo_ubuntu.j2 | 1 +
.../0.8/hooks/before-RESTART/scripts/hook.py | 29 +
.../hooks/before-START/files/checkForFormat.sh | 62 +
.../before-START/files/task-log4j.properties | 134 +
.../0.8/hooks/before-START/scripts/hook.py | 38 +
.../0.8/hooks/before-START/scripts/params.py | 146 +
.../scripts/shared_initialization.py | 175 +
.../templates/commons-logging.properties.j2 | 43 +
.../templates/exclude_hosts_list.j2 | 21 +
.../templates/hadoop-metrics2.properties.j2 | 65 +
.../before-START/templates/health_check-v2.j2 | 81 +
.../before-START/templates/health_check.j2 | 109 +
.../templates/include_hosts_list.j2 | 21 +
.../resources/stacks/BIGTOP/0.8/metainfo.xml | 22 +
.../stacks/BIGTOP/0.8/repos/repoinfo.xml | 35 +
.../stacks/BIGTOP/0.8/role_command_order.json | 74 +
.../services/FLUME/configuration/flume-conf.xml | 31 +
.../services/FLUME/configuration/flume-env.xml | 40 +
.../FLUME/configuration/flume-log4j.xml | 31 +
.../BIGTOP/0.8/services/FLUME/metainfo.xml | 69 +
.../BIGTOP/0.8/services/FLUME/metrics.json | 716 +
.../0.8/services/FLUME/package/scripts/flume.py | 250 +
.../FLUME/package/scripts/flume_check.py | 40 +
.../FLUME/package/scripts/flume_handler.py | 121 +
.../services/FLUME/package/scripts/params.py | 60 +
.../FLUME/package/templates/flume.conf.j2 | 24 +
.../FLUME/package/templates/log4j.properties.j2 | 67 +
.../GANGLIA/configuration/ganglia-env.xml | 72 +
.../BIGTOP/0.8/services/GANGLIA/metainfo.xml | 127 +
.../GANGLIA/package/files/checkGmetad.sh | 37 +
.../GANGLIA/package/files/checkGmond.sh | 62 +
.../GANGLIA/package/files/checkRrdcached.sh | 34 +
.../services/GANGLIA/package/files/gmetad.init | 73 +
.../services/GANGLIA/package/files/gmetadLib.sh | 204 +
.../services/GANGLIA/package/files/gmond.init | 73 +
.../services/GANGLIA/package/files/gmondLib.sh | 539 +
.../GANGLIA/package/files/rrdcachedLib.sh | 47 +
.../GANGLIA/package/files/setupGanglia.sh | 141 +
.../GANGLIA/package/files/startGmetad.sh | 68 +
.../GANGLIA/package/files/startGmond.sh | 85 +
.../GANGLIA/package/files/startRrdcached.sh | 79 +
.../GANGLIA/package/files/stopGmetad.sh | 43 +
.../services/GANGLIA/package/files/stopGmond.sh | 54 +
.../GANGLIA/package/files/stopRrdcached.sh | 41 +
.../GANGLIA/package/files/teardownGanglia.sh | 28 +
.../GANGLIA/package/scripts/functions.py | 31 +
.../services/GANGLIA/package/scripts/ganglia.py | 97 +
.../GANGLIA/package/scripts/ganglia_monitor.py | 236 +
.../package/scripts/ganglia_monitor_service.py | 27 +
.../GANGLIA/package/scripts/ganglia_server.py | 119 +
.../package/scripts/ganglia_server_service.py | 27 +
.../services/GANGLIA/package/scripts/params.py | 155 +
.../GANGLIA/package/scripts/status_params.py | 25 +
.../GANGLIA/package/templates/ganglia.conf.j2 | 34 +
.../package/templates/gangliaClusters.conf.j2 | 43 +
.../GANGLIA/package/templates/gangliaEnv.sh.j2 | 46 +
.../GANGLIA/package/templates/gangliaLib.sh.j2 | 85 +
.../GANGLIA/package/templates/rrd.py.j2 | 361 +
.../services/HBASE/configuration/hbase-env.xml | 133 +
.../HBASE/configuration/hbase-log4j.xml | 143 +
.../HBASE/configuration/hbase-policy.xml | 53 +
.../services/HBASE/configuration/hbase-site.xml | 370 +
.../BIGTOP/0.8/services/HBASE/metainfo.xml | 139 +
.../BIGTOP/0.8/services/HBASE/metrics.json | 13635 +++++++++++++++++
.../HBASE/package/files/draining_servers.rb | 164 +
.../HBASE/package/files/hbaseSmokeVerify.sh | 33 +
.../services/HBASE/package/scripts/__init__.py | 19 +
.../services/HBASE/package/scripts/functions.py | 40 +
.../0.8/services/HBASE/package/scripts/hbase.py | 144 +
.../HBASE/package/scripts/hbase_client.py | 43 +
.../HBASE/package/scripts/hbase_decommission.py | 74 +
.../HBASE/package/scripts/hbase_master.py | 70 +
.../HBASE/package/scripts/hbase_regionserver.py | 66 +
.../HBASE/package/scripts/hbase_service.py | 51 +
.../services/HBASE/package/scripts/params.py | 123 +
.../HBASE/package/scripts/service_check.py | 79 +
.../HBASE/package/scripts/status_params.py | 26 +
...-metrics2-hbase.properties-GANGLIA-MASTER.j2 | 81 +
...doop-metrics2-hbase.properties-GANGLIA-RS.j2 | 80 +
.../HBASE/package/templates/hbase-smoke.sh.j2 | 44 +
.../package/templates/hbase_client_jaas.conf.j2 | 23 +
.../templates/hbase_grant_permissions.j2 | 39 +
.../package/templates/hbase_master_jaas.conf.j2 | 26 +
.../templates/hbase_regionserver_jaas.conf.j2 | 26 +
.../HBASE/package/templates/regionservers.j2 | 20 +
.../services/HDFS/configuration/core-site.xml | 180 +
.../services/HDFS/configuration/hadoop-env.xml | 198 +
.../HDFS/configuration/hadoop-policy.xml | 134 +
.../services/HDFS/configuration/hdfs-log4j.xml | 201 +
.../services/HDFS/configuration/hdfs-site.xml | 496 +
.../BIGTOP/0.8/services/HDFS/metainfo.xml | 225 +
.../BIGTOP/0.8/services/HDFS/metrics.json | 7840 ++++++++++
.../HDFS/package/files/checkForFormat.sh | 68 +
.../services/HDFS/package/files/checkWebUI.py | 53 +
.../scripts/balancer-emulator/balancer-err.log | 1032 ++
.../scripts/balancer-emulator/balancer.log | 29 +
.../scripts/balancer-emulator/hdfs-command.py | 45 +
.../services/HDFS/package/scripts/datanode.py | 59 +
.../0.8/services/HDFS/package/scripts/hdfs.py | 64 +
.../HDFS/package/scripts/hdfs_client.py | 53 +
.../HDFS/package/scripts/hdfs_datanode.py | 47 +
.../HDFS/package/scripts/hdfs_namenode.py | 157 +
.../HDFS/package/scripts/hdfs_rebalance.py | 130 +
.../HDFS/package/scripts/hdfs_snamenode.py | 45 +
.../HDFS/package/scripts/journalnode.py | 73 +
.../services/HDFS/package/scripts/namenode.py | 134 +
.../0.8/services/HDFS/package/scripts/params.py | 213 +
.../HDFS/package/scripts/service_check.py | 111 +
.../services/HDFS/package/scripts/snamenode.py | 65 +
.../HDFS/package/scripts/status_params.py | 31 +
.../0.8/services/HDFS/package/scripts/utils.py | 66 +
.../services/HDFS/package/scripts/zkfc_slave.py | 64 +
.../package/templates/exclude_hosts_list.j2 | 21 +
.../HDFS/package/templates/hdfs.conf.j2 | 35 +
.../services/HDFS/package/templates/slaves.j2 | 21 +
.../services/HIVE/configuration/hive-env.xml | 134 +
.../HIVE/configuration/hive-exec-log4j.xml | 111 +
.../services/HIVE/configuration/hive-log4j.xml | 120 +
.../services/HIVE/configuration/hive-site.xml | 314 +
.../HIVE/etc/hive-schema-0.12.0.mysql.sql | 777 +
.../HIVE/etc/hive-schema-0.12.0.oracle.sql | 718 +
.../HIVE/etc/hive-schema-0.12.0.postgres.sql | 1406 ++
.../BIGTOP/0.8/services/HIVE/metainfo.xml | 271 +
.../services/HIVE/package/files/addMysqlUser.sh | 41 +
.../HIVE/package/files/addPostgreSQLUser.sh | 44 +
.../services/HIVE/package/files/hcatSmoke.sh | 36 +
.../services/HIVE/package/files/hiveSmoke.sh | 24 +
.../services/HIVE/package/files/hiveserver2.sql | 23 +
.../HIVE/package/files/hiveserver2Smoke.sh | 32 +
.../0.8/services/HIVE/package/files/pigSmoke.sh | 18 +
.../HIVE/package/files/startMetastore.sh | 23 +
.../services/HIVE/package/scripts/__init__.py | 19 +
.../0.8/services/HIVE/package/scripts/hcat.py | 55 +
.../HIVE/package/scripts/hcat_client.py | 43 +
.../HIVE/package/scripts/hcat_service_check.py | 78 +
.../0.8/services/HIVE/package/scripts/hive.py | 213 +
.../HIVE/package/scripts/hive_client.py | 42 +
.../HIVE/package/scripts/hive_metastore.py | 64 +
.../HIVE/package/scripts/hive_server.py | 66 +
.../HIVE/package/scripts/hive_service.py | 110 +
.../HIVE/package/scripts/install_jars.py | 99 +
.../HIVE/package/scripts/mysql_server.py | 70 +
.../HIVE/package/scripts/mysql_service.py | 46 +
.../0.8/services/HIVE/package/scripts/params.py | 215 +
.../HIVE/package/scripts/postgresql_server.py | 109 +
.../HIVE/package/scripts/postgresql_service.py | 39 +
.../HIVE/package/scripts/service_check.py | 47 +
.../HIVE/package/scripts/status_params.py | 37 +
.../HIVE/package/templates/hcat-env.sh.j2 | 43 +
.../package/templates/startHiveserver2.sh.j2 | 29 +
.../NAGIOS/configuration/nagios-env.xml | 53 +
.../BIGTOP/0.8/services/NAGIOS/metainfo.xml | 160 +
.../NAGIOS/package/files/check_aggregate.php | 248 +
.../NAGIOS/package/files/check_ambari_alerts.py | 80 +
.../package/files/check_checkpoint_time.py | 112 +
.../services/NAGIOS/package/files/check_cpu.php | 109 +
.../services/NAGIOS/package/files/check_cpu.pl | 114 +
.../NAGIOS/package/files/check_cpu_ha.php | 116 +
.../package/files/check_datanode_storage.php | 100 +
.../NAGIOS/package/files/check_hdfs_blocks.php | 102 +
.../package/files/check_hdfs_capacity.php | 109 +
.../files/check_hive_metastore_status.sh | 45 +
.../NAGIOS/package/files/check_hue_status.sh | 31 +
.../files/check_mapred_local_dir_used.sh | 34 +
.../package/files/check_name_dir_status.php | 93 +
.../NAGIOS/package/files/check_namenodes_ha.sh | 83 +
.../package/files/check_nodemanager_health.sh | 45 +
.../NAGIOS/package/files/check_oozie_status.sh | 45 +
.../NAGIOS/package/files/check_rpcq_latency.php | 104 +
.../package/files/check_rpcq_latency_ha.php | 115 +
.../package/files/check_templeton_status.sh | 46 +
.../NAGIOS/package/files/check_webui.sh | 103 +
.../NAGIOS/package/files/check_webui_ha.sh | 64 +
.../NAGIOS/package/files/check_wrapper.sh | 94 +
.../package/files/hdp_mon_nagios_addons.conf | 24 +
.../NAGIOS/package/files/hdp_nagios_init.php | 81 +
.../NAGIOS/package/files/nagios_alerts.php | 513 +
.../services/NAGIOS/package/files/sys_logger.py | 186 +
.../NAGIOS/package/scripts/functions.py | 47 +
.../services/NAGIOS/package/scripts/nagios.py | 112 +
.../NAGIOS/package/scripts/nagios_server.py | 111 +
.../package/scripts/nagios_server_config.py | 98 +
.../NAGIOS/package/scripts/nagios_service.py | 103 +
.../services/NAGIOS/package/scripts/params.py | 287 +
.../NAGIOS/package/scripts/status_params.py | 29 +
.../NAGIOS/package/templates/contacts.cfg.j2 | 109 +
.../package/templates/hadoop-commands.cfg.j2 | 166 +
.../package/templates/hadoop-hostgroups.cfg.j2 | 33 +
.../package/templates/hadoop-hosts.cfg.j2 | 53 +
.../templates/hadoop-servicegroups.cfg.j2 | 119 +
.../package/templates/hadoop-services.cfg.j2 | 804 +
.../NAGIOS/package/templates/nagios.cfg.j2 | 1365 ++
.../NAGIOS/package/templates/nagios.conf.j2 | 84 +
.../services/NAGIOS/package/templates/nagios.j2 | 164 +
.../NAGIOS/package/templates/resource.cfg.j2 | 51 +
.../services/OOZIE/configuration/oozie-env.xml | 129 +
.../OOZIE/configuration/oozie-log4j.xml | 97 +
.../services/OOZIE/configuration/oozie-site.xml | 312 +
.../BIGTOP/0.8/services/OOZIE/metainfo.xml | 165 +
.../services/OOZIE/package/files/oozieSmoke2.sh | 107 +
.../OOZIE/package/files/wrap_ooziedb.sh | 31 +
.../0.8/services/OOZIE/package/scripts/oozie.py | 152 +
.../OOZIE/package/scripts/oozie_client.py | 43 +
.../OOZIE/package/scripts/oozie_server.py | 56 +
.../OOZIE/package/scripts/oozie_service.py | 75 +
.../services/OOZIE/package/scripts/params.py | 121 +
.../OOZIE/package/scripts/service_check.py | 59 +
.../OOZIE/package/scripts/status_params.py | 26 +
.../package/templates/oozie-log4j.properties.j2 | 92 +
.../0.8/services/PIG/configuration/pig-env.xml | 38 +
.../services/PIG/configuration/pig-log4j.xml | 62 +
.../PIG/configuration/pig-properties.xml | 92 +
.../stacks/BIGTOP/0.8/services/PIG/metainfo.xml | 85 +
.../0.8/services/PIG/package/files/pigSmoke.sh | 18 +
.../0.8/services/PIG/package/scripts/params.py | 45 +
.../0.8/services/PIG/package/scripts/pig.py | 58 +
.../services/PIG/package/scripts/pig_client.py | 41 +
.../PIG/package/scripts/service_check.py | 67 +
.../services/SQOOP/configuration/sqoop-env.xml | 54 +
.../BIGTOP/0.8/services/SQOOP/metainfo.xml | 92 +
.../services/SQOOP/package/scripts/__init__.py | 19 +
.../services/SQOOP/package/scripts/params.py | 37 +
.../SQOOP/package/scripts/service_check.py | 37 +
.../0.8/services/SQOOP/package/scripts/sqoop.py | 57 +
.../SQOOP/package/scripts/sqoop_client.py | 41 +
.../WEBHCAT/configuration/webhcat-env.xml | 54 +
.../WEBHCAT/configuration/webhcat-site.xml | 138 +
.../BIGTOP/0.8/services/WEBHCAT/metainfo.xml | 107 +
.../WEBHCAT/package/files/templetonSmoke.sh | 96 +
.../WEBHCAT/package/scripts/__init__.py | 20 +
.../services/WEBHCAT/package/scripts/params.py | 83 +
.../WEBHCAT/package/scripts/service_check.py | 45 +
.../WEBHCAT/package/scripts/status_params.py | 26 +
.../services/WEBHCAT/package/scripts/webhcat.py | 93 +
.../WEBHCAT/package/scripts/webhcat_server.py | 53 +
.../WEBHCAT/package/scripts/webhcat_service.py | 40 +
.../YARN/configuration-mapred/mapred-env.xml | 65 +
.../YARN/configuration-mapred/mapred-site.xml | 366 +
.../YARN/configuration/capacity-scheduler.xml | 124 +
.../services/YARN/configuration/yarn-env.xml | 184 +
.../services/YARN/configuration/yarn-log4j.xml | 71 +
.../services/YARN/configuration/yarn-site.xml | 413 +
.../BIGTOP/0.8/services/YARN/metainfo.xml | 250 +
.../BIGTOP/0.8/services/YARN/metrics.json | 5360 +++++++
.../files/validateYarnComponentStatus.py | 170 +
.../services/YARN/package/scripts/__init__.py | 20 +
.../scripts/application_timeline_server.py | 55 +
.../YARN/package/scripts/historyserver.py | 53 +
.../package/scripts/mapred_service_check.py | 76 +
.../YARN/package/scripts/mapreduce2_client.py | 42 +
.../YARN/package/scripts/nodemanager.py | 59 +
.../0.8/services/YARN/package/scripts/params.py | 157 +
.../YARN/package/scripts/resourcemanager.py | 100 +
.../services/YARN/package/scripts/service.py | 75 +
.../YARN/package/scripts/service_check.py | 67 +
.../YARN/package/scripts/status_params.py | 35 +
.../0.8/services/YARN/package/scripts/yarn.py | 231 +
.../YARN/package/scripts/yarn_client.py | 42 +
.../package/templates/container-executor.cfg.j2 | 40 +
.../package/templates/exclude_hosts_list.j2 | 21 +
.../YARN/package/templates/mapreduce.conf.j2 | 35 +
.../package/templates/taskcontroller.cfg.j2 | 38 +
.../YARN/package/templates/yarn.conf.j2 | 35 +
.../ZOOKEEPER/configuration/zookeeper-env.xml | 84 +
.../ZOOKEEPER/configuration/zookeeper-log4j.xml | 101 +
.../BIGTOP/0.8/services/ZOOKEEPER/metainfo.xml | 89 +
.../services/ZOOKEEPER/package/files/zkEnv.sh | 96 +
.../ZOOKEEPER/package/files/zkServer.sh | 120 +
.../ZOOKEEPER/package/files/zkService.sh | 26 +
.../services/ZOOKEEPER/package/files/zkSmoke.sh | 78 +
.../ZOOKEEPER/package/scripts/__init__.py | 20 +
.../ZOOKEEPER/package/scripts/params.py | 76 +
.../ZOOKEEPER/package/scripts/service_check.py | 46 +
.../ZOOKEEPER/package/scripts/status_params.py | 26 +
.../ZOOKEEPER/package/scripts/zookeeper.py | 110 +
.../package/scripts/zookeeper_client.py | 42 +
.../package/scripts/zookeeper_server.py | 54 +
.../package/scripts/zookeeper_service.py | 42 +
.../package/templates/configuration.xsl.j2 | 42 +
.../ZOOKEEPER/package/templates/zoo.cfg.j2 | 69 +
.../templates/zookeeper_client_jaas.conf.j2 | 24 +
.../package/templates/zookeeper_jaas.conf.j2 | 26 +
.../stacks/BIGTOP/0.8/services/stack_advisor.py | 439 +
.../stacks/HDP/1.3.2.GlusterFS/metainfo.xml | 23 -
.../HDP/1.3.2.GlusterFS/repos/repoinfo.xml | 40 -
.../GLUSTERFS/configuration/core-site.xml | 277 -
.../GLUSTERFS/configuration/hadoop-policy.xml | 134 -
.../GLUSTERFS/configuration/hdfs-site.xml | 408 -
.../services/GLUSTERFS/metainfo.xml | 58 -
.../GLUSTERFS/package/scripts/glusterfs.py | 29 -
.../package/scripts/glusterfs_client.py | 34 -
.../GLUSTERFS/package/scripts/params.py | 29 -
.../GLUSTERFS/package/scripts/service_check.py | 37 -
.../package/templates/glusterfs-env.sh.j2 | 18 -
.../package/templates/glusterfs.properties.j2 | 36 -
.../services/HDFS/configuration/core-site.xml | 253 -
.../services/HDFS/configuration/global.xml | 187 -
.../HDFS/configuration/hadoop-policy.xml | 134 -
.../services/HDFS/configuration/hdfs-site.xml | 439 -
.../1.3.2.GlusterFS/services/HDFS/metainfo.xml | 27 -
.../stacks/HDP/1.3.2/services/HIVE/metainfo.xml | 6 +
.../1.3.2/services/HIVE/package/scripts/hive.py | 36 +-
.../package/templates/hadoop-services.cfg.j2 | 2 +
.../services/HBASE/package/scripts/params.py | 2 +-
.../stacks/HDP/2.0.6/services/HIVE/metainfo.xml | 6 +
.../2.0.6/services/HIVE/package/scripts/hive.py | 31 +-
.../services/YARN/package/scripts/params.py | 12 +-
.../services/STORM/package/scripts/params.py | 17 +-
.../2.1/services/STORM/package/scripts/storm.py | 19 +-
.../STORM/package/scripts/supervisor.py | 1 -
.../STORM/package/scripts/yaml_config.py | 72 -
.../STORM/package/scripts/yaml_utils.py | 49 +
.../STORM/package/templates/storm.yaml.j2 | 60 +
.../STORM/package/templates/storm_jaas.conf.j2 | 22 +-
.../stacks/HDP/2.2/services/SLIDER/metainfo.xml | 2 +-
.../services/SLIDER/package/scripts/params.py | 9 +-
.../services/STORM/configuration/storm-site.xml | 38 +-
.../src/main/resources/stacks/stack_advisor.py | 17 +-
.../AmbariManagementControllerTest.java | 1 +
.../src/test/python/TestAmbariServer.py | 54 +
.../src/test/python/TestStackAdvisor.py | 9 +-
.../stacks/1.3.2/HIVE/test_hive_client.py | 58 +-
.../stacks/1.3.2/HIVE/test_hive_metastore.py | 46 +-
.../stacks/1.3.2/HIVE/test_hive_server.py | 50 +-
.../stacks/2.0.6/HIVE/test_hive_client.py | 78 +-
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 80 +-
.../stacks/2.0.6/HIVE/test_hive_server.py | 80 +-
.../stacks/2.1/HIVE/test_hive_metastore.py | 80 +-
.../python/stacks/2.1/STORM/test_storm_base.py | 119 +
.../stacks/2.1/STORM/test_storm_drpc_server.py | 90 +-
.../2.1/STORM/test_storm_jaas_configuration.py | 77 +
.../stacks/2.1/STORM/test_storm_nimbus.py | 105 +-
.../stacks/2.1/STORM/test_storm_nimbus_prod.py | 89 +-
.../2.1/STORM/test_storm_rest_api_service.py | 87 +-
.../stacks/2.1/STORM/test_storm_supervisor.py | 42 +-
.../2.1/STORM/test_storm_supervisor_prod.py | 86 +-
.../stacks/2.1/STORM/test_storm_ui_server.py | 93 +-
.../test/python/stacks/2.1/common/hosts.json | 554 +
.../test/python/stacks/2.1/common/services.json | 1036 ++
.../stacks/2.1/common/test_stack_advisor.py | 41 +-
.../stacks/2.1/configs/default-storm-start.json | 356 +
.../stacks/2.1/configs/secured-storm-start.json | 373 +
.../stacks/2.2/SLIDER/test_slider_client.py | 8 +-
.../stacks/HDP/2.0.5/services/HIVE/metainfo.xml | 5 +
.../stacks/HDP/2.0.7/services/HIVE/metainfo.xml | 3 +
ambari-web/app/app.js | 7 +-
ambari-web/app/assets/test/test.html | 1 +
ambari-web/app/assets/test/tests.js | 2 -
ambari-web/app/controllers/application.js | 4 +
.../app/controllers/main/admin/repositories.js | 8 +-
.../main/admin/security/add/step2.js | 37 +-
.../main/admin/security/add/step3.js | 156 +-
.../controllers/main/service/info/configs.js | 8 +-
.../app/controllers/main/views_controller.js | 2 +-
ambari-web/app/data/HDP2.2/site_properties.js | 29 +
ambari-web/app/data/HDP2/secure_configs.js | 16 +-
ambari-web/app/data/HDP2/secure_properties.js | 207 +-
ambari-web/app/data/HDP2/site_properties.js | 41 +-
ambari-web/app/messages.js | 1 +
.../app/mixins/wizard/addSecurityConfigs.js | 35 +-
ambari-web/app/models/stack_service.js | 24 +-
ambari-web/app/router.js | 13 +
ambari-web/app/routes/main.js | 3 +-
ambari-web/app/templates/application.hbs | 2 +-
ambari-web/app/utils/config.js | 34 +-
ambari-web/app/utils/string_utils.js | 4 +-
ambari-web/app/views/main/menu.js | 12 +-
.../main/admin/security/add/step2_test.js | 4 +-
.../main/admin/security/add/step3_test.js | 66 +-
.../main/admin/security/add/step4_test.js | 15 +-
.../test/controllers/main/host/details_test.js | 25 +-
.../test/controllers/wizard/step3_test.js | 4 +-
.../test/controllers/wizard/step7_test.js | 3 +
ambari-web/test/utils/ajax/ajax_test.js | 11 +-
ambari-web/test/utils/string_utils_test.js | 2 +-
.../widgets/uptime_text_widget_test.js | 12 +-
contrib/views/pom.xml | 2 +-
contrib/views/slider/docs/index.md | 2 +-
.../view/slider/SliderAppsViewController.java | 12 +-
.../assets/data/resource/slider-properties.json | 12 +-
.../ui/app/assets/javascripts/ember-qunit.js | 266 +
.../ui/app/assets/javascripts/qunit.js | 2495 +++
.../ui/app/assets/javascripts/tests.js | 29 +
.../ui/app/assets/stylesheets/qunit.css | 237 +
.../src/main/resources/ui/app/assets/tests.html | 43 +
.../src/main/resources/ui/app/config/app.js | 3 +-
.../ui/app/controllers/slider_app_controller.js | 2 +-
.../ui/app/controllers/slider_controller.js | 2 +-
.../src/main/resources/ui/app/helpers/ajax.js | 8 +-
.../src/main/resources/ui/app/helpers/helper.js | 17 +-
.../src/main/resources/ui/app/initialize.js | 10 +-
.../ui/app/mappers/slider_apps_mapper.js | 2 +-
.../main/resources/ui/app/models/slider_app.js | 3 -
.../src/main/resources/ui/app/routes/main.js | 17 +-
.../src/main/resources/ui/app/styles/app.less | 4 +-
.../ui/app/templates/slider_app/configs.hbs | 32 +-
.../ui/app/templates/slider_app/flex_popup.hbs | 25 +-
.../src/main/resources/ui/app/translations.js | 4 +-
.../resources/ui/app/views/common/chart_view.js | 6 +-
.../ui/app/views/slider_app/configs_view.js | 7 +-
.../views/slider_app/metrics/app_metric_view.js | 6 +-
.../slider/src/main/resources/ui/config.js | 3 +-
.../ui/test/demo/demo_integration_test.js | 24 -
.../resources/ui/test/demo/demo_unit_test.js | 21 -
.../src/main/resources/ui/test/helpers.js | 34 -
.../ui/test/integration/pages/index_test.js | 61 +
.../createAppWizard/step1_controller_test.js | 39 +
.../unit/models/slider_app_component_test.js | 51 +
.../ui/test/unit/models/slider_app_test.js | 93 +
.../views/slider/src/main/resources/view.xml | 33 +-
pom.xml | 8 +-
439 files changed, 66680 insertions(+), 3668 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6f9398f0/ambari-server/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6f9398f0/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6f9398f0/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6f9398f0/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
[31/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Conflicts:
ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7f86e75c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7f86e75c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7f86e75c
Branch: refs/heads/trunk
Commit: 7f86e75c0c1e4868973340197b7cab112a319cb1
Parents: e2e7966 327accb
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Sat Sep 20 10:54:04 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Sat Sep 20 10:54:04 2014 -0400
----------------------------------------------------------------------
.../main/resources/ui/admin-web/app/index.html | 1 -
.../app/scripts/controllers/NavbarCtrl.js | 22 +-
.../ui/admin-web/app/scripts/services/ldap.js | 60 -
.../resources/ui/admin-web/app/styles/main.css | 10 +-
.../ui/admin-web/app/views/leftNavbar.html | 9 -
ambari-server/sbin/ambari-server | 4 +
.../LdapSyncEventResourceDefinition.java | 57 +
.../resources/ResourceInstanceFactoryImpl.java | 4 +
.../api/services/LdapSyncEventService.java | 144 ++
.../controller/AmbariManagementController.java | 10 +-
.../AmbariManagementControllerImpl.java | 31 +-
.../internal/ControllerResourceProvider.java | 53 +-
.../internal/DefaultProviderModule.java | 2 +
.../internal/LdapSyncEventResourceProvider.java | 438 ++++++
.../controller/internal/URLStreamProvider.java | 4 +
.../ambari/server/controller/spi/Resource.java | 4 +-
.../orm/entities/LdapSyncEventEntity.java | 284 ++++
.../server/orm/entities/LdapSyncSpecEntity.java | 143 ++
.../ambari/server/proxy/ProxyService.java | 17 +-
.../server/security/authorization/Users.java | 17 +-
.../security/ldap/AmbariLdapDataPopulator.java | 268 +++-
.../ambari/server/state/ConfigHelper.java | 39 +
.../server/state/stack/LatestRepoCallable.java | 59 +-
.../server/upgrade/AbstractUpgradeCatalog.java | 215 ++-
.../server/upgrade/UpgradeCatalog161.java | 2 +-
.../server/upgrade/UpgradeCatalog170.java | 27 +-
.../server/view/HttpImpersonatorImpl.java | 167 +++
.../server/view/ImpersonatorSettingImpl.java | 63 +
.../ambari/server/view/ViewContextImpl.java | 18 +-
.../ambari/server/view/ViewProviderModule.java | 26 +-
.../apache/ambari/server/view/ViewRegistry.java | 22 +-
ambari-server/src/main/python/ambari-server.py | 74 +
.../scripts/application_timeline_server.py | 2 +
.../YARN/package/scripts/status_params.py | 1 +
.../services/SLIDER/package/scripts/params.py | 4 +-
.../services/SLIDER/package/scripts/slider.py | 22 +-
.../SLIDER/package/templates/slider-env.sh.j2 | 38 +
.../SLIDER/package/templates/slider-wrapper.j2 | 42 -
.../LdapSyncEventResourceDefinitionTest.java | 49 +
.../server/api/services/AmbariMetaInfoTest.java | 205 ++-
.../api/services/LdapSyncEventServiceTest.java | 97 ++
.../LdapSyncEventResourceProviderTest.java | 114 ++
.../orm/entities/LdapSyncEventEntityTest.java | 166 +++
.../orm/entities/LdapSyncSpecEntityTest.java | 95 ++
.../ambari/server/proxy/ProxyServiceTest.java | 14 +
.../ldap/AmbariLdapDataPopulatorTest.java | 1329 +++++++++++++++++-
.../security/ldap/LdapPerformanceTest.java | 10 +-
.../server/upgrade/UpgradeCatalog161Test.java | 2 +-
.../server/upgrade/UpgradeCatalog170Test.java | 35 +-
.../server/view/HttpImpersonatorImplTest.java | 128 ++
.../ambari/server/view/ViewRegistryTest.java | 20 +
.../stacks/2.2/SLIDER/test_slider_client.py | 29 +-
.../apache/ambari/view/HttpImpersonator.java | 53 +
.../apache/ambari/view/ImpersonatorSetting.java | 46 +
.../org/apache/ambari/view/ViewContext.java | 15 +
ambari-web/app/utils/ajax/ajax.js | 22 -
contrib/views/jobs/pom.xml | 15 +
.../apache/ambari/view/jobs/ProxyServlet.java | 68 +
.../jobs/src/main/resources/WEB-INF/web.xml | 37 +
.../app/scripts/controllers/jobs_controller.js | 10 +-
.../resources/ui/app/scripts/helpers/ajax.js | 25 +-
.../resources/ui/app/scripts/helpers/jobs.js | 15 +-
.../ui/app/scripts/routes/application_route.js | 8 +
.../ui/app/controllers/slider_app_controller.js | 2 +-
.../ui/app/mappers/slider_apps_mapper.js | 9 +
.../main/resources/ui/app/models/slider_app.js | 5 +
.../resources/ui/app/styles/application.less | 6 +-
.../ui/app/templates/slider_app/summary.hbs | 2 +-
.../resources/ui/app/templates/slider_apps.hbs | 2 +-
69 files changed, 4458 insertions(+), 578 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7f86e75c/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7f86e75c/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7f86e75c/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7f86e75c/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --cc ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 23d0efa,b08ccc0..4c59a36
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@@ -30,11 -27,8 +27,9 @@@ import static org.junit.Assert.fail
import java.io.File;
import java.lang.reflect.Method;
- import java.util.ArrayList;
import java.util.Collection;
- import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@@@ -61,20 -53,14 +54,16 @@@ import org.apache.ambari.server.state.D
import org.apache.ambari.server.state.OperatingSystemInfo;
import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.RepositoryInfo;
- import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.Stack;
- import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.alert.AlertDefinition;
- import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
+import org.apache.ambari.server.state.alert.PortSource;
+import org.apache.ambari.server.state.alert.Reporting;
+import org.apache.ambari.server.state.alert.Source;
import org.apache.ambari.server.state.stack.MetricDefinition;
import org.apache.commons.io.FileUtils;
- import org.easymock.EasyMock;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@@ -124,9 -109,9 +113,12 @@@ public class AmbariMetaInfoTest
@Before
public void before() throws Exception {
- injector = Guice.createInjector(new InMemoryDefaultTestModule());
+ injector = Guice.createInjector(Modules.override(
+ new InMemoryDefaultTestModule()).with(new MockModule()));
+
+ injector.getInstance(GuiceJpaInitializer.class);
+ injector.getInstance(EntityManager.class);
++
File stackRoot = new File("src/test/resources/stacks");
LOG.info("Stacks file " + stackRoot.getAbsolutePath());
metaInfo = new AmbariMetaInfo(stackRoot, new File("target/version"));
@@@ -1450,109 -1559,17 +1566,66 @@@
Assert.assertNotNull(set);
Assert.assertTrue(set.size() > 0);
+ // find two different definitions and test each one
+ AlertDefinition nameNodeProcess = null;
+ AlertDefinition nameNodeCpu = null;
+
+ Iterator<AlertDefinition> iterator = set.iterator();
+ while (iterator.hasNext()) {
+ AlertDefinition definition = iterator.next();
+ if (definition.getName().equals("namenode_process")) {
+ nameNodeProcess = definition;
+ }
+
+ if (definition.getName().equals("namenode_cpu")) {
+ nameNodeCpu = definition;
+ }
+ }
+
+ assertNotNull(nameNodeProcess);
+ assertNotNull(nameNodeCpu);
+
+ assertEquals("NameNode host CPU Utilization", nameNodeCpu.getLabel());
+
+ // test namenode_process
+ Source source = nameNodeProcess.getSource();
+ assertNotNull(source);
+ assertNotNull(((PortSource) source).getPort());
+ Reporting reporting = source.getReporting();
+ assertNotNull(reporting);
+ assertNotNull(reporting.getOk());
+ assertNotNull(reporting.getOk().getText());
+ assertNull(reporting.getOk().getValue());
+ assertNotNull(reporting.getCritical());
+ assertNotNull(reporting.getCritical().getText());
+ assertNull(reporting.getCritical().getValue());
+ assertNull(reporting.getWarning());
+
+ // test namenode_cpu
+ source = nameNodeCpu.getSource();
+ assertNotNull(source);
+ reporting = source.getReporting();
+ assertNotNull(reporting);
+ assertNotNull(reporting.getOk());
+ assertNotNull(reporting.getOk().getText());
+ assertNull(reporting.getOk().getValue());
+ assertNotNull(reporting.getCritical());
+ assertNotNull(reporting.getCritical().getText());
+ assertNotNull(reporting.getCritical().getValue());
+ assertNotNull(reporting.getWarning());
+ assertNotNull(reporting.getWarning().getText());
+ assertNotNull(reporting.getWarning().getValue());
}
- /**
- * @throws Exception
- */
- @Test
- public void testAlertReconcile() throws Exception {
- Clusters clusters = createMock(Clusters.class);
- Cluster cluster = createMock(Cluster.class);
- AlertDefinitionDAO dao = createMock(AlertDefinitionDAO.class);
-
- metaInfo.alertDefinitionDao = dao;
- Set<AlertDefinition> alertDefinitions = metaInfo.getAlertDefinitions(
- STACK_NAME_HDP, "2.0.6", "HDFS");
-
- assertEquals(4, alertDefinitions.size());
-
- Map<String, Cluster> clustersMap = new HashMap<String, Cluster>();
- clustersMap.put("c1", cluster);
-
- StackId stackId = new StackId(STACK_NAME_HDP, "2.0.6");
- Map<String, Service> clusterServiceMap = new HashMap<String, Service>();
- clusterServiceMap.put("HDFS", null);
-
- List<AlertDefinitionEntity> entities = new ArrayList<AlertDefinitionEntity>();
-
- expect(clusters.getClusters()).andReturn(clustersMap).anyTimes();
- expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce();
- expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
- expect(cluster.getDesiredStackVersion()).andReturn(stackId).anyTimes();
- expect(cluster.getServices()).andReturn(clusterServiceMap).anyTimes();
- expect(dao.findAll(EasyMock.anyInt())).andReturn(entities).atLeastOnce();
- dao.createOrUpdate(EasyMock.anyObject(AlertDefinitionEntity.class));
- EasyMock.expectLastCall().times(4);
-
- EasyMock.replay(clusters, cluster, dao);
- metaInfo.reconcileAlertDefinitions(clusters);
- EasyMock.verify(cluster, cluster, dao);
-
- AlertDefinitionFactory alertDefinitionFactory = injector.getInstance(AlertDefinitionFactory.class);
- for (AlertDefinition definition : alertDefinitions) {
- entities.add(alertDefinitionFactory.coerce(1, definition));
- }
-
- EasyMock.reset(clusters, cluster, dao);
- expect(clusters.getClusters()).andReturn(clustersMap).anyTimes();
- expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce();
- expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
- expect(cluster.getDesiredStackVersion()).andReturn(stackId).anyTimes();
- expect(cluster.getServices()).andReturn(clusterServiceMap).anyTimes();
- expect(dao.findAll(EasyMock.anyInt())).andReturn(entities).atLeastOnce();
-
- EasyMock.replay(clusters, cluster, dao);
- metaInfo.reconcileAlertDefinitions(clusters);
- EasyMock.verify(cluster, cluster, dao);
+ private AmbariMetaInfo setupTempAmbariMetaInfo(String buildDir)
+ throws Exception {
+ File stackRootTmp = new File(buildDir + "/ambari-metaInfo");
+ File stackRoot = new File("src/test/resources/stacks");
+ stackRootTmp.mkdir();
+ FileUtils.copyDirectory(stackRoot, stackRootTmp);
+ AmbariMetaInfo ambariMetaInfo = new AmbariMetaInfo(stackRootTmp, new File(
+ "target/version"));
+ injector.injectMembers(ambariMetaInfo);
+ return ambariMetaInfo;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7f86e75c/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
[19/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/05da121a
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/05da121a
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/05da121a
Branch: refs/heads/trunk
Commit: 05da121a58e5768d0d0eda2527bd127c7355a23a
Parents: 1f1059c 813f16c
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Sep 10 09:02:43 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Sep 10 09:02:43 2014 -0400
----------------------------------------------------------------------
.../main/resources/ui/admin-web/app/index.html | 2 +
.../resources/ui/admin-web/app/scripts/app.js | 1 +
.../controllers/ambariViews/ViewsEditCtrl.js | 8 +
.../clusters/ClustersManageAccessCtrl.js | 8 +
.../controllers/groups/GroupsEditCtrl.js | 9 +
.../scripts/controllers/users/UsersShowCtrl.js | 13 +
.../app/scripts/directives/editableList.js | 199 ++++++++
.../ui/admin-web/app/scripts/services/Group.js | 6 +
.../ui/admin-web/app/scripts/services/User.js | 7 +
.../resources/ui/admin-web/app/styles/main.css | 212 +++++++-
.../admin-web/app/views/ambariViews/edit.html | 29 +-
.../app/views/clusters/manageAccess.html | 31 +-
.../app/views/directives/editableList.html | 44 ++
.../ui/admin-web/app/views/groups/edit.html | 23 +-
.../ui/admin-web/app/views/leftNavbar.html | 8 +-
.../ui/admin-web/app/views/users/show.html | 22 +-
.../src/main/resources/ui/admin-web/bower.json | 3 +-
.../libraries/script/script.py | 23 +-
ambari-server/conf/unix/ambari.properties | 3 +
.../ambari/server/api/AmbariPersistFilter.java | 1 -
.../stackadvisor/StackAdvisorHelper.java | 6 +-
.../StackAdvisorRequestException.java | 27 +
.../stackadvisor/StackAdvisorRunner.java | 34 +-
.../commands/StackAdvisorCommand.java | 14 +-
.../server/configuration/Configuration.java | 58 ++-
.../server/controller/AmbariHandlerList.java | 43 +-
.../controller/AmbariManagementController.java | 16 +-
.../AmbariManagementControllerImpl.java | 34 +-
.../ambari/server/controller/AmbariServer.java | 52 +-
.../server/controller/ControllerModule.java | 69 ++-
.../controller/FailsafeServletResponse.java | 22 +-
.../internal/ControllerResourceProvider.java | 22 +-
.../internal/PrivilegeResourceProvider.java | 6 +-
.../RecommendationResourceProvider.java | 9 +-
.../internal/ValidationResourceProvider.java | 9 +-
.../internal/ViewInstanceResourceProvider.java | 44 +-
.../ViewPermissionResourceProvider.java | 8 +-
.../internal/ViewPrivilegeResourceProvider.java | 28 +-
.../internal/ViewVersionResourceProvider.java | 6 +-
.../apache/ambari/server/orm/dao/GroupDAO.java | 30 +-
.../apache/ambari/server/orm/dao/MemberDAO.java | 34 +-
.../ambari/server/orm/dao/PrincipalDAO.java | 27 +-
.../ambari/server/orm/dao/PrincipalTypeDAO.java | 29 +-
.../apache/ambari/server/orm/dao/UserDAO.java | 49 +-
.../server/orm/entities/MemberEntity.java | 7 +-
.../server/orm/entities/PrincipalEntity.java | 2 +-
.../ambari/server/orm/entities/UserEntity.java | 5 +-
.../ambari/server/orm/entities/ViewEntity.java | 9 +
.../server/orm/entities/ViewInstanceEntity.java | 89 ++++
.../ambari/server/security/SecurityFilter.java | 2 +-
.../AmbariAuthorizationFilter.java | 35 +-
.../authorization/AmbariLdapDataPopulator.java | 409 ---------------
.../server/security/authorization/User.java | 2 +-
.../server/security/authorization/Users.java | 158 +++++-
.../security/ldap/AmbariLdapDataPopulator.java | 430 ++++++++++++++++
.../server/security/ldap/LdapBatchDto.java | 67 +++
.../server/security/ldap/LdapGroupDto.java | 113 +++++
.../server/security/ldap/LdapSyncDto.java | 72 +++
.../server/security/ldap/LdapUserDto.java | 133 +++++
.../security/ldap/LdapUserGroupMemberDto.java | 82 +++
.../ambari/server/state/ConfigHelper.java | 3 +-
.../apache/ambari/server/view/ViewRegistry.java | 4 +
ambari-server/src/main/python/ambari-server.py | 6 +-
.../src/main/resources/META-INF/persistence.xml | 4 +
.../src/main/resources/scripts/stack_advisor.py | 8 +-
.../1.3.2/hooks/before-START/scripts/params.py | 23 +-
.../HDFS/package/scripts/hdfs_client.py | 6 +
.../services/HDFS/package/scripts/params.py | 16 +-
.../MAPREDUCE/configuration/mapred-env.xml | 20 +
.../MAPREDUCE/package/scripts/client.py | 7 +
.../MAPREDUCE/package/scripts/params.py | 13 +
.../HDP/1.3.2/services/SQOOP/metainfo.xml | 2 +-
.../stacks/HDP/1.3.2/services/stack_advisor.py | 19 +-
.../2.0.6/services/HIVE/package/scripts/hcat.py | 2 +-
.../2.0.6/services/HIVE/package/scripts/hive.py | 118 ++---
.../services/HIVE/package/scripts/params.py | 9 +-
.../stacks/HDP/2.0.6/services/stack_advisor.py | 37 +-
.../stacks/HDP/2.1/services/stack_advisor.py | 8 +-
.../stacks/HDP/2.2.1/repos/repoinfo.xml | 4 +-
.../stackadvisor/StackAdvisorRunnerTest.java | 44 +-
.../commands/StackAdvisorCommandTest.java | 29 +-
.../ViewInstanceResourceProviderTest.java | 123 +++++
.../ViewPermissionResourceProviderTest.java | 133 +++++
.../ViewPrivilegeResourceProviderTest.java | 8 +-
.../server/orm/entities/ViewEntityTest.java | 17 +
.../orm/entities/ViewInstanceEntityTest.java | 16 +
.../AmbariLdapDataPopulatorTest.java | 261 ----------
.../ldap/AmbariLdapDataPopulatorTest.java | 202 ++++++++
.../security/ldap/LdapPerformanceTest.java | 94 ++++
.../ambari/server/view/ViewRegistryTest.java | 39 ++
.../stacks/1.3.2/HDFS/test_hdfs_client.py | 59 +++
.../1.3.2/MAPREDUCE/test_mapreduce_client.py | 36 +-
.../python/stacks/1.3.2/configs/default.json | 10 +-
.../stacks/2.0.6/HIVE/test_hive_client.py | 286 ++++++-----
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 413 +++++++--------
.../stacks/2.0.6/HIVE/test_hive_server.py | 504 ++++++++++---------
.../stacks/2.0.6/common/test_stack_advisor.py | 157 +++++-
.../stacks/2.1/HIVE/test_hive_metastore.py | 304 +++++------
.../stacks/2.1/common/test_stack_advisor.py | 132 +++++
ambari-web/app/app.js | 3 +-
ambari-web/app/assets/licenses/NOTICE.txt | 6 +-
.../controllers/global/cluster_controller.js | 42 --
.../nameNode/step4_controller.js | 29 +-
.../main/dashboard/config_history_controller.js | 6 +-
ambari-web/app/controllers/main/host/details.js | 7 +-
ambari-web/app/controllers/main/service/item.js | 6 +-
.../service/manage_config_groups_controller.js | 15 +-
.../app/controllers/main/views_controller.js | 4 +-
.../app/controllers/wizard/step7_controller.js | 19 +-
.../app/controllers/wizard/step8_controller.js | 6 +-
ambari-web/app/messages.js | 1 +
.../app/mixins/common/table_server_mixin.js | 3 -
ambari-web/app/models/stack_service.js | 3 +-
ambari-web/app/routes/main.js | 2 +-
ambari-web/app/styles/application.less | 1 +
.../common/configs/services_config.hbs | 2 +
.../admin/highAvailability/nameNode/step4.hbs | 5 +
.../views/main/dashboard/config_history_view.js | 11 +-
ambari-web/app/views/main/menu.js | 48 +-
ambari-web/app/views/main/views/details.js | 28 --
ambari-web/test/app_test.js | 39 +-
.../main/admin/security/add/step1_test.js | 69 +--
.../main/admin/security/add/step4_test.js | 307 ++++++-----
.../test/controllers/main/host/details_test.js | 9 +-
.../jquery.iframe-auto-height.plugin.1.9.5.js | 224 ---------
.../resources/ui/app/assets/data/apps/apps.json | 124 +++++
.../assets/data/resource/service_status.json | 107 ++++
.../app/controllers/slider_apps_controller.js | 136 ++++-
.../src/main/resources/ui/app/helpers/ajax.js | 40 +-
.../src/main/resources/ui/app/helpers/helper.js | 47 +-
.../src/main/resources/ui/app/initialize.js | 4 +-
.../ui/app/mappers/application_status.js | 79 ++-
.../ui/app/mappers/slider_apps_mapper.js | 79 ++-
.../main/resources/ui/app/models/slider_app.js | 5 +
.../resources/ui/app/models/slider_app_alert.js | 172 +++++++
.../resources/ui/app/styles/application.less | 60 +++
.../ui/app/templates/slider_app/summary.hbs | 27 +-
.../src/main/resources/ui/app/translations.js | 21 +
.../ui/app/views/slider_app/summary_view.js | 20 +-
.../slider/src/main/resources/ui/config.js | 1 +
.../ui/vendor/scripts/common/jquery.timeago.js | 214 ++++++++
docs/pom.xml | 42 +-
docs/src/site/site.xml | 70 +--
143 files changed, 5748 insertions(+), 2514 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/05da121a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
[48/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9919b3f4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9919b3f4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9919b3f4
Branch: refs/heads/trunk
Commit: 9919b3f4faf0ead6d7495d28e910f21cbc0f42f5
Parents: 445a53c 76e3bb4
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Oct 6 11:12:39 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Oct 6 11:12:39 2014 -0400
----------------------------------------------------------------------
.../src/main/python/ambari_agent/Facter.py | 17 ++--
.../src/main/python/ambari_commons/os_check.py | 17 ++++
.../ambari/server/agent/HeartBeatHandler.java | 1 +
.../ViewInstanceResourceDefinition.java | 5 +-
.../server/api/services/AmbariMetaInfo.java | 2 +-
.../apache/ambari/server/view/ViewRegistry.java | 35 ++++----
.../src/main/python/ambari_server/utils.py | 4 +-
ambari-server/src/main/resources/os_family.json | 6 ++
.../services/OOZIE/package/scripts/oozie.py | 2 +-
.../services/OOZIE/package/scripts/params.py | 2 -
.../ZOOKEEPER/configuration/zookeeper-env.xml | 1 +
.../ZOOKEEPER/package/scripts/params.py | 2 +
.../services/OOZIE/configuration/oozie-site.xml | 75 +++++++++++++++++
.../ambari/server/view/ViewRegistryTest.java | 28 +++---
.../stacks/2.0.6/OOZIE/test_oozie_server.py | 10 +++
.../templates/main/service/services/storm.hbs | 2 +-
.../app/views/main/service/services/storm.js | 8 ++
.../ui/app/controllers/slider_app_controller.js | 89 ++++++++++++--------
.../main/resources/ui/app/models/slider_app.js | 33 ++++----
.../ui/test/integration/pages/index_test.js | 13 ++-
.../controllers/slider_app_controller_test.js | 64 ++++++++++++++
21 files changed, 322 insertions(+), 94 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/9919b3f4/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/9919b3f4/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
[20/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Conflicts:
ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2262400c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2262400c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2262400c
Branch: refs/heads/trunk
Commit: 2262400c6057aec451027f432b83f2c88ac1d8c3
Parents: 05da121 3035978
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Sep 11 15:02:05 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Sep 11 15:02:05 2014 -0400
----------------------------------------------------------------------
.../ui/admin-web/app/scripts/services/View.js | 6 +-
.../app/views/ambariViews/listTable.html | 2 +-
ambari-server/conf/unix/ambari.properties | 1 +
.../server/api/services/ComponentService.java | 5 +-
.../api/services/HostComponentService.java | 5 +-
.../server/configuration/Configuration.java | 4 +
.../controller/RequestStatusResponse.java | 12 +
.../internal/AbstractResourceProvider.java | 3 +
.../AmbariPrivilegeResourceProvider.java | 8 +-
.../internal/BaseBlueprintProcessor.java | 7 +-
.../internal/ClientConfigResourceProvider.java | 5 +-
.../internal/ClusterResourceProvider.java | 17 +-
.../internal/ServiceResourceProvider.java | 14 +-
.../internal/ViewVersionResourceProvider.java | 3 +
.../server/orm/entities/AlertCurrentEntity.java | 19 ++
.../ambari/server/orm/entities/ViewEntity.java | 29 +-
.../server/upgrade/UpgradeCatalog161.java | 2 +-
.../server/upgrade/UpgradeCatalog170.java | 86 ++++++
.../server/view/configuration/ViewConfig.java | 14 +
ambari-server/src/main/python/bootstrap.py | 24 +-
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 3 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 3 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 3 +-
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 3 +-
.../services/HIVE/package/scripts/params.py | 6 +-
.../services/OOZIE/package/scripts/oozie.py | 2 +-
.../OOZIE/package/scripts/oozie_service.py | 2 +-
.../services/OOZIE/package/scripts/params.py | 10 +
.../2.1.GlusterFS/services/STORM/metainfo.xml | 5 +
.../2.1.GlusterFS/services/YARN/metainfo.xml | 1 +
.../AmbariPrivilegeResourceProviderTest.java | 1 +
.../internal/BlueprintResourceProviderTest.java | 15 +
.../ClientConfigResourceProviderTest.java | 16 +-
.../internal/ClusterResourceProviderTest.java | 239 ++++++++++++---
.../internal/RequestResourceProviderTest.java | 16 +-
.../internal/ServiceResourceProviderTest.java | 122 +++++++-
.../server/orm/entities/ViewEntityTest.java | 11 +
.../server/upgrade/UpgradeCatalog161Test.java | 2 +-
.../server/upgrade/UpgradeCatalog170Test.java | 49 +++-
.../view/configuration/ViewConfigTest.java | 23 ++
ambari-server/src/test/python/TestBootstrap.py | 29 +-
ambari-web/app/app.js | 3 +
.../app/controllers/wizard/step5_controller.js | 2 +-
.../app/controllers/wizard/step6_controller.js | 2 +-
.../app/controllers/wizard/step8_controller.js | 2 +-
ambari-web/app/data/HDP2/config_mapping.js | 4 +-
ambari-web/app/data/config_mapping.js | 4 +-
ambari-web/app/data/site_properties.js | 2 +-
ambari-web/app/styles/application.less | 9 +-
.../common/configs/config_history_flow.hbs | 12 +-
.../main/dashboard/widgets/cluster_metrics.hbs | 2 +-
.../main/dashboard/widgets/hbase_links.hbs | 2 +-
.../main/dashboard/widgets/hdfs_links.hbs | 2 +-
.../main/dashboard/widgets/mapreduce_links.hbs | 2 +-
.../main/dashboard/widgets/mapreduce_slots.hbs | 2 +-
.../main/dashboard/widgets/pie_chart.hbs | 2 +-
.../main/dashboard/widgets/simple_text.hbs | 2 +-
.../templates/main/dashboard/widgets/uptime.hbs | 2 +-
ambari-web/app/utils/config.js | 19 +-
.../views/common/configs/config_history_flow.js | 5 +
ambari-web/app/views/main/dashboard/widget.js | 4 +-
ambari-web/app/views/main/dashboard/widgets.js | 14 +
ambari-web/vendor/scripts/jquery.hoverIntent.js | 115 ++++++++
contrib/views/slider/pom.xml | 8 -
.../view/slider/SliderAppsViewController.java | 5 +
.../slider/SliderAppsViewControllerImpl.java | 262 +++++------------
.../apache/ambari/view/slider/ViewStatus.java | 33 +--
.../view/slider/clients/AmbariClient.java | 3 -
.../slider/clients/AmbariInternalClient.java | 292 -------------------
.../slider/rest/client/JMXMetricHolder.java | 50 ++++
.../slider/rest/client/SliderAppJmxHelper.java | 1 -
.../resources/ui/app/assets/data/apps/apps.json | 16 +-
.../assets/data/resource/service_configs.json | 38 +++
.../ui/app/components/configSection.js | 16 +-
.../createAppWizard/step1_controller.js | 41 ++-
.../createAppWizard/step2_controller.js | 3 +-
.../createAppWizard/step3_controller.js | 123 +++++++-
.../ui/app/controllers/slider_app_controller.js | 127 ++++++--
.../app/controllers/slider_apps_controller.js | 8 +-
.../src/main/resources/ui/app/helpers/ajax.js | 9 +
.../src/main/resources/ui/app/initialize.js | 19 +-
.../ui/app/mappers/slider_apps_mapper.js | 4 +-
.../main/resources/ui/app/mixins/with_panels.js | 50 ++++
.../resources/ui/app/models/config_property.js | 44 +++
.../main/resources/ui/app/models/slider_app.js | 24 +-
.../resources/ui/app/models/slider_app_type.js | 2 +-
.../resources/ui/app/styles/application.less | 46 ++-
.../ui/app/templates/common/config.hbs | 37 +++
.../app/templates/components/configSection.hbs | 95 +++---
.../ui/app/templates/slider_app/configs.hbs | 36 ++-
.../ui/app/templates/slider_app/flex_popup.hbs | 39 +++
.../ui/app/templates/slider_app/summary.hbs | 10 +-
.../src/main/resources/ui/app/translations.js | 9 +-
.../ui/app/views/common/config_set_view.js | 56 ++++
.../ui/app/views/slider_app/configs_view.js | 57 ++++
.../views/slider/src/main/resources/view.xml | 23 +-
96 files changed, 1846 insertions(+), 780 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2262400c/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2262400c/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2262400c/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2262400c/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
index 71cd2d7,0e8aea5..145096d
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
@@@ -73,7 -80,7 +80,8 @@@ import org.apache.ambari.server.state.C
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.alert.Scope;
+ import org.apache.ambari.server.utils.StageUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
http://git-wip-us.apache.org/repos/asf/ambari/blob/2262400c/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2262400c/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2262400c/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2262400c/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
[10/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/8697c91b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/8697c91b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/8697c91b
Branch: refs/heads/trunk
Commit: 8697c91b8309aeb9471585249d20fca6ccfee0f0
Parents: 7a0f509 641e177
Author: Nate Cole <nc...@hortonworks.com>
Authored: Tue Sep 2 16:29:02 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Tue Sep 2 16:29:02 2014 -0400
----------------------------------------------------------------------
.../src/main/package/rpm/posttrans_agent.sh | 6 +
.../ambari/server/agent/ExecutionCommand.java | 2 +
.../AmbariManagementControllerImpl.java | 11 +
.../controller/StackConfigurationResponse.java | 17 +-
.../StackLevelConfigurationResponse.java | 7 +-
.../internal/BlueprintResourceProvider.java | 3 +-
.../internal/ClientConfigResourceProvider.java | 11 +-
.../internal/ClusterResourceProvider.java | 2 +-
.../StackConfigurationResourceProvider.java | 6 +
...StackLevelConfigurationResourceProvider.java | 6 +
.../server/orm/entities/BlueprintEntity.java | 4 +-
.../ambari/server/state/ConfigHelper.java | 28 +
.../ambari/server/state/PropertyInfo.java | 34 +-
.../server/upgrade/UpgradeCatalog170.java | 6 +
.../src/main/package/rpm/posttrans_server.sh | 6 +
.../src/main/resources/properties.json | 2 +
.../HDP/1.3.2/configuration/cluster-env.xml | 2 +
.../1.3.2/hooks/after-INSTALL/scripts/params.py | 1 +
.../hooks/before-INSTALL/scripts/params.py | 29 +-
.../scripts/shared_initialization.py | 111 +-
.../GANGLIA/configuration/ganglia-env.xml | 2 +
.../services/HBASE/configuration/hbase-env.xml | 1 +
.../services/HDFS/configuration/hadoop-env.xml | 12 +
.../services/HDFS/configuration/hdfs-log4j.xml | 1 +
.../services/HDFS/package/scripts/params.py | 2 +-
.../services/HIVE/configuration/hive-env.xml | 3 +
.../services/HIVE/configuration/hive-site.xml | 2 +-
.../MAPREDUCE/configuration/mapred-env.xml | 1 +
.../NAGIOS/configuration/nagios-env.xml | 4 +-
.../services/OOZIE/configuration/oozie-env.xml | 1 +
.../services/OOZIE/configuration/oozie-site.xml | 2 +-
.../services/SQOOP/configuration/sqoop-env.xml | 1 +
.../ZOOKEEPER/configuration/zookeeper-env.xml | 1 +
.../HDP/2.0.6/configuration/cluster-env.xml | 2 +
.../2.0.6/hooks/after-INSTALL/scripts/params.py | 1 +
.../hooks/before-INSTALL/scripts/params.py | 35 +-
.../scripts/shared_initialization.py | 136 +--
.../services/FLUME/configuration/flume-env.xml | 1 +
.../GANGLIA/configuration/ganglia-env.xml | 2 +
.../services/HBASE/configuration/hbase-env.xml | 1 +
.../services/HDFS/configuration/core-site.xml | 11 +
.../services/HDFS/configuration/hadoop-env.xml | 12 +
.../services/HDFS/configuration/hdfs-log4j.xml | 1 +
.../services/HDFS/package/scripts/params.py | 2 +-
.../services/HIVE/configuration/hive-env.xml | 3 +
.../services/HIVE/configuration/hive-site.xml | 2 +-
.../NAGIOS/configuration/nagios-env.xml | 4 +-
.../services/OOZIE/configuration/oozie-env.xml | 1 +
.../services/OOZIE/configuration/oozie-site.xml | 2 +-
.../services/SQOOP/configuration/sqoop-env.xml | 1 +
.../YARN/configuration-mapred/mapred-env.xml | 1 +
.../services/YARN/configuration/yarn-env.xml | 1 +
.../ZOOKEEPER/configuration/zookeeper-env.xml | 1 +
.../services/HIVE/configuration/hive-site.xml | 2 +-
.../FALCON/configuration/falcon-env.xml | 1 +
.../services/HIVE/configuration/hive-site.xml | 2 +-
.../services/STORM/configuration/storm-env.xml | 1 +
.../2.1/services/TEZ/configuration/tez-env.xml | 1 +
.../services/YARN/configuration/yarn-env.xml | 1 +
.../server/api/services/AmbariMetaInfoTest.java | 4 +-
.../api/util/StackExtensionHelperTest.java | 6 +-
.../internal/ClusterResourceProviderTest.java | 10 +-
.../orm/entities/BlueprintEntityTest.java | 24 +-
.../server/upgrade/UpgradeCatalog170Test.java | 7 +
.../services/HIVE/configuration/hive-site.xml | 2 +-
.../app/assets/data/hosts/HDP2/hosts.json | 406 ++++++-
.../app/assets/data/hosts/quick_links.json | 62 +
.../app/assets/data/services/HDP2/services.json | 16 +
.../services/host_component_stale_configs.json | 62 +-
.../data/stacks/HDP-2.1/operating_systems.json | 157 +++
.../data/stacks/HDP-2.1/service_components.json | 1143 +++++++++++++++---
ambari-web/app/assets/data/views/instances.json | 40 +
ambari-web/app/assets/data/views/views.json | 11 +
.../app/controllers/global/update_controller.js | 3 +
.../controllers/main/service/info/configs.js | 1 +
.../app/controllers/wizard/step7_controller.js | 28 +-
ambari-web/app/data/HDP2/site_properties.js | 13 +
ambari-web/app/data/site_properties.js | 13 +
.../common/configs/config_history_flow.hbs | 4 -
.../common/configs/services_config.hbs | 37 +-
ambari-web/app/utils/ajax/ajax.js | 8 +-
ambari-web/app/utils/http_client.js | 2 +-
.../app/views/common/quick_view_link_view.js | 2 +-
.../main/service/info/config_test.js | 8 +-
.../service/reassign/step4_controller_test.js | 21 -
.../test/controllers/wizard/step8_test.js | 20 +-
ambari-web/test/models/stack_service_test.js | 12 +-
.../common/configs/config_history_flow_test.js | 2 +-
.../capacityscheduler/ConfigurationService.java | 1 +
.../ui/app/assets/fonts/fontawesome-webfont.svg | 31 +-
.../fonts/glyphicons-halflings-regular.svg | 229 ++++
.../ui/app/components/confirmDelete.js | 2 +-
.../src/main/resources/ui/app/router.js | 2 +-
.../resources/ui/app/styles/application.less | 52 +-
.../ui/app/templates/capacityEditForm.hbs | 4 +-
.../app/templates/components/totalCapacity.hbs | 22 +-
.../main/resources/ui/app/templates/queue.hbs | 60 +-
.../main/resources/ui/app/templates/queues.hbs | 12 +-
.../ui/app/templates/schedulerPanel.hbs | 14 +-
.../src/main/resources/view.xml | 6 +-
contrib/views/slider/pom.xml | 57 +-
.../slider/SliderAppsViewControllerImpl.java | 2 +-
102 files changed, 2435 insertions(+), 738 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/8697c91b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/8697c91b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/8697c91b/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/8697c91b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
[15/50] [abbrv] git commit: AMBARI-7160. Add endpoints for alert data
(ncole)
Posted by jo...@apache.org.
AMBARI-7160. Add endpoints for alert data (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/84c16c5c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/84c16c5c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/84c16c5c
Branch: refs/heads/trunk
Commit: 84c16c5c5981559454659d069463a5bbd26e7de6
Parents: e508fe5
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Sep 4 18:07:59 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Sun Sep 7 05:45:13 2014 -0400
----------------------------------------------------------------------
.../api/resources/AlertResourceDefinition.java | 41 ++++
.../resources/ClusterResourceDefinition.java | 1 +
.../api/resources/HostResourceDefinition.java | 7 +-
.../resources/ResourceInstanceFactoryImpl.java | 4 +
.../resources/ServiceResourceDefinition.java | 5 +-
.../server/api/services/AlertService.java | 93 +++++++
.../server/api/services/ClusterService.java | 16 ++
.../ambari/server/api/services/HostService.java | 11 +
.../server/api/services/ServiceService.java | 9 +
.../ambari/server/controller/AmbariServer.java | 2 +
.../AbstractControllerResourceProvider.java | 2 +
.../internal/AlertResourceProvider.java | 191 +++++++++++++++
.../ambari/server/controller/spi/Resource.java | 2 +
.../apache/ambari/server/orm/dao/AlertsDAO.java | 21 ++
.../server/orm/entities/AlertCurrentEntity.java | 5 +-
.../src/main/resources/key_properties.json | 6 +
.../src/main/resources/properties.json | 16 ++
.../api/query/render/DefaultRendererTest.java | 3 +-
.../api/query/render/MinimalRendererTest.java | 3 +-
.../ClusterResourceDefinitionTest.java | 3 +-
.../internal/AlertResourceProviderTest.java | 241 +++++++++++++++++++
.../ambari/server/orm/dao/AlertsDAOTest.java | 52 +++-
22 files changed, 724 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java
new file mode 100644
index 0000000..afdbcfc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertResourceDefinition.java
@@ -0,0 +1,41 @@
+/**
+ * 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.ambari.server.api.resources;
+
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Definition for alert resources.
+ */
+public class AlertResourceDefinition extends BaseResourceDefinition {
+
+ public AlertResourceDefinition() {
+ super(Resource.Type.Alert);
+ }
+
+ @Override
+ public String getPluralName() {
+ return "alerts_data";
+ }
+
+ @Override
+ public String getSingularName() {
+ return "alert_data";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
index 702bcf8..ef907c0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
@@ -68,6 +68,7 @@ public class ClusterResourceDefinition extends BaseResourceDefinition {
setChildren.add(new SubResourceDefinition(Resource.Type.ConfigGroup));
setChildren.add(new SubResourceDefinition(Resource.Type.ClusterPrivilege));
setChildren.add(new SubResourceDefinition(Resource.Type.AlertDefinition));
+ setChildren.add(new SubResourceDefinition(Resource.Type.Alert));
return setChildren;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java
index 8aba287..14ed799 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/HostResourceDefinition.java
@@ -19,7 +19,7 @@
package org.apache.ambari.server.api.resources;
-import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
import org.apache.ambari.server.controller.spi.Resource;
@@ -48,6 +48,9 @@ public class HostResourceDefinition extends BaseResourceDefinition {
@Override
public Set<SubResourceDefinition> getSubResourceDefinitions() {
- return Collections.singleton(new SubResourceDefinition(Resource.Type.HostComponent));
+ Set<SubResourceDefinition> subs = new HashSet<SubResourceDefinition>();
+ subs.add(new SubResourceDefinition(Resource.Type.HostComponent));
+ subs.add(new SubResourceDefinition(Resource.Type.Alert));
+ return subs;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index ffbfb29..3b90b30 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -250,6 +250,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
case Permission:
resourceDefinition = new PermissionResourceDefinition();
break;
+
+ case Alert:
+ resourceDefinition = new AlertResourceDefinition();
+ break;
case AlertDefinition:
resourceDefinition = new AlertDefResourceDefinition();
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceResourceDefinition.java
index e1355ad..be8e0b4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceResourceDefinition.java
@@ -47,6 +47,9 @@ public class ServiceResourceDefinition extends BaseResourceDefinition {
@Override
public Set<SubResourceDefinition> getSubResourceDefinitions() {
- return Collections.singleton(new SubResourceDefinition(Resource.Type.Component));
+ Set<SubResourceDefinition> subs = new HashSet<SubResourceDefinition>();
+ subs.add(new SubResourceDefinition(Resource.Type.Component));
+ subs.add(new SubResourceDefinition(Resource.Type.Alert));
+ return subs;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java
new file mode 100644
index 0000000..8e163c2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertService.java
@@ -0,0 +1,93 @@
+/**
+ * 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.ambari.server.api.services;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Endpoint for alert data.
+ */
+public class AlertService extends BaseService {
+
+ private String clusterName = null;
+ private String serviceName = null;
+ private String hostName = null;
+
+ AlertService(String clusterName, String serviceName, String hostName) {
+ this.clusterName = clusterName;
+ this.serviceName = serviceName;
+ this.hostName = hostName;
+ }
+
+ /**
+ * Gets all the definitions for the target
+ */
+ @GET
+ @Produces("text/plain")
+ public Response getDefinitions(String body,
+ @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createResourceInstance(null));
+ }
+
+
+ /**
+ * Gets a specific alert's instance
+ */
+ @GET
+ @Path("{alertId}")
+ @Produces("text/plain")
+ public Response getDefinition(String body,
+ @Context HttpHeaders headers,
+ @Context UriInfo ui,
+ @PathParam("alertId") Long id) {
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createResourceInstance(id));
+ }
+
+
+ /**
+ * Create an alert resource instance
+ * @param alertId the alert id, if requesting a specific one
+ * @return the resource instance
+ */
+ private ResourceInstance createResourceInstance(Long alertId) {
+ Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>();
+ mapIds.put(Resource.Type.Cluster, clusterName);
+ mapIds.put(Resource.Type.Service, serviceName);
+ mapIds.put(Resource.Type.Host, hostName);
+ mapIds.put(Resource.Type.Alert, null == alertId ? null : alertId.toString());
+
+ return createResource(Resource.Type.Alert, mapIds);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
index 3f1ce36..c76acf7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
@@ -357,6 +357,22 @@ public class ClusterService extends BaseService {
hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
return new ClusterPrivilegeService(clusterName);
}
+
+ /**
+ * Gets the alert definition service
+ *
+ * @param request the request
+ * @param clusterName the cluster name
+ *
+ * @return the alert definition service
+ */
+ @Path("{clusterName}/alerts_data")
+ public AlertService getAlertService(
+ @Context javax.ws.rs.core.Request request, @PathParam("clusterName") String clusterName) {
+
+ hasPermission(Request.Type.valueOf(request.getMethod()), clusterName);
+ return new AlertService(clusterName, null, null);
+ }
// ----- helper methods ----------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
index db9d3c0..8cec7e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/HostService.java
@@ -207,6 +207,17 @@ public class HostService extends BaseService {
}
/**
+ * Get the alerts sub-resource.
+ *
+ * @param hostName host id
+ * @return the alerts service
+ */
+ @Path("{hostName}/alerts_data")
+ public AlertService getAlertHandler(@PathParam("hostName") String hostName) {
+ return new AlertService(m_clusterName, null, hostName);
+ }
+
+ /**
* Create a service resource instance.
*
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
index 643ae36..30f4f2f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
@@ -183,6 +183,15 @@ public class ServiceService extends BaseService {
return new ComponentService(m_clusterName, serviceName);
}
+
+ /**
+ * Gets the alerts sub-resource.
+ */
+ @Path("{serviceName}/alerts_data")
+ public AlertService getAlertHandler(
+ @PathParam("serviceName") String serviceName) {
+ return new AlertService(m_clusterName, serviceName, null);
+ }
/**
* Create a service resource instance.
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 31d6518..73e4013 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -47,6 +47,7 @@ import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.internal.AbstractControllerResourceProvider;
import org.apache.ambari.server.controller.internal.AlertDefinitionResourceProvider;
import org.apache.ambari.server.controller.internal.AlertGroupResourceProvider;
+import org.apache.ambari.server.controller.internal.AlertResourceProvider;
import org.apache.ambari.server.controller.internal.AlertTargetResourceProvider;
import org.apache.ambari.server.controller.internal.AmbariPrivilegeResourceProvider;
import org.apache.ambari.server.controller.internal.BlueprintResourceProvider;
@@ -531,6 +532,7 @@ public class AmbariServer {
injector.getInstance(Gson.class), ambariMetaInfo);
StackDependencyResourceProvider.init(ambariMetaInfo);
ClusterResourceProvider.init(injector.getInstance(BlueprintDAO.class), ambariMetaInfo, injector.getInstance(ConfigHelper.class));
+ AlertResourceProvider.init(injector);
AlertDefinitionResourceProvider.init(injector);
AlertGroupResourceProvider.init(injector);
AlertTargetResourceProvider.init(injector);
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 31c350b..f3f92a1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -149,6 +149,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc
return new RecommendationResourceProvider(propertyIds, keyPropertyIds, managementController);
case Validation:
return new ValidationResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case Alert:
+ return new AlertResourceProvider(propertyIds, keyPropertyIds, managementController);
case AlertDefinition:
return new AlertDefinitionResourceProvider(propertyIds, keyPropertyIds, managementController);
case AlertGroup:
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
new file mode 100644
index 0000000..639a02f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
@@ -0,0 +1,191 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.state.Cluster;
+
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+/**
+ * ResourceProvider for Alert instances
+ */
+public class AlertResourceProvider extends ReadOnlyResourceProvider {
+
+ protected static final String ALERT_CLUSTER_NAME = "Alert/cluster_name";
+ protected static final String ALERT_ID = "Alert/id";
+ protected static final String ALERT_NAME = "Alert/name";
+ protected static final String ALERT_LATEST_TIMESTAMP = "Alert/latest_timestamp";
+ protected static final String ALERT_MAINTENANCE_STATE = "Alert/maintenance_state";
+ protected static final String ALERT_ORIGINAL_TIMESTAMP = "Alert/original_timestamp";
+ protected static final String ALERT_INSTANCE = "Alert/instance";
+ protected static final String ALERT_LABEL = "Alert/label";
+ protected static final String ALERT_STATE = "Alert/state";
+ protected static final String ALERT_TEXT = "Alert/text";
+ protected static final String ALERT_COMPONENT = "Alert/component_name";
+ protected static final String ALERT_HOST = "Alert/host_name";
+ protected static final String ALERT_SERVICE = "Alert/service_name";
+ protected static final String ALERT_SCOPE = "Alert/scope";
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(
+ Arrays.asList(ALERT_ID, ALERT_NAME));
+
+ private static AlertsDAO alertsDAO = null;
+
+ /**
+ * @param injector the injector
+ */
+ @Inject
+ public static void init(Injector injector) {
+ alertsDAO = injector.getInstance(AlertsDAO.class);
+ }
+
+ AlertResourceProvider(Set<String> propertyIds,
+ Map<Resource.Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate);
+
+ Set<Resource> results = new HashSet<Resource>();
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+
+ String clusterName = (String) propertyMap.get(ALERT_CLUSTER_NAME);
+
+ if (null == clusterName || clusterName.isEmpty()) {
+ throw new IllegalArgumentException("Invalid argument, cluster name is required");
+ }
+
+ String id = (String) propertyMap.get(ALERT_ID);
+ if (null != id) {
+ AlertCurrentEntity entity = alertsDAO.findCurrentById(Long.parseLong(id));
+
+ if (null != entity) {
+ results.add(toResource(false, clusterName, entity, requestPropertyIds));
+ }
+
+ } else {
+ Cluster cluster = null;
+
+ try {
+ cluster = getManagementController().getClusters().getCluster(clusterName);
+ } catch (AmbariException e) {
+ throw new NoSuchResourceException("Parent Cluster resource doesn't exist", e);
+ }
+
+ String serviceName = (String) propertyMap.get(ALERT_SERVICE);
+ String hostName = (String) propertyMap.get(ALERT_HOST);
+
+ List<AlertCurrentEntity> entities = null;
+
+ if (null != hostName) {
+ entities = alertsDAO.findCurrentByHost(cluster.getClusterId(),
+ hostName);
+ } else if (null != serviceName) {
+ entities = alertsDAO.findCurrentByService(cluster.getClusterId(),
+ serviceName);
+ } else {
+ entities = alertsDAO.findCurrentByCluster(cluster.getClusterId());
+ }
+
+ if (null == entities)
+ entities = Collections.emptyList();
+
+ for (AlertCurrentEntity entity : entities) {
+ results.add(toResource(true, clusterName, entity, requestPropertyIds));
+ }
+ }
+ }
+
+ return results;
+ }
+
+ /**
+ * Converts an entity to a resource.
+ *
+ * @param isCollection {@code true} if the response is for a collection
+ * @param clusterName the cluster name
+ * @param entity the entity
+ * @param requestedIds the requested ids
+ * @return the resource
+ */
+ private Resource toResource(boolean isCollection, String clusterName,
+ AlertCurrentEntity entity, Set<String> requestedIds) {
+ Resource resource = new ResourceImpl(Resource.Type.Alert);
+
+ setResourceProperty(resource, ALERT_CLUSTER_NAME, clusterName, requestedIds);
+ setResourceProperty(resource, ALERT_ID, entity.getAlertId(), requestedIds);
+ setResourceProperty(resource, ALERT_LATEST_TIMESTAMP, entity.getLatestTimestamp(), requestedIds);
+ setResourceProperty(resource, ALERT_MAINTENANCE_STATE, entity.getMaintenanceState(), requestedIds);
+ setResourceProperty(resource, ALERT_ORIGINAL_TIMESTAMP, entity.getOriginalTimestamp(), requestedIds);
+
+ AlertHistoryEntity history = entity.getAlertHistory();
+ setResourceProperty(resource, ALERT_INSTANCE, history.getAlertInstance(), requestedIds);
+ setResourceProperty(resource, ALERT_LABEL, history.getAlertLabel(), requestedIds);
+ setResourceProperty(resource, ALERT_STATE, history.getAlertState(), requestedIds);
+ setResourceProperty(resource, ALERT_TEXT, history.getAlertText(), requestedIds);
+ setResourceProperty(resource, ALERT_COMPONENT, history.getComponentName(), requestedIds);
+ setResourceProperty(resource, ALERT_HOST, history.getHostName(), requestedIds);
+ setResourceProperty(resource, ALERT_SERVICE, history.getServiceName(), requestedIds);
+
+ AlertDefinitionEntity definition = history.getAlertDefinition();
+ setResourceProperty(resource, ALERT_NAME, definition.getDefinitionName(), requestedIds);
+ setResourceProperty(resource, ALERT_SCOPE, definition.getScope(), requestedIds);
+
+ if (isCollection) {
+ // !!! want name to be populated as if it were a PK when requesting the collection
+ resource.setProperty(ALERT_NAME, definition.getDefinitionName());
+ }
+
+ return resource;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index 2cf6d99..59f9a89 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -114,6 +114,7 @@ public interface Resource {
Validation,
HostComponentProcess,
Permission,
+ Alert,
AlertDefinition,
AlertGroup,
AlertTarget,
@@ -198,6 +199,7 @@ public interface Resource {
public static final Type Validation = InternalType.Validation.getType();
public static final Type HostComponentProcess = InternalType.HostComponentProcess.getType();
public static final Type Permission = InternalType.Permission.getType();
+ public static final Type Alert = InternalType.Alert.getType();
public static final Type AlertDefinition = InternalType.AlertDefinition.getType();
public static final Type AlertGroup = InternalType.AlertGroup.getType();
public static final Type AlertTarget = InternalType.AlertTarget.getType();
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index b43b5b1..5fcc1ec 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -19,6 +19,7 @@ package org.apache.ambari.server.orm.dao;
import java.util.Collections;
import java.util.Date;
+import java.util.EnumSet;
import java.util.List;
import javax.persistence.EntityManager;
@@ -28,6 +29,7 @@ import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.alert.Scope;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -205,6 +207,23 @@ public class AlertsDAO {
}
/**
+ * Gets the current alerts for a given cluster.
+ *
+ * @return the current alerts for the given clusteror an empty list if none
+ * exist (never {@code null}).
+ */
+ @RequiresSession
+ public List<AlertCurrentEntity> findCurrentByCluster(long clusterId) {
+ TypedQuery<AlertCurrentEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertCurrentEntity.findByCluster", AlertCurrentEntity.class);
+
+ query.setParameter("clusterId", Long.valueOf(clusterId));
+
+ return daoUtils.selectList(query);
+ }
+
+
+ /**
* Gets the current alerts for a given service.
*
* @return the current alerts for the given service or an empty list if none
@@ -218,6 +237,7 @@ public class AlertsDAO {
query.setParameter("clusterId", clusterId);
query.setParameter("serviceName", serviceName);
+ query.setParameter("inlist", EnumSet.of(Scope.ANY, Scope.SERVICE));
return daoUtils.selectList(query);
}
@@ -236,6 +256,7 @@ public class AlertsDAO {
query.setParameter("clusterId", clusterId);
query.setParameter("hostName", hostName);
+ query.setParameter("inlist", EnumSet.of(Scope.ANY, Scope.HOST));
return daoUtils.selectList(query);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
index 31b1673..6d6073f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
@@ -47,8 +47,9 @@ import org.apache.ambari.server.state.MaintenanceState;
@TableGenerator(name = "alert_current_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "alert_current_id_seq", initialValue = 0, allocationSize = 1)
@NamedQueries({
@NamedQuery(name = "AlertCurrentEntity.findAll", query = "SELECT alert FROM AlertCurrentEntity alert"),
- @NamedQuery(name = "AlertCurrentEntity.findByService", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.serviceName = :serviceName"),
- @NamedQuery(name = "AlertCurrentEntity.findByHost", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.hostName = :hostName"),
+ @NamedQuery(name = "AlertCurrentEntity.findByCluster", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId"),
+ @NamedQuery(name = "AlertCurrentEntity.findByService", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.serviceName = :serviceName AND history.alertDefinition.scope IN :inlist"),
+ @NamedQuery(name = "AlertCurrentEntity.findByHost", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.hostName = :hostName AND history.alertDefinition.scope IN :inlist"),
@NamedQuery(name = "AlertCurrentEntity.findByHostAndName", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.alertDefinition.definitionName = :definitionName AND history.hostName = :hostName"),
@NamedQuery(name = "AlertCurrentEntity.removeByHistoryId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.alertId = :historyId"),
@NamedQuery(name = "AlertCurrentEntity.removeByDefinitionId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertDefinition.definitionId = :definitionId") })
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/resources/key_properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/key_properties.json b/ambari-server/src/main/resources/key_properties.json
index db34920..d127bc5 100644
--- a/ambari-server/src/main/resources/key_properties.json
+++ b/ambari-server/src/main/resources/key_properties.json
@@ -145,6 +145,12 @@
"HostComponent": "HostComponentProcess/component_name",
"HostComponentProcess": "HostComponentProcess/name"
},
+ "Alert": {
+ "Cluster": "Alert/cluster_name",
+ "Service": "Alert/service_name",
+ "Host": "Alert/host_name",
+ "Alert": "Alert/id"
+ },
"AlertDefinition": {
"Cluster": "AlertDefinition/cluster_name",
"AlertDefinition": "AlertDefinition/id"
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index accab44..eeef6ec 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -419,6 +419,22 @@
"HostComponentProcess/name",
"HostComponentProcess/status"
],
+ "Alert": [
+ "Alert/cluster_name",
+ "Alert/id",
+ "Alert/name",
+ "Alert/latest_timestamp",
+ "Alert/maintenance_state",
+ "Alert/original_timestamp",
+ "Alert/instance",
+ "Alert/label",
+ "Alert/state",
+ "Alert/text",
+ "Alert/component_name",
+ "Alert/host_name",
+ "Alert/service_name",
+ "Alert/scope"
+ ],
"AlertDefinition": [
"AlertDefinition/cluster_name",
"AlertDefinition/service_name",
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/DefaultRendererTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/DefaultRendererTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/DefaultRendererTest.java
index eb0f28f..3e0617e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/DefaultRendererTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/DefaultRendererTest.java
@@ -50,6 +50,7 @@ public class DefaultRendererTest {
// schema expectations
expect(schemaFactory.getSchema(Resource.Type.Component)).andReturn(schema).anyTimes();
+ expect(schemaFactory.getSchema(Resource.Type.Alert)).andReturn(schema).anyTimes();
expect(schema.getKeyPropertyId(Resource.Type.Component)).andReturn("ServiceComponentInfo/component_name").anyTimes();
expect(schema.getKeyPropertyId(Resource.Type.Service)).andReturn("ServiceComponentInfo/service_name").anyTimes();
@@ -63,7 +64,7 @@ public class DefaultRendererTest {
TreeNode<Set<String>> propertyTree = renderer.finalizeProperties(queryTree, false);
// no properties should have been added
assertTrue(propertyTree.getObject().isEmpty());
- assertEquals(1, propertyTree.getChildren().size());
+ assertEquals(2, propertyTree.getChildren().size());
TreeNode<Set<String>> componentNode = propertyTree.getChild("Component");
assertEquals(2, componentNode.getObject().size());
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/MinimalRendererTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/MinimalRendererTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/MinimalRendererTest.java
index 16cbb2a..9b03c51 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/MinimalRendererTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/query/render/MinimalRendererTest.java
@@ -57,6 +57,7 @@ public class MinimalRendererTest {
// schema expectations
expect(schemaFactory.getSchema(Resource.Type.Component)).andReturn(schema).anyTimes();
+ expect(schemaFactory.getSchema(Resource.Type.Alert)).andReturn(schema).anyTimes();
expect(schema.getKeyPropertyId(Resource.Type.Component)).andReturn("ServiceComponentInfo/component_name").anyTimes();
replay(schemaFactory, schema);
@@ -69,7 +70,7 @@ public class MinimalRendererTest {
TreeNode<Set<String>> propertyTree = renderer.finalizeProperties(queryTree, false);
// no properties should have been added
assertTrue(propertyTree.getObject().isEmpty());
- assertEquals(1, propertyTree.getChildren().size());
+ assertEquals(2, propertyTree.getChildren().size());
TreeNode<Set<String>> componentNode = propertyTree.getChild("Component");
assertEquals(1, componentNode.getObject().size());
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java
index eabb5ab..7296e8d 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java
@@ -50,7 +50,7 @@ public class ClusterResourceDefinitionTest {
ResourceDefinition resource = new ClusterResourceDefinition();
Set<SubResourceDefinition> subResources = resource.getSubResourceDefinitions();
- assertEquals(9, subResources.size());
+ assertEquals(10, subResources.size());
assertTrue(includesType(subResources, Resource.Type.Service));
assertTrue(includesType(subResources, Resource.Type.Host));
assertTrue(includesType(subResources, Resource.Type.Configuration));
@@ -60,6 +60,7 @@ public class ClusterResourceDefinitionTest {
assertTrue(includesType(subResources, Resource.Type.AlertDefinition));
assertTrue(includesType(subResources, Resource.Type.ServiceConfigVersion));
assertTrue(includesType(subResources, Resource.Type.ClusterPrivilege));
+ assertTrue(includesType(subResources, Resource.Type.Alert));
}
@Test
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java
new file mode 100644
index 0000000..4fd44af
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertResourceProviderTest.java
@@ -0,0 +1,241 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.captureLong;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
+/**
+ * Test the AlertResourceProvider class
+ */
+public class AlertResourceProviderTest {
+
+ private static final Long ALERT_VALUE_ID = Long.valueOf(1000L);
+ private static final String ALERT_VALUE_LABEL = "My Label";
+ private static final Long ALERT_VALUE_TIMESTAMP = Long.valueOf(1L);
+ private static final String ALERT_VALUE_TEXT = "My Text";
+ private static final String ALERT_VALUE_COMPONENT = "component";
+ private static final String ALERT_VALUE_HOSTNAME = "host";
+ private static final String ALERT_VALUE_SERVICE = "service";
+
+ private AlertsDAO m_dao;
+// private Injector m_injector;
+ private AmbariManagementController m_amc;
+
+ @Before
+ @SuppressWarnings("boxing")
+ public void before() throws Exception {
+ Injector m_injector = Guice.createInjector(new MockModule());
+
+ m_amc = m_injector.getInstance(AmbariManagementController.class);
+
+ Cluster cluster = EasyMock.createMock(Cluster.class);
+ Clusters clusters = m_injector.getInstance(Clusters.class);
+ expect(m_amc.getClusters()).andReturn(clusters).atLeastOnce();
+ expect(clusters.getCluster(capture(new Capture<String>()))).andReturn(cluster).atLeastOnce();
+ expect(cluster.getClusterId()).andReturn(Long.valueOf(1L));
+
+ replay(m_amc, clusters, cluster);
+
+ m_dao = m_injector.getInstance(AlertsDAO.class);
+
+ AlertResourceProvider.init(m_injector);
+ }
+
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testGetCluster() throws Exception {
+ expect(m_dao.findCurrentByCluster(
+ captureLong(new Capture<Long>()))).andReturn(getClusterMockEntities()).anyTimes();
+
+ replay(m_dao);
+
+ Request request = PropertyHelper.getReadRequest(
+ AlertResourceProvider.ALERT_ID,
+ AlertResourceProvider.ALERT_NAME,
+ AlertResourceProvider.ALERT_LABEL);
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertResourceProvider.ALERT_CLUSTER_NAME).equals("c1").toPredicate();
+
+ AlertResourceProvider provider = createProvider();
+ Set<Resource> results = provider.getResources(request, predicate);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+ assertEquals("c1", r.getPropertyValue(AlertResourceProvider.ALERT_CLUSTER_NAME));
+
+ verify(m_dao);
+ }
+
+ /**
+ * Test for service
+ */
+ @Test
+ public void testGetService() throws Exception {
+ expect(m_dao.findCurrentByService(captureLong(new Capture<Long>()),
+ capture(new Capture<String>()))).andReturn(getClusterMockEntities()).anyTimes();
+
+ replay(m_dao);
+
+ Request request = PropertyHelper.getReadRequest(
+ AlertResourceProvider.ALERT_ID,
+ AlertResourceProvider.ALERT_NAME,
+ AlertResourceProvider.ALERT_LABEL);
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertResourceProvider.ALERT_CLUSTER_NAME).equals("c1").and()
+ .property(AlertResourceProvider.ALERT_SERVICE).equals(ALERT_VALUE_SERVICE).toPredicate();
+
+ AlertResourceProvider provider = createProvider();
+ Set<Resource> results = provider.getResources(request, predicate);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+ assertEquals("c1", r.getPropertyValue(AlertResourceProvider.ALERT_CLUSTER_NAME));
+ assertEquals(ALERT_VALUE_SERVICE, r.getPropertyValue(AlertResourceProvider.ALERT_SERVICE));
+
+ verify(m_dao);
+ }
+
+ /**
+ * Test for service
+ */
+ @Test
+ public void testGetHost() throws Exception {
+ expect(m_dao.findCurrentByHost(captureLong(new Capture<Long>()),
+ capture(new Capture<String>()))).andReturn(getClusterMockEntities()).anyTimes();
+
+ replay(m_dao);
+
+ Request request = PropertyHelper.getReadRequest(
+ AlertResourceProvider.ALERT_ID,
+ AlertResourceProvider.ALERT_NAME,
+ AlertResourceProvider.ALERT_LABEL);
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertResourceProvider.ALERT_CLUSTER_NAME).equals("c1").and()
+ .property(AlertResourceProvider.ALERT_HOST).equals(ALERT_VALUE_HOSTNAME).toPredicate();
+
+ AlertResourceProvider provider = createProvider();
+ Set<Resource> results = provider.getResources(request, predicate);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+ assertEquals("c1", r.getPropertyValue(AlertResourceProvider.ALERT_CLUSTER_NAME));
+ assertEquals(ALERT_VALUE_HOSTNAME, r.getPropertyValue(AlertResourceProvider.ALERT_HOST));
+
+ verify(m_dao);
+ }
+
+
+
+ private AlertResourceProvider createProvider() {
+ return new AlertResourceProvider(
+ PropertyHelper.getPropertyIds(Resource.Type.Alert),
+ PropertyHelper.getKeyPropertyIds(Resource.Type.Alert),
+ m_amc);
+ }
+
+ /**
+ * @return
+ */
+ private List<AlertCurrentEntity> getClusterMockEntities() throws Exception {
+ AlertCurrentEntity current = new AlertCurrentEntity();
+ current.setAlertId(Long.valueOf(1000L));
+ current.setLatestTimestamp(Long.valueOf(1L));
+ current.setOriginalTimestamp(Long.valueOf(2L));
+
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setAlertId(ALERT_VALUE_ID);
+ history.setAlertInstance(null);
+ history.setAlertLabel(ALERT_VALUE_LABEL);
+ history.setAlertState(AlertState.OK);
+ history.setAlertText(ALERT_VALUE_TEXT);
+ history.setAlertTimestamp(ALERT_VALUE_TIMESTAMP);
+ history.setClusterId(Long.valueOf(1L));
+ history.setComponentName(ALERT_VALUE_COMPONENT);
+ history.setHostName(ALERT_VALUE_HOSTNAME);
+ history.setServiceName(ALERT_VALUE_SERVICE);
+
+ AlertDefinitionEntity definition = new AlertDefinitionEntity();
+
+ history.setAlertDefinition(definition);
+ current.setAlertHistory(history);
+
+ return Arrays.asList(current);
+ }
+
+
+ /**
+ *
+ */
+ private class MockModule implements Module {
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(EntityManager.class).toInstance(EasyMock.createMock(EntityManager.class));
+ binder.bind(AlertsDAO.class).toInstance(EasyMock.createMock(AlertsDAO.class));
+ binder.bind(AmbariManagementController.class).toInstance(createMock(AmbariManagementController.class));
+
+ Clusters clusters = EasyMock.createNiceMock(Clusters.class);
+
+ binder.bind(Clusters.class).toInstance(clusters);
+
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/84c16c5c/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index 4500c1c..7c206a2 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -81,13 +81,13 @@ public class AlertsDAOTest {
definition.setComponentName(null);
definition.setClusterId(clusterId);
definition.setHash(UUID.randomUUID().toString());
- definition.setScheduleInterval(60);
+ definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.SERVICE);
definition.setSource("Source " + i);
definition.setSourceType("SCRIPT");
definitionDao.create(definition);
}
-
+
List<AlertDefinitionEntity> definitions = definitionDao.findAll();
assertNotNull(definitions);
assertEquals(5, definitions.size());
@@ -192,6 +192,54 @@ public class AlertsDAOTest {
assertNotNull(currentAlerts);
assertEquals(0, currentAlerts.size());
}
+
+ /**
+ * Test looking up current by a host name.
+ */
+ @Test
+ public void testFindCurrentByHost() {
+ // create a host
+ AlertDefinitionEntity hostDef = new AlertDefinitionEntity();
+ hostDef.setDefinitionName("Host Alert Definition ");
+ hostDef.setServiceName("HostService");
+ hostDef.setComponentName(null);
+ hostDef.setClusterId(clusterId);
+ hostDef.setHash(UUID.randomUUID().toString());
+ hostDef.setScheduleInterval(Integer.valueOf(60));
+ hostDef.setScope(Scope.HOST);
+ hostDef.setSource("HostService");
+ hostDef.setSourceType("SCRIPT");
+ definitionDao.create(hostDef);
+
+ // history for the definition
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setServiceName(hostDef.getServiceName());
+ history.setClusterId(clusterId);
+ history.setAlertDefinition(hostDef);
+ history.setAlertLabel(hostDef.getDefinitionName());
+ history.setAlertText(hostDef.getDefinitionName());
+ history.setAlertTimestamp(Long.valueOf(1L));
+ history.setHostName("h2");
+ history.setAlertState(AlertState.OK);
+
+ // current for the history
+ AlertCurrentEntity current = new AlertCurrentEntity();
+ current.setOriginalTimestamp(1L);
+ current.setLatestTimestamp(2L);
+ current.setAlertHistory(history);
+ dao.create(current);
+
+
+ List<AlertCurrentEntity> currentAlerts = dao.findCurrentByHost(clusterId, history.getHostName());
+
+ assertNotNull(currentAlerts);
+ assertEquals(1, currentAlerts.size());
+
+ currentAlerts = dao.findCurrentByHost(clusterId, "foo");
+
+ assertNotNull(currentAlerts);
+ assertEquals(0, currentAlerts.size());
+ }
/**
*
[38/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/73243741
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/73243741
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/73243741
Branch: refs/heads/trunk
Commit: 73243741b60846264bf6924387719418f04b7089
Parents: 7db82c9 20f112a
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Sep 26 09:47:59 2014 -0700
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Sep 26 09:47:59 2014 -0700
----------------------------------------------------------------------
.../admin-web/app/views/ambariViews/create.html | 2 +-
.../admin-web/app/views/ambariViews/edit.html | 8 +-
.../resource_management/TestCopyFromLocal.py | 4 +-
.../libraries/providers/copy_from_local.py | 2 +-
.../controller/AmbariManagementController.java | 10 +-
.../AmbariManagementControllerImpl.java | 40 +-
.../server/controller/LdapSyncRequest.java | 94 ++
.../BlueprintConfigurationProcessor.java | 60 ++
.../internal/ControllerResourceProvider.java | 14 +-
.../internal/DefaultProviderModule.java | 2 +-
.../internal/LdapSyncEventResourceProvider.java | 124 ++-
.../apache/ambari/server/orm/DBAccessor.java | 6 +-
.../ambari/server/orm/DBAccessorImpl.java | 5 +-
.../ambari/server/orm/dao/PermissionDAO.java | 2 +-
.../orm/entities/LdapSyncEventEntity.java | 127 ++-
.../server/orm/entities/LdapSyncSpecEntity.java | 24 +-
.../server/orm/helpers/dbms/DbmsHelper.java | 7 +-
.../server/orm/helpers/dbms/DerbyHelper.java | 4 +-
.../orm/helpers/dbms/GenericDbmsHelper.java | 7 +-
.../server/orm/helpers/dbms/MySqlHelper.java | 5 +-
.../server/orm/helpers/dbms/OracleHelper.java | 4 +-
.../server/orm/helpers/dbms/PostgresHelper.java | 4 +-
.../server/state/cluster/ClusterImpl.java | 13 +-
.../server/upgrade/UpgradeCatalog170.java | 17 +-
.../HIVE/package/scripts/hive_service.py | 1 +
.../HIVE/package/scripts/service_check.py | 1 +
.../stacks/HDP/1.3.2/services/stack_advisor.py | 10 +-
.../YARN/configuration/capacity-scheduler.xml | 8 +
.../scripts/shared_initialization.py | 5 +-
.../services/HIVE/configuration/hive-site.xml | 8 +-
.../HIVE/package/scripts/hive_service.py | 4 +-
.../services/HIVE/package/scripts/params.py | 2 +-
.../HIVE/package/scripts/service_check.py | 1 +
.../YARN/configuration/capacity-scheduler.xml | 8 +
.../stacks/HDP/2.0.6/services/stack_advisor.py | 10 +-
.../GLUSTERFS/configuration/core-site.xml | 11 -
.../YARN/configuration/capacity-scheduler.xml | 7 +
.../FALCON/configuration/oozie-site.xml | 9 +
.../stacks/HDP/2.1/services/FLUME/metainfo.xml | 2 +-
.../services/OOZIE/configuration/oozie-site.xml | 11 -
.../YARN/configuration/capacity-scheduler.xml | 7 +
.../stacks/HDP/2.1/services/stack_advisor.py | 39 +-
.../resources/stacks/HDP/2.2.1/metainfo.xml | 23 -
.../stacks/HDP/2.2.1/repos/repoinfo.xml | 67 --
.../stacks/HDP/2.2.1/role_command_order.json | 85 --
.../HDP/2.2.1/services/FALCON/metainfo.xml | 26 -
.../HDP/2.2.1/services/FLUME/metainfo.xml | 26 -
.../HDP/2.2.1/services/HBASE/metainfo.xml | 26 -
.../stacks/HDP/2.2.1/services/HDFS/metainfo.xml | 26 -
.../stacks/HDP/2.2.1/services/HIVE/metainfo.xml | 26 -
.../HDP/2.2.1/services/OOZIE/metainfo.xml | 26 -
.../stacks/HDP/2.2.1/services/PIG/metainfo.xml | 26 -
.../HDP/2.2.1/services/SQOOP/metainfo.xml | 26 -
.../HDP/2.2.1/services/STORM/metainfo.xml | 27 -
.../services/TEZ/configuration/tez-site.xml | 29 -
.../stacks/HDP/2.2.1/services/TEZ/metainfo.xml | 26 -
.../stacks/HDP/2.2.1/services/YARN/metainfo.xml | 39 -
.../HDP/2.2.1/services/ZOOKEEPER/metainfo.xml | 26 -
.../resources/stacks/HDP/2.2/repos/repoinfo.xml | 32 +-
.../stacks/HDP/2.2/services/FALCON/metainfo.xml | 2 +-
.../stacks/HDP/2.2/services/FLUME/metainfo.xml | 4 +-
.../stacks/HDP/2.2/services/HBASE/metainfo.xml | 4 +-
.../services/HDFS/configuration/hadoop-env.xml | 2 +-
.../stacks/HDP/2.2/services/HDFS/metainfo.xml | 6 +-
.../stacks/HDP/2.2/services/HIVE/metainfo.xml | 8 +-
.../stacks/HDP/2.2/services/OOZIE/metainfo.xml | 6 +-
.../stacks/HDP/2.2/services/PIG/metainfo.xml | 4 +-
.../stacks/HDP/2.2/services/SLIDER/metainfo.xml | 16 +
.../stacks/HDP/2.2/services/SQOOP/metainfo.xml | 4 +-
.../stacks/HDP/2.2/services/STORM/metainfo.xml | 4 +-
.../stacks/HDP/2.2/services/TEZ/metainfo.xml | 4 +-
.../stacks/HDP/2.2/services/YARN/metainfo.xml | 10 +-
.../HDP/2.2/services/ZOOKEEPER/metainfo.xml | 4 +-
.../src/main/resources/stacks/stack_advisor.py | 90 +-
.../AmbariManagementControllerImplTest.java | 154 ++-
.../server/controller/LdapSyncRequestTest.java | 84 ++
.../BlueprintConfigurationProcessorTest.java | 9 +
.../LdapSyncEventResourceProviderTest.java | 28 +-
.../ambari/server/orm/DBAccessorImplTest.java | 6 +-
.../orm/entities/LdapSyncEventEntityTest.java | 47 +-
.../orm/entities/LdapSyncSpecEntityTest.java | 40 +-
.../server/state/cluster/ClusterTest.java | 5 +
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 8 +-
.../stacks/2.0.6/HIVE/test_hive_server.py | 8 +-
.../stacks/2.0.6/common/test_stack_advisor.py | 12 +-
.../stacks/2.1/HIVE/test_hive_metastore.py | 8 +-
ambari-web/app/assets/test/tests.js | 1 +
ambari-web/app/config.js | 2 +-
ambari-web/app/controllers/installer.js | 253 ++---
ambari-web/app/controllers/main/host/details.js | 14 +-
ambari-web/app/controllers/wizard.js | 30 +-
.../app/controllers/wizard/step1_controller.js | 12 +-
.../app/controllers/wizard/step7_controller.js | 6 +-
.../app/controllers/wizard/step8_controller.js | 56 +-
ambari-web/app/data/HDP2/site_properties.js | 30 +-
ambari-web/app/data/site_properties.js | 18 -
ambari-web/app/mappers.js | 1 +
ambari-web/app/mappers/stack_mapper.js | 114 +++
ambari-web/app/mappers/stack_service_mapper.js | 2 +
ambari-web/app/messages.js | 6 +-
ambari-web/app/models.js | 3 +
ambari-web/app/models/config_group.js | 15 +-
ambari-web/app/models/operating_system.js | 33 +
ambari-web/app/models/repository.js | 67 ++
ambari-web/app/models/service_config.js | 15 +-
ambari-web/app/models/stack.js | 70 ++
ambari-web/app/models/stack_service.js | 1 +
ambari-web/app/routes/installer.js | 32 +-
ambari-web/app/styles/application.less | 2 +-
ambari-web/app/templates/wizard/step1.hbs | 14 +-
ambari-web/app/utils/components.js | 12 +
ambari-web/app/utils/date.js | 6 +-
.../views/common/configs/config_history_flow.js | 3 +
ambari-web/app/views/common/filter_view.js | 20 +-
ambari-web/app/views/common/table_view.js | 1 +
.../views/main/dashboard/config_history_view.js | 1 +
ambari-web/app/views/main/dashboard/widgets.js | 6 +
.../dashboard/widgets/uptime_text_widget.js | 2 +-
ambari-web/app/views/wizard/step1_view.js | 214 ++---
ambari-web/test/controllers/installer_test.js | 47 +-
.../main/service/info/config_test.js | 61 +-
.../test/controllers/wizard/step7_test.js | 46 +-
.../test/controllers/wizard/step8_test.js | 56 --
ambari-web/test/mappers/stack_mapper_test.js | 285 ++++++
ambari-web/test/models/run_test.js | 10 -
ambari-web/test/stack.js | 265 ++++++
ambari-web/test/utils/date_test.js | 40 -
ambari-web/test/utils/helper_test.js | 4 +-
ambari-web/test/views/wizard/step1_view_test.js | 633 +++++--------
.../createAppWizard/step1_controller.js | 52 +-
.../createAppWizard/step2_controller.js | 31 +-
.../app/controllers/slider_apps_controller.js | 15 +-
.../ui/app/controllers/slider_controller.js | 1 +
.../src/main/resources/ui/app/helpers/ajax.js | 7 +-
.../src/main/resources/ui/app/initialize.js | 7 +-
.../ui/app/mappers/slider_apps_mapper.js | 39 +-
.../resources/ui/app/mixins/run_periodically.js | 37 +-
.../ui/app/routes/create_app_wizard.js | 19 +
.../src/main/resources/ui/app/styles/app.less | 276 ++++++
.../resources/ui/app/styles/application.less | 941 +------------------
.../resources/ui/app/styles/application.styl | 3 -
.../resources/ui/app/styles/apps-table.less | 320 +++++++
.../main/resources/ui/app/styles/common.less | 102 ++
.../resources/ui/app/styles/old-bootstrap.less | 164 ++++
.../main/resources/ui/app/styles/wizard.less | 205 ++++
.../resources/ui/app/templates/application.hbs | 2 +-
.../ui/app/templates/createAppWizard.hbs | 1 +
.../ui/app/templates/createAppWizard/step1.hbs | 152 ++-
.../ui/app/templates/createAppWizard/step2.hbs | 31 +-
.../ui/app/templates/createAppWizard/step3.hbs | 8 +-
.../ui/app/templates/createAppWizard/step4.hbs | 4 +-
.../resources/ui/app/templates/slider_apps.hbs | 2 +-
.../ui/app/templates/unavailable_apps.hbs | 19 +
.../src/main/resources/ui/app/translations.js | 26 +-
.../ui/app/views/common/filter_view.js | 4 +-
.../ui/app/views/createAppWizard/step1_view.js | 47 +-
.../ui/app/views/createAppWizard/step2_view.js | 15 +-
.../ui/app/views/create_app_wizard_view.js | 10 +
...test-patch-find-new-patch-available-jiras.sh | 0
dev-support/test-patch.sh | 0
160 files changed, 3874 insertions(+), 3043 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/73243741/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/73243741/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
[11/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/03a5be1e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/03a5be1e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/03a5be1e
Branch: refs/heads/trunk
Commit: 03a5be1e193d6ade127fe38cd56d63688b9d5598
Parents: 8697c91 ca2106f
Author: Nate Cole <nc...@hortonworks.com>
Authored: Wed Sep 3 07:38:07 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Wed Sep 3 07:38:07 2014 -0400
----------------------------------------------------------------------
.../controllers/ambariViews/ViewsEditCtrl.js | 1 +
.../clusters/ClustersManageAccessCtrl.js | 1 +
.../controllers/groups/GroupsListCtrl.js | 2 +-
.../scripts/controllers/users/UsersListCtrl.js | 2 +-
.../scripts/controllers/users/UsersShowCtrl.js | 2 +-
.../admin-web/app/views/ambariViews/create.html | 2 +-
.../admin-web/app/views/ambariViews/edit.html | 4 +-
.../app/views/clusters/manageAccess.html | 4 +-
.../ui/admin-web/app/views/groups/list.html | 9 ----
.../ui/admin-web/app/views/users/show.html | 2 +-
.../main/resources/ui/admin-web/package.json | 2 +-
.../stacks/HDP/2.0.6/services/YARN/metainfo.xml | 2 +-
.../stacks/HDP/2.1/services/YARN/metainfo.xml | 1 +
ambari-web/app/app.js | 15 +++---
.../app/controllers/global/update_controller.js | 3 +-
.../main/admin/serviceAccounts_controller.js | 17 ++++--
.../controllers/main/service/info/configs.js | 7 +--
ambari-web/app/data/secure_properties.js | 1 +
ambari-web/app/models/service_config.js | 9 +++-
ambari-web/app/views/main/service/item.js | 2 +-
ambari-web/test/app_test.js | 55 --------------------
.../admin/serviceAccounts_controller_test.js | 24 ---------
22 files changed, 49 insertions(+), 118 deletions(-)
----------------------------------------------------------------------
[47/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/445a53cf
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/445a53cf
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/445a53cf
Branch: refs/heads/trunk
Commit: 445a53cf5bcbba89ff04131d9802e205bfc3ab42
Parents: 3e54f95 e069b30
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Fri Oct 3 23:15:57 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Fri Oct 3 23:15:57 2014 -0400
----------------------------------------------------------------------
ambari-admin/pom.xml | 19 +-
.../main/resources/ui/admin-web/app/index.html | 4 +-
.../resources/ui/admin-web/app/scripts/app.js | 1 -
.../app/scripts/controllers/NavbarCtrl.js | 8 +-
.../ambariViews/CreateViewInstanceCtrl.js | 8 +-
.../controllers/ambariViews/ViewsEditCtrl.js | 22 +-
.../controllers/ambariViews/ViewsListCtrl.js | 5 +-
.../clusters/ClustersManageAccessCtrl.js | 6 +-
.../controllers/groups/GroupsCreateCtrl.js | 7 +-
.../controllers/groups/GroupsEditCtrl.js | 34 +-
.../app/scripts/controllers/mainCtrl.js | 17 +-
.../controllers/users/UsersCreateCtrl.js | 7 +-
.../scripts/controllers/users/UsersShowCtrl.js | 49 +-
.../ui/admin-web/app/scripts/services/Alert.js | 106 ++
.../ui/admin-web/app/scripts/services/Auth.js | 9 +-
.../ui/admin-web/app/scripts/services/Group.js | 2 +-
.../app/scripts/services/PermissionLoader.js | 8 +-
.../ui/admin-web/app/scripts/services/User.js | 2 +-
.../admin-web/app/scripts/services/uiAlert.js | 115 --
.../resources/ui/admin-web/app/styles/main.css | 96 ++
.../admin-web/app/views/ambariViews/edit.html | 2 +-
.../src/main/resources/ui/admin-web/bower.json | 15 +-
.../main/resources/ui/admin-web/package.json | 19 +
.../resources/ui/admin-web/test/e2e/signout.js | 43 +
.../resources/ui/admin-web/test/karma.conf.js | 58 +
.../ui/admin-web/test/protractor-conf.js | 51 +
.../resources/ui/admin-web/test/spec/test.js | 30 -
.../test/unit/controllers/mainCtrl_test.js | 54 +
.../resource_management/TestFileSystem.py | 117 ++
.../python/resource_management/core/logger.py | 18 +-
.../resource_management/core/providers/mount.py | 86 +-
.../libraries/functions/dfs_datanode_helper.py | 149 +++
.../libraries/functions/file_system.py | 72 ++
ambari-server/pom.xml | 9 +
.../internal/AbstractProviderModule.java | 24 +-
.../BlueprintConfigurationProcessor.java | 4 +
.../controller/internal/ResourceImpl.java | 19 +-
.../internal/StackDefinedPropertyProvider.java | 227 ++--
.../server/controller/jmx/JMXHostProvider.java | 13 -
.../controller/jmx/JMXPropertyProvider.java | 274 +----
.../controller/metrics/MetricsHostProvider.java | 38 +
.../controller/metrics/MetricsProvider.java | 302 +++++
.../metrics/RestMetricsPropertyProvider.java | 448 ++++++++
.../apache/ambari/server/view/ViewRegistry.java | 2 +-
.../src/main/package/deb/control/preinst | 8 +
.../src/main/package/rpm/preinstall.sh | 8 +
ambari-server/src/main/python/ambari-server.py | 6 +-
.../YARN/configuration/capacity-scheduler.xml | 2 +-
.../0.8/services/YARN/package/scripts/yarn.py | 9 +-
.../services/HDFS/configuration/hadoop-env.xml | 6 +
.../HDFS/package/scripts/hdfs_datanode.py | 38 +-
.../services/HDFS/package/scripts/params.py | 2 +
.../configuration/capacity-scheduler.xml | 2 +-
.../YARN/configuration/capacity-scheduler.xml | 2 +-
.../services/YARN/package/scripts/yarn.py | 19 +-
.../HBASE/package/scripts/hbase_decommission.py | 62 +-
.../services/HBASE/package/scripts/params.py | 2 +-
.../services/HDFS/configuration/hadoop-env.xml | 7 +-
.../HDFS/package/scripts/hdfs_datanode.py | 27 +-
.../services/HDFS/package/scripts/params.py | 12 +-
.../services/HDFS/package/scripts/utils.py | 91 +-
.../2.0.6/services/HIVE/package/scripts/hive.py | 30 +-
.../YARN/configuration/capacity-scheduler.xml | 2 +-
.../2.0.6/services/YARN/package/scripts/yarn.py | 9 +-
.../templates/zookeeper_client_jaas.conf.j2 | 1 -
.../stacks/HDP/2.0.6/services/stack_advisor.py | 27 +-
.../YARN/configuration/capacity-scheduler.xml | 2 +-
.../services/YARN/package/scripts/yarn.py | 19 +-
.../FALCON/configuration/falcon-env.xml | 2 +-
.../services/FALCON/package/scripts/falcon.py | 6 +-
.../package/templates/startup.properties.j2 | 89 --
.../stacks/HDP/2.1/services/STORM/metrics.json | 55 +-
.../YARN/configuration/capacity-scheduler.xml | 2 +-
.../stacks/HDP/2.1/services/stack_advisor.py | 4 +-
.../configuration/falcon-startup.properties.xml | 84 ++
.../services/HDFS/configuration/hadoop-env.xml | 192 ++++
.../services/HIVE/configuration/hive-site.xml | 29 +
.../stacks/HDP/2.2/services/SLIDER/metainfo.xml | 2 +-
.../stacks/HDP/2.2/services/STORM/metrics.json | 1079 ++++++++++++++++++
.../stacks/HDP/2.2/services/stack_advisor.py | 151 +++
.../api/util/StackExtensionHelperTest.java | 2 +-
.../BlueprintConfigurationProcessorTest.java | 6 +
.../StackDefinedPropertyProviderTest.java | 357 +++---
.../controller/jmx/JMXPropertyProviderTest.java | 513 ---------
.../metrics/JMXPropertyProviderTest.java | 522 +++++++++
.../src/test/python/TestAmbariServer.py | 123 +-
.../python/stacks/1.3.2/configs/default.json | 3 +-
.../python/stacks/1.3.2/configs/secured.json | 3 +-
.../stacks/2.0.6/HBASE/test_hbase_master.py | 6 +-
.../python/stacks/2.0.6/HDFS/test_datanode.py | 136 +++
.../stacks/2.0.6/HIVE/test_hive_client.py | 16 +-
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 52 +-
.../stacks/2.0.6/HIVE/test_hive_server.py | 52 +-
.../stacks/2.0.6/YARN/test_historyserver.py | 30 -
.../stacks/2.0.6/YARN/test_mapreduce2_client.py | 30 -
.../stacks/2.0.6/YARN/test_nodemanager.py | 60 +-
.../stacks/2.0.6/YARN/test_resourcemanager.py | 30 -
.../stacks/2.0.6/YARN/test_yarn_client.py | 50 -
.../python/stacks/2.0.6/configs/default.json | 3 +-
.../python/stacks/2.0.6/configs/secured.json | 3 +-
.../stacks/2.1/FALCON/test_falcon_server.py | 2 +
.../stacks/2.1/HIVE/test_hive_metastore.py | 52 +-
.../stacks/2.1/YARN/test_apptimelineserver.py | 20 -
.../stacks/2.2/common/test_stack_advisor.py | 311 +++++
.../src/test/python/stacks/utils/RMFTestCase.py | 19 +-
.../YARN/configuration/capacity-scheduler.xml | 2 +-
.../HDP/2.1.1/services/STORM/metrics.json | 209 ++--
ambari-web/app/assets/test/tests.js | 1 +
ambari-web/app/controllers/installer.js | 7 +-
.../app/controllers/main/admin/repositories.js | 7 +-
.../main/dashboard/config_history_controller.js | 2 +-
ambari-web/app/controllers/main/host.js | 4 +-
ambari-web/app/controllers/main/host/details.js | 281 +++--
ambari-web/app/controllers/main/service/item.js | 3 +-
.../app/controllers/main/views_controller.js | 3 +
ambari-web/app/data/HDP2/site_properties.js | 17 +-
ambari-web/app/data/site_properties.js | 17 +-
.../mappers/service_config_version_mapper.js | 23 +
ambari-web/app/messages.js | 2 +-
ambari-web/app/models/service_config_version.js | 4 +-
ambari-web/app/router.js | 15 +-
ambari-web/app/routes/installer.js | 2 +-
ambari-web/app/styles/application.less | 2 +-
ambari-web/app/templates/main/host/configs.hbs | 22 +-
ambari-web/app/utils/config.js | 6 +-
ambari-web/app/views/main/host/configs.js | 6 +-
.../app/views/main/host/configs_service_menu.js | 37 +-
ambari-web/package.json | 47 +-
ambari-web/pom.xml | 28 +-
.../controllers/main/admin/repositories_test.js | 17 +-
.../dashboard/config_history_controller_test.js | 8 +-
.../test/controllers/main/host/details_test.js | 51 +
.../controllers/main/views_controller_test.js | 48 +
.../test/controllers/wizard/step9_test.js | 26 +-
ambari-web/test/views/application_test.js | 2 +-
.../view/filebrowser/FileOperationService.java | 37 +
.../apache/ambari/view/filebrowser/HdfsApi.java | 21 +
.../files/src/main/resources/ui/app/adapter.js | 59 +-
.../resources/ui/app/components/breadCrumbs.js | 47 +
.../resources/ui/app/components/bsPopover.js | 21 +
.../resources/ui/app/components/bulkCheckbox.js | 40 +
.../resources/ui/app/components/chmodInput.js | 79 ++
.../ui/app/components/confirmDelete.js | 59 +
.../resources/ui/app/components/contextMenu.js | 36 +-
.../resources/ui/app/components/mkdirInput.js | 45 +
.../ui/app/components/popoverDelete.js | 50 +
.../resources/ui/app/components/renameInput.js | 7 +-
.../resources/ui/app/components/sortArrow.js | 39 +
.../ui/app/components/toggleContext.js | 56 +
.../resources/ui/app/components/uploader.js | 13 +-
.../main/resources/ui/app/controllers/error.js | 5 +-
.../main/resources/ui/app/controllers/file.js | 104 +-
.../main/resources/ui/app/controllers/files.js | 103 +-
.../resources/ui/app/controllers/filesAlert.js | 10 +
.../src/main/resources/ui/app/initialize.js | 24 +-
.../src/main/resources/ui/app/routes/file.js | 3 +
.../resources/ui/app/styles/application.less | 67 +-
.../ui/app/templates/components/chmodInput.hbs | 100 ++
.../ui/app/templates/components/contextMenu.hbs | 43 +
.../ui/app/templates/components/deleteBulk.hbs | 46 +
.../app/templates/components/deletePopover.hbs | 38 +
.../ui/app/templates/components/mkdirInput.hbs | 37 +
.../ui/app/templates/components/renameInput.hbs | 38 +
.../ui/app/templates/components/uploader.hbs | 35 +
.../main/resources/ui/app/templates/files.hbs | 229 ++--
.../ui/app/templates/util/contextMenu.hbs | 56 -
.../ui/app/templates/util/deleteBulk.hbs | 38 -
.../ui/app/templates/util/deletePopover.hbs | 38 -
.../resources/ui/app/templates/util/fileRow.hbs | 84 ++
.../ui/app/templates/util/renameInput.hbs | 38 -
.../ui/app/templates/util/uploader.hbs | 35 -
.../src/main/resources/ui/app/views/file.js | 182 +--
.../main/resources/ui/app/views/filesAlert.js | 23 +
.../files/src/main/resources/ui/bower.json | 10 +-
.../main/resources/ui/vendor/js/bsPopover.js | 190 +++
contrib/views/files/src/main/resources/view.xml | 2 +-
.../resources/ui/app/scripts/helpers/ajax.js | 6 +
.../resources/ui/app/scripts/helpers/jobs.js | 3 +
.../view/slider/SliderAppsViewController.java | 19 +-
.../slider/SliderAppsViewControllerImpl.java | 245 +++-
.../apache/ambari/view/slider/ViewStatus.java | 40 +
.../slider/rest/client/AmbariHttpClient.java | 72 +-
.../data/resource/slider-properties-2.json | 8 +
.../src/main/resources/ui/app/assets/index.html | 9 -
.../app/controllers/application_controller.js | 27 +
.../createAppWizard/step3_controller.js | 9 +-
.../ui/app/controllers/slider_app_controller.js | 7 +
.../app/controllers/slider_apps_controller.js | 2 +-
.../ui/app/controllers/slider_controller.js | 50 +-
.../src/main/resources/ui/app/helpers/ajax.js | 20 +
.../src/main/resources/ui/app/helpers/helper.js | 10 +-
.../src/main/resources/ui/app/initialize.js | 11 +-
.../ui/app/mappers/slider_apps_mapper.js | 3 +
.../main/resources/ui/app/mixins/with_panels.js | 5 +-
.../main/resources/ui/app/models/slider_app.js | 3 +
.../resources/ui/app/models/slider_config.js | 14 +-
.../src/main/resources/ui/app/routes/main.js | 19 +-
.../main/resources/ui/app/styles/common.less | 11 +
.../main/resources/ui/app/styles/wizard.less | 19 +-
.../resources/ui/app/templates/application.hbs | 27 +-
.../ui/app/templates/createAppWizard/step1.hbs | 60 +-
.../ui/app/templates/slider_app/configs.hbs | 32 +-
.../ui/app/templates/slider_app/summary.hbs | 7 -
.../src/main/resources/ui/app/translations.js | 25 +-
.../resources/ui/app/views/application_view.js | 7 +-
.../ui/app/views/createAppWizard/step1_view.js | 3 +-
.../ui/app/views/create_app_wizard_view.js | 2 +
.../ui/app/views/slider_app/configs_view.js | 7 +-
.../ui/app/views/slider_app/summary_view.js | 7 -
.../ui/test/integration/pages/index_test.js | 9 +-
.../integration/pages/slider_errors_test.js | 46 +
.../processes/create_new_app_test.js | 199 ++++
.../views/slider/src/main/resources/view.xml | 117 +-
docs/pom.xml | 16 +-
214 files changed, 8147 insertions(+), 3203 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/445a53cf/ambari-server/pom.xml
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/445a53cf/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
index f50955c,b5164fe..da6c886
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
@@@ -41,25 -29,20 +41,26 @@@ import org.apache.ambari.server.control
import org.apache.ambari.server.controller.ganglia.GangliaComponentPropertyProvider;
import org.apache.ambari.server.controller.ganglia.GangliaHostComponentPropertyProvider;
import org.apache.ambari.server.controller.ganglia.GangliaHostPropertyProvider;
-import org.apache.ambari.server.controller.ganglia.GangliaReportPropertyProvider;
import org.apache.ambari.server.controller.ganglia.GangliaHostProvider;
+import org.apache.ambari.server.controller.ganglia.GangliaReportPropertyProvider;
import org.apache.ambari.server.controller.jmx.JMXHostProvider;
import org.apache.ambari.server.controller.jmx.JMXPropertyProvider;
+ import org.apache.ambari.server.controller.metrics.MetricsHostProvider;
import org.apache.ambari.server.controller.nagios.NagiosPropertyProvider;
-import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.ProviderModule;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.controller.AmbariManagementController;
-
-import com.google.inject.Inject;
-
import org.apache.ambari.server.controller.utilities.StreamProvider;
+import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.DesiredConfig;
import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.Service;
http://git-wip-us.apache.org/repos/asf/ambari/blob/445a53cf/ambari-web/app/controllers/main/host.js
----------------------------------------------------------------------
[07/50] [abbrv] git commit: AMBARI-7094 - Alerts: Implement Property
Updates for Alert Targets (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7094 - Alerts: Implement Property Updates for Alert Targets (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2f5c78e7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2f5c78e7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2f5c78e7
Branch: refs/heads/trunk
Commit: 2f5c78e7f90f575ab2c469da1095eaa5d252d872
Parents: 52d1af7
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Sun Aug 31 08:25:14 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Sun Aug 31 08:25:14 2014 -0400
----------------------------------------------------------------------
.../resources/AlertDefResourceDefinition.java | 3 -
.../server/api/services/AlertTargetService.java | 10 ++
.../services/parsers/JsonRequestBodyParser.java | 14 +-
.../internal/AlertTargetResourceProvider.java | 134 ++++++++++++++++--
.../ambari/server/state/ConfigFactory.java | 2 -
.../ambari/server/state/alert/AlertTarget.java | 10 +-
.../AlertTargetResourceProviderTest.java | 140 +++++++++++++------
7 files changed, 249 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5c78e7/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java
index 1a63097..66e5a83 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java
@@ -21,8 +21,6 @@ import org.apache.ambari.server.controller.spi.Resource;
/**
* Resource Definition for AlertDefinition types.
- * @author ncole
- *
*/
public class AlertDefResourceDefinition extends BaseResourceDefinition {
@@ -32,7 +30,6 @@ public class AlertDefResourceDefinition extends BaseResourceDefinition {
@Override
public String getPluralName() {
- // TODO Auto-generated method stub
return "alert_definitions";
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5c78e7/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java
index 86281b3..2a2ecdf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertTargetService.java
@@ -23,6 +23,7 @@ import java.util.Map;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@@ -67,6 +68,15 @@ public class AlertTargetService extends BaseService {
createAlertTargetResource(null));
}
+ @PUT
+ @Produces("text/plain")
+ @Path("{targetId}")
+ public Response updateGroup(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui, @PathParam("targetId") Long targetId) {
+ return handleRequest(headers, body, ui, Request.Type.PUT,
+ createAlertTargetResource(targetId));
+ }
+
@DELETE
@Produces("text/plain")
@Path("{targetId}")
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5c78e7/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
index 59dd1af..bbe7647 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/parsers/JsonRequestBodyParser.java
@@ -18,6 +18,15 @@
package org.apache.ambari.server.api.services.parsers;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import org.apache.ambari.server.api.services.NamedPropertySet;
import org.apache.ambari.server.api.services.RequestBody;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
@@ -26,9 +35,6 @@ import org.codehaus.jackson.map.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
-import java.util.*;
-
/**
* JSON parser which parses a JSON string into a map of properties and values.
*/
@@ -120,7 +126,7 @@ public class JsonRequestBodyParser implements RequestBodyParser {
if (next.isValueNode()) {
// All remain nodes will be also primitives
- primitives.add(next.getTextValue());
+ primitives.add(next.asText());
} else {
NamedPropertySet arrayPropertySet = new NamedPropertySet(name,
new HashMap<String, Object>());
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5c78e7/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
index e00f60f..f2b82d6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
@@ -17,11 +17,13 @@
*/
package org.apache.ambari.server.controller.internal;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
@@ -36,11 +38,14 @@ import org.apache.ambari.server.controller.spi.Resource.Type;
import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
import org.apache.ambari.server.controller.spi.SystemException;
import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.alert.AlertTarget;
import org.apache.commons.lang.StringUtils;
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
import com.google.inject.Inject;
import com.google.inject.Injector;
@@ -70,6 +75,11 @@ public class AlertTargetResourceProvider extends
private static AlertDispatchDAO s_dao;
/**
+ * Used for serializationa and deserialization of some fields.
+ */
+ private static final Gson s_gson = new Gson();
+
+ /**
* Initializes the injectable members of this class with the specified
* injector.
*
@@ -143,11 +153,21 @@ public class AlertTargetResourceProvider extends
}
@Override
- public RequestStatus updateResources(Request request, Predicate predicate)
+ public RequestStatus updateResources(final Request request,
+ Predicate predicate)
throws SystemException, UnsupportedPropertyException,
NoSuchResourceException, NoSuchParentResourceException {
- throw new UnsupportedOperationException();
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ updateAlertTargets(request.getProperties());
+ return null;
+ }
+ });
+
+ notifyUpdate(Resource.Type.AlertTarget, request, predicate);
+ return getRequestStatus(null);
}
@Override
@@ -203,7 +223,6 @@ public class AlertTargetResourceProvider extends
String name = (String) requestMap.get(ALERT_TARGET_NAME);
String description = (String) requestMap.get(ALERT_TARGET_DESCRIPTION);
String notificationType = (String) requestMap.get(ALERT_TARGET_NOTIFICATION_TYPE);
- String properties = (String) requestMap.get(ALERT_TARGET_PROPERTIES);
if (StringUtils.isEmpty(name)) {
throw new IllegalArgumentException(
@@ -215,6 +234,12 @@ public class AlertTargetResourceProvider extends
"The type of the alert target is required.");
}
+ String properties = extractProperties(requestMap);
+ if (StringUtils.isEmpty(properties)) {
+ throw new IllegalArgumentException(
+ "Alert targets must be created with their connection properties");
+ }
+
entity.setDescription(description);
entity.setNotificationType(notificationType);
entity.setProperties(properties);
@@ -227,10 +252,65 @@ public class AlertTargetResourceProvider extends
}
/**
+ * Updates existing {@link AlertTargetEntity}s with the specified properties.
+ *
+ * @param requestMaps
+ * a set of property maps, one map for each entity.
+ * @throws AmbariException
+ * if the entity could not be found.
+ */
+ private void updateAlertTargets(Set<Map<String, Object>> requestMaps)
+ throws AmbariException {
+
+ for (Map<String, Object> requestMap : requestMaps) {
+ String stringId = (String) requestMap.get(ALERT_TARGET_ID);
+
+ if (StringUtils.isEmpty(stringId)) {
+ throw new IllegalArgumentException(
+ "The ID of the alert target is required when updating an existing target");
+ }
+
+ long id = Long.parseLong(stringId);
+ AlertTargetEntity entity = s_dao.findTargetById(id);
+
+ if (null == entity) {
+ String message = MessageFormat.format(
+ "The alert target with ID {0} could not be found", id);
+ throw new AmbariException(message);
+ }
+
+ String name = (String) requestMap.get(ALERT_TARGET_NAME);
+ String description = (String) requestMap.get(ALERT_TARGET_DESCRIPTION);
+ String notificationType = (String) requestMap.get(ALERT_TARGET_NOTIFICATION_TYPE);
+
+ if (!StringUtils.isBlank(name)) {
+ entity.setTargetName(name);
+ }
+
+ if (null != description) {
+ entity.setDescription(description);
+ }
+
+ if (!StringUtils.isBlank(notificationType)) {
+ entity.setNotificationType(notificationType);
+ }
+
+ String properties = extractProperties(requestMap);
+ if (!StringUtils.isEmpty(properties)) {
+ entity.setProperties(properties);
+ }
+
+ s_dao.merge(entity);
+ }
+ }
+
+ /**
* Convert the given {@link AlertTargetEntity} to a {@link Resource}.
*
* @param isCollection
- * {@code true} if the resource is part of a collection.
+ * {@code true} if the resource is part of a collection. Some
+ * properties are not returned when a collection of targets is
+ * requested.
* @param entity
* the entity to convert.
* @param requestedIds
@@ -244,15 +324,49 @@ public class AlertTargetResourceProvider extends
resource.setProperty(ALERT_TARGET_ID, entity.getTargetId());
resource.setProperty(ALERT_TARGET_NAME, entity.getTargetName());
- setResourceProperty(resource, ALERT_TARGET_DESCRIPTION,
- entity.getDescription(), requestedIds);
+ resource.setProperty(ALERT_TARGET_DESCRIPTION, entity.getDescription());
+ resource.setProperty(ALERT_TARGET_NOTIFICATION_TYPE,
+ entity.getNotificationType());
- setResourceProperty(resource, ALERT_TARGET_NOTIFICATION_TYPE,
- entity.getNotificationType(), requestedIds);
+ if (!isCollection) {
+ String properties = entity.getProperties();
+ Map<String, String> map = s_gson.<Map<String, String>> fromJson(
+ properties,
+ Map.class);
- setResourceProperty(resource, ALERT_TARGET_PROPERTIES,
- entity.getProperties(), requestedIds);
+ resource.setProperty(ALERT_TARGET_PROPERTIES, map);
+ }
return resource;
}
+
+ /**
+ * Looks through the flat list of propery keys in the supplied map and builds
+ * a JSON string of key:value pairs for the {@link #ALERT_TARGET_PROPERTIES}
+ * key.
+ *
+ * @param requestMap
+ * the map of flattened properties (not {@code null}).
+ * @return the JSON representing the key/value pairs of all properties, or
+ * {@code null} if none.
+ */
+ private String extractProperties( Map<String, Object> requestMap ){
+ JsonObject jsonObject = new JsonObject();
+ for (Entry<String, Object> entry : requestMap.entrySet()) {
+ String key = entry.getKey();
+ String propCat = PropertyHelper.getPropertyCategory(key);
+
+ if (propCat.equals(ALERT_TARGET_PROPERTIES)) {
+ String propKey = PropertyHelper.getPropertyName(key);
+ jsonObject.addProperty(propKey, entry.getValue().toString());
+ }
+ }
+
+ String properties = null;
+ if (jsonObject.entrySet().size() > 0) {
+ properties = jsonObject.toString();
+ }
+
+ return properties;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5c78e7/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigFactory.java
index 28dfc1c..eaf68aa 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigFactory.java
@@ -25,8 +25,6 @@ import com.google.inject.assistedinject.Assisted;
/**
* Factory for creating configuration objects using {@link Assisted} constructor parameters
- *
- * @author ncole
*/
public interface ConfigFactory {
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5c78e7/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
index f495787..2d10dda 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertTarget.java
@@ -17,6 +17,8 @@
*/
package org.apache.ambari.server.state.alert;
+import java.util.Map;
+
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.codehaus.jackson.annotate.JsonProperty;
@@ -31,7 +33,7 @@ public class AlertTarget {
private String m_name;
private String m_description;
private String m_notificationType;
- private String m_properties;
+ private Map<String, String> m_properties;
/**
* @return the id
@@ -101,7 +103,7 @@ public class AlertTarget {
* @return the properties
*/
@JsonProperty("properties")
- public String getProperties() {
+ public Map<String, String> getProperties() {
return m_properties;
}
@@ -109,7 +111,7 @@ public class AlertTarget {
* @param properties
* the properties to set
*/
- public void setProperties(String properties) {
+ public void setProperties(Map<String, String> properties) {
m_properties = properties;
}
@@ -123,8 +125,6 @@ public class AlertTarget {
target.setDescription(entity.getDescription());
target.setName(entity.getTargetName());
target.setNotificationType(entity.getNotificationType());
- target.setProperties(entity.getProperties());
-
return target;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2f5c78e7/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
index 6ca2035..1c964a3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
@@ -17,6 +17,8 @@
*/
package org.apache.ambari.server.controller.internal;
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createStrictMock;
@@ -25,7 +27,6 @@ import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.resetToStrict;
import static org.easymock.EasyMock.verify;
-import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collections;
@@ -68,13 +69,17 @@ public class AlertTargetResourceProviderTest {
private static final String ALERT_TARGET_NAME = "The Administrators";
private static final String ALERT_TARGET_DESC = "Admins and Others";
private static final String ALERT_TARGET_TYPE = TargetType.EMAIL.name();
+ private static final String ALERT_TARGET_PROPS = "{\"foo\":\"bar\",\"foobar\":\"baz\"}";
+ private static final String ALERT_TARGET_PROPS2 = "{\"foobar\":\"baz\"}";
private AlertDispatchDAO m_dao;
private Injector m_injector;
+ private AmbariManagementController m_amc;
@Before
public void before() {
m_dao = createStrictMock(AlertDispatchDAO.class);
+ m_amc = createMock(AmbariManagementController.class);
m_injector = Guice.createInjector(Modules.override(
new InMemoryDefaultTestModule()).with(new MockModule()));
@@ -96,8 +101,7 @@ public class AlertTargetResourceProviderTest {
expect(m_dao.findAllTargets()).andReturn(getMockEntities());
replay(m_dao);
- AmbariManagementController amc = createMock(AmbariManagementController.class);
- AlertTargetResourceProvider provider = createProvider(amc);
+ AlertTargetResourceProvider provider = createProvider(m_amc);
Set<Resource> results = provider.getResources(request, null);
assertEquals(1, results.size());
@@ -113,6 +117,7 @@ public class AlertTargetResourceProviderTest {
* @throws Exception
*/
@Test
+ @SuppressWarnings("unchecked")
public void testGetSingleResource() throws Exception {
Request request = PropertyHelper.getReadRequest(
AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
@@ -120,8 +125,6 @@ public class AlertTargetResourceProviderTest {
AlertTargetResourceProvider.ALERT_TARGET_NAME,
AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE);
- AmbariManagementController amc = createMock(AmbariManagementController.class);
-
Predicate predicate = new PredicateBuilder().property(
AlertTargetResourceProvider.ALERT_TARGET_ID).equals(
ALERT_TARGET_ID.toString()).toPredicate();
@@ -129,9 +132,9 @@ public class AlertTargetResourceProviderTest {
expect(m_dao.findTargetById(ALERT_TARGET_ID.longValue())).andReturn(
getMockEntities().get(0));
- replay(amc, m_dao);
+ replay(m_amc, m_dao);
- AlertTargetResourceProvider provider = createProvider(amc);
+ AlertTargetResourceProvider provider = createProvider(m_amc);
Set<Resource> results = provider.getResources(request, predicate);
assertEquals(1, results.size());
@@ -143,7 +146,11 @@ public class AlertTargetResourceProviderTest {
Assert.assertEquals(ALERT_TARGET_NAME,
r.getPropertyValue(AlertTargetResourceProvider.ALERT_TARGET_NAME));
- verify(amc, m_dao);
+ Map<String, String> properties = (Map<String, String>) r.getPropertyValue(AlertTargetResourceProvider.ALERT_TARGET_PROPERTIES);
+ assertEquals( "bar", properties.get("foo") );
+ assertEquals( "baz", properties.get("foobar") );
+
+ verify(m_amc, m_dao);
}
/**
@@ -151,25 +158,15 @@ public class AlertTargetResourceProviderTest {
*/
@Test
public void testCreateResources() throws Exception {
- AmbariManagementController amc = createMock(AmbariManagementController.class);
Capture<List<AlertTargetEntity>> listCapture = new Capture<List<AlertTargetEntity>>();
m_dao.createTargets(capture(listCapture));
expectLastCall();
- replay(amc, m_dao);
-
- AlertTargetResourceProvider provider = createProvider(amc);
- Map<String, Object> requestProps = new HashMap<String, Object>();
- requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_NAME,
- ALERT_TARGET_NAME);
+ replay(m_amc, m_dao);
- requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
- ALERT_TARGET_DESC);
-
- requestProps.put(
- AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE,
- ALERT_TARGET_TYPE);
+ AlertTargetResourceProvider provider = createProvider(m_amc);
+ Map<String, Object> requestProps = getCreationProperties();
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
provider.createResources(request);
@@ -178,18 +175,63 @@ public class AlertTargetResourceProviderTest {
AlertTargetEntity entity = listCapture.getValue().get(0);
Assert.assertNotNull(entity);
- Assert.assertEquals(ALERT_TARGET_NAME, entity.getTargetName());
- Assert.assertEquals(ALERT_TARGET_DESC, entity.getDescription());
- Assert.assertEquals(ALERT_TARGET_TYPE, entity.getNotificationType());
+ assertEquals(ALERT_TARGET_NAME, entity.getTargetName());
+ assertEquals(ALERT_TARGET_DESC, entity.getDescription());
+ assertEquals(ALERT_TARGET_TYPE, entity.getNotificationType());
+ assertEquals(ALERT_TARGET_PROPS, entity.getProperties());
- verify(amc, m_dao);
+ verify(m_amc, m_dao);
}
/**
* @throws Exception
*/
@Test
+ @SuppressWarnings("unchecked")
public void testUpdateResources() throws Exception {
+ Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
+
+ m_dao.createTargets(EasyMock.anyObject(List.class));
+ expectLastCall().times(1);
+
+ AlertTargetEntity target = new AlertTargetEntity();
+ expect(m_dao.findTargetById(ALERT_TARGET_ID)).andReturn(target).times(1);
+
+ expect(m_dao.merge(capture(entityCapture))).andReturn(target).once();
+
+ replay(m_amc, m_dao);
+
+ AlertTargetResourceProvider provider = createProvider(m_amc);
+ Map<String, Object> requestProps = getCreationProperties();
+ Request request = PropertyHelper.getCreateRequest(
+ Collections.singleton(requestProps), null);
+ provider.createResources(request);
+
+ // create new properties, and include the ID since we're not going through
+ // a service layer which would add it for us automatically
+ requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_ID,
+ ALERT_TARGET_ID.toString());
+
+ String newName = ALERT_TARGET_NAME + " Foo";
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_NAME, newName);
+
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_PROPERTIES
+ + "/foobar", "baz");
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertTargetResourceProvider.ALERT_TARGET_ID).equals(
+ ALERT_TARGET_ID.toString()).toPredicate();
+
+ request = PropertyHelper.getUpdateRequest(requestProps, null);
+ provider.updateResources(request, predicate);
+
+ assertTrue(entityCapture.hasCaptured());
+
+ AlertTargetEntity entity = entityCapture.getValue();
+ assertEquals(newName, entity.getTargetName());
+ assertEquals(ALERT_TARGET_PROPS2, entity.getProperties());
+ verify(m_amc, m_dao);
}
/**
@@ -197,28 +239,17 @@ public class AlertTargetResourceProviderTest {
*/
@Test
public void testDeleteResources() throws Exception {
- AmbariManagementController amc = createMock(AmbariManagementController.class);
Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
Capture<List<AlertTargetEntity>> listCapture = new Capture<List<AlertTargetEntity>>();
m_dao.createTargets(capture(listCapture));
expectLastCall();
- replay(amc, m_dao);
+ replay(m_amc, m_dao);
- AlertTargetResourceProvider provider = createProvider(amc);
-
- Map<String, Object> requestProps = new HashMap<String, Object>();
- requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_NAME,
- ALERT_TARGET_NAME);
-
- requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
- ALERT_TARGET_DESC);
-
- requestProps.put(
- AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE,
- ALERT_TARGET_TYPE);
+ AlertTargetResourceProvider provider = createProvider(m_amc);
+ Map<String, Object> requestProps = getCreationProperties();
Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
provider.createResources(request);
@@ -244,7 +275,7 @@ public class AlertTargetResourceProviderTest {
AlertTargetEntity entity1 = entityCapture.getValue();
Assert.assertEquals(ALERT_TARGET_ID, entity1.getTargetId());
- verify(amc, m_dao);
+ verify(m_amc, m_dao);
}
/**
@@ -267,10 +298,39 @@ public class AlertTargetResourceProviderTest {
entity.setDescription(ALERT_TARGET_DESC);
entity.setTargetName(ALERT_TARGET_NAME);
entity.setNotificationType(ALERT_TARGET_TYPE);
+ entity.setProperties(ALERT_TARGET_PROPS);
return Arrays.asList(entity);
}
/**
+ * Gets the maps of properties that simulate a deserialzied JSON request to
+ * create an alert target.
+ *
+ * @return
+ * @throws Exception
+ */
+ private Map<String, Object> getCreationProperties() throws Exception {
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_NAME,
+ ALERT_TARGET_NAME);
+
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
+ ALERT_TARGET_DESC);
+
+ requestProps.put(
+ AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE,
+ ALERT_TARGET_TYPE);
+
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_PROPERTIES
+ + "/foo", "bar");
+
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_PROPERTIES
+ + "/foobar", "baz");
+
+ return requestProps;
+ }
+
+ /**
*
*/
private class MockModule implements Module {
[26/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a4e97aaa
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a4e97aaa
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a4e97aaa
Branch: refs/heads/trunk
Commit: a4e97aaa2df20b7434676dbdcc8afa9f28bdc84d
Parents: b7ae2d7 24f0b47
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Sep 17 08:33:22 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Sep 17 08:33:22 2014 -0400
----------------------------------------------------------------------
.../app/scripts/controllers/mainCtrl.js | 13 +-
.../resources/ui/admin-web/app/styles/main.css | 42 +-
.../resources/ui/admin-web/app/views/main.html | 41 +-
.../src/main/python/ambari_jinja2/ext/jinja.el | 213 -
.../server/actionmanager/ActionScheduler.java | 26 +-
.../ambari/server/actionmanager/Request.java | 23 +-
.../server/api/util/StackExtensionHelper.java | 35 +-
.../server/controller/ExecuteActionRequest.java | 20 +-
.../controller/MaintenanceStateHelper.java | 2 +-
.../internal/ConfigGroupResourceProvider.java | 20 +-
.../internal/RequestResourceProvider.java | 12 +-
.../server/orm/entities/RequestEntity.java | 12 +
.../server/upgrade/UpgradeCatalog170.java | 4 +
.../apache/ambari/server/view/ViewRegistry.java | 67 +-
ambari-server/src/main/python/ambari-server.py | 42 +-
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 2 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 2 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 2 +-
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 2 +-
.../src/main/resources/properties.json | 1 +
.../HDFS/package/scripts/service_check.py | 2 +-
.../services/HIVE/configuration/hive-site.xml | 19 +
.../HDFS/package/scripts/service_check.py | 2 +-
.../services/HIVE/configuration/hive-site.xml | 19 +
.../stacks/HDP/2.0/role_command_order.json | 2 +-
.../stacks/HDP/2.0/services/HBASE/metainfo.xml | 3 -
.../stacks/HDP/2.0/services/HDFS/metainfo.xml | 1 -
.../stacks/HDP/2.0/services/HIVE/metainfo.xml | 6 -
.../stacks/HDP/2.0/services/OOZIE/metainfo.xml | 3 -
.../stacks/HDP/2.0/services/PIG/metainfo.xml | 1 -
.../stacks/HDP/2.0/services/SQOOP/metainfo.xml | 3 -
.../HDP/2.0/services/WEBHCAT/metainfo.xml | 27 -
.../stacks/HDP/2.0/services/YARN/metainfo.xml | 2 -
.../HDP/2.0/services/ZOOKEEPER/metainfo.xml | 1 -
.../GLUSTERFS/configuration/hadoop-env.xml | 2 +
.../services/HIVE/configuration/hive-site.xml | 19 +
.../services/YARN/configuration/core-site.xml | 20 -
.../stacks/HDP/2.1/services/FLUME/metainfo.xml | 3 +-
.../stacks/HDP/2.1/services/HBASE/metainfo.xml | 3 -
.../stacks/HDP/2.1/services/HDFS/metainfo.xml | 1 -
.../services/HIVE/configuration/hive-site.xml | 19 +
.../stacks/HDP/2.1/services/HIVE/metainfo.xml | 1 -
.../stacks/HDP/2.1/services/NAGIOS/metainfo.xml | 1 -
.../stacks/HDP/2.1/services/OOZIE/metainfo.xml | 2 -
.../stacks/HDP/2.1/services/PIG/metainfo.xml | 1 -
.../stacks/HDP/2.1/services/SQOOP/metainfo.xml | 3 -
.../stacks/HDP/2.1/services/YARN/metainfo.xml | 1 -
.../HDP/2.1/services/ZOOKEEPER/metainfo.xml | 2 -
.../stacks/HDP/2.2.1/repos/repoinfo.xml | 2 +-
.../stacks/HDP/2.2.1/services/HDFS/metainfo.xml | 1 -
.../stacks/HDP/2.2.1/services/HIVE/metainfo.xml | 1 -
.../stacks/HDP/2.2/services/FALCON/metainfo.xml | 1 -
.../stacks/HDP/2.2/services/FLUME/metainfo.xml | 1 -
.../stacks/HDP/2.2/services/HBASE/metainfo.xml | 3 -
.../stacks/HDP/2.2/services/HDFS/metainfo.xml | 1 -
.../stacks/HDP/2.2/services/HIVE/metainfo.xml | 1 -
.../stacks/HDP/2.2/services/OOZIE/metainfo.xml | 2 -
.../stacks/HDP/2.2/services/PIG/metainfo.xml | 1 -
.../stacks/HDP/2.2/services/SQOOP/metainfo.xml | 3 -
.../stacks/HDP/2.2/services/STORM/metainfo.xml | 1 -
.../stacks/HDP/2.2/services/TEZ/metainfo.xml | 1 -
.../HDP/2.2/services/WEBHCAT/metainfo.xml | 1 -
.../stacks/HDP/2.2/services/YARN/metainfo.xml | 2 -
.../HDP/2.2/services/ZOOKEEPER/metainfo.xml | 1 -
.../actionmanager/TestActionDBAccessorImpl.java | 2 +-
.../actionmanager/TestActionScheduler.java | 264 +-
.../api/util/StackExtensionHelperTest.java | 20 +
.../AmbariCustomCommandExecutionHelperTest.java | 2 +-
.../AmbariManagementControllerTest.java | 86 +-
.../BackgroundCustomCommandExecutionTest.java | 2 +-
.../ambari/server/view/ViewRegistryTest.java | 90 +
.../view/configuration/ViewConfigTest.java | 1 +
.../stacks/1.3.2/HDFS/test_service_check.py | 2 +-
.../stacks/2.0.6/HDFS/test_service_check.py | 2 +-
.../stacks/HDP/2.0.7/services/HDFS/metrics.json | 7840 ------------------
ambari-web/app/controllers/installer.js | 15 +
.../controllers/main/service/info/configs.js | 240 +-
ambari-web/app/controllers/main/service/item.js | 36 +-
ambari-web/app/data/HDP2/site_properties.js | 9 +
ambari-web/app/data/site_properties.js | 9 +
ambari-web/app/messages.js | 1 +
ambari-web/app/models/cluster_states.js | 1 -
ambari-web/app/models/service_config.js | 1 +
ambari-web/app/router.js | 84 +-
ambari-web/app/routes/installer.js | 12 +-
ambari-web/app/routes/reassign_master_routes.js | 96 +-
.../common/configs/compare_property.hbs | 30 +-
.../common/configs/service_config_category.hbs | 6 +-
ambari-web/app/utils/ajax/ajax.js | 17 +-
.../app/utils/batch_scheduled_requests.js | 6 +-
contrib/views/slider/pom.xml | 2 +-
.../slider/SliderAppTypesResourceProvider.java | 6 +-
.../view/slider/SliderAppsViewController.java | 4 +
.../slider/SliderAppsViewControllerImpl.java | 70 +-
.../view/slider/rest/SliderAppsResource.java | 21 +-
.../ambari/view/slider/rest/client/Metric.java | 9 +-
.../ui/app/controllers/slider_app_controller.js | 17 +-
.../ui/app/controllers/slider_controller.js | 107 +-
.../src/main/resources/ui/app/helpers/ajax.js | 6 +-
.../src/main/resources/ui/app/initialize.js | 31 +-
.../ui/app/mappers/application_status.js | 115 -
.../ui/app/models/slider_app_component.js | 10 +-
.../resources/ui/app/styles/application.less | 119 +
.../resources/ui/app/templates/application.hbs | 4 +-
.../ui/app/templates/slider_app/summary.hbs | 2 +-
.../ui/app/templates/slider_title_tooltip.hbs | 27 +
.../src/main/resources/ui/app/translations.js | 2 +-
.../resources/ui/app/views/application_view.js | 64 +
108 files changed, 1641 insertions(+), 8622 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a4e97aaa/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a4e97aaa/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a4e97aaa/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a4e97aaa/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a4e97aaa/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a4e97aaa/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a4e97aaa/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a4e97aaa/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
[33/50] [abbrv] git commit: AMBARI-7443 - Alerts: Implement Email
Dispatcher (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7443 - Alerts: Implement Email Dispatcher (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d838ca95
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d838ca95
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d838ca95
Branch: refs/heads/trunk
Commit: d838ca95b644a3222c27b7415f2711373affcd83
Parents: e6cc058
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Sep 22 23:45:06 2014 -0700
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Sep 23 09:02:11 2014 -0700
----------------------------------------------------------------------
.../internal/AlertTargetResourceProvider.java | 15 +-
.../server/events/AlertStateChangeEvent.java | 2 +-
.../events/listeners/AlertReceivedListener.java | 46 +++--
.../listeners/AlertServiceStateListener.java | 1 -
.../notifications/DispatchCredentials.java | 44 +++++
.../server/notifications/DispatchFactory.java | 16 ++
.../server/notifications/Notification.java | 18 ++
.../ambari/server/notifications/Recipient.java | 45 +++++
.../dispatchers/EmailDispatcher.java | 129 +++++++++++++-
.../apache/ambari/server/orm/dao/AlertsDAO.java | 114 +++++++-----
.../server/orm/entities/AlertCurrentEntity.java | 13 +-
.../services/AlertNoticeDispatchService.java | 175 ++++++++++++++++++-
.../stacks/HDP/2.0.6/services/HDFS/alerts.json | 2 +-
.../AlertTargetResourceProviderTest.java | 58 ++++++
.../notifications/EmailDispatcherTest.java | 117 +++++++++++++
.../server/notifications/MockDispatcher.java | 46 +++++
.../ambari/server/orm/dao/AlertsDAOTest.java | 133 +++++++++-----
.../alerts/AlertStateChangedEventTest.java | 139 +++++++++++++++
18 files changed, 984 insertions(+), 129 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
index f2b82d6..b0cc52b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.controller.internal;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -45,7 +46,6 @@ import org.apache.ambari.server.state.alert.AlertTarget;
import org.apache.commons.lang.StringUtils;
import com.google.gson.Gson;
-import com.google.gson.JsonObject;
import com.google.inject.Inject;
import com.google.inject.Injector;
@@ -351,22 +351,19 @@ public class AlertTargetResourceProvider extends
* {@code null} if none.
*/
private String extractProperties( Map<String, Object> requestMap ){
- JsonObject jsonObject = new JsonObject();
+ Map<String, Object> normalizedMap = new HashMap<String, Object>(
+ requestMap.size());
+
for (Entry<String, Object> entry : requestMap.entrySet()) {
String key = entry.getKey();
String propCat = PropertyHelper.getPropertyCategory(key);
if (propCat.equals(ALERT_TARGET_PROPERTIES)) {
String propKey = PropertyHelper.getPropertyName(key);
- jsonObject.addProperty(propKey, entry.getValue().toString());
+ normalizedMap.put(propKey, entry.getValue());
}
}
- String properties = null;
- if (jsonObject.entrySet().size() > 0) {
- properties = jsonObject.toString();
- }
-
- return properties;
+ return s_gson.toJson(normalizedMap);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
index ab2c3dd..efb7119 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
@@ -25,7 +25,7 @@ import org.apache.ambari.server.state.AlertState;
* The {@link AlertStateChangeEvent} is fired when an {@link Alert} instance has
* its {@link AlertState} changed.
*/
-public final class AlertStateChangeEvent extends AlertEvent {
+public class AlertStateChangeEvent extends AlertEvent {
/**
* The prior alert state.
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
index fb7a608..e87ba7d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
@@ -28,8 +28,8 @@ import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.AlertState;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.Subscribe;
@@ -46,7 +46,7 @@ public class AlertReceivedListener {
/**
* Logger.
*/
- private static Log LOG = LogFactory.getLog(AlertReceivedListener.class);
+ private static final Logger LOG = LoggerFactory.getLogger(AlertReceivedListener.class);
@Inject
private AlertsDAO m_alertsDao;
@@ -70,30 +70,33 @@ public class AlertReceivedListener {
m_alertEventPublisher.register(this);
}
-
/**
- * Adds an alert. Checks for a new state before creating a new history record.
+ * Adds an alert. Checks for a new state before creating a new history record.
*
- * @param clusterId the id for the cluster
- * @param alert the alert to add
+ * @param clusterId
+ * the id for the cluster
+ * @param alert
+ * the alert to add
*/
@Subscribe
@AllowConcurrentEvents
public void onAlertEvent(AlertReceivedEvent event) {
- LOG.debug(event);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(event.toString());
+ }
long clusterId = event.getClusterId();
Alert alert = event.getAlert();
AlertCurrentEntity current = null;
-
+
if (null == alert.getHost()) {
current = m_alertsDao.findCurrentByNameNoHost(clusterId, alert.getName());
} else {
current = m_alertsDao.findCurrentByHostAndName(clusterId, alert.getHost(),
alert.getName());
}
-
+
if (null == current) {
AlertDefinitionEntity definition = m_definitionDao.findByName(clusterId,
alert.getName());
@@ -111,13 +114,20 @@ public class AlertReceivedListener {
current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
current.setLatestText(alert.getText());
- m_alertsDao.merge(current);
+ current = m_alertsDao.merge(current);
} else {
- AlertState oldState = current.getAlertHistory().getAlertState();
+ LOG.debug(
+ "Alert State Changed: CurrentId {}, CurrentTimestamp {}, HistoryId {}, HistoryState {}",
+ current.getAlertId(), current.getLatestTimestamp(),
+ current.getAlertHistory().getAlertId(),
+ current.getAlertHistory().getAlertState());
+
+ AlertHistoryEntity oldHistory = current.getAlertHistory();
+ AlertState oldState = oldHistory.getAlertState();
// insert history, update current
AlertHistoryEntity history = createHistory(clusterId,
- current.getAlertHistory().getAlertDefinition(), alert);
+ oldHistory.getAlertDefinition(), alert);
// manually create the new history entity since we are merging into
// an existing current entity
@@ -127,8 +137,14 @@ public class AlertReceivedListener {
current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
- m_alertsDao.merge(current);
-
+ current = m_alertsDao.merge(current);
+
+ LOG.debug(
+ "Alert State Merged: CurrentId {}, CurrentTimestamp {}, HistoryId {}, HistoryState {}",
+ current.getAlertId(), current.getLatestTimestamp(),
+ current.getAlertHistory().getAlertId(),
+ current.getAlertHistory().getAlertState());
+
// broadcast the alert changed event for other subscribers
AlertStateChangeEvent alertChangedEvent = new AlertStateChangeEvent(
event.getClusterId(), event.getAlert(), current.getAlertHistory(),
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
index f1ce617..6215cc1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertServiceStateListener.java
@@ -94,7 +94,6 @@ public class AlertServiceStateListener {
publisher.register(this);
}
-
/**
* Handles service installed events by populating the database with all known
* alert definitions for the newly installed service and creates the service's
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchCredentials.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchCredentials.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchCredentials.java
new file mode 100644
index 0000000..9514474
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchCredentials.java
@@ -0,0 +1,44 @@
+/**
+ * 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.ambari.server.notifications;
+
+/**
+ * The {@link DispatchCredentials} represent a generic username/password model
+ * that can be passed to a {@link NotificationDispatcher} in order to authentice
+ * with a backend dispatcher.
+ */
+public class DispatchCredentials {
+
+ /**
+ * The username.
+ */
+ public String UserName;
+
+ /**
+ * The password.
+ */
+ public String Password;
+
+ /**
+ * Constructor.
+ *
+ */
+ public DispatchCredentials() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java
index 3414035..13f2da2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/DispatchFactory.java
@@ -50,6 +50,22 @@ public final class DispatchFactory {
}
/**
+ * Registers a dispatcher instance with a type.
+ *
+ * @param type
+ * the type
+ * @param dispatcher
+ * the dispatcher to register with the type.
+ */
+ public void register(String type, NotificationDispatcher dispatcher) {
+ if (null == dispatcher) {
+ m_dispatchers.remove(type);
+ } else {
+ m_dispatchers.put(type, dispatcher);
+ }
+ }
+
+ /**
* Gets a dispatcher based on the type.
*
* @param type
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java
index 08c5242..12dffd7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/Notification.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.notifications;
import java.util.List;
+import java.util.Map;
/**
* The {@link Notification} class is a generic way to relay content through an
@@ -36,6 +37,23 @@ public class Notification {
public String Body;
/**
+ * The optional recipients of the notification. Some dispatchers may not
+ * require explicit recipients.
+ */
+ public List<Recipient> Recipients;
+
+ /**
+ * A map of all of the properties that a {@link NotificationDispatcher} needs
+ * in order to dispatch this notification.
+ */
+ public Map<String, String> DispatchProperties;
+
+ /**
+ * The optional credentials used to authenticate with the dispatcher.
+ */
+ public DispatchCredentials Credentials;
+
+ /**
* An optional callback implementation that the dispatcher can use to report
* success/failure on delivery.
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/notifications/Recipient.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/Recipient.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/Recipient.java
new file mode 100644
index 0000000..933038b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/Recipient.java
@@ -0,0 +1,45 @@
+/**
+ * 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.ambari.server.notifications;
+
+/**
+ * The {@link Recipient} class represents a target of a {@link Notification}.
+ */
+public class Recipient {
+
+ /**
+ * A string that the concrete {@link NotificationDispatcher} can use to build
+ * a backend recipient that will work with the dispatch mechanism.
+ */
+ public String Identifier;
+
+ /**
+ * Constructor.
+ *
+ */
+ public Recipient() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return Identifier;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java
index d0858d3..a5dad84 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/notifications/dispatchers/EmailDispatcher.java
@@ -17,8 +17,24 @@
*/
package org.apache.ambari.server.notifications.dispatchers;
-import org.apache.ambari.server.notifications.NotificationDispatcher;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Timer;
+
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.Message.RecipientType;
+import javax.mail.MessagingException;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.ambari.server.notifications.DispatchCredentials;
import org.apache.ambari.server.notifications.Notification;
+import org.apache.ambari.server.notifications.NotificationDispatcher;
+import org.apache.ambari.server.notifications.Recipient;
import org.apache.ambari.server.state.alert.TargetType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -27,7 +43,14 @@ import com.google.inject.Singleton;
/**
* The {@link EmailDispatcher} class is used to dispatch {@link Notification}
- * via JavaMail.
+ * via JavaMail. This class currently does not attempt to reuse an existing
+ * {@link Session} or {@link Transport} since each {@link Notification} could
+ * have a different target server with different properties.
+ * <p/>
+ * In the future, this class could keep various {@link Transport} instances open
+ * on a {@link Timer}, but those instances would need to be hashed so that the
+ * proper instance is retrieved from the properties of the incoming
+ * {@link Notification}.
*/
@Singleton
public class EmailDispatcher implements NotificationDispatcher {
@@ -52,9 +75,105 @@ public class EmailDispatcher implements NotificationDispatcher {
public void dispatch(Notification notification) {
LOG.info("Sending email: {}", notification);
- // callback to inform the interested parties about the successful dispatch
- if (null != notification.Callback) {
- notification.Callback.onSuccess(notification.CallbackIds);
+ if (null == notification.DispatchProperties) {
+ LOG.error("Unable to dispatch an email notification that does not contain SMTP properties");
+
+ if (null != notification.Callback) {
+ notification.Callback.onFailure(notification.CallbackIds);
+ }
+
+ return;
+ }
+
+ // convert properties to JavaMail properties
+ Properties properties = new Properties();
+ for (Entry<String, String> entry : notification.DispatchProperties.entrySet()) {
+ properties.put(entry.getKey(), entry.getValue());
+ }
+
+ // notifications must have recipients
+ if (null == notification.Recipients) {
+ LOG.error("Unable to dispatch an email notification that does not have recipients");
+
+ if (null != notification.Callback) {
+ notification.Callback.onFailure(notification.CallbackIds);
+ }
+
+ return;
+ }
+
+ // create a simple email authentication for username/password
+ final Session session;
+ EmailAuthenticator authenticator = null;
+
+ if (null != notification.Credentials) {
+ authenticator = new EmailAuthenticator(notification.Credentials);
+ }
+
+ session = Session.getInstance(properties, authenticator);
+
+ try {
+ Message message = new MimeMessage(session);
+
+ for (Recipient recipient : notification.Recipients) {
+ InternetAddress address = new InternetAddress(recipient.Identifier);
+ message.addRecipient(RecipientType.TO, address);
+ }
+
+ message.setSubject(notification.Subject);
+ message.setText(notification.Body);
+
+ Transport.send(message);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Successfully dispatched email to {}",
+ notification.Recipients);
+ }
+
+ // callback to inform the interested parties about the successful dispatch
+ if (null != notification.Callback) {
+ notification.Callback.onSuccess(notification.CallbackIds);
+ }
+ } catch (Exception exception) {
+ LOG.error("Unable to dispatch notification via Email", exception);
+
+ // callback failure
+ if (null != notification.Callback) {
+ notification.Callback.onFailure(notification.CallbackIds);
+ }
+ } finally {
+ try {
+ session.getTransport().close();
+ } catch (MessagingException me) {
+ LOG.warn("Dispatcher unable to close SMTP transport", me);
+ }
+ }
+ }
+
+ /**
+ * The {@link EmailAuthenticator} class is used to provide a username and
+ * password combination to an SMTP server.
+ */
+ private static final class EmailAuthenticator extends Authenticator{
+
+ private final DispatchCredentials m_credentials;
+
+ /**
+ * Constructor.
+ *
+ * @param credentials
+ */
+ private EmailAuthenticator(DispatchCredentials credentials) {
+ m_credentials = credentials;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected PasswordAuthentication getPasswordAuthentication() {
+ return new PasswordAuthentication(m_credentials.UserName,
+ m_credentials.Password);
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
index aba41a5..a28b448 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -30,6 +30,8 @@ import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.alert.Scope;
+import org.eclipse.persistence.config.HintValues;
+import org.eclipse.persistence.config.QueryHints;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -57,7 +59,7 @@ public class AlertsDAO {
/**
* Gets an alert with the specified ID.
- *
+ *
* @param alertId
* the ID of the alert to retrieve.
* @return the alert or {@code null} if none exists.
@@ -68,7 +70,7 @@ public class AlertsDAO {
/**
* Gets all alerts stored in the database across all clusters.
- *
+ *
* @return all alerts or an empty list if none exist (never {@code null}).
*/
public List<AlertHistoryEntity> findAll() {
@@ -80,7 +82,7 @@ public class AlertsDAO {
/**
* Gets all alerts stored in the database for the given cluster.
- *
+ *
* @param clusterId
* the ID of the cluster.
* @return all alerts in the specified cluster or an empty list if none exist
@@ -98,7 +100,7 @@ public class AlertsDAO {
/**
* Gets all alerts stored in the database for the given cluster that have one
* of the specified alert states.
- *
+ *
* @param clusterId
* the ID of the cluster.
* @param alertStates
@@ -126,7 +128,7 @@ public class AlertsDAO {
* Gets all alerts stored in the database for the given cluster and that fall
* withing the specified date range. Dates are expected to be in milliseconds
* since the epoch, normalized to UTC time.
- *
+ *
* @param clusterId
* the ID of the cluster.
* @param startDate
@@ -141,8 +143,9 @@ public class AlertsDAO {
*/
public List<AlertHistoryEntity> findAll(long clusterId, Date startDate,
Date endDate) {
- if (null == startDate && null == endDate)
+ if (null == startDate && null == endDate) {
return Collections.emptyList();
+ }
TypedQuery<AlertHistoryEntity> query = null;
@@ -174,15 +177,16 @@ public class AlertsDAO {
query.setParameter("beforeDate", endDate.getTime());
}
- if (null == query)
+ if (null == query) {
return Collections.emptyList();
+ }
return daoUtils.selectList(query);
}
/**
* Gets the current alerts.
- *
+ *
* @return the current alerts or an empty list if none exist (never
* {@code null}).
*/
@@ -196,7 +200,7 @@ public class AlertsDAO {
/**
* Gets a current alert with the specified ID.
- *
+ *
* @param alertId
* the ID of the alert to retrieve.
* @return the alert or {@code null} if none exists.
@@ -208,7 +212,7 @@ public class AlertsDAO {
/**
* Gets the current alerts for a given cluster.
- *
+ *
* @return the current alerts for the given clusteror an empty list if none
* exist (never {@code null}).
*/
@@ -218,14 +222,15 @@ public class AlertsDAO {
"AlertCurrentEntity.findByCluster", AlertCurrentEntity.class);
query.setParameter("clusterId", Long.valueOf(clusterId));
+ query = setQueryRefreshHint(query);
return daoUtils.selectList(query);
}
-
+
/**
* Retrieves the summary information for a particular scope. The result is a DTO
* since the columns are aggregated and don't fit to an entity.
- *
+ *
* @param clusterId the cluster id
* @param serviceName the service name. Use {@code null} to not filter on service.
* @param hostName the host name. Use {@code null} to not filter on host.
@@ -240,41 +245,41 @@ public class AlertsDAO {
sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END), ");
sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END)) ");
sb.append("FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId");
-
+
if (null != serviceName) {
sb.append(" AND history.serviceName = :serviceName");
}
-
+
if (null != hostName) {
sb.append(" AND history.hostName = :hostName");
}
-
+
String str = String.format(sb.toString(),
AlertSummaryDTO.class.getName(),
AlertState.class.getName(), AlertState.OK.name(),
AlertState.class.getName(), AlertState.WARNING.name(),
AlertState.class.getName(), AlertState.CRITICAL.name(),
AlertState.class.getName(), AlertState.UNKNOWN.name());
-
+
TypedQuery<AlertSummaryDTO> query = entityManagerProvider.get().createQuery(
str, AlertSummaryDTO.class);
-
+
query.setParameter("clusterId", Long.valueOf(clusterId));
-
+
if (null != serviceName) {
query.setParameter("serviceName", serviceName);
}
-
+
if (null != hostName) {
query.setParameter("hostName", hostName);
}
-
+
return daoUtils.selectSingle(query);
}
-
+
/**
* Gets the current alerts for a given service.
- *
+ *
* @return the current alerts for the given service or an empty list if none
* exist (never {@code null}).
*/
@@ -288,12 +293,13 @@ public class AlertsDAO {
query.setParameter("serviceName", serviceName);
query.setParameter("inlist", EnumSet.of(Scope.ANY, Scope.SERVICE));
+ query = setQueryRefreshHint(query);
return daoUtils.selectList(query);
}
/**
* Gets the current alerts for a given host.
- *
+ *
* @return the current alerts for the given host or an empty list if none
* exist (never {@code null}).
*/
@@ -307,13 +313,14 @@ public class AlertsDAO {
query.setParameter("hostName", hostName);
query.setParameter("inlist", EnumSet.of(Scope.ANY, Scope.HOST));
+ query = setQueryRefreshHint(query);
return daoUtils.selectList(query);
}
-
+
@RequiresSession
public AlertCurrentEntity findCurrentByHostAndName(long clusterId, String hostName,
String alertName) {
-
+
TypedQuery<AlertCurrentEntity> query = entityManagerProvider.get().createNamedQuery(
"AlertCurrentEntity.findByHostAndName", AlertCurrentEntity.class);
@@ -321,6 +328,7 @@ public class AlertsDAO {
query.setParameter("hostName", hostName);
query.setParameter("definitionName", alertName);
+ query = setQueryRefreshHint(query);
return daoUtils.selectOne(query);
}
@@ -328,7 +336,7 @@ public class AlertsDAO {
* Removes alert history and current alerts for the specified alert defintiion
* ID. This will invoke {@link EntityManager#clear()} when completed since the
* JPQL statement will remove entries without going through the EM.
- *
+ *
* @param definitionId
* the ID of the definition to remove.
*/
@@ -352,7 +360,7 @@ public class AlertsDAO {
/**
* Remove a current alert whose history entry matches the specfied ID.
- *
+ *
* @param historyId the ID of the history entry.
* @return the number of alerts removed.
*/
@@ -367,7 +375,7 @@ public class AlertsDAO {
/**
* Persists a new alert.
- *
+ *
* @param alert
* the alert to persist (not {@code null}).
*/
@@ -378,7 +386,7 @@ public class AlertsDAO {
/**
* Refresh the state of the alert from the database.
- *
+ *
* @param alert
* the alert to refresh (not {@code null}).
*/
@@ -389,7 +397,7 @@ public class AlertsDAO {
/**
* Merge the speicified alert with the existing alert in the database.
- *
+ *
* @param alert
* the alert to merge (not {@code null}).
* @return the updated alert with merged content (never {@code null}).
@@ -401,7 +409,7 @@ public class AlertsDAO {
/**
* Removes the specified alert from the database.
- *
+ *
* @param alert
* the alert to remove.
*/
@@ -415,7 +423,7 @@ public class AlertsDAO {
/**
* Persists a new current alert.
- *
+ *
* @param alert
* the current alert to persist (not {@code null}).
*/
@@ -426,7 +434,7 @@ public class AlertsDAO {
/**
* Refresh the state of the current alert from the database.
- *
+ *
* @param alert
* the current alert to refresh (not {@code null}).
*/
@@ -437,7 +445,7 @@ public class AlertsDAO {
/**
* Merge the speicified current alert with the existing alert in the database.
- *
+ *
* @param alert
* the current alert to merge (not {@code null}).
* @return the updated current alert with merged content (never {@code null}).
@@ -449,7 +457,7 @@ public class AlertsDAO {
/**
* Removes the specified current alert from the database.
- *
+ *
* @param alert
* the current alert to remove.
*/
@@ -457,9 +465,9 @@ public class AlertsDAO {
public void remove(AlertCurrentEntity alert) {
entityManagerProvider.get().remove(merge(alert));
}
-
+
/**
- * Finds the aggregate counts for an alert name, across all hosts.
+ * Finds the aggregate counts for an alert name, across all hosts.
* @param clusterId the cluster id
* @param alertName the name of the alert to find the aggregate
* @return the summary data
@@ -474,22 +482,22 @@ public class AlertsDAO {
sb.append("SUM(CASE WHEN history.alertState = %s.%s THEN 1 ELSE 0 END)) ");
sb.append("FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId");
sb.append(" AND history.alertDefinition.definitionName = :definitionName");
-
+
String str = String.format(sb.toString(),
AlertSummaryDTO.class.getName(),
AlertState.class.getName(), AlertState.WARNING.name(),
AlertState.class.getName(), AlertState.CRITICAL.name(),
AlertState.class.getName(), AlertState.UNKNOWN.name());
-
+
TypedQuery<AlertSummaryDTO> query = entityManagerProvider.get().createQuery(
str, AlertSummaryDTO.class);
-
+
query.setParameter("clusterId", Long.valueOf(clusterId));
query.setParameter("definitionName", alertName);
-
- return daoUtils.selectSingle(query);
+
+ return daoUtils.selectSingle(query);
}
-
+
/**
* Locate the current alert for the provided service and alert name, but when
* host is not set ({@code IS NULL}).
@@ -500,7 +508,7 @@ public class AlertsDAO {
*/
@RequiresSession
public AlertCurrentEntity findCurrentByNameNoHost(long clusterId, String alertName) {
-
+
TypedQuery<AlertCurrentEntity> query = entityManagerProvider.get().createNamedQuery(
"AlertCurrentEntity.findByNameAndNoHost", AlertCurrentEntity.class);
@@ -510,4 +518,22 @@ public class AlertsDAO {
return daoUtils.selectOne(query);
}
+ /**
+ * Sets {@link QueryHints#REFRESH} on the specified query so that child
+ * entities are not stale.
+ * <p/>
+ * See <a
+ * href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=398067">https://bugs
+ * .eclipse.org/bugs/show_bug.cgi?id=398067</a>
+ *
+ * @param query
+ * @return
+ */
+ private <T> TypedQuery<T> setQueryRefreshHint(TypedQuery<T> query) {
+ // !!! https://bugs.eclipse.org/bugs/show_bug.cgi?id=398067
+ // ensure that an associated entity with a JOIN is not stale; this causes
+ // the associated AlertHistoryEntity to be stale
+ query.setHint(QueryHints.REFRESH, HintValues.TRUE);
+ return query;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
index 5b54d57..8ca297b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
@@ -47,11 +47,11 @@ import org.apache.ambari.server.state.MaintenanceState;
@TableGenerator(name = "alert_current_id_generator", table = "ambari_sequences", pkColumnName = "sequence_name", valueColumnName = "sequence_value", pkColumnValue = "alert_current_id_seq", initialValue = 0, allocationSize = 1)
@NamedQueries({
@NamedQuery(name = "AlertCurrentEntity.findAll", query = "SELECT alert FROM AlertCurrentEntity alert"),
- @NamedQuery(name = "AlertCurrentEntity.findByCluster", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId"),
- @NamedQuery(name = "AlertCurrentEntity.findByService", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.serviceName = :serviceName AND history.alertDefinition.scope IN :inlist"),
- @NamedQuery(name = "AlertCurrentEntity.findByHost", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.hostName = :hostName AND history.alertDefinition.scope IN :inlist"),
- @NamedQuery(name = "AlertCurrentEntity.findByHostAndName", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.alertDefinition.definitionName = :definitionName AND history.hostName = :hostName"),
- @NamedQuery(name = "AlertCurrentEntity.findByNameAndNoHost", query = "SELECT alert FROM AlertCurrentEntity alert JOIN alert.alertHistory history WHERE history.clusterId = :clusterId AND history.alertDefinition.definitionName = :definitionName AND history.hostName IS NULL"),
+ @NamedQuery(name = "AlertCurrentEntity.findByCluster", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId"),
+ @NamedQuery(name = "AlertCurrentEntity.findByService", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId AND alert.alertHistory.serviceName = :serviceName AND alert.alertHistory.alertDefinition.scope IN :inlist"),
+ @NamedQuery(name = "AlertCurrentEntity.findByHost", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId AND alert.alertHistory.hostName = :hostName AND alert.alertHistory.alertDefinition.scope IN :inlist"),
+ @NamedQuery(name = "AlertCurrentEntity.findByHostAndName", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId AND alert.alertHistory.alertDefinition.definitionName = :definitionName AND alert.alertHistory.hostName = :hostName"),
+ @NamedQuery(name = "AlertCurrentEntity.findByNameAndNoHost", query = "SELECT alert FROM AlertCurrentEntity alert WHERE alert.alertHistory.clusterId = :clusterId AND alert.alertHistory.alertDefinition.definitionName = :definitionName AND alert.alertHistory.hostName IS NULL"),
@NamedQuery(name = "AlertCurrentEntity.removeByHistoryId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertHistory.alertId = :historyId"),
@NamedQuery(name = "AlertCurrentEntity.removeByDefinitionId", query = "DELETE FROM AlertCurrentEntity alert WHERE alert.alertDefinition.definitionId = :definitionId") })
public class AlertCurrentEntity {
@@ -77,8 +77,7 @@ public class AlertCurrentEntity {
/**
* Unidirectional one-to-one association to {@link AlertHistoryEntity}
*/
- @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE,
- CascadeType.REFRESH })
+ @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.REFRESH })
@JoinColumn(name = "history_id", unique = true, nullable = false)
private AlertHistoryEntity alertHistory;
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
index 7025e14..72487b3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AlertNoticeDispatchService.java
@@ -17,10 +17,13 @@
*/
package org.apache.ambari.server.state.services;
+import java.lang.reflect.Type;
+import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
@@ -29,19 +32,32 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.ambari.server.events.AlertEvent;
+import org.apache.ambari.server.notifications.DispatchCallback;
+import org.apache.ambari.server.notifications.DispatchCredentials;
import org.apache.ambari.server.notifications.DispatchFactory;
import org.apache.ambari.server.notifications.DispatchRunnable;
-import org.apache.ambari.server.notifications.DispatchCallback;
-import org.apache.ambari.server.notifications.NotificationDispatcher;
import org.apache.ambari.server.notifications.Notification;
+import org.apache.ambari.server.notifications.NotificationDispatcher;
+import org.apache.ambari.server.notifications.Recipient;
import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.NotificationState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.util.concurrent.AbstractScheduledService;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.reflect.TypeToken;
import com.google.inject.Inject;
import com.google.inject.Singleton;
@@ -49,6 +65,10 @@ import com.google.inject.Singleton;
* The {@link AlertNoticeDispatchService} is used to scan the database for
* {@link AlertNoticeEntity} that are in the {@link NotificationState#PENDING}.
* It will then process them through the dispatch system.
+ * <p/>
+ * The dispatch system will then make a callback to
+ * {@link AlertNoticeDispatchCallback} so that the {@link NotificationState} can
+ * be updated to its final value.
*/
@Singleton
public class AlertNoticeDispatchService extends AbstractScheduledService {
@@ -59,6 +79,26 @@ public class AlertNoticeDispatchService extends AbstractScheduledService {
private static final Logger LOG = LoggerFactory.getLogger(AlertNoticeDispatchService.class);
/**
+ * The property containing the dispatch authentication username.
+ */
+ private static final String AMBARI_DISPATCH_CREDENTIAL_USERNAME = "ambari.dispatch.credential.username";
+
+ /**
+ * The property containing the dispatch authentication password.
+ */
+ private static final String AMBARI_DISPATCH_CREDENTIAL_PASSWORD = "ambari.dispatch.credential.password";
+
+ /**
+ * The property containing the dispatch recipients
+ */
+ private static final String AMBARI_DISPATCH_RECIPIENTS = "ambari.dispatch.recipients";
+
+ /**
+ * Gson used to convert JSON properties to a map.
+ */
+ private final Gson m_gson;
+
+ /**
* Dispatch DAO to query pending {@link AlertNoticeEntity} instances from.
*/
@Inject
@@ -84,6 +124,12 @@ public class AlertNoticeDispatchService extends AbstractScheduledService {
TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(),
new AlertDispatchThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
+
+ GsonBuilder gsonBuilder = new GsonBuilder();
+ gsonBuilder.registerTypeAdapter(AlertTargetProperties.class,
+ new AlertTargetPropertyDeserializer());
+
+ m_gson = gsonBuilder.create();
}
/**
@@ -122,16 +168,82 @@ public class AlertNoticeDispatchService extends AbstractScheduledService {
continue;
}
+ String propertiesJson = target.getProperties();
+ AlertTargetProperties targetProperties = m_gson.fromJson(propertiesJson,
+ AlertTargetProperties.class);
+
+ Map<String, String> properties = targetProperties.Properties;
+
Notification notification = new Notification();
- notification.Subject = target.getTargetName();
- notification.Body = target.getDescription();
notification.Callback = new AlertNoticeDispatchCallback();
notification.CallbackIds = new ArrayList<String>(notices.size());
+ // !!! FIXME: temporary until velocity templates are implemented
+ String subject = "OK ({0}), Warning ({1}), Critical ({2})";
+ StringBuilder buffer = new StringBuilder(512);
+
+ int okCount = 0;
+ int warningCount = 0;
+ int criticalCount = 0;
+
for (AlertNoticeEntity notice : notices) {
+ AlertHistoryEntity history = notice.getAlertHistory();
notification.CallbackIds.add(notice.getUuid());
+
+ AlertState alertState = history.getAlertState();
+ switch (alertState) {
+ case CRITICAL:
+ criticalCount++;
+ break;
+ case OK:
+ okCount++;
+ break;
+ case UNKNOWN:
+ // !!! hmmmmmm
+ break;
+ case WARNING:
+ warningCount++;
+ break;
+ default:
+ break;
+ }
+
+ buffer.append(history.getAlertLabel());
+ buffer.append(": ");
+ buffer.append(history.getAlertText());
+ buffer.append("\n");
}
+ notification.Subject = MessageFormat.format(subject, okCount,
+ warningCount, criticalCount);
+
+ notification.Body = buffer.toString();
+
+ // set dispatch credentials
+ if (properties.containsKey(AMBARI_DISPATCH_CREDENTIAL_USERNAME)
+ && properties.containsKey(AMBARI_DISPATCH_CREDENTIAL_PASSWORD)) {
+ DispatchCredentials credentials = new DispatchCredentials();
+ credentials.UserName = properties.get(AMBARI_DISPATCH_CREDENTIAL_USERNAME);
+ credentials.Password = properties.get(AMBARI_DISPATCH_CREDENTIAL_PASSWORD);
+ notification.Credentials = credentials;
+ }
+
+ if (null != targetProperties.Recipients) {
+ List<Recipient> recipients = new ArrayList<Recipient>(
+ targetProperties.Recipients.size());
+
+ for (String stringRecipient : targetProperties.Recipients) {
+ Recipient recipient = new Recipient();
+ recipient.Identifier = stringRecipient;
+ recipients.add(recipient);
+ }
+
+ notification.Recipients = recipients;
+ }
+
+ // set all other dispatch properties
+ notification.DispatchProperties = properties;
+
NotificationDispatcher dispatcher = m_dispatchFactory.getDispatcher(target.getNotificationType());
DispatchRunnable runnable = new DispatchRunnable(dispatcher, notification);
@@ -151,6 +263,61 @@ public class AlertNoticeDispatchService extends AbstractScheduledService {
}
/**
+ * The {@link AlertTargetProperties} separates out the dispatcher properties
+ * from the list of recipients which is a JSON array and not a String.
+ */
+ private static final class AlertTargetProperties {
+ /**
+ * The properties to pass to the concrete dispatcher.
+ */
+ public Map<String, String> Properties;
+
+ /**
+ * The recipients of the notice.
+ */
+ public List<String> Recipients;
+ }
+
+ /**
+ * The {@link AlertTargetPropertyDeserializer} is used to dump the majority of
+ * JSON serialized properties into a {@link Map} of {@link String} while at
+ * the same time, converting
+ * {@link AlertNoticeDispatchService#AMBARI_DISPATCH_RECIPIENTS} into a list.
+ */
+ private static final class AlertTargetPropertyDeserializer implements
+ JsonDeserializer<AlertTargetProperties> {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public AlertTargetProperties deserialize(JsonElement json, Type typeOfT,
+ JsonDeserializationContext context) throws JsonParseException {
+
+ AlertTargetProperties properties = new AlertTargetProperties();
+ properties.Properties = new HashMap<String, String>();
+
+ final JsonObject jsonObject = json.getAsJsonObject();
+ Set<Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
+
+ for (Entry<String, JsonElement> entry : entrySet) {
+ String entryKey = entry.getKey();
+ JsonElement entryValue = entry.getValue();
+
+ if (entryKey.equals(AMBARI_DISPATCH_RECIPIENTS)) {
+ Type listType = new TypeToken<List<String>>() {}.getType();
+ JsonArray jsonArray = entryValue.getAsJsonArray();
+ properties.Recipients = context.deserialize(jsonArray, listType);
+ } else {
+ properties.Properties.put(entryKey, entryValue.getAsString());
+ }
+ }
+
+ return properties;
+ }
+ }
+
+ /**
* A custom {@link ThreadFactory} for the threads that will handle dispatching
* {@link AlertNoticeEntity} instances. Threads created will have slightly
* reduced priority since {@link AlertEvent} instances are not critical to the
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
index 88503af..620c89f 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
@@ -2,7 +2,7 @@
"service": [
{
"name": "percent_datanode",
- "label": "Percent DataNodes live",
+ "label": "Percent DataNodes Live",
"interval": 1,
"scope": "SERVICE",
"source": {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
index 1c964a3..b96a4f3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
@@ -187,6 +187,39 @@ public class AlertTargetResourceProviderTest {
* @throws Exception
*/
@Test
+ public void testCreateWithRecipientArray() throws Exception {
+ Capture<List<AlertTargetEntity>> listCapture = new Capture<List<AlertTargetEntity>>();
+
+ m_dao.createTargets(capture(listCapture));
+ expectLastCall();
+
+ replay(m_amc, m_dao);
+
+ AlertTargetResourceProvider provider = createProvider(m_amc);
+ Map<String, Object> requestProps = getRecipientCreationProperties();
+
+ Request request = PropertyHelper.getCreateRequest(
+ Collections.singleton(requestProps), null);
+ provider.createResources(request);
+
+ Assert.assertTrue(listCapture.hasCaptured());
+ AlertTargetEntity entity = listCapture.getValue().get(0);
+ Assert.assertNotNull(entity);
+
+ assertEquals(ALERT_TARGET_NAME, entity.getTargetName());
+ assertEquals(ALERT_TARGET_DESC, entity.getDescription());
+ assertEquals(ALERT_TARGET_TYPE, entity.getNotificationType());
+ assertEquals(
+ "{\"ambari.dispatch.recipients\":\"[\\\"ambari@ambari.apache.org\\\"]\"}",
+ entity.getProperties());
+
+ verify(m_amc, m_dao);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
@SuppressWarnings("unchecked")
public void testUpdateResources() throws Exception {
Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
@@ -331,6 +364,31 @@ public class AlertTargetResourceProviderTest {
}
/**
+ * Gets the maps of properties that simulate a deserialzied JSON request with
+ * a nested JSON array.
+ *
+ * @return
+ * @throws Exception
+ */
+ private Map<String, Object> getRecipientCreationProperties() throws Exception {
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_NAME,
+ ALERT_TARGET_NAME);
+
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
+ ALERT_TARGET_DESC);
+
+ requestProps.put(
+ AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE,
+ ALERT_TARGET_TYPE);
+
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_PROPERTIES
+ + "/ambari.dispatch.recipients", "[\"ambari@ambari.apache.org\"]");
+
+ return requestProps;
+ }
+
+ /**
*
*/
private class MockModule implements Module {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/test/java/org/apache/ambari/server/notifications/EmailDispatcherTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/notifications/EmailDispatcherTest.java b/ambari-server/src/test/java/org/apache/ambari/server/notifications/EmailDispatcherTest.java
new file mode 100644
index 0000000..1e7689f
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/notifications/EmailDispatcherTest.java
@@ -0,0 +1,117 @@
+/**
+ * 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.ambari.server.notifications;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.state.alert.TargetType;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.util.Modules;
+
+/**
+ *
+ */
+public class EmailDispatcherTest {
+
+ private Injector m_injector;
+ private DispatchFactory m_dispatchFactory;
+
+ @Before
+ public void before() throws Exception {
+ m_injector = Guice.createInjector(Modules.override(
+ new InMemoryDefaultTestModule()).with(new MockModule()));
+
+ m_dispatchFactory = m_injector.getInstance(DispatchFactory.class);
+ }
+
+ /**
+ * Tests that an email without recipients causes a callback error.
+ */
+ @Test
+ public void testNoRecipients() {
+ Notification notification = new Notification();
+ DispatchCallback callback = EasyMock.createMock(DispatchCallback.class);
+ notification.Callback = callback;
+
+ List<String> callbackIds = new ArrayList<String>();
+ callbackIds.add(UUID.randomUUID().toString());
+ notification.CallbackIds = callbackIds;
+
+ callback.onFailure(callbackIds);
+
+ EasyMock.expectLastCall();
+ EasyMock.replay(callback);
+
+ NotificationDispatcher dispatcher = m_dispatchFactory.getDispatcher(TargetType.EMAIL.name());
+ dispatcher.dispatch(notification);
+
+ EasyMock.verify(callback);
+ }
+
+ /**
+ * Tests that an email without properties causes a callback error.
+ */
+ @Test
+ public void testNoEmailPropeties() {
+ Notification notification = new Notification();
+ DispatchCallback callback = EasyMock.createMock(DispatchCallback.class);
+ notification.Callback = callback;
+ notification.Recipients = new ArrayList<Recipient>();
+
+ Recipient recipient = new Recipient();
+ recipient.Identifier = "foo";
+
+ notification.Recipients.add(recipient);
+
+ List<String> callbackIds = new ArrayList<String>();
+ callbackIds.add(UUID.randomUUID().toString());
+ notification.CallbackIds = callbackIds;
+
+ callback.onFailure(callbackIds);
+
+ EasyMock.expectLastCall();
+ EasyMock.replay(callback);
+
+ NotificationDispatcher dispatcher = m_dispatchFactory.getDispatcher(TargetType.EMAIL.name());
+ dispatcher.dispatch(notification);
+
+ EasyMock.verify(callback);
+ }
+
+ /**
+ *
+ */
+ private class MockModule implements Module {
+ /**
+ *
+ */
+ @Override
+ public void configure(Binder binder) {
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/test/java/org/apache/ambari/server/notifications/MockDispatcher.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/notifications/MockDispatcher.java b/ambari-server/src/test/java/org/apache/ambari/server/notifications/MockDispatcher.java
new file mode 100644
index 0000000..616551f
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/notifications/MockDispatcher.java
@@ -0,0 +1,46 @@
+/**
+ * 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.ambari.server.notifications;
+
+/**
+ *
+ */
+public class MockDispatcher implements NotificationDispatcher {
+
+ /**
+ * Constructor.
+ *
+ */
+ public MockDispatcher() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getType() {
+ return "MOCK";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispatch(Notification notification) {
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index 9e638e8..6e4d4af 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -22,6 +22,7 @@ package org.apache.ambari.server.orm.dao;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Calendar;
@@ -63,7 +64,7 @@ public class AlertsDAOTest {
private AlertDefinitionDAO definitionDao;
/**
- *
+ *
*/
@Before
public void setup() throws Exception {
@@ -88,7 +89,7 @@ public class AlertsDAOTest {
definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
}
-
+
List<AlertDefinitionEntity> definitions = definitionDao.findAll();
assertNotNull(definitions);
assertEquals(5, definitions.size());
@@ -142,7 +143,7 @@ public class AlertsDAOTest {
}
/**
- *
+ *
*/
@After
public void teardown() {
@@ -152,7 +153,7 @@ public class AlertsDAOTest {
/**
- *
+ *
*/
@Test
public void testFindAll() {
@@ -162,7 +163,7 @@ public class AlertsDAOTest {
}
/**
- *
+ *
*/
@Test
public void testFindAllCurrent() {
@@ -172,16 +173,16 @@ public class AlertsDAOTest {
}
/**
- *
+ *
*/
@Test
public void testFindCurrentByService() {
List<AlertCurrentEntity> currentAlerts = dao.findCurrent();
AlertCurrentEntity current = currentAlerts.get(0);
AlertHistoryEntity history = current.getAlertHistory();
-
+
assertNotNull(history);
-
+
currentAlerts = dao.findCurrentByService(clusterId,
history.getServiceName());
@@ -193,7 +194,7 @@ public class AlertsDAOTest {
assertNotNull(currentAlerts);
assertEquals(0, currentAlerts.size());
}
-
+
/**
* Test looking up current by a host name.
*/
@@ -211,7 +212,7 @@ public class AlertsDAOTest {
hostDef.setSource("HostService");
hostDef.setSourceType(SourceType.SCRIPT);
definitionDao.create(hostDef);
-
+
// history for the definition
AlertHistoryEntity history = new AlertHistoryEntity();
history.setServiceName(hostDef.getServiceName());
@@ -222,14 +223,14 @@ public class AlertsDAOTest {
history.setAlertTimestamp(Long.valueOf(1L));
history.setHostName("h2");
history.setAlertState(AlertState.OK);
-
+
// current for the history
AlertCurrentEntity current = new AlertCurrentEntity();
current.setOriginalTimestamp(1L);
current.setLatestTimestamp(2L);
current.setAlertHistory(history);
dao.create(current);
-
+
List<AlertCurrentEntity> currentAlerts = dao.findCurrentByHost(clusterId, history.getHostName());
assertNotNull(currentAlerts);
@@ -239,10 +240,10 @@ public class AlertsDAOTest {
assertNotNull(currentAlerts);
assertEquals(0, currentAlerts.size());
- }
+ }
/**
- *
+ *
*/
@Test
public void testFindByState() {
@@ -250,7 +251,7 @@ public class AlertsDAOTest {
allStates.add(AlertState.OK);
allStates.add(AlertState.WARNING);
allStates.add(AlertState.CRITICAL);
-
+
List<AlertHistoryEntity> history = dao.findAll(clusterId, allStates);
assertNotNull(history);
assertEquals(50, history.size());
@@ -263,21 +264,21 @@ public class AlertsDAOTest {
Collections.singletonList(AlertState.CRITICAL));
assertNotNull(history);
assertEquals(10, history.size());
-
+
history = dao.findAll(clusterId,
Collections.singletonList(AlertState.WARNING));
assertNotNull(history);
- assertEquals(0, history.size());
+ assertEquals(0, history.size());
}
/**
- *
+ *
*/
@Test
public void testFindByDate() {
calendar.clear();
calendar.set(2014, Calendar.JANUARY, 1);
-
+
// on or after 1/1/2014
List<AlertHistoryEntity> history = dao.findAll(clusterId,
calendar.getTime(), null);
@@ -311,21 +312,21 @@ public class AlertsDAOTest {
assertNotNull(history);
assertEquals(0, history.size());
}
-
+
@Test
public void testFindCurrentByHostAndName() throws Exception {
AlertCurrentEntity entity = dao.findCurrentByHostAndName(clusterId.longValue(), "h2", "Alert Definition 1");
assertNull(entity);
-
+
entity = dao.findCurrentByHostAndName(clusterId.longValue(), "h1", "Alert Definition 1");
-
+
assertNotNull(entity);
assertNotNull(entity.getAlertHistory());
assertNotNull(entity.getAlertHistory().getAlertDefinition());
}
-
+
/**
- *
+ *
*/
@Test
public void testFindCurrentSummary() throws Exception {
@@ -341,12 +342,12 @@ public class AlertsDAOTest {
dao.merge(h2);
h3.setAlertState(AlertState.UNKNOWN);
dao.merge(h3);
-
+
int ok = 0;
int warn = 0;
int crit = 0;
int unk = 0;
-
+
for (AlertCurrentEntity h : dao.findCurrentByCluster(clusterId.longValue())) {
switch (h.getAlertHistory().getAlertState()) {
case CRITICAL:
@@ -362,22 +363,22 @@ public class AlertsDAOTest {
warn++;
break;
}
-
+
}
-
+
summary = dao.findCurrentCounts(clusterId.longValue(), null, null);
// !!! db-to-db compare
assertEquals(ok, summary.getOkCount());
assertEquals(warn, summary.getWarningCount());
assertEquals(crit, summary.getCriticalCount());
assertEquals(unk, summary.getCriticalCount());
-
+
// !!! expected
assertEquals(2, summary.getOkCount());
assertEquals(1, summary.getWarningCount());
assertEquals(1, summary.getCriticalCount());
assertEquals(1, summary.getCriticalCount());
-
+
summary = dao.findCurrentCounts(clusterId.longValue(), "Service 0", null);
assertEquals(1, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
@@ -389,15 +390,14 @@ public class AlertsDAOTest {
assertEquals(1, summary.getWarningCount());
assertEquals(1, summary.getCriticalCount());
assertEquals(1, summary.getCriticalCount());
-
+
summary = dao.findCurrentCounts(clusterId.longValue(), "foo", null);
assertEquals(0, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(0, summary.getCriticalCount());
assertEquals(0, summary.getCriticalCount());
-
}
-
+
@Test
public void testFindAggregates() throws Exception {
// definition
@@ -412,7 +412,7 @@ public class AlertsDAOTest {
definition.setSource("SourceScript");
definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
-
+
// history record #1 and current
AlertHistoryEntity history = new AlertHistoryEntity();
history.setAlertDefinition(definition);
@@ -425,13 +425,13 @@ public class AlertsDAOTest {
history.setComponentName("");
history.setHostName("h1");
history.setServiceName("ServiceName");
-
+
AlertCurrentEntity current = new AlertCurrentEntity();
current.setAlertHistory(history);
current.setLatestTimestamp(Long.valueOf(1L));
current.setOriginalTimestamp(Long.valueOf(1L));
dao.merge(current);
-
+
// history record #2 and current
history = new AlertHistoryEntity();
history.setAlertDefinition(definition);
@@ -444,35 +444,84 @@ public class AlertsDAOTest {
history.setComponentName("");
history.setHostName("h2");
history.setServiceName("ServiceName");
-
+
current = new AlertCurrentEntity();
current.setAlertHistory(history);
current.setLatestTimestamp(Long.valueOf(1L));
current.setOriginalTimestamp(Long.valueOf(1L));
dao.merge(current);
-
+
AlertSummaryDTO summary = dao.findAggregateCounts(clusterId.longValue(), "many_per_cluster");
assertEquals(2, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(0, summary.getCriticalCount());
assertEquals(0, summary.getUnknownCount());
-
+
AlertCurrentEntity c = dao.findCurrentByHostAndName(clusterId.longValue(),
"h2", "many_per_cluster");
AlertHistoryEntity h = c.getAlertHistory();
h.setAlertState(AlertState.CRITICAL);
dao.merge(h);
-
+
summary = dao.findAggregateCounts(clusterId.longValue(), "many_per_cluster");
assertEquals(2, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(1, summary.getCriticalCount());
assertEquals(0, summary.getUnknownCount());
-
+
summary = dao.findAggregateCounts(clusterId.longValue(), "foo");
assertEquals(0, summary.getOkCount());
assertEquals(0, summary.getWarningCount());
assertEquals(0, summary.getCriticalCount());
assertEquals(0, summary.getUnknownCount());
- }
+ }
+
+ /**
+ * Tests <a
+ * href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=398067">https:/
+ * /bugs.eclipse.org/bugs/show_bug.cgi?id=398067</a> which causes an inner
+ * entity to be stale.
+ */
+ @Test
+ public void testJPAInnerEntityStaleness() {
+ List<AlertCurrentEntity> currents = dao.findCurrent();
+ AlertCurrentEntity current = currents.get(0);
+ AlertHistoryEntity oldHistory = current.getAlertHistory();
+
+ AlertHistoryEntity newHistory = new AlertHistoryEntity();
+ newHistory.setAlertDefinition(oldHistory.getAlertDefinition());
+ newHistory.setAlertInstance(oldHistory.getAlertInstance());
+ newHistory.setAlertLabel(oldHistory.getAlertLabel());
+
+ if (oldHistory.getAlertState() == AlertState.OK) {
+ newHistory.setAlertState(AlertState.CRITICAL);
+ } else {
+ newHistory.setAlertState(AlertState.OK);
+ }
+
+ newHistory.setAlertText("New History");
+ newHistory.setClusterId(oldHistory.getClusterId());
+ newHistory.setAlertTimestamp(System.currentTimeMillis());
+ newHistory.setComponentName(oldHistory.getComponentName());
+ newHistory.setHostName(oldHistory.getHostName());
+ newHistory.setServiceName(oldHistory.getServiceName());
+
+ dao.create(newHistory);
+
+ assertTrue(newHistory.getAlertId().longValue() != oldHistory.getAlertId().longValue());
+
+ current.setAlertHistory(newHistory);
+ dao.merge(current);
+
+ AlertCurrentEntity newCurrent = dao.findCurrentByHostAndName(
+ newHistory.getClusterId(),
+ newHistory.getHostName(),
+ newHistory.getAlertDefinition().getDefinitionName());
+
+ assertEquals(newHistory.getAlertId(),
+ newCurrent.getAlertHistory().getAlertId());
+
+ assertEquals(newHistory.getAlertState(),
+ newCurrent.getAlertHistory().getAlertState());
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d838ca95/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
new file mode 100644
index 0000000..312f297
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/alerts/AlertStateChangedEventTest.java
@@ -0,0 +1,139 @@
+/**
+ * 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.ambari.server.state.alerts;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.server.events.AlertStateChangeEvent;
+import org.apache.ambari.server.events.listeners.AlertServiceStateListener;
+import org.apache.ambari.server.events.listeners.AlertStateChangedListener;
+import org.apache.ambari.server.events.publishers.AlertEventPublisher;
+import org.apache.ambari.server.orm.GuiceJpaInitializer;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.persist.PersistService;
+import com.google.inject.util.Modules;
+
+/**
+ * Tests that {@link AlertStateChangeEvent} instances cause
+ * {@link AlertNoticeEntity} instances to be created.
+ */
+public class AlertStateChangedEventTest {
+
+ private AlertEventPublisher eventPublisher;
+ private AlertDispatchDAO dispatchDao;
+ private Injector injector;
+
+ /**
+ *
+ */
+ @Before
+ public void setup() throws Exception {
+ injector = Guice.createInjector(Modules.override(
+ new InMemoryDefaultTestModule()).with(new MockModule()));
+
+ injector.getInstance(GuiceJpaInitializer.class);
+
+ // force singleton init via Guice so the listener registers with the bus
+ injector.getInstance(AlertServiceStateListener.class);
+ injector.getInstance(AlertStateChangedListener.class);
+
+ dispatchDao = injector.getInstance(AlertDispatchDAO.class);
+ eventPublisher = injector.getInstance(AlertEventPublisher.class);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @After
+ public void teardown() throws Exception {
+ injector.getInstance(PersistService.class).stop();
+ injector = null;
+ }
+
+ /**
+ * Tests that an {@link AlertStateChangeEvent} causes
+ * {@link AlertNoticeEntity} instances to be written.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testAlertNoticeCreationFromEvent() throws Exception {
+ AlertHistoryEntity history = EasyMock.createNiceMock(AlertHistoryEntity.class);
+ AlertStateChangeEvent event = EasyMock.createNiceMock(AlertStateChangeEvent.class);
+ EasyMock.expect(event.getNewHistoricalEntry()).andReturn(history).atLeastOnce();
+
+ EasyMock.replay(history, event);
+
+ // async publishing
+ eventPublisher.publish(event);
+ Thread.sleep(2000);
+
+ EasyMock.verify(dispatchDao, history, event);
+ }
+
+ /**
+ *
+ */
+ private class MockModule implements Module {
+ /**
+ *
+ */
+ @Override
+ public void configure(Binder binder) {
+ AlertTargetEntity alertTarget = EasyMock.createMock(AlertTargetEntity.class);
+ AlertGroupEntity alertGroup = EasyMock.createMock(AlertGroupEntity.class);
+ List<AlertGroupEntity> groups = new ArrayList<AlertGroupEntity>();
+ Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
+
+ targets.add(alertTarget);
+ groups.add(alertGroup);
+
+ EasyMock.expect(alertGroup.getAlertTargets()).andReturn(targets).once();
+
+ AlertDispatchDAO dispatchDao = EasyMock.createMock(AlertDispatchDAO.class);
+ EasyMock.expect(
+ dispatchDao.findGroupsByDefinition(EasyMock.anyObject(AlertDefinitionEntity.class))).andReturn(
+ groups).once();
+
+ dispatchDao.create(EasyMock.anyObject(AlertNoticeEntity.class));
+ EasyMock.expectLastCall().once();
+
+ binder.bind(AlertDispatchDAO.class).toInstance(dispatchDao);
+
+ EasyMock.replay(alertTarget, alertGroup, dispatchDao);
+ }
+ }
+}
[02/50] [abbrv] AMBARI-7021 - Alerts: Create Group and Target REST
Endpoints (jonathanhurley)
Posted by jo...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
new file mode 100644
index 0000000..982dd4b
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java
@@ -0,0 +1,290 @@
+/**
+ * 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.ambari.server.controller.internal;
+
+import static org.easymock.EasyMock.capture;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createStrictMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.resetToStrict;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.metadata.ActionMetadata;
+import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.alert.TargetType;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.inject.Binder;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.google.inject.util.Modules;
+
+/**
+ * {@link AlertTargetResourceProvider} tests.
+ */
+public class AlertTargetResourceProviderTest {
+
+ private static final Long ALERT_TARGET_ID = Long.valueOf(28);
+ private static final String ALERT_TARGET_NAME = "The Administrators";
+ private static final String ALERT_TARGET_DESC = "Admins and Others";
+ private static final String ALERT_TARGET_TYPE = TargetType.EMAIL.name();
+
+ private AlertDispatchDAO m_dao;
+ private Injector m_injector;
+
+ @Before
+ public void before() {
+ m_dao = createStrictMock(AlertDispatchDAO.class);
+
+ m_injector = Guice.createInjector(Modules.override(
+ new InMemoryDefaultTestModule()).with(new MockModule()));
+
+ AlertTargetResourceProvider.init(m_injector);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testGetResourcesNoPredicate() throws Exception {
+ Request request = PropertyHelper.getReadRequest(
+ AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
+ AlertTargetResourceProvider.ALERT_TARGET_ID,
+ AlertTargetResourceProvider.ALERT_TARGET_NAME,
+ AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE);
+
+ expect(m_dao.findAllTargets()).andReturn(getMockEntities());
+ replay(m_dao);
+
+ AmbariManagementController amc = createMock(AmbariManagementController.class);
+ AlertTargetResourceProvider provider = createProvider(amc);
+ Set<Resource> results = provider.getResources(request, null);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+ Assert.assertEquals(ALERT_TARGET_NAME,
+ r.getPropertyValue(AlertTargetResourceProvider.ALERT_TARGET_NAME));
+
+ verify(m_dao);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testGetSingleResource() throws Exception {
+ Request request = PropertyHelper.getReadRequest(
+ AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
+ AlertTargetResourceProvider.ALERT_TARGET_ID,
+ AlertTargetResourceProvider.ALERT_TARGET_NAME,
+ AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE);
+
+ AmbariManagementController amc = createMock(AmbariManagementController.class);
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertTargetResourceProvider.ALERT_TARGET_ID).equals(
+ ALERT_TARGET_ID.toString()).toPredicate();
+
+ expect(m_dao.findTargetById(ALERT_TARGET_ID.longValue())).andReturn(
+ getMockEntities().get(0));
+
+ replay(amc, m_dao);
+
+ AlertTargetResourceProvider provider = createProvider(amc);
+ Set<Resource> results = provider.getResources(request, predicate);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+ Assert.assertEquals(ALERT_TARGET_ID,
+ r.getPropertyValue(AlertTargetResourceProvider.ALERT_TARGET_ID));
+
+ Assert.assertEquals(ALERT_TARGET_NAME,
+ r.getPropertyValue(AlertTargetResourceProvider.ALERT_TARGET_NAME));
+
+ verify(amc, m_dao);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testCreateResources() throws Exception {
+ AmbariManagementController amc = createMock(AmbariManagementController.class);
+ Capture<List<AlertTargetEntity>> listCapture = new Capture<List<AlertTargetEntity>>();
+
+ m_dao.createTargets(capture(listCapture));
+ expectLastCall();
+
+ replay(amc, m_dao);
+
+ AlertTargetResourceProvider provider = createProvider(amc);
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_NAME,
+ ALERT_TARGET_NAME);
+
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
+ ALERT_TARGET_DESC);
+
+ requestProps.put(
+ AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE,
+ ALERT_TARGET_TYPE);
+
+ Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
+ provider.createResources(request);
+
+ Assert.assertTrue(listCapture.hasCaptured());
+ AlertTargetEntity entity = listCapture.getValue().get(0);
+ Assert.assertNotNull(entity);
+
+ Assert.assertEquals(ALERT_TARGET_NAME, entity.getTargetName());
+ Assert.assertEquals(ALERT_TARGET_DESC, entity.getDescription());
+ Assert.assertEquals(ALERT_TARGET_TYPE, entity.getNotificationType());
+
+ verify(amc, m_dao);
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testUpdateResources() throws Exception {
+ }
+
+ /**
+ * @throws Exception
+ */
+ @Test
+ public void testDeleteResources() throws Exception {
+ AmbariManagementController amc = createMock(AmbariManagementController.class);
+ Capture<AlertTargetEntity> entityCapture = new Capture<AlertTargetEntity>();
+ Capture<List<AlertTargetEntity>> listCapture = new Capture<List<AlertTargetEntity>>();
+
+ m_dao.createTargets(capture(listCapture));
+ expectLastCall();
+
+ replay(amc, m_dao);
+
+ AlertTargetResourceProvider provider = createProvider(amc);
+
+ Map<String, Object> requestProps = new HashMap<String, Object>();
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_NAME,
+ ALERT_TARGET_NAME);
+
+ requestProps.put(AlertTargetResourceProvider.ALERT_TARGET_DESCRIPTION,
+ ALERT_TARGET_DESC);
+
+ requestProps.put(
+ AlertTargetResourceProvider.ALERT_TARGET_NOTIFICATION_TYPE,
+ ALERT_TARGET_TYPE);
+
+ Request request = PropertyHelper.getCreateRequest(Collections.singleton(requestProps), null);
+ provider.createResources(request);
+
+ Assert.assertTrue(listCapture.hasCaptured());
+ AlertTargetEntity entity = listCapture.getValue().get(0);
+ Assert.assertNotNull(entity);
+
+ Predicate p = new PredicateBuilder().property(
+ AlertTargetResourceProvider.ALERT_TARGET_ID).equals(
+ ALERT_TARGET_ID.toString()).toPredicate();
+
+ // everything is mocked, there is no DB
+ entity.setTargetId(ALERT_TARGET_ID);
+
+ resetToStrict(m_dao);
+ expect(m_dao.findTargetById(ALERT_TARGET_ID.longValue())).andReturn(entity).anyTimes();
+ m_dao.remove(capture(entityCapture));
+ expectLastCall();
+ replay(m_dao);
+
+ provider.deleteResources(p);
+
+ AlertTargetEntity entity1 = entityCapture.getValue();
+ Assert.assertEquals(ALERT_TARGET_ID, entity1.getTargetId());
+
+ verify(amc, m_dao);
+ }
+
+ /**
+ * @param amc
+ * @return
+ */
+ private AlertTargetResourceProvider createProvider(
+ AmbariManagementController amc) {
+ return new AlertTargetResourceProvider(
+ PropertyHelper.getPropertyIds(Resource.Type.AlertTarget),
+ PropertyHelper.getKeyPropertyIds(Resource.Type.AlertTarget), amc);
+ }
+
+ /**
+ * @return
+ */
+ private List<AlertTargetEntity> getMockEntities() throws Exception {
+ AlertTargetEntity entity = new AlertTargetEntity();
+ entity.setTargetId(ALERT_TARGET_ID);
+ entity.setDescription(ALERT_TARGET_DESC);
+ entity.setTargetName(ALERT_TARGET_NAME);
+ entity.setNotificationType(TargetType.EMAIL.name());
+ return Arrays.asList(entity);
+ }
+
+ /**
+ *
+ */
+ private class MockModule implements Module {
+ /**
+ *
+ */
+ @Override
+ public void configure(Binder binder) {
+ binder.bind(AlertDispatchDAO.class).toInstance(m_dao);
+ binder.bind(Clusters.class).toInstance(
+ EasyMock.createNiceMock(Clusters.class));
+ binder.bind(Cluster.class).toInstance(
+ EasyMock.createNiceMock(Cluster.class));
+ binder.bind(ActionMetadata.class);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4a4644b8/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
index c0bdaa2..d7c8c54 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostTest.java
@@ -105,12 +105,12 @@ public class ServiceComponentHostTest {
metaInfo.init();
clusters.mapHostToCluster("h1","C1");
}
-
+
private void setOsFamily(Host host, String osFamily, String osVersion) {
Map<String, String> hostAttributes = new HashMap<String, String>(2);
hostAttributes.put("os_family", osFamily);
hostAttributes.put("os_release_version", osVersion);
-
+
host.setHostAttributes(hostAttributes);
}
@@ -118,15 +118,16 @@ public class ServiceComponentHostTest {
public void teardown() {
injector.getInstance(PersistService.class).stop();
}
-
+
private ServiceComponentHost createNewServiceComponentHost(
String svc,
String svcComponent,
String hostName, boolean isClient) throws AmbariException{
Cluster c = clusters.getCluster("C1");
-
+
return createNewServiceComponentHost(c, svc, svcComponent, hostName);
}
+
private ServiceComponentHost createNewServiceComponentHost(
Cluster c,
String svc,
@@ -156,18 +157,22 @@ public class ServiceComponentHostTest {
ServiceComponentHost impl = serviceComponentHostFactory.createNew(
sc, hostName);
+
impl.persist();
- Assert.assertEquals(State.INIT,
- impl.getState());
- Assert.assertEquals(State.INIT,
- impl.getDesiredState());
+
+ Assert.assertEquals(State.INIT, impl.getState());
+ Assert.assertEquals(State.INIT, impl.getDesiredState());
Assert.assertEquals(c.getClusterName(), impl.getClusterName());
Assert.assertEquals(c.getClusterId(), impl.getClusterId());
Assert.assertEquals(s.getName(), impl.getServiceName());
Assert.assertEquals(sc.getName(), impl.getServiceComponentName());
Assert.assertEquals(hostName, impl.getHostName());
+
+ Assert.assertNotNull(c.getServiceComponentHosts(hostName));
+
Assert.assertFalse(
impl.getDesiredStackVersion().getStackId().isEmpty());
+
Assert.assertTrue(impl.getStackVersion().getStackId().isEmpty());
return impl;
@@ -264,7 +269,7 @@ public class ServiceComponentHostTest {
ServiceComponentHostEvent installEvent2 = createEvent(impl, ++timestamp,
startEventType);
-
+
boolean exceptionThrown = false;
LOG.info("Transitioning from " + impl.getState() + " " + installEvent2.getType());
try {
@@ -503,7 +508,7 @@ public class ServiceComponentHostTest {
Assert.assertEquals("HDP-1.1.0",
sch.getDesiredStackVersion().getStackId());
}
-
+
@Test
public void testActualConfigs() throws Exception {
ServiceComponentHost sch =
@@ -520,25 +525,25 @@ public class ServiceComponentHostTest {
configGroup.persist();
cluster.addConfigGroup(configGroup);
-
+
Map<String, Map<String,String>> actual =
new HashMap<String, Map<String, String>>() {{
put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
put("core-site", new HashMap<String,String>() {{ put("tag", "version1");
put(configGroup.getId().toString(), "version2"); }});
}};
-
+
sch.updateActualConfigs(actual);
-
+
Map<String, HostConfig> confirm = sch.getActualConfigs();
-
+
Assert.assertEquals(2, confirm.size());
Assert.assertTrue(confirm.containsKey("global"));
Assert.assertTrue(confirm.containsKey("core-site"));
Assert.assertEquals(1, confirm.get("core-site").getConfigGroupOverrides().size());
}
-
+
@Test
public void testConvertToResponse() throws AmbariException {
ServiceComponentHost sch =
@@ -555,7 +560,7 @@ public class ServiceComponentHostTest {
Assert.assertEquals(State.INSTALLED.toString(), r.getDesiredState());
Assert.assertEquals(State.INSTALLING.toString(), r.getLiveState());
Assert.assertEquals("HDP-1.0.0", r.getStackVersion());
-
+
Assert.assertFalse(r.isStaleConfig());
// TODO check configs
@@ -615,62 +620,61 @@ public class ServiceComponentHostTest {
impl.getState());
}
- @Test
- public void TestDisableInVariousStates() throws AmbariException,
- InvalidStateTransitionException {
- ServiceComponentHost sch =
- createNewServiceComponentHost("HDFS", "DATANODE", "h1", false);
- ServiceComponentHostImpl impl = (ServiceComponentHostImpl) sch;
-
- // Test valid states in which host component can be disabled
- long timestamp = 0;
- HashSet<State> validStates = new HashSet<State>();
- validStates.add(State.INSTALLED);
- validStates.add(State.INSTALL_FAILED);
- validStates.add(State.UNKNOWN);
- validStates.add(State.DISABLED);
- for (State state : validStates)
- {
- sch.setState(state);
- ServiceComponentHostEvent disableEvent = createEvent(
- impl, ++timestamp, ServiceComponentHostEventType.HOST_SVCCOMP_DISABLE);
- impl.handleEvent(disableEvent);
- // TODO: At present operation timestamps are not getting updated.
- Assert.assertEquals(-1, impl.getLastOpStartTime());
- Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
- Assert.assertEquals(-1, impl.getLastOpEndTime());
- Assert.assertEquals(State.DISABLED, impl.getState());
- }
-
- // Test invalid states in which host component cannot be disabled
- HashSet<State> invalidStates = new HashSet<State>();
- invalidStates.add(State.INIT);
- invalidStates.add(State.INSTALLING);
- invalidStates.add(State.STARTING);
- invalidStates.add(State.STARTED);
- invalidStates.add(State.STOPPING);
- invalidStates.add(State.UNINSTALLING);
- invalidStates.add(State.UNINSTALLED);
- invalidStates.add(State.UPGRADING);
-
- for(State state : invalidStates)
- {
- sch.setState(state);
- ServiceComponentHostEvent disableEvent = createEvent(
- impl, ++timestamp, ServiceComponentHostEventType.HOST_SVCCOMP_DISABLE);
- boolean exceptionThrown = false;
- try {
- impl.handleEvent(disableEvent);
- } catch (Exception e) {
- exceptionThrown = true;
- }
- Assert.assertTrue("Exception not thrown on invalid event", exceptionThrown);
- // TODO: At present operation timestamps are not getting updated.
- Assert.assertEquals(-1, impl.getLastOpStartTime());
- Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
- Assert.assertEquals(-1, impl.getLastOpEndTime());
- }
- }
+ @Test
+ public void testDisableInVariousStates() throws AmbariException,
+ InvalidStateTransitionException {
+ ServiceComponentHost sch = createNewServiceComponentHost("HDFS",
+ "DATANODE", "h1", false);
+ ServiceComponentHostImpl impl = (ServiceComponentHostImpl) sch;
+
+ // Test valid states in which host component can be disabled
+ long timestamp = 0;
+ HashSet<State> validStates = new HashSet<State>();
+ validStates.add(State.INSTALLED);
+ validStates.add(State.INSTALL_FAILED);
+ validStates.add(State.UNKNOWN);
+ validStates.add(State.DISABLED);
+ for (State state : validStates) {
+ sch.setState(state);
+ ServiceComponentHostEvent disableEvent = createEvent(impl, ++timestamp,
+ ServiceComponentHostEventType.HOST_SVCCOMP_DISABLE);
+ impl.handleEvent(disableEvent);
+ // TODO: At present operation timestamps are not getting updated.
+ Assert.assertEquals(-1, impl.getLastOpStartTime());
+ Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
+ Assert.assertEquals(-1, impl.getLastOpEndTime());
+ Assert.assertEquals(State.DISABLED, impl.getState());
+ }
+
+ // Test invalid states in which host component cannot be disabled
+ HashSet<State> invalidStates = new HashSet<State>();
+ invalidStates.add(State.INIT);
+ invalidStates.add(State.INSTALLING);
+ invalidStates.add(State.STARTING);
+ invalidStates.add(State.STARTED);
+ invalidStates.add(State.STOPPING);
+ invalidStates.add(State.UNINSTALLING);
+ invalidStates.add(State.UNINSTALLED);
+ invalidStates.add(State.UPGRADING);
+
+ for (State state : invalidStates) {
+ sch.setState(state);
+ ServiceComponentHostEvent disableEvent = createEvent(impl, ++timestamp,
+ ServiceComponentHostEventType.HOST_SVCCOMP_DISABLE);
+ boolean exceptionThrown = false;
+ try {
+ impl.handleEvent(disableEvent);
+ } catch (Exception e) {
+ exceptionThrown = true;
+ }
+ Assert.assertTrue("Exception not thrown on invalid event",
+ exceptionThrown);
+ // TODO: At present operation timestamps are not getting updated.
+ Assert.assertEquals(-1, impl.getLastOpStartTime());
+ Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
+ Assert.assertEquals(-1, impl.getLastOpEndTime());
+ }
+ }
@Test
public void testCanBeRemoved() throws Exception{
@@ -688,13 +692,13 @@ public class ServiceComponentHostTest {
}
}
}
-
+
@Test
public void testStaleConfigs() throws Exception {
String stackVersion="HDP-2.0.6";
String clusterName = "c2";
String hostName = "h3";
-
+
clusters.addCluster(clusterName);
clusters.addHost(hostName);
setOsFamily(clusters.getHost(hostName), "redhat", "5.9");
@@ -702,14 +706,14 @@ public class ServiceComponentHostTest {
clusters.getCluster(clusterName).setDesiredStackVersion(
new StackId(stackVersion));
metaInfo.init();
- clusters.mapHostToCluster(hostName, clusterName);
-
+ clusters.mapHostToCluster(hostName, clusterName);
+
Cluster cluster = clusters.getCluster(clusterName);
-
+
ServiceComponentHost sch1 = createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", hostName);
ServiceComponentHost sch2 = createNewServiceComponentHost(cluster, "HDFS", "DATANODE", hostName);
ServiceComponentHost sch3 = createNewServiceComponentHost(cluster, "MAPREDUCE2", "HISTORYSERVER", hostName);
-
+
sch1.setDesiredState(State.INSTALLED);
sch1.setState(State.INSTALLING);
sch1.setStackVersion(new StackId(stackVersion));
@@ -717,10 +721,10 @@ public class ServiceComponentHostTest {
sch2.setDesiredState(State.INSTALLED);
sch2.setState(State.INSTALLING);
sch2.setStackVersion(new StackId(stackVersion));
-
+
sch3.setDesiredState(State.INSTALLED);
sch3.setState(State.INSTALLING);
- sch3.setStackVersion(new StackId(stackVersion));
+ sch3.setStackVersion(new StackId(stackVersion));
Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
@@ -735,7 +739,7 @@ public class ServiceComponentHostTest {
Map<String, Map<String, String>> actual = new HashMap<String, Map<String, String>>() {{
put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
}};
-
+
sch1.updateActualConfigs(actual);
sch2.updateActualConfigs(actual);
sch3.updateActualConfigs(actual);
@@ -746,7 +750,7 @@ public class ServiceComponentHostTest {
// HDP-x/HDFS does not define type 'foo', so changes do not count to stale
Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
-
+
makeConfig(cluster, "hdfs-site", "version1",
new HashMap<String,String>() {{ put("a", "b"); }}, new HashMap<String, Map<String,String>>());
@@ -755,7 +759,7 @@ public class ServiceComponentHostTest {
Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
actual.put("hdfs-site", new HashMap<String, String>() {{ put ("tag", "version1"); }});
-
+
sch1.updateActualConfigs(actual);
// previous value from cache
Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
@@ -765,7 +769,7 @@ public class ServiceComponentHostTest {
// HDP-x/HDFS/hdfs-site up to date, only for sch1
Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-
+
sch2.updateActualConfigs(actual);
// previous value from cache
Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
@@ -775,15 +779,15 @@ public class ServiceComponentHostTest {
// HDP-x/HDFS/hdfs-site up to date for both
Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
-
+
makeConfig(cluster, "hdfs-site", "version2",
- new HashMap<String, String>() {{ put("dfs.journalnode.http-address", "http://foo"); }},
+ new HashMap<String, String>() {{ put("dfs.journalnode.http-address", "http://foo"); }},
new HashMap<String, Map<String,String>>());
// HDP-x/HDFS/hdfs-site updated to changed property
Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-
+
actual.get("hdfs-site").put("tag", "version2");
sch1.updateActualConfigs(actual);
sch2.updateActualConfigs(actual);
@@ -794,13 +798,13 @@ public class ServiceComponentHostTest {
// HDP-x/HDFS/hdfs-site updated to changed property
Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
-
+
// make a host override
final Host host = clusters.getHostsForCluster(cluster.getClusterName()).get(hostName);
Assert.assertNotNull(host);
-
+
final Config c = configFactory.createNew(cluster, "hdfs-site",
- new HashMap<String, String>() {{ put("dfs.journalnode.http-address", "http://goo"); }},
+ new HashMap<String, String>() {{ put("dfs.journalnode.http-address", "http://goo"); }},
new HashMap<String, Map<String,String>>());
c.setTag("version3");
c.persist();
@@ -811,11 +815,11 @@ public class ServiceComponentHostTest {
new HashMap<String, Host>() {{ put("h3", host); }});
configGroup.persist();
cluster.addConfigGroup(configGroup);
-
+
// HDP-x/HDFS/hdfs-site updated host to changed property
Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
-
+
actual.get("hdfs-site").put(configGroup.getId().toString(), "version3");
sch2.updateActualConfigs(actual);
// previous value from cache
@@ -826,7 +830,7 @@ public class ServiceComponentHostTest {
// HDP-x/HDFS/hdfs-site updated host to changed property
Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
-
+
sch1.updateActualConfigs(actual);
// previous value from cache
Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
@@ -836,7 +840,7 @@ public class ServiceComponentHostTest {
// HDP-x/HDFS/hdfs-site updated host to changed property
Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
-
+
// change 'global' property only affecting global/HDFS
makeConfig(cluster, "global", "version2",
new HashMap<String,String>() {{
@@ -844,7 +848,7 @@ public class ServiceComponentHostTest {
put("dfs_namenode_name_dir", "/foo3"); // HDFS only
put("mapred_log_dir_prefix", "/foo2"); // MR2 only
}}, new HashMap<String, Map<String,String>>());
-
+
Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
@@ -867,7 +871,7 @@ public class ServiceComponentHostTest {
sch1.updateActualConfigs(actual);
final Config c1 = configFactory.createNew(cluster, "core-site",
- new HashMap<String, String>() {{ put("fs.trash.interval", "400"); }},
+ new HashMap<String, String>() {{ put("fs.trash.interval", "400"); }},
new HashMap<String, Map<String,String>>());
c1.setTag("version2");
c1.persist();
@@ -912,13 +916,13 @@ public class ServiceComponentHostTest {
sch3.setRestartRequired(false);
Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
}
-
+
@Test
public void testStaleConfigsAttributes() throws Exception {
String stackVersion="HDP-2.0.6";
String clusterName = "c2";
String hostName = "h3";
-
+
clusters.addCluster(clusterName);
clusters.addHost(hostName);
setOsFamily(clusters.getHost(hostName), "redhat", "5.9");
@@ -926,14 +930,14 @@ public class ServiceComponentHostTest {
clusters.getCluster(clusterName).setDesiredStackVersion(
new StackId(stackVersion));
metaInfo.init();
- clusters.mapHostToCluster(hostName, clusterName);
-
+ clusters.mapHostToCluster(hostName, clusterName);
+
Cluster cluster = clusters.getCluster(clusterName);
-
+
ServiceComponentHost sch1 = createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", hostName);
ServiceComponentHost sch2 = createNewServiceComponentHost(cluster, "HDFS", "DATANODE", hostName);
ServiceComponentHost sch3 = createNewServiceComponentHost(cluster, "MAPREDUCE2", "HISTORYSERVER", hostName);
-
+
sch1.setDesiredState(State.INSTALLED);
sch1.setState(State.INSTALLING);
sch1.setStackVersion(new StackId(stackVersion));
@@ -941,10 +945,10 @@ public class ServiceComponentHostTest {
sch2.setDesiredState(State.INSTALLED);
sch2.setState(State.INSTALLING);
sch2.setStackVersion(new StackId(stackVersion));
-
+
sch3.setDesiredState(State.INSTALLED);
sch3.setState(State.INSTALLING);
- sch3.setStackVersion(new StackId(stackVersion));
+ sch3.setStackVersion(new StackId(stackVersion));
Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
@@ -963,7 +967,7 @@ public class ServiceComponentHostTest {
put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
put("hdfs-site", new HashMap<String,String>() {{ put("tag", "version1"); }});
}};
-
+
sch1.updateActualConfigs(actual);
sch2.updateActualConfigs(actual);
sch3.updateActualConfigs(actual);
@@ -972,7 +976,7 @@ public class ServiceComponentHostTest {
new HashMap<String,String>() {{ put("a", "c"); }},new HashMap<String, Map<String,String>>(){{
put("final", new HashMap<String, String>(){{
put("a", "true");
- }});
+ }});
}});
// HDP-x/HDFS does not define type 'foo', so changes do not count to stale
Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
@@ -985,7 +989,7 @@ public class ServiceComponentHostTest {
sch3.setRestartRequired(false);
sch3.updateActualConfigs(actual);
Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
-
+
// Now add config-attributes
Map<String, Map<String, String>> c1PropAttributes = new HashMap<String, Map<String,String>>();
c1PropAttributes.put("final", new HashMap<String, String>());
@@ -1000,7 +1004,7 @@ public class ServiceComponentHostTest {
Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
-
+
// Now change config-attributes
Map<String, Map<String, String>> c2PropAttributes = new HashMap<String, Map<String,String>>();
c2PropAttributes.put("final", new HashMap<String, String>());
@@ -1015,7 +1019,7 @@ public class ServiceComponentHostTest {
Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
-
+
// Now change config-attributes
makeConfig(cluster, "hdfs-site", "version4",
new HashMap<String,String>() {{
@@ -1043,13 +1047,13 @@ public class ServiceComponentHostTest {
cluster.addConfig(config);
cluster.addDesiredConfig("user", config);
}
-
+
@Test
public void testMaintenance() throws Exception {
String stackVersion="HDP-2.0.6";
String clusterName = "c2";
String hostName = "h3";
-
+
clusters.addCluster(clusterName);
clusters.addHost(hostName);
setOsFamily(clusters.getHost(hostName), "redhat", "5.9");
@@ -1057,10 +1061,10 @@ public class ServiceComponentHostTest {
clusters.getCluster(clusterName).setDesiredStackVersion(
new StackId(stackVersion));
metaInfo.init();
- clusters.mapHostToCluster(hostName, clusterName);
-
+ clusters.mapHostToCluster(hostName, clusterName);
+
Cluster cluster = clusters.getCluster(clusterName);
-
+
ServiceComponentHost sch1 = createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", hostName);
ServiceComponentHost sch2 = createNewServiceComponentHost(cluster, "HDFS", "DATANODE", hostName);
ServiceComponentHost sch3 = createNewServiceComponentHost(cluster, "MAPREDUCE2", "HISTORYSERVER", hostName);
@@ -1070,20 +1074,20 @@ public class ServiceComponentHostTest {
pk.setComponentName(sch1.getServiceComponentName());
pk.setServiceName(sch1.getServiceName());
pk.setHostName(hostName);
-
+
HostComponentDesiredStateDAO dao = injector.getInstance(HostComponentDesiredStateDAO.class);
HostComponentDesiredStateEntity entity = dao.findByPK(pk);
Assert.assertEquals(MaintenanceState.OFF, entity.getMaintenanceState());
Assert.assertEquals(MaintenanceState.OFF, sch1.getMaintenanceState());
-
+
sch1.setMaintenanceState(MaintenanceState.ON);
Assert.assertEquals(MaintenanceState.ON, sch1.getMaintenanceState());
-
+
entity = dao.findByPK(pk);
Assert.assertEquals(MaintenanceState.ON, entity.getMaintenanceState());
}
-
-
+
+
}
[18/50] [abbrv] git commit: AMBARI-7221 - Ambari Server REST API
Memory Leak (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7221 - Ambari Server REST API Memory Leak (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/813f16c0
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/813f16c0
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/813f16c0
Branch: refs/heads/trunk
Commit: 813f16c0c731d6f6a35d8462d16194a3abac9f98
Parents: c91fab7
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Sep 9 21:30:46 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Sep 10 09:01:51 2014 -0400
----------------------------------------------------------------------
ambari-server/conf/unix/ambari.properties | 3 ++
.../server/configuration/Configuration.java | 44 ++++++++++++++------
.../ambari/server/controller/AmbariServer.java | 22 +++++++---
3 files changed, 52 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/813f16c0/ambari-server/conf/unix/ambari.properties
----------------------------------------------------------------------
diff --git a/ambari-server/conf/unix/ambari.properties b/ambari-server/conf/unix/ambari.properties
index b77ae32..a0557b7 100644
--- a/ambari-server/conf/unix/ambari.properties
+++ b/ambari-server/conf/unix/ambari.properties
@@ -52,3 +52,6 @@ agent.threadpool.size.max=25
# linux open-file limit
ulimit.open.files=10000
+
+# Server HTTP settings
+server.http.session.inactive_timeout=60
http://git-wip-us.apache.org/repos/asf/ambari/blob/813f16c0/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index a21f98c..2839c2c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -260,12 +260,11 @@ public class Configuration {
private static final String RESOURCES_DIR_DEFAULT =
"/var/lib/ambari-server/resources/";
private static final String ANONYMOUS_AUDIT_NAME_KEY = "anonymous.audit.name";
- private static final String CLIENT_SECURITY_DEFAULT = "local";
+
private static final int CLIENT_API_PORT_DEFAULT = 8080;
private static final int CLIENT_API_SSL_PORT_DEFAULT = 8443;
- private static final String USER_ROLE_NAME_DEFAULT = "user";
- private static final String ADMIN_ROLE_NAME_DEFAULT = "admin";
private static final String LDAP_BIND_ANONYMOUSLY_DEFAULT = "true";
+
//TODO For embedded server only - should be removed later
private static final String LDAP_PRIMARY_URL_DEFAULT = "localhost:33389";
private static final String LDAP_BASE_DN_DEFAULT = "dc=ambari,dc=apache,dc=org";
@@ -309,6 +308,8 @@ public class Configuration {
private static final String VIEW_EXTRACTION_THREADPOOL_TIMEOUT_KEY = "view.extraction.threadpool.timeout";
private static final long VIEW_EXTRACTION_THREADPOOL_TIMEOUT_DEFAULT = 100000L;
+ private static final String SERVER_HTTP_SESSION_INACTIVE_TIMEOUT = "server.http.session.inactive_timeout";
+
private static final Logger LOG = LoggerFactory.getLogger(
Configuration.class);
private Properties properties;
@@ -401,7 +402,7 @@ public class Configuration {
}
configsMap.put(SRVR_CRT_PASS_KEY, password);
- if (this.getApiSSLAuthentication()) {
+ if (getApiSSLAuthentication()) {
LOG.info("API SSL Authentication is turned on.");
File httpsPassFile = new File(configsMap.get(CLIENT_API_SSL_KSTR_DIR_NAME_KEY)
+ File.separator + configsMap.get(CLIENT_API_SSL_CRT_PASS_FILE_NAME_KEY));
@@ -464,14 +465,14 @@ public class Configuration {
private synchronized void loadCredentialProvider() {
if (!credentialProviderInitialized) {
try {
- this.credentialProvider = new CredentialProvider(null,
+ credentialProvider = new CredentialProvider(null,
getMasterKeyLocation(), isMasterKeyPersisted());
} catch (Exception e) {
LOG.info("Credential provider creation failed. Reason: " + e.getMessage());
if (LOG.isDebugEnabled()) {
e.printStackTrace();
}
- this.credentialProvider = null;
+ credentialProvider = null;
}
credentialProviderInitialized = true;
}
@@ -487,8 +488,9 @@ public class Configuration {
//Get property file stream from classpath
InputStream inputStream = Configuration.class.getClassLoader().getResourceAsStream(CONFIG_FILE);
- if (inputStream == null)
+ if (inputStream == null) {
throw new RuntimeException(CONFIG_FILE + " not found in classpath");
+ }
// load the properties
try {
@@ -531,8 +533,9 @@ public class Configuration {
public String getBootSetupAgentPassword() {
String pass = configsMap.get(PASSPHRASE_KEY);
- if (null != pass)
+ if (null != pass) {
return pass;
+ }
// fallback
return properties.getProperty(BOOTSTRAP_SETUP_AGENT_PASSWORD, "password");
@@ -685,8 +688,9 @@ public class Configuration {
public String getLocalDatabaseUrl() {
String dbName = properties.getProperty(SERVER_DB_NAME_KEY);
- if(dbName == null || dbName.isEmpty())
+ if(dbName == null || dbName.isEmpty()) {
throw new RuntimeException("Server DB Name is not configured!");
+ }
return JDBC_LOCAL_URL + dbName;
}
@@ -702,10 +706,11 @@ public class Configuration {
dbpasswd = readPasswordFromStore(passwdProp);
}
- if (dbpasswd != null)
+ if (dbpasswd != null) {
return dbpasswd;
- else
+ } else {
return readPasswordFromFile(passwdProp, SERVER_JDBC_USER_PASSWD_DEFAULT);
+ }
}
public String getRcaDatabaseDriver() {
@@ -724,8 +729,9 @@ public class Configuration {
String passwdProp = properties.getProperty(SERVER_JDBC_RCA_USER_PASSWD_KEY);
if (passwdProp != null) {
String dbpasswd = readPasswordFromStore(passwdProp);
- if (dbpasswd != null)
+ if (dbpasswd != null) {
return dbpasswd;
+ }
}
return readPasswordFromFile(passwdProp, SERVER_JDBC_RCA_USER_PASSWD_DEFAULT);
}
@@ -1081,4 +1087,18 @@ public class Configuration {
return Long.parseLong(properties.getProperty(
VIEW_EXTRACTION_THREADPOOL_TIMEOUT_KEY, String.valueOf(VIEW_EXTRACTION_THREADPOOL_TIMEOUT_DEFAULT)));
}
+
+ /**
+ * Gets the inactivity timeout value, in seconds, for sessions created in
+ * Jetty by Spring Security. Without this timeout value, each request to the
+ * REST APIs will create new sessions that are never reaped since their
+ * default time is -1.
+ *
+ * @return the time value or {@code 60} seconds for default.
+ */
+ public int getHttpSessionInactiveTimeout() {
+ return Integer.parseInt(properties.getProperty(
+ SERVER_HTTP_SESSION_INACTIVE_TIMEOUT,
+ "60"));
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/813f16c0/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index fc74e00..e109f7e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -230,8 +230,18 @@ public class AmbariServer {
root.setErrorHandler(injector.getInstance(AmbariErrorHandler.class));
root.getSessionHandler().setSessionManager(sessionManager);
- //Changing session cookie name to avoid conflicts
- root.getSessionHandler().getSessionManager().setSessionCookie("AMBARISESSIONID");
+ SessionManager jettySessionManager = root.getSessionHandler().getSessionManager();
+
+ // use AMBARISESSIONID instead of JSESSIONID to avoid conflicts with
+ // other services (like HDFS) that run on the same context but a different
+ // port
+ jettySessionManager.setSessionCookie("AMBARISESSIONID");
+
+ // each request that does not use AMBARISESSIONID will create a new
+ // HashedSession in Jetty; these MUST be reaped after inactivity in order
+ // to prevent a memory leak
+ int sessionInactivityTimeout = configs.getHttpSessionInactiveTimeout();
+ jettySessionManager.setMaxInactiveInterval(sessionInactivityTimeout);
GenericWebApplicationContext springWebAppContext = new GenericWebApplicationContext();
springWebAppContext.setServletContext(root.getServletContext());
@@ -246,8 +256,10 @@ public class AmbariServer {
certMan.initRootCert();
- ServletContextHandler agentroot = new ServletContextHandler(serverForAgent,
- "/", ServletContextHandler.SESSIONS );
+ // the agent communication (heartbeats, registration, etc) is stateless
+ // and does not use sessions.
+ ServletContextHandler agentroot = new ServletContextHandler(
+ serverForAgent, "/", ServletContextHandler.NO_SESSIONS);
ServletHolder rootServlet = root.addServlet(DefaultServlet.class, "/");
rootServlet.setInitParameter("dirAllowed", "false");
@@ -262,8 +274,8 @@ public class AmbariServer {
root.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/proxy/*", 1);
root.addFilter(new FilterHolder(new MethodOverrideFilter()), "/api/*", 1);
root.addFilter(new FilterHolder(new MethodOverrideFilter()), "/proxy/*", 1);
- agentroot.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/agent/*", 1);
+ agentroot.addFilter(new FilterHolder(injector.getInstance(AmbariPersistFilter.class)), "/agent/*", 1);
agentroot.addFilter(SecurityFilter.class, "/*", 1);
if (configs.getApiAuthentication()) {
[24/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Conflicts:
ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/17b8e799
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/17b8e799
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/17b8e799
Branch: refs/heads/trunk
Commit: 17b8e799048b96c7fb1074a21c52e2e7ecaaf607
Parents: 760bedf bd04a28
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Sep 16 08:50:14 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Sep 16 08:50:14 2014 -0400
----------------------------------------------------------------------
.../ui/admin-web/app/views/leftNavbar.html | 2 +-
ambari-agent/src/main/package/rpm/preremove.sh | 2 +-
.../ambari_agent/TestActualConfigHandler.py | 6 +-
.../test/python/ambari_agent/TestLiveStatus.py | 4 +-
.../TestExecuteHadoopResource.py | 37 ++-
ambari-server/docs/api/v1/services.md | 7 -
.../stackadvisor/StackAdvisorRunner.java | 10 +-
.../server/controller/AmbariHandlerList.java | 33 +-
.../AmbariPrivilegeResourceProvider.java | 2 +-
.../internal/BaseBlueprintProcessor.java | 2 +-
.../BlueprintConfigurationProcessor.java | 30 +-
.../RecommendationResourceProvider.java | 6 +-
.../internal/ValidationResourceProvider.java | 6 +-
.../internal/ViewInstanceResourceProvider.java | 10 +-
.../ViewPermissionResourceProvider.java | 4 +-
.../internal/ViewPrivilegeResourceProvider.java | 8 +-
.../ambari/server/metadata/ActionMetadata.java | 1 -
.../ambari/server/orm/entities/ViewEntity.java | 8 +-
.../org/apache/ambari/server/state/Service.java | 8 +-
.../server/upgrade/UpgradeCatalog170.java | 142 +++++++-
.../apache/ambari/server/view/ViewRegistry.java | 10 +-
ambari-server/src/main/package/rpm/preremove.sh | 2 +-
.../custom_actions/validate_configs.py | 2 -
.../scripts/shared_initialization.py | 3 +-
.../stacks/HDP/1.3.2/role_command_order.json | 4 +-
.../services/HIVE/configuration/webhcat-env.xml | 54 +++
.../HIVE/configuration/webhcat-site.xml | 156 +++++++++
.../stacks/HDP/1.3.2/services/HIVE/metainfo.xml | 154 +++++----
.../HIVE/package/files/templetonSmoke.sh | 96 ++++++
.../services/HIVE/package/scripts/params.py | 31 +-
.../HIVE/package/scripts/service_check.py | 2 +
.../HIVE/package/scripts/status_params.py | 3 +
.../services/HIVE/package/scripts/webhcat.py | 107 ++++++
.../HIVE/package/scripts/webhcat_server.py | 53 +++
.../HIVE/package/scripts/webhcat_service.py | 40 +++
.../package/scripts/webhcat_service_check.py | 42 +++
.../HDP/1.3.2/services/NAGIOS/metainfo.xml | 2 +-
.../templates/hadoop-servicegroups.cfg.j2 | 6 -
.../package/templates/hadoop-services.cfg.j2 | 2 +-
.../WEBHCAT/configuration/webhcat-env.xml | 54 ---
.../WEBHCAT/configuration/webhcat-site.xml | 156 ---------
.../HDP/1.3.2/services/WEBHCAT/metainfo.xml | 103 ------
.../WEBHCAT/package/files/templetonSmoke.sh | 96 ------
.../WEBHCAT/package/scripts/__init__.py | 20 --
.../services/WEBHCAT/package/scripts/params.py | 78 -----
.../WEBHCAT/package/scripts/service_check.py | 44 ---
.../WEBHCAT/package/scripts/status_params.py | 26 --
.../services/WEBHCAT/package/scripts/webhcat.py | 107 ------
.../WEBHCAT/package/scripts/webhcat_server.py | 53 ---
.../WEBHCAT/package/scripts/webhcat_service.py | 40 ---
.../stacks/HDP/1.3/role_command_order.json | 4 +-
.../stacks/HDP/1.3/services/HIVE/metainfo.xml | 5 -
.../services/HDFS/configuration/core-site.xml | 9 +
.../scripts/shared_initialization.py | 3 +-
.../stacks/HDP/2.0.6/role_command_order.json | 4 +-
.../services/HDFS/configuration/core-site.xml | 10 +
.../services/HIVE/configuration/webhcat-env.xml | 54 +++
.../HIVE/configuration/webhcat-site.xml | 138 ++++++++
.../stacks/HDP/2.0.6/services/HIVE/metainfo.xml | 165 +++++-----
.../HIVE/package/files/templetonSmoke.sh | 96 ++++++
.../services/HIVE/package/scripts/params.py | 44 ++-
.../HIVE/package/scripts/service_check.py | 2 +
.../HIVE/package/scripts/status_params.py | 1 +
.../services/HIVE/package/scripts/webhcat.py | 112 +++++++
.../HIVE/package/scripts/webhcat_server.py | 53 +++
.../HIVE/package/scripts/webhcat_service.py | 40 +++
.../package/scripts/webhcat_service_check.py | 41 +++
.../HDP/2.0.6/services/NAGIOS/metainfo.xml | 2 +-
.../templates/hadoop-servicegroups.cfg.j2 | 8 +-
.../package/templates/hadoop-services.cfg.j2 | 2 +-
.../services/OOZIE/package/scripts/params.py | 3 +-
.../services/SQOOP/package/scripts/params.py | 12 +-
.../WEBHCAT/configuration/webhcat-env.xml | 54 ---
.../WEBHCAT/configuration/webhcat-site.xml | 138 --------
.../HDP/2.0.6/services/WEBHCAT/metainfo.xml | 110 -------
.../WEBHCAT/package/files/templetonSmoke.sh | 96 ------
.../WEBHCAT/package/scripts/__init__.py | 20 --
.../services/WEBHCAT/package/scripts/params.py | 102 ------
.../WEBHCAT/package/scripts/service_check.py | 45 ---
.../WEBHCAT/package/scripts/status_params.py | 26 --
.../services/WEBHCAT/package/scripts/webhcat.py | 112 -------
.../WEBHCAT/package/scripts/webhcat_server.py | 53 ---
.../WEBHCAT/package/scripts/webhcat_service.py | 40 ---
.../HDP/2.1.GlusterFS/role_command_order.json | 4 +-
.../2.1.GlusterFS/services/HIVE/metainfo.xml | 100 +++---
.../WEBHCAT/configuration/webhcat-site.xml | 143 --------
.../2.1.GlusterFS/services/WEBHCAT/metainfo.xml | 46 ---
.../stacks/HDP/2.1/role_command_order.json | 3 +-
.../services/FALCON/package/scripts/params.py | 9 +-
.../stacks/HDP/2.1/services/HIVE/metainfo.xml | 62 +++-
.../services/STORM/configuration/storm-env.xml | 2 +-
.../WEBHCAT/configuration/webhcat-site.xml | 143 --------
.../HDP/2.1/services/WEBHCAT/metainfo.xml | 47 ---
.../stacks/HDP/2.2.1/services/HIVE/metainfo.xml | 4 -
.../HDP/2.2.1/services/WEBHCAT/metainfo.xml | 26 --
.../resources/stacks/HDP/2.2/repos/repoinfo.xml | 27 +-
.../stacks/HDP/2.2/services/FALCON/metainfo.xml | 12 +-
.../stacks/HDP/2.2/services/FLUME/metainfo.xml | 2 +-
.../stacks/HDP/2.2/services/HBASE/metainfo.xml | 2 +-
.../services/HDFS/configuration/hadoop-env.xml | 2 +-
.../services/HDFS/configuration/hdfs-site.xml | 2 +-
.../stacks/HDP/2.2/services/HDFS/metainfo.xml | 4 +-
.../HIVE/configuration/webhcat-site.xml | 59 ++++
.../stacks/HDP/2.2/services/HIVE/metainfo.xml | 48 ++-
.../services/OOZIE/configuration/oozie-site.xml | 2 +-
.../stacks/HDP/2.2/services/OOZIE/metainfo.xml | 27 +-
.../stacks/HDP/2.2/services/PIG/metainfo.xml | 5 +-
.../stacks/HDP/2.2/services/SQOOP/metainfo.xml | 15 +-
.../stacks/HDP/2.2/services/STORM/metainfo.xml | 12 +-
.../stacks/HDP/2.2/services/TEZ/metainfo.xml | 2 +-
.../WEBHCAT/configuration/webhcat-site.xml | 59 ----
.../HDP/2.2/services/WEBHCAT/metainfo.xml | 2 +-
.../YARN/configuration-mapred/mapred-site.xml | 2 +-
.../services/YARN/configuration/yarn-site.xml | 2 +-
.../stacks/HDP/2.2/services/YARN/metainfo.xml | 6 +-
.../HDP/2.2/services/ZOOKEEPER/metainfo.xml | 2 +-
.../api/util/StackExtensionHelperTest.java | 29 +-
.../AmbariManagementControllerTest.java | 6 +-
.../AmbariPrivilegeResourceProviderTest.java | 2 +-
.../internal/BaseBlueprintProcessorTest.java | 27 +-
.../BlueprintConfigurationProcessorTest.java | 21 ++
.../ViewInstanceResourceProviderTest.java | 10 +-
.../ViewPermissionResourceProviderTest.java | 4 +-
.../ViewPrivilegeResourceProviderTest.java | 2 +-
.../server/orm/entities/ViewEntityTest.java | 22 +-
.../server/upgrade/UpgradeCatalog170Test.java | 241 ++++++++++----
.../ambari/server/view/ViewRegistryTest.java | 28 +-
.../1.3.2/HIVE/test_hive_service_check.py | 20 ++
.../stacks/1.3.2/HIVE/test_webhcat_server.py | 258 +++++++++++++++
.../stacks/1.3.2/WEBHCAT/test_webhcat_server.py | 258 ---------------
.../1.3.2/WEBHCAT/test_webhcat_service_check.py | 61 ----
.../hooks/before-START/test_before_start.py | 6 +-
.../2.0.6/HIVE/test_hive_service_check.py | 21 ++
.../stacks/2.0.6/HIVE/test_webhcat_server.py | 270 +++++++++++++++
.../stacks/2.0.6/WEBHCAT/test_webhcat_server.py | 273 ---------------
.../2.0.6/WEBHCAT/test_webhcat_service_check.py | 61 ----
.../hooks/before-START/test_before_start.py | 6 +-
.../stacks/HDP/2.0.5/services/HIVE/metainfo.xml | 74 +++++
.../WEBHCAT/configuration/webhcat-site.xml | 126 -------
.../HDP/2.0.5/services/WEBHCAT/metainfo.xml | 102 ------
.../HDP/2.0.6/services/WEBHCAT/metainfo.xml | 28 --
.../org/apache/ambari/view/ViewDefinition.java | 8 +-
ambari-web/app/assets/data/alerts/alerts.json | 2 +-
.../app/assets/data/dashboard/services.json | 117 -------
.../app/assets/data/hosts/HDP2/hosts.json | 11 +-
.../data/services/HDP2/components_state.json | 9 -
.../app/assets/data/services/HDP2/services.json | 16 -
.../services/host_component_actual_configs.json | 118 +------
.../data/stacks/HDP-2.1/recommendations.json | 2 +-
.../stacks/HDP-2.1/recommendations_configs.json | 2 +-
.../data/stacks/HDP-2.1/service_components.json | 218 +++++-------
.../data/wizard/stack/hdp/version/1.2.0.json | 18 -
.../data/wizard/stack/hdp/version/1.2.1.json | 11 -
.../data/wizard/stack/hdp/version/1.3.0.json | 11 -
.../data/wizard/stack/hdp/version/1.3.1.json | 11 -
.../data/wizard/stack/hdp/version/2.0.1.json | 11 -
.../data/wizard/stack/hdp/version/2.0.5.json | 11 -
.../data/wizard/stack/hdp/version0.1.json | 17 -
.../wizard/stack/hdp/version01/HCATALOG.json | 20 --
.../wizard/stack/hdp/version1.2.1/HCATALOG.json | 4 -
.../wizard/stack/hdp/version1.3.0/HCATALOG.json | 4 -
.../wizard/stack/hdp/version131/HCATALOG.json | 4 -
.../wizard/stack/hdp/version2.0.1/HCATALOG.json | 4 -
.../app/assets/data/wizard/stack/stacks.json | 55 ----
.../main/admin/security/add/step2.js | 4 +-
.../main/admin/serviceAccounts_controller.js | 2 +-
.../controllers/main/service/info/configs.js | 130 +++++---
ambari-web/app/controllers/main/service/item.js | 2 +-
.../app/controllers/wizard/step5_controller.js | 92 ++++--
.../app/controllers/wizard/step6_controller.js | 31 +-
.../app/controllers/wizard/step7_controller.js | 18 +-
.../app/controllers/wizard/step8_controller.js | 3 +-
ambari-web/app/data/HDP2/secure_configs.js | 15 +-
ambari-web/app/data/HDP2/secure_mapping.js | 12 +-
ambari-web/app/data/HDP2/secure_properties.js | 8 +-
ambari-web/app/data/HDP2/site_properties.js | 22 +-
ambari-web/app/data/secure_configs.js | 15 +-
ambari-web/app/data/secure_mapping.js | 12 +-
ambari-web/app/data/secure_properties.js | 8 +-
ambari-web/app/data/site_properties.js | 22 +-
ambari-web/app/mixins/common/serverValidator.js | 8 +-
.../app/mixins/wizard/addSecurityConfigs.js | 2 +-
ambari-web/app/models/service.js | 12 -
ambari-web/app/models/stack_service.js | 15 +-
ambari-web/app/styles/application.less | 14 +
ambari-web/app/templates/application.hbs | 2 +-
.../app/templates/main/service/info/configs.hbs | 2 +-
.../app/templates/main/service/info/summary.hbs | 26 +-
ambari-web/app/utils/ajax/ajax.js | 9 +
.../app/utils/batch_scheduled_requests.js | 1 -
ambari-web/app/utils/config.js | 2 +-
ambari-web/app/utils/helper.js | 1 -
.../views/common/configs/config_history_flow.js | 2 +-
.../app/views/common/quick_view_link_view.js | 6 +-
.../app/views/main/host/configs_service_menu.js | 2 +-
.../app/views/main/service/info/summary.js | 64 +++-
ambari-web/app/views/main/service/item.js | 7 +-
ambari-web/app/views/main/service/menu.js | 8 +-
.../security/add/addSecurity_controller_test.js | 2 -
.../main/service/info/config_test.js | 8 +-
.../test/controllers/wizard/step4_test.js | 34 +-
.../test/controllers/wizard/step8_test.js | 14 +-
ambari-web/test/models/service_test.js | 8 -
ambari-web/test/models/stack_service_test.js | 8 -
ambari-web/test/service_components.js | 229 +++++--------
ambari-web/test/utils/helper_test.js | 1 -
.../src/addOns/nagios/scripts/nagios_alerts.php | 8 +-
.../apache/ambari/msi/ClusterDefinition.java | 2 +-
.../ambari/msi/ClusterDefinitionTest.java | 4 -
.../Scripts/HostComponentsDiscovery.ps1 | 3 +-
.../slider-core/0.41.0/slider-core-0.41.0.jar | Bin 1125710 -> 0 bytes
.../slider-core/0.41.0/slider-core-0.41.0.pom | 25 --
.../slider-core/0.51.0/slider-core-0.51.0.jar | Bin 0 -> 1144236 bytes
.../slider-core/0.51.0/slider-core-0.51.0.pom | 25 ++
.../slider/slider-core/maven-metadata-local.xml | 6 +-
contrib/views/slider/lib/slider-agent.tar.gz | Bin 0 -> 480985 bytes
contrib/views/slider/pom.xml | 10 +-
.../view/slider/SliderAppsResourceProvider.java | 15 +-
.../view/slider/SliderAppsViewController.java | 9 +-
.../slider/SliderAppsViewControllerImpl.java | 329 +++++++++++--------
.../view/slider/rest/SliderAppsResource.java | 2 +-
.../ambari/view/slider/rest/client/Metric.java | 3 +
.../assets/data/resource/service_status.json | 12 -
.../main/resources/ui/app/models/slider_app.js | 2 +-
.../resources/ui/app/styles/application.less | 1 -
225 files changed, 3669 insertions(+), 4671 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/17b8e799/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
index 4ee2ac2,75635cc..435dd37
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog170.java
@@@ -18,75 -18,30 +18,88 @@@
package org.apache.ambari.server.upgrade;
-import com.google.common.reflect.TypeToken;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
+import java.lang.reflect.Type;
-
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
++import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
++import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
- import java.util.Date;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Expression;
+import javax.persistence.criteria.Predicate;
+import javax.persistence.criteria.Root;
+
- import com.google.common.reflect.TypeToken;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo;
-import org.apache.ambari.server.orm.dao.*;
-import org.apache.ambari.server.orm.entities.*;
-import org.apache.ambari.server.state.*;
+import org.apache.ambari.server.orm.dao.ClusterDAO;
++import org.apache.ambari.server.orm.dao.ClusterServiceDAO;
++import org.apache.ambari.server.orm.dao.ConfigGroupConfigMappingDAO;
+import org.apache.ambari.server.orm.dao.DaoUtils;
++import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
++import org.apache.ambari.server.orm.dao.HostComponentStateDAO;
+import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
+import org.apache.ambari.server.orm.dao.KeyValueDAO;
+import org.apache.ambari.server.orm.dao.PermissionDAO;
+import org.apache.ambari.server.orm.dao.PrincipalDAO;
+import org.apache.ambari.server.orm.dao.PrincipalTypeDAO;
+import org.apache.ambari.server.orm.dao.PrivilegeDAO;
+import org.apache.ambari.server.orm.dao.ResourceDAO;
+import org.apache.ambari.server.orm.dao.ResourceTypeDAO;
- import org.apache.ambari.server.orm.dao.ConfigGroupConfigMappingDAO;
++import org.apache.ambari.server.orm.dao.ServiceComponentDesiredStateDAO;
++import org.apache.ambari.server.orm.dao.ServiceDesiredStateDAO;
+import org.apache.ambari.server.orm.dao.UserDAO;
+import org.apache.ambari.server.orm.dao.ViewDAO;
+import org.apache.ambari.server.orm.dao.ViewInstanceDAO;
++import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
- import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
++import org.apache.ambari.server.orm.entities.ClusterServiceEntity;
++import org.apache.ambari.server.orm.entities.ClusterServiceEntityPK;
+import org.apache.ambari.server.orm.entities.ConfigGroupConfigMappingEntity;
- import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
++import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
++import org.apache.ambari.server.orm.entities.HostComponentStateEntity;
++import org.apache.ambari.server.orm.entities.HostRoleCommandEntity;
+import org.apache.ambari.server.orm.entities.HostRoleCommandEntity_;
+import org.apache.ambari.server.orm.entities.KeyValueEntity;
+import org.apache.ambari.server.orm.entities.PermissionEntity;
+import org.apache.ambari.server.orm.entities.PrincipalEntity;
+import org.apache.ambari.server.orm.entities.PrincipalTypeEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.apache.ambari.server.orm.entities.ResourceEntity;
+import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
++import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntity;
++import org.apache.ambari.server.orm.entities.ServiceComponentDesiredStateEntityPK;
++import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity;
++import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntityPK;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.orm.entities.ViewEntity;
+import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.ambari.server.state.alert.Scope;
import org.apache.ambari.server.utils.StageUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.persistence.EntityManager;
-import javax.persistence.TypedQuery;
-import javax.persistence.criteria.*;
-import java.lang.reflect.Type;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.*;
-import java.util.Map.Entry;
++import com.google.common.reflect.TypeToken;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
/**
* Upgrade catalog for version 1.7.0.
@@@ -598,6 -556,117 +614,118 @@@ public class UpgradeCatalog170 extends
moveConfigGroupsGlobalToEnv();
}
+ public void moveHcatalogIntoHiveService() throws AmbariException {
+ final String serviceName = "HIVE";
+ final String serviceNameToBeDeleted = "HCATALOG";
+ final String componentName = "HCAT";
+ moveComponentsIntoService(serviceName, serviceNameToBeDeleted, componentName);
+ }
+
+ private void moveWebHcatIntoHiveService() throws AmbariException {
+ final String serviceName = "HIVE";
+ final String serviceNameToBeDeleted = "WEBHCAT";
+ final String componentName = "WEBHCAT_SERVER";
+ moveComponentsIntoService(serviceName, serviceNameToBeDeleted, componentName);
+ }
+
+ private void moveComponentsIntoService(String serviceName, String serviceNameToBeDeleted, String componentName) throws AmbariException {
+ /**
+ * 1. ADD servicecomponentdesiredstate: Add HCAT HIVE entry:
+ * 2. Update hostcomponentdesiredstate: service_name to HIVE where service_name is HCATALOG:
+ * 3. Update hostcomponentstate: service_name to HIVE where service_name is HCATALOG:
+ * 4. DELETE servicecomponentdesiredstate: where component_name is HCAT and service_name is HCATALOG :
+ * 5. Delete servicedesiredstate where service_name is HCATALOG:
+ * 6. Delete clusterservices where service_name is HCATALOG:
+ */
+ ClusterDAO clusterDAO = injector.getInstance(ClusterDAO.class);
+ ClusterServiceDAO clusterServiceDAO = injector.getInstance(ClusterServiceDAO.class);
+ ServiceDesiredStateDAO serviceDesiredStateDAO = injector.getInstance(ServiceDesiredStateDAO.class);
+ ServiceComponentDesiredStateDAO serviceComponentDesiredStateDAO = injector.getInstance(ServiceComponentDesiredStateDAO.class);
+ HostComponentDesiredStateDAO hostComponentDesiredStateDAO = injector.getInstance(HostComponentDesiredStateDAO.class);
+ HostComponentStateDAO hostComponentStateDAO = injector.getInstance(HostComponentStateDAO.class);
+
+ List<ClusterEntity> clusterEntities = clusterDAO.findAll();
+ for (final ClusterEntity clusterEntity : clusterEntities) {
+ ServiceComponentDesiredStateEntityPK pkHCATInHcatalog = new ServiceComponentDesiredStateEntityPK();
+ pkHCATInHcatalog.setComponentName(componentName);
+ pkHCATInHcatalog.setClusterId(clusterEntity.getClusterId());
+ pkHCATInHcatalog.setServiceName(serviceNameToBeDeleted);
+ ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntityToDelete = serviceComponentDesiredStateDAO.findByPK(pkHCATInHcatalog);
+
- if (serviceComponentDesiredStateEntityToDelete == null)
++ if (serviceComponentDesiredStateEntityToDelete == null) {
+ continue;
++ }
+
+ ServiceDesiredStateEntityPK serviceDesiredStateEntityPK = new ServiceDesiredStateEntityPK();
+ serviceDesiredStateEntityPK.setClusterId(clusterEntity.getClusterId());
+ serviceDesiredStateEntityPK.setServiceName(serviceNameToBeDeleted);
+ ServiceDesiredStateEntity serviceDesiredStateEntity = serviceDesiredStateDAO.findByPK(serviceDesiredStateEntityPK);
+
+ ClusterServiceEntityPK clusterServiceEntityToBeDeletedPK = new ClusterServiceEntityPK();
+ clusterServiceEntityToBeDeletedPK.setClusterId(clusterEntity.getClusterId());
+ clusterServiceEntityToBeDeletedPK.setServiceName(serviceNameToBeDeleted);
+ ClusterServiceEntity clusterServiceEntityToBeDeleted = clusterServiceDAO.findByPK(clusterServiceEntityToBeDeletedPK);
+
+ ClusterServiceEntityPK clusterServiceEntityPK = new ClusterServiceEntityPK();
+ clusterServiceEntityPK.setClusterId(clusterEntity.getClusterId());
+ clusterServiceEntityPK.setServiceName(serviceName);
+
+
+ ClusterServiceEntity clusterServiceEntity = clusterServiceDAO.findByPK(clusterServiceEntityPK);
+
+ ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity = new ServiceComponentDesiredStateEntity();
+ serviceComponentDesiredStateEntity.setServiceName(serviceName);
+ serviceComponentDesiredStateEntity.setComponentName(serviceComponentDesiredStateEntityToDelete.getComponentName());
+ serviceComponentDesiredStateEntity.setClusterId(clusterEntity.getClusterId());
+ serviceComponentDesiredStateEntity.setDesiredStackVersion(serviceComponentDesiredStateEntityToDelete.getDesiredStackVersion());
+ serviceComponentDesiredStateEntity.setDesiredState(serviceComponentDesiredStateEntityToDelete.getDesiredState());
+ serviceComponentDesiredStateEntity.setClusterServiceEntity(clusterServiceEntity);
+ //serviceComponentDesiredStateDAO.create(serviceComponentDesiredStateEntity);
+
+ Iterator<HostComponentDesiredStateEntity> hostComponentDesiredStateIterator = serviceComponentDesiredStateEntityToDelete.getHostComponentDesiredStateEntities().iterator();
+ Iterator<HostComponentStateEntity> hostComponentStateIterator = serviceComponentDesiredStateEntityToDelete.getHostComponentStateEntities().iterator();
+
+ while (hostComponentDesiredStateIterator.hasNext()) {
+ HostComponentDesiredStateEntity hcDesiredStateEntityToBeDeleted = hostComponentDesiredStateIterator.next();
+ HostComponentDesiredStateEntity hostComponentDesiredStateEntity = new HostComponentDesiredStateEntity();
+ hostComponentDesiredStateEntity.setClusterId(clusterEntity.getClusterId());
+ hostComponentDesiredStateEntity.setComponentName(hcDesiredStateEntityToBeDeleted.getComponentName());
+ hostComponentDesiredStateEntity.setDesiredStackVersion(hcDesiredStateEntityToBeDeleted.getDesiredStackVersion());
+ hostComponentDesiredStateEntity.setDesiredState(hcDesiredStateEntityToBeDeleted.getDesiredState());
+ hostComponentDesiredStateEntity.setHostName(hcDesiredStateEntityToBeDeleted.getHostName());
+ hostComponentDesiredStateEntity.setHostEntity(hcDesiredStateEntityToBeDeleted.getHostEntity());
+ hostComponentDesiredStateEntity.setAdminState(hcDesiredStateEntityToBeDeleted.getAdminState());
+ hostComponentDesiredStateEntity.setMaintenanceState(hcDesiredStateEntityToBeDeleted.getMaintenanceState());
+ hostComponentDesiredStateEntity.setRestartRequired(hcDesiredStateEntityToBeDeleted.isRestartRequired());
+ hostComponentDesiredStateEntity.setServiceName(serviceName);
+ hostComponentDesiredStateEntity.setServiceComponentDesiredStateEntity(serviceComponentDesiredStateEntity);
+ hostComponentDesiredStateDAO.merge(hostComponentDesiredStateEntity);
+ hostComponentDesiredStateDAO.remove(hcDesiredStateEntityToBeDeleted);
+ }
+
+ while (hostComponentStateIterator.hasNext()) {
+ HostComponentStateEntity hcStateToBeDeleted = hostComponentStateIterator.next();
+ HostComponentStateEntity hostComponentStateEntity = new HostComponentStateEntity();
+ hostComponentStateEntity.setClusterId(clusterEntity.getClusterId());
+ hostComponentStateEntity.setComponentName(hcStateToBeDeleted.getComponentName());
+ hostComponentStateEntity.setCurrentStackVersion(hcStateToBeDeleted.getCurrentStackVersion());
+ hostComponentStateEntity.setCurrentState(hcStateToBeDeleted.getCurrentState());
+ hostComponentStateEntity.setHostName(hcStateToBeDeleted.getHostName());
+ hostComponentStateEntity.setHostEntity(hcStateToBeDeleted.getHostEntity());
+ hostComponentStateEntity.setServiceName(serviceName);
+ hostComponentStateEntity.setServiceComponentDesiredStateEntity(serviceComponentDesiredStateEntity);
+ hostComponentStateDAO.merge(hostComponentStateEntity);
+ hostComponentStateDAO.remove(hcStateToBeDeleted);
+ }
+ serviceComponentDesiredStateEntity.setClusterServiceEntity(clusterServiceEntity);
+ serviceComponentDesiredStateDAO.merge(serviceComponentDesiredStateEntity);
+ serviceComponentDesiredStateDAO.remove(serviceComponentDesiredStateEntityToDelete);
+ serviceDesiredStateDAO.remove(serviceDesiredStateEntity);
+ clusterServiceDAO.remove(clusterServiceEntityToBeDeleted);
+ }
+ }
+
+
private void moveConfigGroupsGlobalToEnv() throws AmbariException {
final ConfigGroupConfigMappingDAO confGroupConfMappingDAO = injector.getInstance(ConfigGroupConfigMappingDAO.class);
ConfigHelper configHelper = injector.getInstance(ConfigHelper.class);
http://git-wip-us.apache.org/repos/asf/ambari/blob/17b8e799/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
diff --cc ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
index 6c868b4,8a3e270..8966fc0
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
@@@ -3131,7 -3059,7 +3131,7 @@@ public class AmbariManagementController
Assert.assertNull(stage1.getExecutionCommandWrapper(host2, "DATANODE"));
Assert.assertNotNull(stage3.getExecutionCommandWrapper(host1, "HBASE_SERVICE_CHECK"));
Assert.assertNotNull(stage2.getExecutionCommandWrapper(host2, "HDFS_SERVICE_CHECK"));
--
++
Type type = new TypeToken<Map<String, String>>() {}.getType();
@@@ -6516,7 -6442,7 +6516,7 @@@
}
}
}
--
++
Type type = new TypeToken<Map<String, String>>(){}.getType();
for (Stage stage : actionDB.getAllStages(requestId)){
Map<String, String> hostParamsStage = StageUtils.getGson().fromJson(stage.getHostParamsStage(), type);
http://git-wip-us.apache.org/repos/asf/ambari/blob/17b8e799/ambari-web/app/utils/ajax/ajax.js
----------------------------------------------------------------------
[06/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/52d1af76
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/52d1af76
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/52d1af76
Branch: refs/heads/trunk
Commit: 52d1af7634e4a13ea4f9b94e34a1734c2bcd416c
Parents: 76fc94e 869b00c
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Thu Aug 28 13:49:15 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Thu Aug 28 13:49:15 2014 -0400
----------------------------------------------------------------------
.../resource_management/TestPackageResource.py | 6 +-
.../core/providers/package/apt.py | 11 +-
.../libraries/script/script.py | 9 +-
ambari-server/pom.xml | 22 ++
.../ambari/server/api/query/QueryImpl.java | 1 -
.../resources/ResourceInstanceFactoryImpl.java | 4 +
...ackLevelConfigurationResourceDefinition.java | 53 +++
.../StackVersionResourceDefinition.java | 1 +
.../server/api/services/AmbariMetaInfo.java | 34 +-
.../server/api/services/StacksService.java | 35 +-
.../server/api/util/StackExtensionHelper.java | 105 ++++--
.../controller/AmbariManagementController.java | 8 +
.../AmbariManagementControllerImpl.java | 44 +++
.../StackLevelConfigurationRequest.java | 42 +++
.../StackLevelConfigurationResponse.java | 37 +++
.../server/controller/StackVersionResponse.java | 14 +-
.../AbstractControllerResourceProvider.java | 2 +
...StackLevelConfigurationResourceProvider.java | 159 +++++++++
.../internal/StackVersionResourceProvider.java | 6 +
.../ambari/server/controller/spi/Resource.java | 4 +-
.../apache/ambari/server/state/ServiceInfo.java | 1 +
.../apache/ambari/server/state/StackInfo.java | 26 +-
.../ambari/server/view/ViewContextImpl.java | 9 +
.../apache/ambari/server/view/ViewRegistry.java | 30 +-
.../main/resources/custom_actions/check_host.py | 2 +-
.../src/main/resources/key_properties.json | 5 +
.../src/main/resources/properties.json | 11 +
.../src/main/resources/scripts/stack_advisor.py | 2 +-
.../HDP/1.3.2/configuration/cluster-env.xml | 49 +++
.../1.3.2/hooks/before-START/scripts/params.py | 4 +-
.../HDP/1.3.2/services/HBASE/metainfo.xml | 2 +-
.../stacks/HDP/1.3.2/services/HDFS/metainfo.xml | 4 +-
.../HIVE/package/scripts/hive_service.py | 2 +-
.../HDP/1.3.2/services/MAPREDUCE/metainfo.xml | 9 +-
.../OOZIE/package/scripts/oozie_service.py | 2 +-
.../stacks/HDP/1.3.2/services/PIG/metainfo.xml | 2 +-
.../HDP/1.3.2/services/ZOOKEEPER/metainfo.xml | 2 +-
.../stacks/HDP/1.3.2/services/stack_advisor.py | 4 +-
.../HDP/2.0.6/configuration/cluster-env.xml | 49 +++
.../HDP/2.0.6/services/HBASE/metainfo.xml | 2 +-
.../stacks/HDP/2.0.6/services/HDFS/metainfo.xml | 4 +-
.../HIVE/package/scripts/hive_service.py | 2 +-
.../OOZIE/package/scripts/oozie_service.py | 2 +-
.../stacks/HDP/2.0.6/services/PIG/metainfo.xml | 10 +-
.../stacks/HDP/2.0.6/services/YARN/metainfo.xml | 4 +-
.../HDP/2.0.6/services/ZOOKEEPER/metainfo.xml | 2 +-
.../stacks/HDP/2.0.6/services/stack_advisor.py | 60 ++--
.../services/FALCON/configuration/global.xml | 63 ----
.../2.1.GlusterFS/services/FALCON/metainfo.xml | 19 +-
.../GLUSTERFS/configuration/core-site.xml | 169 ----------
.../services/GLUSTERFS/configuration/global.xml | 59 ----
.../services/GLUSTERFS/metainfo.xml | 1 +
.../services/STORM/configuration/global.xml | 39 ---
.../2.1.GlusterFS/services/STORM/metainfo.xml | 1 +
.../services/TEZ/configuration/global.xml | 29 --
.../HDP/2.1.GlusterFS/services/TEZ/metainfo.xml | 22 +-
.../stacks/HDP/2.1/services/FALCON/metainfo.xml | 10 +
.../stacks/HDP/2.1/services/stack_advisor.py | 14 +-
.../main/resources/stacks/HDP/stack_advisor.py | 37 ---
.../src/main/resources/stacks/stack_advisor.py | 37 +++
.../ambari/server/api/query/QueryImplTest.java | 2 +-
.../server/api/services/AmbariMetaInfoTest.java | 4 +-
.../api/util/StackExtensionHelperTest.java | 23 +-
.../AmbariManagementControllerTest.java | 2 +-
.../internal/AbstractResourceProviderTest.java | 45 +++
...kLevelConfigurationResourceProviderTest.java | 181 +++++++++++
.../ambari/server/view/ViewRegistryTest.java | 50 +++
ambari-server/src/test/python/TestCheckHost.py | 2 +-
.../src/test/python/TestResourceFilesKeeper.py | 2 +-
.../src/test/python/TestStackAdvisor.py | 93 ++++++
.../stacks/1.3.2/HIVE/test_hive_metastore.py | 4 +-
.../stacks/1.3.2/HIVE/test_hive_server.py | 4 +-
.../hooks/before-START/test_before_start.py | 2 +-
.../stacks/2.0.6/HDFS/test_hdfs_client.py | 4 +
.../stacks/2.0.6/HIVE/test_hive_metastore.py | 4 +-
.../stacks/2.0.6/HIVE/test_hive_server.py | 4 +-
.../stacks/2.0.6/common/test_stack_advisor.py | 38 ++-
.../python/stacks/2.0.6/configs/default.json | 2 +-
.../stacks/2.1/HIVE/test_hive_metastore.py | 4 +-
.../HIVE/package/scripts/hive_service.py | 2 +-
.../stacks/XYZ/1.0.0/services/stack_advisor.py | 67 ++++
.../stacks/XYZ/1.0.1/services/stack_advisor.py | 30 ++
.../org/apache/ambari/view/ViewController.java | 19 ++
.../controllers/global/cluster_controller.js | 44 ---
.../main/dashboard/config_history_controller.js | 28 +-
.../controllers/main/service/add_controller.js | 24 +-
.../controllers/main/service/info/configs.js | 24 +-
.../app/controllers/wizard/step3_controller.js | 1 +
.../app/controllers/wizard/step4_controller.js | 42 ++-
.../app/controllers/wizard/step8_controller.js | 30 +-
.../mappers/service_config_version_mapper.js | 5 +-
ambari-web/app/mappers/stack_service_mapper.js | 2 +-
ambari-web/app/messages.js | 12 +-
ambari-web/app/mixins/common/serverValidator.js | 4 +-
ambari-web/app/models/service_config.js | 4 +
ambari-web/app/models/service_config_version.js | 16 +-
ambari-web/app/models/stack_service.js | 63 +---
ambari-web/app/router.js | 14 +-
ambari-web/app/routes/add_host_routes.js | 2 +
ambari-web/app/routes/add_service_routes.js | 2 +
ambari-web/app/routes/installer.js | 2 +
ambari-web/app/routes/main.js | 1 +
ambari-web/app/routes/views.js | 15 +-
ambari-web/app/styles/application.less | 29 +-
ambari-web/app/styles/apps.less | 6 +
.../common/configs/compare_property.hbs | 8 +
.../common/configs/config_history_flow.hbs | 142 ++++----
.../common/configs/service_config_category.hbs | 30 +-
ambari-web/app/utils/ajax/ajax.js | 8 +-
.../views/common/configs/config_history_flow.js | 29 +-
ambari-web/app/views/main/menu.js | 4 +-
ambari-web/app/views/main/views_view.js | 2 +-
.../dashboard/config_history_controller_test.js | 38 +--
.../main/service/add_controller_test.js | 10 +
.../test/controllers/wizard/step3_test.js | 325 +++++++++++++++++++
.../test/controllers/wizard/step4_test.js | 38 ++-
.../test/controllers/wizard/step5_test.js | 19 --
.../test/controllers/wizard/step6_test.js | 34 --
.../test/controllers/wizard/step7_test.js | 92 +-----
ambari-web/test/models/stack_service_test.js | 52 +--
ambari-web/test/service_components.js | 58 +++-
.../src/main/resources/ui/app/scripts/app.js | 2 +-
.../app/scripts/controllers/job_controller.js | 2 +-
.../app/scripts/controllers/jobs_controller.js | 14 +-
.../resources/ui/app/scripts/helpers/ajax.js | 17 +-
.../resources/ui/app/scripts/helpers/jobs.js | 78 ++---
.../mappers/application_status_mapper.js | 47 +++
contrib/views/jobs/src/main/resources/view.xml | 10 +
.../ui/app/components/configSection.js | 150 +++++++++
.../createAppWizard/step1_controller.js | 31 ++
.../createAppWizard/step3_controller.js | 55 +++-
.../controllers/create_app_wizard_controller.js | 27 +-
.../src/main/resources/ui/app/helpers/ajax.js | 27 +-
.../src/main/resources/ui/app/helpers/helper.js | 37 ++-
.../src/main/resources/ui/app/initialize.js | 2 +
.../ui/app/mappers/application_status.js | 25 ++
.../ui/app/mappers/slider_apps_mapper.js | 2 +-
.../app/templates/components/configSection.hbs | 76 +++++
.../ui/app/templates/createAppWizard/step3.hbs | 8 +-
.../resources/ui/app/templates/slider_app.hbs | 2 +-
.../ui/app/templates/slider_app/summary.hbs | 2 +-
.../src/main/resources/ui/app/translations.js | 6 +
142 files changed, 2717 insertions(+), 1148 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52d1af76/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52d1af76/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52d1af76/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52d1af76/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52d1af76/ambari-server/src/main/resources/key_properties.json
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52d1af76/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52d1af76/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/52d1af76/ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java
----------------------------------------------------------------------
[34/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/090ed514
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/090ed514
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/090ed514
Branch: refs/heads/trunk
Commit: 090ed5143c3869e070c0df91d15c3f77fffcd8f8
Parents: d838ca9 efa0fa6
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Tue Sep 23 09:02:47 2014 -0700
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Sep 23 09:02:47 2014 -0700
----------------------------------------------------------------------
.../resources/ui/admin-web/app/styles/main.css | 5 +
.../BlueprintConfigurationProcessor.java | 184 +++-
ambari-server/src/main/python/ambari-server.py | 53 +-
.../services/HIVE/package/scripts/params.py | 4 +
.../services/HIVE/package/scripts/webhcat.py | 4 +-
.../stacks/HDP/2.2/services/HIVE/metainfo.xml | 6 -
.../BlueprintConfigurationProcessorTest.java | 906 ++++++++++++++++++-
.../src/test/python/TestAmbariServer.py | 72 +-
ambari-web/app/messages.js | 4 +-
ambari-web/app/styles/application.less | 8 +-
.../common/configs/config_history_flow.hbs | 124 +--
.../common/configs/service_version_box.hbs | 3 +-
.../views/common/configs/config_history_flow.js | 14 +-
ambari-web/app/views/main/host.js | 10 +-
contrib/views/slider/docs/index.md | 20 +-
.../view/slider/SliderAppsViewController.java | 1 +
.../slider/SliderAppsViewControllerImpl.java | 2 +-
.../rest/client/SliderAppMasterClient.java | 2 +-
.../resources/ui/app/assets/data/apps/apps.json | 2 +-
.../assets/data/resource/slider-properties.json | 1 +
.../ui/app/controllers/slider_app_controller.js | 139 ++-
.../ui/app/mappers/slider_apps_mapper.js | 9 +-
.../ui/app/models/slider_app_component.js | 16 +-
.../src/main/resources/ui/app/routes/main.js | 21 +-
.../resources/ui/app/styles/application.less | 32 +
.../resources/ui/app/templates/slider_app.hbs | 9 +-
.../slider_app/destroy/destroy_popup.hbs | 20 +
.../slider_app/destroy/destroy_popup_footer.hbs | 28 +
.../ui/app/templates/slider_app/summary.hbs | 8 +-
.../src/main/resources/ui/app/translations.js | 5 +
.../slider_app/destroy_modal_footer_view.js | 41 +
.../app/views/slider_app/destroy_popup_view.js | 37 +
.../views/slider/src/main/resources/view.xml | 7 +-
33 files changed, 1613 insertions(+), 184 deletions(-)
----------------------------------------------------------------------
[35/50] [abbrv] git commit: AMBARI-7480 - Alerts: data collection
starts on install before config values are available (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7480 - Alerts: data collection starts on install before config values are available (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ae9bf4c3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ae9bf4c3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ae9bf4c3
Branch: refs/heads/trunk
Commit: ae9bf4c38705074821c853301c079f2f2c484ed7
Parents: 090ed51
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Wed Sep 24 12:56:54 2014 -0700
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Wed Sep 24 13:49:59 2014 -0700
----------------------------------------------------------------------
.../server/agent/AlertDefinitionCommand.java | 15 ++--
.../ambari/server/agent/HeartBeatHandler.java | 2 +-
.../server/api/services/AmbariMetaInfo.java | 45 ++++++----
.../server/controller/ControllerModule.java | 4 +
.../AlertDefinitionResourceProvider.java | 11 ++-
.../AlertDefinitionRegistrationEvent.java | 57 ++++++++++++
.../ambari/server/events/AmbariEvent.java | 24 ++---
.../ambari/server/events/ClusterEvent.java | 50 +++++++++++
.../ambari/server/events/ServiceEvent.java | 2 +-
.../listeners/AlertAggregateListener.java | 92 ++++++++------------
.../listeners/AlertLifecycleListener.java | 73 ++++++++++++++++
.../server/orm/dao/AlertDefinitionDAO.java | 40 +++++++++
.../state/alert/AggregateDefinitionMapping.java | 88 +++++++++++++++++++
.../server/state/alert/AlertDefinition.java | 20 +++++
.../state/alert/AlertDefinitionFactory.java | 3 +-
.../server/state/alert/AlertDefinitionHash.java | 19 +++-
.../AlertGroupResourceProviderTest.java | 2 +-
.../apache/ambari/server/orm/OrmTestHelper.java | 2 +-
.../server/orm/dao/AlertDefinitionDAOTest.java | 2 +-
.../server/orm/dao/AlertDispatchDAOTest.java | 2 +-
.../ambari/server/orm/dao/AlertsDAOTest.java | 6 +-
.../state/cluster/AlertDataManagerTest.java | 59 ++++++++-----
22 files changed, 482 insertions(+), 136 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertDefinitionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertDefinitionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertDefinitionCommand.java
index 5ae1741..fdd7f1d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertDefinitionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/AlertDefinitionCommand.java
@@ -34,6 +34,12 @@ import com.google.gson.annotations.SerializedName;
* The {@link AlertDefinitionCommand} class is used to encapsulate the
* {@link AlertDefinition}s that will be returned to an agent given a requested
* hash.
+ * <p/>
+ * Commands must have {@link #addConfigs(ConfigHelper, Cluster)} invoked before
+ * being sent to the agent so that the definitions will have the required
+ * configuration data when they run. Failure to do this will cause the alerts to
+ * be scheduled and run, but the result will always be a failure since the
+ * parameterized properties they depend on will not be available.
*/
public class AlertDefinitionCommand extends AgentCommand {
@SerializedName("clusterName")
@@ -47,7 +53,7 @@ public class AlertDefinitionCommand extends AgentCommand {
@SerializedName("alertDefinitions")
private final List<AlertDefinition> m_definitions;
-
+
@SerializedName("configurations")
private Map<String, Map<String, String>> m_configurations;
@@ -118,7 +124,7 @@ public class AlertDefinitionCommand extends AgentCommand {
/**
* Adds cluster configuration properties as required by commands sent to agent.
- *
+ *
* @param configHelper the helper
* @param cluster the cluster, matching the cluster name specified by the command
*/
@@ -129,7 +135,7 @@ public class AlertDefinitionCommand extends AgentCommand {
Map<String, Map<String, String>> allConfigTags =
configHelper.getEffectiveDesiredTags(cluster, m_hostName);
-
+
for(Config clusterConfig: cluster.getAllConfigs()) {
if (null == clusterConfig) {
// !!! hard to believe
@@ -158,8 +164,5 @@ public class AlertDefinitionCommand extends AgentCommand {
m_configurations.put(clusterConfig.getType(), props);
}
-
}
-
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index a366301..c826153 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -831,8 +831,8 @@ public class HeartBeatHandler {
String hash = alertDefinitionHash.getHash(clusterName, hostname);
AlertDefinitionCommand command = new AlertDefinitionCommand(clusterName,
hostname, hash, definitions);
- command.addConfigs(configHelper, cluster);
+ command.addConfigs(configHelper, cluster);
commands.add(command);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index ec53afc..c15f73b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -47,7 +47,8 @@ import org.apache.ambari.server.api.util.StackExtensionHelper;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.customactions.ActionDefinition;
import org.apache.ambari.server.customactions.ActionDefinitionManager;
-import org.apache.ambari.server.events.listeners.AlertAggregateListener;
+import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.MetainfoDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
@@ -66,7 +67,6 @@ import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
-import org.apache.ambari.server.state.alert.SourceType;
import org.apache.ambari.server.state.stack.LatestRepoCallable;
import org.apache.ambari.server.state.stack.MetricDefinition;
import org.apache.ambari.server.state.stack.RepositoryXml;
@@ -149,6 +149,16 @@ public class AmbariMetaInfo {
*/
private AlertDefinitionFactory alertDefinitionFactory;
+ /**
+ * Publishes the following events:
+ * <ul>
+ * <li>{@link AlertDefinitionRegistrationEvent} when new alerts are merged
+ * from the stack</li>
+ * </ul>
+ */
+ @Inject
+ private AmbariEventPublisher eventPublisher;
+
// Required properties by stack version
private final Map<StackId, Map<String, Map<String, PropertyInfo>>> requiredProperties =
new HashMap<StackId, Map<String, Map<String, PropertyInfo>>>();
@@ -704,7 +714,7 @@ public class AmbariMetaInfo {
return propertiesResult;
}
-
+
public Set<PropertyInfo> getStackProperties(String stackName, String version)
throws AmbariException {
StackInfo stackInfo = getStackInfo(stackName, version);
@@ -742,27 +752,30 @@ public class AmbariMetaInfo {
return propertyResult;
}
-
+
public Set<PropertyInfo> getStackPropertiesByName(String stackName, String version, String propertyName)
throws AmbariException {
Set<PropertyInfo> properties = getStackProperties(stackName, version);
- if (properties.size() == 0)
+ if (properties.size() == 0) {
throw new StackAccessException("stackName=" + stackName
+ ", stackVersion=" + version
+ ", propertyName=" + propertyName);
+ }
Set<PropertyInfo> propertyResult = new HashSet<PropertyInfo>();
for (PropertyInfo property : properties) {
- if (property.getName().equals(propertyName))
+ if (property.getName().equals(propertyName)) {
propertyResult.add(property);
+ }
}
- if (propertyResult.isEmpty())
+ if (propertyResult.isEmpty()) {
throw new StackAccessException("stackName=" + stackName
+ ", stackVersion=" + version
+ ", propertyName=" + propertyName);
+ }
return propertyResult;
}
@@ -1280,18 +1293,16 @@ public class AmbariMetaInfo {
}
alertDefinitionDao.createOrUpdate(entity);
}
-
- // all definitions have been resolved. pull and initialize the aggregates
+
+ // all definition resolved; publish their registration
for (AlertDefinitionEntity def : alertDefinitionDao.findAll(cluster.getClusterId())) {
- if (def.getSourceType().equals(SourceType.AGGREGATE)) {
- AlertDefinition realDef = alertDefinitionFactory.coerce(def);
-
- AlertAggregateListener listener = injector.getInstance(AlertAggregateListener.class);
-
- listener.addAggregateType(cluster.getClusterId(), realDef);
- }
+ AlertDefinition realDef = alertDefinitionFactory.coerce(def);
+
+ AlertDefinitionRegistrationEvent event = new AlertDefinitionRegistrationEvent(
+ cluster.getClusterId(), realDef);
+
+ eventPublisher.publish(event);
}
-
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index cfab1f8..da78639 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -53,6 +53,8 @@ import org.apache.ambari.server.controller.internal.HostResourceProvider;
import org.apache.ambari.server.controller.internal.MemberResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.events.listeners.AlertAggregateListener;
+import org.apache.ambari.server.events.listeners.AlertLifecycleListener;
import org.apache.ambari.server.events.listeners.AlertReceivedListener;
import org.apache.ambari.server.events.listeners.AlertServiceStateListener;
import org.apache.ambari.server.events.listeners.AlertStateChangedListener;
@@ -337,5 +339,7 @@ public class ControllerModule extends AbstractModule {
bind(AlertReceivedListener.class).asEagerSingleton();
bind(AlertStateChangedListener.class).asEagerSingleton();
bind(AlertServiceStateListener.class).asEagerSingleton();
+ bind(AlertLifecycleListener.class).asEagerSingleton();
+ bind(AlertAggregateListener.class).asEagerSingleton();
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
index 7cb9886..e2d2837 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
@@ -330,7 +330,7 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
if (null != desiredScope && desiredScope.length() > 0) {
scope = Scope.valueOf(desiredScope);
}
-
+
SourceType sourceType = null;
if (null != type && type.length() > 0) {
sourceType = SourceType.valueOf(type);
@@ -473,18 +473,17 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP
private Resource toResource(boolean isCollection, String clusterName,
AlertDefinitionEntity entity, Set<String> requestedIds) {
Resource resource = new ResourceImpl(Resource.Type.AlertDefinition);
+ resource.setProperty(ALERT_DEF_ID, entity.getDefinitionId());
+ resource.setProperty(ALERT_DEF_CLUSTER_NAME, clusterName);
+ resource.setProperty(ALERT_DEF_NAME, entity.getDefinitionName());
+ resource.setProperty(ALERT_DEF_LABEL, entity.getLabel());
- setResourceProperty(resource, ALERT_DEF_CLUSTER_NAME, clusterName, requestedIds);
- setResourceProperty(resource, ALERT_DEF_ID, entity.getDefinitionId(), requestedIds);
- setResourceProperty(resource, ALERT_DEF_NAME, entity.getDefinitionName(), requestedIds);
setResourceProperty(resource, ALERT_DEF_INTERVAL, entity.getScheduleInterval(), requestedIds);
setResourceProperty(resource, ALERT_DEF_SERVICE_NAME, entity.getServiceName(), requestedIds);
setResourceProperty(resource, ALERT_DEF_COMPONENT_NAME, entity.getComponentName(), requestedIds);
setResourceProperty(resource, ALERT_DEF_ENABLED, Boolean.valueOf(entity.getEnabled()), requestedIds);
setResourceProperty(resource, ALERT_DEF_SCOPE, entity.getScope(), requestedIds);
setResourceProperty(resource, ALERT_DEF_SOURCE_TYPE, entity.getSourceType(), requestedIds);
- setResourceProperty(resource, ALERT_DEF_LABEL, entity.getLabel(),
- requestedIds);
if (!isCollection && null != resource.getPropertyValue(ALERT_DEF_SOURCE_TYPE)) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionRegistrationEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionRegistrationEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionRegistrationEvent.java
new file mode 100644
index 0000000..4b68ae9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertDefinitionRegistrationEvent.java
@@ -0,0 +1,57 @@
+/**
+ * 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.ambari.server.events;
+
+import org.apache.ambari.server.state.alert.AlertDefinition;
+
+/**
+ * The {@link AlertDefinitionRegistrationEvent} is used to represent that an
+ * {@link AlertDefinition} is now a part of the system. This usually happens at
+ * startup when the alerts are being merged from the stack. It also occurs when
+ * a new alert is created via the REST APIs or when a new service is installed.
+ */
+public class AlertDefinitionRegistrationEvent extends ClusterEvent {
+
+ /**
+ * The newly registered alert defintiion
+ */
+ private final AlertDefinition m_definition;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterId
+ * the ID of the cluster that the definition is in.
+ * @param definition
+ * the alert definition being registered.
+ */
+ public AlertDefinitionRegistrationEvent(
+ long clusterId, AlertDefinition definition) {
+ super(AmbariEventType.ALERT_DEFINITION_REGISTRATION, clusterId);
+ m_definition = definition;
+ }
+
+ /**
+ * Get the registered alert definition.
+ *
+ * @return the alert definition (not {@code null}).
+ */
+ public AlertDefinition getDefinition() {
+ return m_definition;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
index dda18c7..6cf752e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
@@ -30,7 +30,12 @@ public abstract class AmbariEvent {
/**
* A service was successfully installed.
*/
- SERVICE_INSTALL_SUCCESS;
+ SERVICE_INSTALL_SUCCESS,
+
+ /**
+ * An alert definition is registered with the system.
+ */
+ ALERT_DEFINITION_REGISTRATION;
}
/**
@@ -39,29 +44,14 @@ public abstract class AmbariEvent {
protected final AmbariEventType m_eventType;
/**
- * The cluster ID.
- */
- protected final long m_clusterId;
-
- /**
* Constructor.
*
* @param eventType
* the type of event (not {@code null}).
* @param clusterId
*/
- public AmbariEvent(AmbariEventType eventType, long clusterId) {
+ public AmbariEvent(AmbariEventType eventType) {
m_eventType = eventType;
- m_clusterId = clusterId;
- }
-
- /**
- * Gets the cluster ID that the event belongs to.
- *
- * @return the ID of the cluster.
- */
- public long getClusterId() {
- return m_clusterId;
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/events/ClusterEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ClusterEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ClusterEvent.java
new file mode 100644
index 0000000..8f39ac3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ClusterEvent.java
@@ -0,0 +1,50 @@
+/**
+ * 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.ambari.server.events;
+
+/**
+ * The {@link ClusterEvent} represents all events in Ambari that can be scoped
+ * within a cluster.
+ */
+public class ClusterEvent extends AmbariEvent {
+ /**
+ * The cluster ID.
+ */
+ protected final long m_clusterId;
+
+ /**
+ * Constructor.
+ *
+ * @param eventType
+ * @param clusterId
+ */
+ public ClusterEvent(AmbariEventType eventType, long clusterId) {
+ super(eventType);
+ m_clusterId = clusterId;
+ }
+
+ /**
+ * Gets the cluster ID that the event belongs to.
+ *
+ * @return the ID of the cluster.
+ */
+ public long getClusterId() {
+ return m_clusterId;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
index 5e01431..3bc5c17 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
@@ -21,7 +21,7 @@ package org.apache.ambari.server.events;
/**
* The {@link ServiceEvent} class is the base for all service events in Ambari.
*/
-public abstract class ServiceEvent extends AmbariEvent {
+public abstract class ServiceEvent extends ClusterEvent {
/**
* The name of the service.
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
index 8340c26..a0c8e46 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertAggregateListener.java
@@ -18,10 +18,6 @@
package org.apache.ambari.server.events.listeners;
import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.apache.ambari.server.events.AlertReceivedEvent;
import org.apache.ambari.server.events.publishers.AlertEventPublisher;
@@ -29,116 +25,100 @@ import org.apache.ambari.server.orm.dao.AlertSummaryDTO;
import org.apache.ambari.server.orm.dao.AlertsDAO;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.alert.AggregateDefinitionMapping;
import org.apache.ambari.server.state.alert.AggregateSource;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.Reporting;
-import org.apache.ambari.server.state.alert.Reporting.ReportTemplate;
+import org.apache.ambari.server.state.alert.SourceType;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
+import com.google.inject.Singleton;
/**
- * Used to aggregate alerts.
+ * The {@link AlertAggregateListener} is used to listen for all incoming
+ * {@link AlertReceivedEvent} instances and determine if there exists a
+ * {@link SourceType#AGGREGATE} alert that needs to run.
*/
+@Singleton
public class AlertAggregateListener {
@Inject
private AlertsDAO m_alertsDao = null;
- private AlertEventPublisher m_publisher = null;
- private Map<Long, Map<String, AlertDefinition>> m_aggregateMap =
- new HashMap<Long, Map<String, AlertDefinition>>();
-
+ /**
+ * The event publisher used to receive incoming events and publish new events
+ * when an aggregate alert is run.
+ */
+ private final AlertEventPublisher m_publisher;
+
+ /**
+ * Used for quick lookups of aggregate alerts.
+ */
+ @Inject
+ private AggregateDefinitionMapping m_aggregateMapping;
+
@Inject
public AlertAggregateListener(AlertEventPublisher publisher) {
m_publisher = publisher;
-
- publisher.register(this);
+ m_publisher.register(this);
}
-
+
/**
* Consume an alert that was received.
*/
@Subscribe
public void onAlertEvent(AlertReceivedEvent event) {
- AlertDefinition def = getAggregateDefinition(event.getClusterId(), event.getAlert().getName());
-
+ AlertDefinition def = m_aggregateMapping.getAggregateDefinition(
+ event.getClusterId(), event.getAlert().getName());
+
if (null == def || null == m_alertsDao) {
return;
}
-
+
AggregateSource as = (AggregateSource) def.getSource();
-
+
AlertSummaryDTO summary = m_alertsDao.findAggregateCounts(
event.getClusterId(), as.getAlertName());
-
+
Alert alert = new Alert(def.getName(), null, def.getServiceName(),
null, null, AlertState.UNKNOWN);
+
alert.setLabel(def.getLabel());
alert.setTimestamp(System.currentTimeMillis());
-
+
if (0 == summary.getOkCount()) {
alert.setText("Cannot determine, there are no records");
} else if (summary.getUnknownCount() > 0) {
alert.setText("There are alerts with status UNKNOWN.");
} else {
Reporting reporting = as.getReporting();
-
+
int numerator = summary.getCriticalCount() + summary.getWarningCount();
int denominator = summary.getOkCount();
double value = (double)(numerator) / denominator;
-
+
if (value > reporting.getCritical().getValue().doubleValue()) {
alert.setState(AlertState.CRITICAL);
alert.setText(MessageFormat.format(reporting.getCritical().getText(),
Integer.valueOf(denominator), Integer.valueOf(numerator)));
-
+
} else if (value > reporting.getWarning().getValue().doubleValue()) {
alert.setState(AlertState.WARNING);
alert.setText(MessageFormat.format(reporting.getWarning().getText(),
Integer.valueOf(denominator), Integer.valueOf(numerator)));
-
+
} else {
alert.setState(AlertState.OK);
alert.setText(MessageFormat.format(reporting.getOk().getText(),
Integer.valueOf(denominator), Integer.valueOf(numerator)));
}
-
+
}
-
+
// make a new event and allow others to consume it
AlertReceivedEvent aggEvent = new AlertReceivedEvent(event.getClusterId(), alert);
-
- m_publisher.publish(aggEvent);
- }
-
- private AlertDefinition getAggregateDefinition(long clusterId, String name) {
- Long id = Long.valueOf(clusterId);
- if (!m_aggregateMap.containsKey(id))
- return null;
-
- if (!m_aggregateMap.get(id).containsKey(name))
- return null;
-
- return m_aggregateMap.get(id).get(name);
- }
- /**
- * @param source the aggregate source
- */
- public void addAggregateType(long clusterId, AlertDefinition definition) {
- Long id = Long.valueOf(clusterId);
-
- if (!m_aggregateMap.containsKey(id)) {
- m_aggregateMap.put(id, new HashMap<String, AlertDefinition>());
- }
-
- Map<String, AlertDefinition> map = m_aggregateMap.get(id);
-
- AggregateSource as = (AggregateSource) definition.getSource();
-
- map.put(as.getAlertName(), definition);
+ m_publisher.publish(aggEvent);
}
-
-
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
new file mode 100644
index 0000000..43d4b35
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertLifecycleListener.java
@@ -0,0 +1,73 @@
+/**
+ * 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.ambari.server.events.listeners;
+
+import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.state.alert.AggregateDefinitionMapping;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.SourceType;
+
+import com.google.common.eventbus.AllowConcurrentEvents;
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AlertLifecycleListener} handles events that are part of the alert
+ * infrastructure lifecycle such as definition registration events.
+ */
+@Singleton
+public class AlertLifecycleListener {
+
+ /**
+ * Used for quick lookups of aggregate alerts.
+ */
+ @Inject
+ private AggregateDefinitionMapping m_aggregateMapping;
+
+ /**
+ * Constructor.
+ *
+ * @param publisher
+ */
+ @Inject
+ public AlertLifecycleListener(AmbariEventPublisher publisher) {
+ publisher.register(this);
+ }
+
+ /**
+ * Handles {@link AlertDefinitionRegistrationEvent} by performing the
+ * following tasks:
+ * <ul>
+ * <li>Registration with {@link AggregateDefinitionMapping}</li>
+ * </ul>
+ *
+ * @param event
+ * the event being handled.
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ public void onAmbariEvent(AlertDefinitionRegistrationEvent event) {
+ AlertDefinition definition = event.getDefinition();
+
+ if (definition.getSource().getType() == SourceType.AGGREGATE) {
+ m_aggregateMapping.addAggregateType(event.getClusterId(), definition);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
index 570f268..075ee04 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
@@ -25,9 +25,15 @@ import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.apache.ambari.server.controller.RootServiceResponseFactory;
+import org.apache.ambari.server.events.AlertDefinitionRegistrationEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.state.alert.AlertDefinition;
+import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
import org.apache.ambari.server.state.alert.Scope;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -41,6 +47,11 @@ import com.google.inject.persist.Transactional;
@Singleton
public class AlertDefinitionDAO {
/**
+ * Logger.
+ */
+ private static Logger LOG = LoggerFactory.getLogger(AlertDefinitionDAO.class);
+
+ /**
* JPA entity manager
*/
@Inject
@@ -65,6 +76,23 @@ public class AlertDefinitionDAO {
AlertDispatchDAO dispatchDao;
/**
+ * Publishes the following events:
+ * <ul>
+ * <li>{@link AlertDefinitionRegistrationEvent} when new alerts are merged
+ * from the stack</li>
+ * </ul>
+ */
+ @Inject
+ private AmbariEventPublisher eventPublisher;
+
+ /**
+ * A factory that assists in the creation of {@link AlertDefinition} and
+ * {@link AlertDefinitionEntity}.
+ */
+ @Inject
+ private AlertDefinitionFactory alertDefinitionFactory;
+
+ /**
* Gets an alert definition with the specified ID.
*
* @param definitionId
@@ -264,6 +292,18 @@ public class AlertDefinitionDAO {
group.addAlertDefinition(alertDefinition);
dispatchDao.merge(group);
}
+
+ // publish the alert definition registration
+ AlertDefinition coerced = alertDefinitionFactory.coerce(alertDefinition);
+ if (null != coerced) {
+ AlertDefinitionRegistrationEvent event = new AlertDefinitionRegistrationEvent(
+ alertDefinition.getClusterId(), coerced);
+
+ eventPublisher.publish(event);
+ } else {
+ LOG.warn("Unable to broadcast alert registration event for {}",
+ alertDefinition.getDefinitionName());
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
new file mode 100644
index 0000000..04f20f9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AggregateDefinitionMapping.java
@@ -0,0 +1,88 @@
+/**
+ * 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.ambari.server.state.alert;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AggregateDefinitionMapping} is used to keep an in-memory mapping
+ * of all of the {@link AlertDefinition}s that have aggregate definitions
+ * associated with them.
+ */
+@Singleton
+public final class AggregateDefinitionMapping {
+ /**
+ * In-memory mapping of cluster ID to definition name / aggregate definition.
+ * This is used for fast lookups when receiving events.
+ */
+ private Map<Long, Map<String, AlertDefinition>> m_aggregateMap = new HashMap<Long, Map<String, AlertDefinition>>();
+
+ /**
+ * Constructor.
+ *
+ */
+ public AggregateDefinitionMapping() {
+ }
+
+ /**
+ * Gets an aggregate definition based on a given alert definition name.
+ *
+ * @param clusterId
+ * the ID of the cluster that the definition is bound to.
+ * @param name
+ * the unique name of the definition.
+ * @return the aggregate definition, or {@code null} if none.
+ */
+ public AlertDefinition getAggregateDefinition(long clusterId, String name) {
+ Long id = Long.valueOf(clusterId);
+ if (!m_aggregateMap.containsKey(id)) {
+ return null;
+ }
+
+ if (!m_aggregateMap.get(id).containsKey(name)) {
+ return null;
+ }
+
+ return m_aggregateMap.get(id).get(name);
+ }
+
+ /**
+ * Adds a mapping for a new aggregate definition.
+ *
+ * @param clusterId
+ * the ID of the cluster that the definition is bound to.
+ * @param name
+ * the unique name of the definition.
+ */
+ public void addAggregateType(long clusterId, AlertDefinition definition) {
+ Long id = Long.valueOf(clusterId);
+
+ if (!m_aggregateMap.containsKey(id)) {
+ m_aggregateMap.put(id, new HashMap<String, AlertDefinition>());
+ }
+
+ Map<String, AlertDefinition> map = m_aggregateMap.get(id);
+
+ AggregateSource as = (AggregateSource) definition.getSource();
+
+ map.put(as.getAlertName(), definition);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
index f227c0a..5058e91 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
@@ -43,6 +43,7 @@ public class AlertDefinition {
private boolean enabled = true;
private Source source = null;
private String label = null;
+ private String uuid = null;
/**
* @return the service name
@@ -150,6 +151,25 @@ public class AlertDefinition {
}
/**
+ * Sets the UUID of the definition
+ *
+ * @param definitionUuid
+ */
+ public void setUuid(String definitionUuid) {
+ uuid = definitionUuid;
+ }
+
+ /**
+ * Gets the UUID of the definition. The UUID is a unique identifier that is
+ * generated every time the definition's state changes.
+ *
+ * @return the UUID
+ */
+ public String getUuid() {
+ return uuid;
+ }
+
+ /**
* Compares {@link #equals(Object)} of every field. This is used mainly for
* reconciling the stack versus the database.
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
index f8e44bd..4f6a9a3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionFactory.java
@@ -132,6 +132,7 @@ public class AlertDefinitionFactory {
definition.setScope(entity.getScope());
definition.setServiceName(entity.getServiceName());
definition.setLabel(entity.getLabel());
+ definition.setUuid(entity.getHash());
try{
String sourceJson = entity.getSource();
@@ -139,7 +140,7 @@ public class AlertDefinitionFactory {
definition.setSource(source);
} catch (Exception exception) {
LOG.error(
- "Unable to deserialized the alert definition source during coercion",
+ "Unable to deserialize the alert definition source during coercion",
exception);
return null;
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
index 0a1c73a..9ea039c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinitionHash.java
@@ -42,6 +42,7 @@ import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponent;
@@ -51,6 +52,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
+import com.google.inject.Provider;
import com.google.inject.Singleton;
/**
@@ -91,6 +93,14 @@ public class AlertDefinitionHash {
private ActionQueue m_actionQueue;
/**
+ * Used to add configurations to the {@link AlertDefinitionCommand} instances
+ * so that alerts can be scheduled to run with access to the properties they
+ * need.
+ */
+ @Inject
+ private Provider<ConfigHelper> m_configHelper;
+
+ /**
* !!! TODO: this class needs some thoughts on locking
*/
private ReadWriteLock m_lock = new ReentrantReadWriteLock();
@@ -489,7 +499,7 @@ public class AlertDefinitionHash {
* This method is typically called after
* {@link #invalidateHosts(AlertDefinitionEntity)} has caused a cache
* invalidation of the alert definition hash.
- *
+ *
* @param clusterName
* the name of the cluster (not {@code null}).
* @param hosts
@@ -514,6 +524,13 @@ public class AlertDefinitionHash {
AlertDefinitionCommand command = new AlertDefinitionCommand(clusterName,
hostName, hash, definitions);
+ try {
+ Cluster cluster = m_clusters.getCluster(clusterName);
+ command.addConfigs(m_configHelper.get(), cluster);
+ } catch (AmbariException ae) {
+ LOG.warn("Unable to add configurations to alert definition command", ae);
+ }
+
// unlike other commands, the alert definitions commands are really
// designed to be 1:1 per change; if multiple invalidations happened
// before the next heartbeat, there would be several commands that would
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
index d2ce6fb..5583617 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java
@@ -479,7 +479,7 @@ public class AlertGroupResourceProviderTest {
entity.setScheduleInterval(Integer.valueOf(2));
entity.setServiceName(null);
entity.setSourceType(SourceType.METRIC);
- entity.setSource(null);
+ entity.setSource("{\"type\" : \"METRIC\"}");
Set<AlertDefinitionEntity> definitions = new HashSet<AlertDefinitionEntity>();
definitions.add(entity);
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
index 08cd7b8..dc71862 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/OrmTestHelper.java
@@ -330,7 +330,7 @@ public class OrmTestHelper {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
- definition.setSource("Source " + System.currentTimeMillis());
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
alertDefinitionDAO.create(definition);
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index 3e20cd6..4d182cc 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -97,7 +97,7 @@ public class AlertDefinitionDAOTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
- definition.setSource("Source " + i);
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
dao.create(definition);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
index 7f4deda..015acc0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
@@ -431,7 +431,7 @@ public class AlertDispatchDAOTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(60);
definition.setScope(Scope.SERVICE);
- definition.setSource("Source " + i);
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
index 6e4d4af..0cc2ae7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java
@@ -85,7 +85,7 @@ public class AlertsDAOTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.SERVICE);
- definition.setSource("Source " + i);
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
}
@@ -209,7 +209,7 @@ public class AlertsDAOTest {
hostDef.setHash(UUID.randomUUID().toString());
hostDef.setScheduleInterval(Integer.valueOf(60));
hostDef.setScope(Scope.HOST);
- hostDef.setSource("HostService");
+ hostDef.setSource("{\"type\" : \"SCRIPT\"}");
hostDef.setSourceType(SourceType.SCRIPT);
definitionDao.create(hostDef);
@@ -409,7 +409,7 @@ public class AlertsDAOTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.SERVICE);
- definition.setSource("SourceScript");
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
http://git-wip-us.apache.org/repos/asf/ambari/blob/ae9bf4c3/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
index 00ba942..85a6e9b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
@@ -50,7 +50,9 @@ import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.alert.AggregateDefinitionMapping;
import org.apache.ambari.server.state.alert.AggregateSource;
+import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
import org.apache.ambari.server.state.alert.Reporting;
import org.apache.ambari.server.state.alert.Reporting.ReportTemplate;
@@ -108,7 +110,7 @@ public class AlertDataManagerTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.SERVICE);
- definition.setSource("Source " + i);
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
}
@@ -268,7 +270,7 @@ public class AlertDataManagerTest {
notices = dispatchDao.findAllNotices();
assertEquals(1, notices.size());
}
-
+
@Test
public void testAggregateAlerts() throws Exception {
// create definition
@@ -281,10 +283,10 @@ public class AlertDataManagerTest {
definition.setHash(UUID.randomUUID().toString());
definition.setScheduleInterval(Integer.valueOf(60));
definition.setScope(Scope.HOST);
- definition.setSource("Source");
+ definition.setSource("{\"type\" : \"SCRIPT\"}");
definition.setSourceType(SourceType.SCRIPT);
definitionDao.create(definition);
-
+
// create aggregate of definition
AlertDefinitionEntity aggDef = new AlertDefinitionEntity();
aggDef.setDefinitionName("aggregate_test");
@@ -294,7 +296,7 @@ public class AlertDataManagerTest {
aggDef.setHash(UUID.randomUUID().toString());
aggDef.setScheduleInterval(Integer.valueOf(60));
aggDef.setScope(Scope.SERVICE);
-
+
AggregateSource source = new AggregateSource();
source.setAlertName("to_aggregate");
@@ -304,7 +306,7 @@ public class AlertDataManagerTest {
field.set(source, SourceType.AGGREGATE);
Reporting reporting = new Reporting();
-
+
ReportTemplate template = new ReportTemplate();
template.setText("You are good {1}/{0}");
reporting.setOk(template);
@@ -313,20 +315,20 @@ public class AlertDataManagerTest {
template.setText("Going bad {1}/{0}");
template.setValue(Double.valueOf(0.33d));
reporting.setWarning(template);
-
+
template = new ReportTemplate();
template.setText("On fire! {1}/{0}");
template.setValue(Double.valueOf(0.66d));
reporting.setCritical(template);
-
+
source.setReporting(reporting);
Gson gson = new Gson();
-
+
aggDef.setSource(gson.toJson(source));
aggDef.setSourceType(SourceType.AGGREGATE);
definitionDao.create(aggDef);
-
+
// add current and history across four hosts
for (int i = 0; i < 4; i++) {
AlertHistoryEntity history = new AlertHistoryEntity();
@@ -341,7 +343,7 @@ public class AlertDataManagerTest {
history.setHostName("h" + (i+1));
history.setServiceName(definition.getServiceName());
dao.create(history);
-
+
AlertCurrentEntity current = new AlertCurrentEntity();
current.setAlertHistory(history);
current.setLatestText(history.getAlertText());
@@ -349,7 +351,7 @@ public class AlertDataManagerTest {
current.setOriginalTimestamp(Long.valueOf(1L));
dao.merge(current);
}
-
+
AlertEventPublisher publisher = injector.getInstance(AlertEventPublisher.class);
// !!! need a synchronous op for testing
@@ -357,17 +359,28 @@ public class AlertDataManagerTest {
field.setAccessible(true);
field.set(publisher, new EventBus());
- final AtomicReference<Alert> ref = new AtomicReference<Alert>();
+ final AtomicReference<Alert> ref = new AtomicReference<Alert>();
publisher.register(new TestListener() {
+ @Override
@Subscribe
public void catchIt(AlertReceivedEvent event) {
ref.set(event.getAlert());
}
});
-
+
AlertAggregateListener listener = injector.getInstance(AlertAggregateListener.class);
AlertDefinitionFactory factory = new AlertDefinitionFactory();
- listener.addAggregateType(clusterId.longValue(), factory.coerce(aggDef));
+ AggregateDefinitionMapping aggregateMapping = injector.getInstance(AggregateDefinitionMapping.class);
+
+ AlertDefinition aggregateDefinition = factory.coerce(aggDef);
+ aggregateMapping.addAggregateType(clusterId.longValue(),
+ aggregateDefinition );
+
+ AggregateSource as = (AggregateSource) aggregateDefinition.getSource();
+ AlertDefinition aggregatedDefinition = aggregateMapping.getAggregateDefinition(
+ clusterId.longValue(), as.getAlertName());
+
+ assertNotNull(aggregatedDefinition);
// any alert and event will do that is for the definition since an aggregate
// checks them all regardless of state
@@ -379,12 +392,12 @@ public class AlertDataManagerTest {
"h1",
AlertState.OK);
AlertReceivedEvent event = new AlertReceivedEvent(clusterId.longValue(), alert);
-
+
listener.onAlertEvent(event);
assertNotNull(ref.get());
assertEquals(AlertState.OK, ref.get().getState());
assertTrue(ref.get().getText().indexOf("0/4") > -1);
-
+
// check if one is critical, still ok
AlertCurrentEntity current = dao.findCurrentByHostAndName(
clusterId.longValue(), "h1", definition.getDefinitionName());
@@ -392,7 +405,7 @@ public class AlertDataManagerTest {
dao.merge(current.getAlertHistory());
listener.onAlertEvent(event);
- assertEquals("aggregate_test", ref.get().getName());
+ assertEquals("aggregate_test", ref.get().getName());
assertEquals(AlertState.OK, ref.get().getState());
assertTrue(ref.get().getText().indexOf("1/4") > -1);
@@ -401,7 +414,7 @@ public class AlertDataManagerTest {
clusterId.longValue(), "h2", definition.getDefinitionName());
current.getAlertHistory().setAlertState(AlertState.WARNING);
dao.merge(current.getAlertHistory());
-
+
listener.onAlertEvent(event);
assertEquals("aggregate_test", ref.get().getName());
assertEquals(AlertState.WARNING, ref.get().getState());
@@ -412,15 +425,15 @@ public class AlertDataManagerTest {
clusterId.longValue(), "h3", definition.getDefinitionName());
current.getAlertHistory().setAlertState(AlertState.CRITICAL);
dao.merge(current.getAlertHistory());
-
+
listener.onAlertEvent(event);
- assertEquals("aggregate_test", ref.get().getName());
+ assertEquals("aggregate_test", ref.get().getName());
assertEquals(AlertState.CRITICAL, ref.get().getState());
assertTrue(ref.get().getText().indexOf("3/4") > -1);
}
-
+
/**
- * Test interface collects aggregate alert invocations
+ * Test interface collects aggregate alert invocations
*/
private static interface TestListener {
public void catchIt(AlertReceivedEvent event);
[49/50] [abbrv] git commit: Merge branch 'trunk' into
branch-alerts-dev
Posted by jo...@apache.org.
Merge branch 'trunk' into branch-alerts-dev
Conflicts:
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
ambari-server/src/main/resources/key_properties.json
ambari-server/src/main/resources/properties.json
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/cc2d9341
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/cc2d9341
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/cc2d9341
Branch: refs/heads/trunk
Commit: cc2d9341336218878af81bea0cc8ee7fc2a7d9ec
Parents: 9919b3f 811ea58
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Oct 6 16:27:12 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Oct 6 16:27:12 2014 -0400
----------------------------------------------------------------------
.../resources/ControllerResourceDefinition.java | 60 ----
.../resources/ResourceInstanceFactoryImpl.java | 6 -
.../server/api/services/ControllerService.java | 98 -------
.../server/api/util/StackExtensionHelper.java | 14 +-
.../AbstractControllerResourceProvider.java | 2 -
.../internal/ControllerResourceProvider.java | 282 -------------------
.../controller/internal/ControllerType.java | 65 -----
.../internal/StackDefinedPropertyProvider.java | 10 +-
.../metrics/RestMetricsPropertyProvider.java | 19 +-
.../ambari/server/controller/spi/Resource.java | 2 -
ambari-server/src/main/python/ambari-server.py | 13 +-
.../src/main/resources/key_properties.json | 3 -
.../src/main/resources/properties.json | 9 -
.../stacks/HDP/2.2/services/HIVE/metainfo.xml | 5 +
.../stacks/HDP/2.2/services/stack_advisor.py | 5 +-
.../api/util/StackExtensionHelperTest.java | 27 ++
.../stacks/2.2/common/test_stack_advisor.py | 137 +++++++--
.../single_stack/ABC/1.0.0/metainfo.xml | 22 ++
.../ABC/1.0.0/services/HDFS/metainfo.xml | 193 +++++++++++++
.../ui/app/scripts/models/jobs/tez_dag.js | 4 +-
.../main/resources/ui/app/models/slider_app.js | 16 ++
.../resources/ui/app/templates/slider_apps.hbs | 4 +-
.../ui/app/views/common/filter_view.js | 4 +-
.../resources/ui/app/views/common/table_view.js | 2 +-
.../resources/ui/app/views/slider_apps_view.js | 15 +-
.../ui/test/unit/views/slider_apps_view_test.js | 37 +++
26 files changed, 469 insertions(+), 585 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc2d9341/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc2d9341/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --cc ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index f3f92a1,17df861..5810633
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@@ -149,16 -149,8 +149,14 @@@ public abstract class AbstractControlle
return new RecommendationResourceProvider(propertyIds, keyPropertyIds, managementController);
case Validation:
return new ValidationResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case Alert:
+ return new AlertResourceProvider(propertyIds, keyPropertyIds, managementController);
case AlertDefinition:
return new AlertDefinitionResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case AlertGroup:
+ return new AlertGroupResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case AlertTarget:
+ return new AlertTargetResourceProvider(propertyIds, keyPropertyIds, managementController);
- case Controller:
- return new ControllerResourceProvider(propertyIds, keyPropertyIds, managementController);
case ClientConfig:
return new ClientConfigResourceProvider(propertyIds, keyPropertyIds, managementController);
default:
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc2d9341/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc2d9341/ambari-server/src/main/resources/key_properties.json
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/key_properties.json
index d127bc5,b4dfbf7..085dc11
--- a/ambari-server/src/main/resources/key_properties.json
+++ b/ambari-server/src/main/resources/key_properties.json
@@@ -155,16 -149,6 +155,13 @@@
"Cluster": "AlertDefinition/cluster_name",
"AlertDefinition": "AlertDefinition/id"
},
+ "AlertTarget": {
+ "AlertTarget": "AlertTarget/id"
+ },
+ "AlertGroup": {
+ "Cluster": "AlertGroup/cluster_name",
+ "AlertGroup": "AlertGroup/id"
+ },
- "Controller": {
- "Controller": "Controllers/name"
- },
"ClientConfig": {
"Cluster": "ServiceComponentInfo/cluster_name",
"Service": "ServiceComponentInfo/service_name",
http://git-wip-us.apache.org/repos/asf/ambari/blob/cc2d9341/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --cc ambari-server/src/main/resources/properties.json
index 96f44c4,bff0c94..8a0a58a
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@@ -447,34 -431,8 +447,25 @@@
"AlertDefinition/interval",
"AlertDefinition/enabled",
"AlertDefinition/scope",
- "AlertDefinition/source"
- ],
+ "AlertDefinition/source",
+ "AlertDefinition/run_now"
+ ],
+ "AlertGroup": [
+ "AlertGroup/id",
+ "AlertGroup/name",
+ "AlertGroup/cluster_name",
+ "AlertGroup/default",
+ "AlertGroup/definitions",
+ "AlertGroup/targets"
+ ],
+ "AlertTarget": [
+ "AlertTarget/id",
+ "AlertTarget/name",
+ "AlertTarget/description",
+ "AlertTarget/notification_type",
+ "AlertTarget/properties",
+ "AlertTarget/groups"
+ ],
- "Controller":[
- "Controllers/name",
- "LDAP/configured",
- "LDAP/users",
- "LDAP/groups",
- "LDAP/synced_users",
- "LDAP/synced_groups",
- "_"
- ],
"ClientConfig":[
"ServiceComponentInfo/service_name",
"ServiceComponentInfo/component_name",
[23/50] [abbrv] git commit: AMBARI-7316 - Alerts: Create Alert
Notices For Incoming Alert State Changes (jonathanhurley)
Posted by jo...@apache.org.
AMBARI-7316 - Alerts: Create Alert Notices For Incoming Alert State Changes (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/760bedfe
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/760bedfe
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/760bedfe
Branch: refs/heads/trunk
Commit: 760bedfe32f2a673a14cc14e7f2d41794ca3db98
Parents: aaf0513
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Sep 15 14:04:42 2014 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Mon Sep 15 14:04:42 2014 -0400
----------------------------------------------------------------------
.../ambari/server/agent/HeartBeatHandler.java | 20 ++-
.../server/controller/ControllerModule.java | 15 ++
.../apache/ambari/server/events/AlertEvent.java | 58 +++++++
.../server/events/AlertReceivedEvent.java | 50 +++++++
.../server/events/AlertStateChangeEvent.java | 85 +++++++++++
.../events/listeners/AlertReceivedListener.java | 150 +++++++++++++++++++
.../listeners/AlertStateChangedListener.java | 98 ++++++++++++
.../events/publishers/AlertEventPublisher.java | 100 +++++++++++++
.../ambari/server/orm/dao/AlertDispatchDAO.java | 22 +++
.../server/orm/entities/AlertGroupEntity.java | 7 +-
.../org/apache/ambari/server/state/Alert.java | 55 ++++---
.../server/state/cluster/AlertDataManager.java | 111 --------------
.../server/orm/dao/AlertDispatchDAOTest.java | 29 ++++
.../state/cluster/AlertDataManagerTest.java | 129 ++++++++++++----
14 files changed, 753 insertions(+), 176 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
index 492d832..a366301 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
@@ -39,6 +39,9 @@ import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.MaintenanceStateHelper;
+import org.apache.ambari.server.events.AlertEvent;
+import org.apache.ambari.server.events.AlertReceivedEvent;
+import org.apache.ambari.server.events.publishers.AlertEventPublisher;
import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.state.AgentVersion;
import org.apache.ambari.server.state.Alert;
@@ -60,7 +63,6 @@ import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.AlertDefinitionHash;
-import org.apache.ambari.server.state.cluster.AlertDataManager;
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
import org.apache.ambari.server.state.host.HostHealthyHeartbeatEvent;
import org.apache.ambari.server.state.host.HostRegistrationRequestEvent;
@@ -115,9 +117,12 @@ public class HeartBeatHandler {
@Inject
private AlertDefinitionHash alertDefinitionHash;
-
+
+ /**
+ * Publishes {@link AlertEvent} instances.
+ */
@Inject
- private AlertDataManager alertManager;
+ private AlertEventPublisher alertEventPublisher;
private Map<String, Long> hostResponseIds = new ConcurrentHashMap<String, Long>();
@@ -236,13 +241,16 @@ public class HeartBeatHandler {
if (null == hostname || null == heartbeat) {
return;
}
-
+
if (null != heartbeat.getAlerts()) {
for (Alert alert : heartbeat.getAlerts()) {
- if (null == alert.getHost())
+ if (null == alert.getHost()) {
alert.setHost(hostname);
+ }
+
Cluster cluster = clusterFsm.getCluster(alert.getCluster());
- alertManager.add(cluster.getClusterId(), alert);
+ AlertEvent event = new AlertReceivedEvent(cluster.getClusterId(), alert);
+ alertEventPublisher.publish(event);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index c395df6..8413762 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -51,6 +51,8 @@ import org.apache.ambari.server.controller.internal.HostResourceProvider;
import org.apache.ambari.server.controller.internal.MemberResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.events.listeners.AlertReceivedListener;
+import org.apache.ambari.server.events.listeners.AlertStateChangedListener;
import org.apache.ambari.server.orm.DBAccessor;
import org.apache.ambari.server.orm.DBAccessorImpl;
import org.apache.ambari.server.orm.PersistenceType;
@@ -222,6 +224,8 @@ public class ControllerModule extends AbstractModule {
bind(ViewInstanceHandlerList.class).to(AmbariHandlerList.class);
requestStaticInjection(ExecutionCommandWrapper.class);
+
+ bindEagerSingletons();
}
@@ -299,4 +303,15 @@ public class ControllerModule extends AbstractModule {
bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class);
bind(SecurityHelper.class).toInstance(SecurityHelperImpl.getInstance());
}
+
+ /**
+ * Initializes all eager singletons that should be instantiated as soon as
+ * possible and not wait for injection.
+ */
+ private void bindEagerSingletons() {
+ // alert subscribers are "headless" and have no guice references; created
+ // them as eager singletons to have them register with the eventbus
+ bind(AlertReceivedListener.class).asEagerSingleton();
+ bind(AlertStateChangedListener.class).asEagerSingleton();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java
new file mode 100644
index 0000000..a75477d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertEvent.java
@@ -0,0 +1,58 @@
+/**
+ * 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.ambari.server.events;
+
+import org.apache.ambari.server.state.Alert;
+
+/**
+ * The {@link AlertEvent} class the base for all events related to alerts.
+ */
+public abstract class AlertEvent {
+
+ protected long m_clusterId;
+ protected Alert m_alert;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterId
+ * @param alert
+ */
+ public AlertEvent(long clusterId, Alert alert) {
+ m_clusterId = clusterId;
+ m_alert = alert;
+ }
+
+ /**
+ * Gets the cluster ID that the alert belongs to.
+ *
+ * @return the ID of the cluster.
+ */
+ public long getClusterId() {
+ return m_clusterId;
+ }
+
+ /**
+ * Gets the alert that this event is created for.
+ *
+ * @return the alert (never {@code null}).
+ */
+ public Alert getAlert(){
+ return m_alert;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/events/AlertReceivedEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertReceivedEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertReceivedEvent.java
new file mode 100644
index 0000000..558c9da
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertReceivedEvent.java
@@ -0,0 +1,50 @@
+/**
+ * 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.ambari.server.events;
+
+import org.apache.ambari.server.state.Alert;
+
+/**
+ * The {@link AlertReceivedEvent} is fired when an {@link Alert} is received or
+ * generated.
+ */
+public final class AlertReceivedEvent extends AlertEvent {
+
+ /**
+ * Constructor.
+ *
+ * @param clusterId
+ * @param alert
+ */
+ public AlertReceivedEvent(long clusterId, Alert alert) {
+ super(clusterId, alert);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder("AlertReceivedEvent{ ");
+ buffer.append("cluserId=").append(m_clusterId);
+ buffer.append(", alert=").append(m_alert);
+
+ buffer.append("}");
+ return buffer.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
new file mode 100644
index 0000000..ab2c3dd
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AlertStateChangeEvent.java
@@ -0,0 +1,85 @@
+/**
+ * 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.ambari.server.events;
+
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.AlertState;
+
+/**
+ * The {@link AlertStateChangeEvent} is fired when an {@link Alert} instance has
+ * its {@link AlertState} changed.
+ */
+public final class AlertStateChangeEvent extends AlertEvent {
+
+ /**
+ * The prior alert state.
+ */
+ private final AlertState m_fromState;
+
+ /**
+ * The newly created historical entry.
+ */
+ private final AlertHistoryEntity m_newEntity;
+
+ /**
+ * Constructor.
+ *
+ * @param clusterId
+ * @param alert
+ */
+ public AlertStateChangeEvent(long clusterId, Alert alert,
+ AlertHistoryEntity newEntity, AlertState fromState) {
+ super(clusterId, alert);
+
+ m_newEntity = newEntity;
+ m_fromState = fromState;
+ }
+
+ /**
+ * Gets the newly created item in alert history.
+ *
+ * @return the newly created historical item.
+ */
+ public AlertHistoryEntity getNewHistoricalEntry() {
+ return m_newEntity;
+ }
+
+ /**
+ * Gets the prior state of the alert.
+ *
+ * @return the prior state of the alert.
+ */
+ public AlertState getFromState() {
+ return m_fromState;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ StringBuilder buffer = new StringBuilder("AlertStateChangeEvent{ ");
+ buffer.append("cluserId=").append(m_clusterId);
+ buffer.append(", fromState=").append(m_fromState);
+ buffer.append(", alert=").append(m_alert);
+
+ buffer.append("}");
+ return buffer.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
new file mode 100644
index 0000000..1bdd7e2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertReceivedListener.java
@@ -0,0 +1,150 @@
+/**
+ * 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.ambari.server.events.listeners;
+
+import org.apache.ambari.server.events.AlertEvent;
+import org.apache.ambari.server.events.AlertReceivedEvent;
+import org.apache.ambari.server.events.AlertStateChangeEvent;
+import org.apache.ambari.server.events.publishers.AlertEventPublisher;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.state.Alert;
+import org.apache.ambari.server.state.AlertState;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.eventbus.AllowConcurrentEvents;
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AlertReceivedListener} class handles {@link AlertReceivedEvent}
+ * and updates the appropirate DAOs. It may also fire new
+ * {@link AlertStateChangeEvent} when an {@link AlertState} change is detected.
+ */
+@Singleton
+public class AlertReceivedListener {
+ /**
+ * Logger.
+ */
+ private static Log LOG = LogFactory.getLog(AlertReceivedListener.class);
+
+ @Inject
+ private AlertsDAO m_alertsDao;
+
+ @Inject
+ private AlertDefinitionDAO m_definitionDao;
+
+ /**
+ * Receives and publishes {@link AlertEvent} instances.
+ */
+ private AlertEventPublisher m_alertEventPublisher;
+
+ /**
+ * Constructor.
+ *
+ * @param publisher
+ */
+ @Inject
+ public AlertReceivedListener(AlertEventPublisher publisher) {
+ m_alertEventPublisher = publisher;
+ m_alertEventPublisher.register(this);
+ }
+
+
+ /**
+ * Adds an alert. Checks for a new state before creating a new history record.
+ *
+ * @param clusterId the id for the cluster
+ * @param alert the alert to add
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ public void onAlertEvent(AlertReceivedEvent event) {
+ long clusterId = event.getClusterId();
+ Alert alert = event.getAlert();
+
+ AlertCurrentEntity current = m_alertsDao.findCurrentByHostAndName(clusterId,
+ alert.getHost(), alert.getName());
+
+ if (null == current) {
+ AlertDefinitionEntity definition = m_definitionDao.findByName(clusterId,
+ alert.getName());
+
+ AlertHistoryEntity history = createHistory(clusterId, definition, alert);
+
+ current = new AlertCurrentEntity();
+ current.setAlertHistory(history);
+ current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
+ current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
+
+ m_alertsDao.create(current);
+
+ } else if (alert.getState() == current.getAlertHistory().getAlertState()) {
+ current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
+ current.setLatestText(alert.getText());
+
+ m_alertsDao.merge(current);
+ } else {
+ AlertState oldState = current.getAlertHistory().getAlertState();
+
+ // insert history, update current
+ AlertHistoryEntity history = createHistory(clusterId,
+ current.getAlertHistory().getAlertDefinition(), alert);
+
+ current.setAlertHistory(history);
+ current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
+ current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
+
+ m_alertsDao.merge(current);
+
+ // broadcast the alert changed event for other subscribers
+ AlertStateChangeEvent alertChangedEvent = new AlertStateChangeEvent(
+ event.getClusterId(), event.getAlert(), history, oldState);
+
+ m_alertEventPublisher.publish(alertChangedEvent);
+ }
+ }
+
+ /**
+ * Convenience to create a new alert.
+ * @param clusterId the cluster id
+ * @param definition the definition
+ * @param alert the alert data
+ * @return the new history record
+ */
+ private AlertHistoryEntity createHistory(long clusterId, AlertDefinitionEntity definition, Alert alert) {
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setAlertDefinition(definition);
+ history.setAlertInstance(alert.getInstance());
+ history.setAlertLabel(alert.getLabel());
+ history.setAlertState(alert.getState());
+ history.setAlertText(alert.getText());
+ history.setAlertTimestamp(Long.valueOf(alert.getTimestamp()));
+ history.setClusterId(Long.valueOf(clusterId));
+ history.setComponentName(alert.getComponent());
+ history.setHostName(alert.getHost());
+ history.setServiceName(alert.getService());
+
+ return history;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
new file mode 100644
index 0000000..a327110
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/listeners/AlertStateChangedListener.java
@@ -0,0 +1,98 @@
+/**
+ * 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.ambari.server.events.listeners;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.server.events.AlertStateChangeEvent;
+import org.apache.ambari.server.events.publishers.AlertEventPublisher;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.NotificationState;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.google.common.eventbus.AllowConcurrentEvents;
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AlertStateChangedListener} class response to
+ * {@link AlertStateChangeEvent} and updates {@link AlertNoticeEntity} instances
+ * in the database.
+ */
+@Singleton
+public class AlertStateChangedListener {
+
+ /**
+ * Logger.
+ */
+ private static Log LOG = LogFactory.getLog(AlertStateChangedListener.class);
+
+ /**
+ * Used for looking up groups and targets.
+ */
+ @Inject
+ private AlertDispatchDAO m_alertsDispatchDao;
+
+ /**
+ * Constructor.
+ *
+ * @param publisher
+ */
+ @Inject
+ public AlertStateChangedListener(AlertEventPublisher publisher) {
+ publisher.register(this);
+ }
+
+ /**
+ * Listens for when an alert's state has changed.
+ */
+ @Subscribe
+ @AllowConcurrentEvents
+ public void onAlertEvent(AlertStateChangeEvent event) {
+ AlertHistoryEntity history = event.getNewHistoricalEntry();
+ AlertDefinitionEntity definition = history.getAlertDefinition();
+
+ List<AlertGroupEntity> groups = m_alertsDispatchDao.findGroupsByDefinition(definition);
+
+ // for each group, determine if there are any targets that need to receive
+ // a notification about the alert state change event
+ for (AlertGroupEntity group : groups) {
+ Set<AlertTargetEntity> targets = group.getAlertTargets();
+ if (null == targets || targets.size() == 0) {
+ continue;
+ }
+
+ for (AlertTargetEntity target : targets) {
+ AlertNoticeEntity notice = new AlertNoticeEntity();
+ notice.setAlertTarget(target);
+ notice.setAlertHistory(event.getNewHistoricalEntry());
+ notice.setNotifyState(NotificationState.PENDING);
+
+ m_alertsDispatchDao.merge(notice);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java b/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
new file mode 100644
index 0000000..e42e317
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/publishers/AlertEventPublisher.java
@@ -0,0 +1,100 @@
+/**
+ * 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.ambari.server.events.publishers;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.ambari.server.events.AlertEvent;
+
+import com.google.common.eventbus.AsyncEventBus;
+import com.google.common.eventbus.EventBus;
+import com.google.common.eventbus.Subscribe;
+import com.google.inject.Singleton;
+
+/**
+ * The {@link AlertEventPublisher} is used to wrap a customized instance of an
+ * {@link AsyncEventBus} that is only used for alerts. In general, Ambari should
+ * have its own application-wide event bus for application events (session
+ * information, state changes, etc), but since alerts can contain many events
+ * being published concurrently, it makes sense to encapsulate a specific alert
+ * bus in this publisher.
+ */
+@Singleton
+public final class AlertEventPublisher {
+
+ /**
+ * A multi-threaded event bus that can handle dispatching {@link AlertEvent}s.
+ */
+ private final EventBus s_eventBus;
+
+ /**
+ * Constructor.
+ */
+ public AlertEventPublisher() {
+ s_eventBus = new AsyncEventBus(Executors.newFixedThreadPool(2,
+ new AlertEventBusThreadFactory()));
+ }
+
+ /**
+ * Publishes the specified event to all registered listeners that
+ * {@link Subscribe} to any of the {@link AlertEvent} instances.
+ *
+ * @param event
+ */
+ public void publish(AlertEvent event) {
+ s_eventBus.post(event);
+ }
+
+ /**
+ * Register a listener to receive events. The listener should use the
+ * {@link Subscribe} annotation.
+ *
+ * @param object
+ * the listener to receive events.
+ */
+ public void register(Object object) {
+ s_eventBus.register(object);
+ }
+
+ /**
+ * A custom {@link ThreadFactory} for the threads that will handle published
+ * {@link AlertEvent}. Threads created will have slightly reduced priority
+ * since {@link AlertEvent} instances are not critical to the system.
+ */
+ private static final class AlertEventBusThreadFactory implements
+ ThreadFactory {
+
+ private static final AtomicInteger s_threadIdPool = new AtomicInteger(1);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread thread = new Thread(r, "alert-event-bus-"
+ + s_threadIdPool.getAndIncrement());
+
+ thread.setDaemon(false);
+ thread.setPriority(Thread.NORM_PRIORITY - 1);
+
+ return thread;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
index e08c948..6d4d19b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
@@ -22,9 +22,11 @@ import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.orm.entities.AlertGroupEntity;
import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.alert.AlertGroup;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -192,6 +194,26 @@ public class AlertDispatchDAO {
}
/**
+ * Gets all of the {@link AlertGroup} instances that include the specified
+ * alert definition.
+ *
+ * @param definitionEntity
+ * the definition that the group must include (not {@code null}).
+ * @return all alert groups that have an association with the specified
+ * definition or empty list if none exist (never {@code null}).
+ */
+ public List<AlertGroupEntity> findGroupsByDefinition(
+ AlertDefinitionEntity definitionEntity) {
+
+ TypedQuery<AlertGroupEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertGroupEntity.findByAssociatedDefinition", AlertGroupEntity.class);
+
+ query.setParameter("alertDefinition", definitionEntity);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
* Gets all alert notifications stored in the database.
*
* @return all alert notifications or empty list if none exist (never
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
index f97a0eb..e7fa9c6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
@@ -48,7 +48,8 @@ import javax.persistence.UniqueConstraint;
@NamedQuery(name = "AlertGroupEntity.findAll", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup"),
@NamedQuery(name = "AlertGroupEntity.findAllInCluster", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.clusterId = :clusterId"),
@NamedQuery(name = "AlertGroupEntity.findByName", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName"),
- @NamedQuery(name = "AlertGroupEntity.findByNameInCluster", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName AND alertGroup.clusterId = :clusterId"), })
+ @NamedQuery(name = "AlertGroupEntity.findByNameInCluster", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName AND alertGroup.clusterId = :clusterId"),
+ @NamedQuery(name = "AlertGroupEntity.findByAssociatedDefinition", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE :alertDefinition MEMBER OF alertGroup.alertDefinitions"), })
public class AlertGroupEntity {
@Id
@@ -224,7 +225,7 @@ public class AlertGroupEntity {
/**
* Adds the specified definition to the definitions that this group will
* dispatch to.
- *
+ *
* @param definition
* the definition to add (not {@code null}).
*/
@@ -240,7 +241,7 @@ public class AlertGroupEntity {
/**
* Removes the specified definition from the definitions that this group will
* dispatch to.
- *
+ *
* @param definition
* the definition to remove (not {@code null}).
*/
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
index 7b8aabd..3675f87 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Alert.java
@@ -32,8 +32,8 @@ public class Alert {
private String label = null;
private String text = null;
private long timestamp = 0L;
-
-
+
+
/**
* Constructor.
* @param alertName the name of the alert
@@ -56,32 +56,32 @@ public class Alert {
public Alert() {
}
-
+
/**
* @return the name
*/
- @JsonProperty("name")
+ @JsonProperty("name")
public String getName() {
return name;
}
-
+
/**
* @return the service
*/
- @JsonProperty("service")
+ @JsonProperty("service")
public String getService() {
return service;
}
-
+
/**
* @return the component
*/
- @JsonProperty("component")
+ @JsonProperty("component")
public String getComponent() {
return component;
}
-
+
/**
* @return the host
*/
@@ -89,7 +89,7 @@ public class Alert {
public String getHost() {
return host;
}
-
+
/**
* @return the state
*/
@@ -101,7 +101,7 @@ public class Alert {
/**
* @return a short descriptive label for the alert
*/
- @JsonProperty("label")
+ @JsonProperty("label")
public String getLabel() {
return label;
}
@@ -109,32 +109,32 @@ public class Alert {
/**
* @param alertLabel a short descriptive label for the alert
*/
- @JsonProperty("label")
+ @JsonProperty("label")
public void setLabel(String alertLabel) {
label = alertLabel;
}
-
+
/**
* @return detail text about the alert
*/
- @JsonProperty("text")
+ @JsonProperty("text")
public String getText() {
return text;
}
-
+
/**
* @param alertText detail text about the alert
*/
- @JsonProperty("text")
+ @JsonProperty("text")
public void setText(String alertText) {
text = alertText;
}
- @JsonProperty("instance")
+ @JsonProperty("instance")
public String getInstance() {
return instance;
}
-
+
@JsonProperty("instance")
public void setInstance(String instance) {
this.instance = instance;
@@ -164,24 +164,24 @@ public class Alert {
public void setState(AlertState state) {
this.state = state;
}
-
+
@JsonProperty("timestamp")
public void setTimestamp(long ts) {
timestamp = ts;
}
-
+
@JsonProperty("timestamp")
public long getTimestamp() {
return timestamp;
}
-
+
/**
* @return
*/
public String getCluster() {
return cluster;
}
-
+
@Override
public int hashCode() {
int result = alertHashCode();
@@ -197,8 +197,9 @@ public class Alert {
*/
@Override
public boolean equals(Object o) {
- if (null == o || !Alert.class.isInstance(o))
+ if (null == o || !Alert.class.isInstance(o)) {
return false;
+ }
return hashCode() == o.hashCode();
}
@@ -217,7 +218,7 @@ public class Alert {
/**
* Checks equality with another alert, not taking into account instance info
- *
+ *
* @param that
* the other alert to compare against
* @return <code>true</code> when the alert is equal in every way except the
@@ -226,8 +227,7 @@ public class Alert {
public boolean almostEquals(Alert that) {
return alertHashCode() == that.alertHashCode();
}
-
-
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
@@ -242,7 +242,4 @@ public class Alert {
sb.append('}');
return sb.toString();
}
-
-
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
deleted file mode 100644
index 4a65d5a..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/AlertDataManager.java
+++ /dev/null
@@ -1,111 +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 org.apache.ambari.server.state.cluster;
-
-import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
-import org.apache.ambari.server.orm.dao.AlertsDAO;
-import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
-import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
-import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
-import org.apache.ambari.server.state.Alert;
-
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-
-/**
- * The AlertManager is reponsible for tracking all alerts generated for a cluster.
- */
-@Singleton
-public class AlertDataManager {
-
- @Inject
- private AlertsDAO m_alertsDao;
- @Inject
- private AlertDefinitionDAO m_definitionDao;
-
-
- AlertDataManager() {
- }
-
- /**
- * Adds an alert. Checks for a new state before creating a new history record.
- *
- * @param clusterId the id for the cluster
- * @param alert the alert to add
- */
- public void add(long clusterId, Alert alert) {
-
- AlertCurrentEntity current = m_alertsDao.findCurrentByHostAndName(clusterId,
- alert.getHost(), alert.getName());
-
- if (null == current) {
- AlertDefinitionEntity definition = m_definitionDao.findByName(clusterId,
- alert.getName());
-
- AlertHistoryEntity history = createHistory(clusterId, definition, alert);
-
- current = new AlertCurrentEntity();
- current.setAlertHistory(history);
- current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
- current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
-
- m_alertsDao.create(current);
-
- } else if (alert.getState() == current.getAlertHistory().getAlertState()) {
- current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
- current.setLatestText(alert.getText());
-
- m_alertsDao.merge(current);
- } else {
- // insert history, update current
- AlertHistoryEntity history = createHistory(clusterId,
- current.getAlertHistory().getAlertDefinition(), alert);
-
- current.setAlertHistory(history);
- current.setLatestTimestamp(Long.valueOf(alert.getTimestamp()));
- current.setOriginalTimestamp(Long.valueOf(alert.getTimestamp()));
-
- m_alertsDao.merge(current);
- }
-
- }
- /**
- * Convenience to create a new alert.
- * @param clusterId the cluster id
- * @param definition the definition
- * @param alert the alert data
- * @return the new history record
- */
- private AlertHistoryEntity createHistory(long clusterId, AlertDefinitionEntity definition, Alert alert) {
- AlertHistoryEntity history = new AlertHistoryEntity();
- history.setAlertDefinition(definition);
- history.setAlertInstance(alert.getInstance());
- history.setAlertLabel(alert.getLabel());
- history.setAlertState(alert.getState());
- history.setAlertText(alert.getText());
- history.setAlertTimestamp(Long.valueOf(alert.getTimestamp()));
- history.setClusterId(Long.valueOf(clusterId));
- history.setComponentName(alert.getComponent());
- history.setHostName(alert.getHost());
- history.setServiceName(alert.getService());
-
- return history;
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
index 8451c9b..1103961 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDispatchDAOTest.java
@@ -351,6 +351,35 @@ public class AlertDispatchDAOTest {
}
/**
+ * Tests finding groups by a definition ID that they are associatd with.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testFindGroupsByDefinition() throws Exception {
+ List<AlertDefinitionEntity> definitions = createDefinitions();
+ AlertGroupEntity group = helper.createAlertGroup(clusterId, null);
+
+ group = dao.findGroupById(group.getGroupId());
+ assertNotNull(group);
+
+ for (AlertDefinitionEntity definition : definitions) {
+ group.addAlertDefinition(definition);
+ }
+
+ dao.merge(group);
+
+ group = dao.findGroupByName(group.getGroupName());
+ assertEquals(definitions.size(), group.getAlertDefinitions().size());
+
+ for (AlertDefinitionEntity definition : definitions) {
+ List<AlertGroupEntity> groups = dao.findGroupsByDefinition(definition);
+ assertEquals(1, groups.size());
+ assertEquals(group.getGroupId(), groups.get(0).getGroupId());
+ }
+ }
+
+ /**
* @return
*/
private List<AlertDefinitionEntity> createDefinitions() throws Exception {
http://git-wip-us.apache.org/repos/asf/ambari/blob/760bedfe/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
index eae1de6..bbf7774 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/cluster/AlertDataManagerTest.java
@@ -21,17 +21,28 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.UUID;
+import org.apache.ambari.server.events.AlertEvent;
+import org.apache.ambari.server.events.AlertReceivedEvent;
+import org.apache.ambari.server.events.AlertStateChangeEvent;
+import org.apache.ambari.server.events.listeners.AlertReceivedListener;
+import org.apache.ambari.server.events.listeners.AlertStateChangedListener;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
import org.apache.ambari.server.orm.dao.AlertsDAO;
import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+import org.apache.ambari.server.orm.entities.AlertNoticeEntity;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.AlertState;
import org.apache.ambari.server.state.alert.Scope;
@@ -44,22 +55,24 @@ import com.google.inject.Injector;
import com.google.inject.persist.PersistService;
/**
- * Tests the alert manager.
+ * Tests the management of {@link AlertEvent}s in the system.
*/
public class AlertDataManagerTest {
-
+
private static final String ALERT_DEFINITION = "Alert Definition 1";
private static final String SERVICE = "service1";
private static final String COMPONENT = "component1";
private static final String HOST1 = "h1";
private static final String HOST2 = "h2";
private static final String ALERT_LABEL = "My Label";
-
+
private Long clusterId;
private Injector injector;
private OrmTestHelper helper;
private AlertsDAO dao;
-
+ private AlertDispatchDAO dispatchDao;
+ private AlertDefinitionDAO definitionDao;
+
@Before
public void setup() throws Exception {
injector = Guice.createInjector(new InMemoryDefaultTestModule());
@@ -67,7 +80,8 @@ public class AlertDataManagerTest {
helper = injector.getInstance(OrmTestHelper.class);
clusterId = helper.createCluster();
dao = injector.getInstance(AlertsDAO.class);
- AlertDefinitionDAO definitionDao = injector.getInstance(AlertDefinitionDAO.class);
+ dispatchDao = injector.getInstance(AlertDispatchDAO.class);
+ definitionDao = injector.getInstance(AlertDefinitionDAO.class);
// create 5 definitions
for (int i = 0; i < 5; i++) {
@@ -83,18 +97,16 @@ public class AlertDataManagerTest {
definition.setSourceType("SCRIPT");
definitionDao.create(definition);
}
-
}
-
+
@After
public void teardown() {
injector.getInstance(PersistService.class).stop();
injector = null;
}
-
+
@Test
public void testAlertRecords() {
-
Alert alert1 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST1, AlertState.OK);
alert1.setLabel(ALERT_LABEL);
alert1.setText("Component component1 is OK");
@@ -103,18 +115,24 @@ public class AlertDataManagerTest {
Alert alert2 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST2, AlertState.CRITICAL);
alert2.setLabel(ALERT_LABEL);
alert2.setText("Component component2 is not OK");
-
- AlertDataManager am = injector.getInstance(AlertDataManager.class);
-
- am.add(clusterId.longValue(), alert1);
- am.add(clusterId.longValue(), alert2);
-
+
+ AlertReceivedListener listener = injector.getInstance(AlertReceivedListener.class);
+
+ AlertReceivedEvent event1 = new AlertReceivedEvent(clusterId.longValue(),
+ alert1);
+
+ AlertReceivedEvent event2 = new AlertReceivedEvent(clusterId.longValue(),
+ alert2);
+
+ listener.onAlertEvent(event1);
+ listener.onAlertEvent(event2);
+
List<AlertCurrentEntity> allCurrent = dao.findCurrentByService(clusterId.longValue(), SERVICE);
assertEquals(2, allCurrent.size());
-
+
List<AlertHistoryEntity> allHistory = dao.findAll(clusterId.longValue());
assertEquals(2, allHistory.size());
-
+
AlertCurrentEntity current = dao.findCurrentByHostAndName(clusterId.longValue(), HOST1, ALERT_DEFINITION);
assertNotNull(current);
assertEquals(HOST1, current.getAlertHistory().getHostName());
@@ -124,17 +142,21 @@ public class AlertDataManagerTest {
assertEquals(current.getAlertHistory().getAlertState(), AlertState.OK);
assertEquals(1L, current.getOriginalTimestamp().longValue());
assertEquals(1L, current.getLatestTimestamp().longValue());
-
+
Long currentId = current.getAlertId();
Long historyId = current.getAlertHistory().getAlertId();
-
+
// no new history since the state is the same
Alert alert3 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST1, AlertState.OK);
alert3.setLabel(ALERT_LABEL);
alert3.setText("Component component1 is OK");
alert3.setTimestamp(2L);
- am.add(clusterId.longValue(), alert3);
-
+
+ AlertReceivedEvent event3 = new AlertReceivedEvent(clusterId.longValue(),
+ alert3);
+
+ listener.onAlertEvent(event3);
+
current = dao.findCurrentByHostAndName(clusterId.longValue(), HOST1, ALERT_DEFINITION);
assertNotNull(current);
assertEquals(currentId, current.getAlertId());
@@ -146,24 +168,28 @@ public class AlertDataManagerTest {
assertEquals(current.getAlertHistory().getAlertState(), AlertState.OK);
assertEquals(1L, current.getOriginalTimestamp().longValue());
assertEquals(2L, current.getLatestTimestamp().longValue());
-
+
allCurrent = dao.findCurrentByService(clusterId.longValue(), SERVICE);
assertEquals(2, allCurrent.size());
-
+
allHistory = dao.findAll(clusterId.longValue());
assertEquals(2, allHistory.size());
-
+
// change to warning
Alert alert4 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST1, AlertState.WARNING);
alert4.setLabel(ALERT_LABEL);
alert4.setText("Component component1 is about to go down");
alert4.setTimestamp(3L);
- am.add(clusterId.longValue(), alert4);
+
+ AlertReceivedEvent event4 = new AlertReceivedEvent(clusterId.longValue(),
+ alert4);
+
+ listener.onAlertEvent(event4);
current = dao.findCurrentByHostAndName(clusterId.longValue(), HOST1, ALERT_DEFINITION);
assertNotNull(current);
assertEquals(current.getAlertId(), currentId);
- assertFalse(historyId.equals(current.getAlertHistory().getAlertId()));
+ assertFalse(historyId.equals(current.getAlertHistory().getAlertId()));
assertEquals(HOST1, current.getAlertHistory().getHostName());
assertEquals(ALERT_DEFINITION, current.getAlertHistory().getAlertDefinition().getDefinitionName());
assertEquals(ALERT_LABEL, current.getAlertHistory().getAlertLabel());
@@ -174,8 +200,57 @@ public class AlertDataManagerTest {
allCurrent = dao.findCurrentByService(clusterId.longValue(), SERVICE);
assertEquals(2, allCurrent.size());
-
+
allHistory = dao.findAll(clusterId.longValue());
assertEquals(3, allHistory.size());
}
+
+ /**
+ * Tests that {@link AlertStateChangeEvent} cause an {@link AlertNoticeEntity}
+ * entry.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testAlertNotices() throws Exception {
+ List<AlertNoticeEntity> notices = dispatchDao.findAllNotices();
+ assertEquals( 0, notices.size() );
+
+ List<AlertDefinitionEntity> definitions = definitionDao.findAll(clusterId);
+ AlertDefinitionEntity definition = definitions.get(0);
+
+ AlertHistoryEntity history = new AlertHistoryEntity();
+ history.setServiceName(definition.getServiceName());
+ history.setClusterId(clusterId);
+ history.setAlertDefinition(definition);
+ history.setAlertLabel(definition.getDefinitionName());
+ history.setAlertText(definition.getDefinitionName());
+ history.setAlertTimestamp(System.currentTimeMillis());
+ history.setHostName(HOST1);
+ history.setAlertState(AlertState.OK);
+ dao.create(history);
+
+ List<AlertHistoryEntity> histories = dao.findAll(clusterId);
+ assertEquals(1, histories.size());
+
+ AlertTargetEntity target = helper.createAlertTarget();
+ Set<AlertTargetEntity> targets = new HashSet<AlertTargetEntity>();
+ targets.add(target);
+
+ AlertGroupEntity group = helper.createAlertGroup(clusterId, targets);
+ group.addAlertDefinition( definitions.get(0) );
+ dispatchDao.merge(group);
+
+ Alert alert1 = new Alert(ALERT_DEFINITION, null, SERVICE, COMPONENT, HOST1,
+ AlertState.OK);
+
+ AlertStateChangeEvent event = new AlertStateChangeEvent(clusterId, alert1,
+ histories.get(0), AlertState.CRITICAL);
+
+ AlertStateChangedListener listener = injector.getInstance(AlertStateChangedListener.class);
+ listener.onAlertEvent(event);
+
+ notices = dispatchDao.findAllNotices();
+ assertEquals(1, notices.size());
+ }
}