Author: jspeidel
Date: Thu Jan 24 05:14:25 2013
New Revision: 1437859
URL: http://svn.apache.org/viewvc?rev=1437859&view=rev
Log:
AMBARI-1237. Expose Nagios alerts via API
Added:
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HttpPropertyProviderTest.java
Modified:
incubator/ambari/trunk/CHANGES.txt
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java
Modified: incubator/ambari/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/CHANGES.txt?rev=1437859&r1=1437858&r2=1437859&view=diff
==============================================================================
--- incubator/ambari/trunk/CHANGES.txt (original)
+++ incubator/ambari/trunk/CHANGES.txt Thu Jan 24 05:14:25 2013
@@ -12,6 +12,7 @@ Trunk (unreleased changes):
NEW FEATURES
+ AMBARI-1237. Expose Nagios alerts via Rest API. (Nate Cole via jspeidel)
AMBARI-1163. During agent registration and heartbeat, send information about
various hadoop artifacts back to Ambari. (Nate Cole via mahadev)
Modified:
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java?rev=1437859&r1=1437858&r2=1437859&view=diff
==============================================================================
---
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
(original)
+++
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
Thu Jan 24 05:14:25 2013
@@ -222,6 +222,13 @@ public abstract class AbstractProviderMo
PropertyHelper.getPropertyId("HostRoles", "cluster_name"),
PropertyHelper.getPropertyId("HostRoles", "host_name"),
PropertyHelper.getPropertyId("HostRoles", "component_name")));
+
+ providers.add(new HttpProxyPropertyProvider(
+ new URLStreamProvider(1500),
+ PropertyHelper.getPropertyId("HostRoles", "cluster_name"),
+ PropertyHelper.getPropertyId("HostRoles", "host_name"),
+ PropertyHelper.getPropertyId("HostRoles", "component_name")));
+
break;
default :
break;
Added:
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java?rev=1437859&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java
(added)
+++
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HttpProxyPropertyProvider.java
Thu Jan 24 05:14:25 2013
@@ -0,0 +1,151 @@
+/**
+ * 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.io.IOException;
+import java.io.InputStream;
+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.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.controller.utilities.StreamProvider;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Property provider that is used to read HTTP data from another server.
+ */
+public class HttpProxyPropertyProvider implements PropertyProvider {
+
+ protected final static Logger LOG =
+ LoggerFactory.getLogger(HttpProxyPropertyProvider.class);
+
+ private static final Map<String, String> URL_TEMPLATES = new HashMap<String,
String>();
+ private static final Map<String, String> MAPPINGS = new HashMap<String,
String>();
+
+ static {
+ URL_TEMPLATES.put("NAGIOS_SERVER",
"http://%s/hdp/nagios/nagios_alerts.php?q1=alerts&alert_type=all");
+
+ MAPPINGS.put("NAGIOS_SERVER", PropertyHelper.getPropertyId("HostRoles",
"nagios_alerts"));
+ }
+
+ private StreamProvider streamProvider = null;
+ // !!! not yet used, but make consistent
+ private String clusterNamePropertyId = null;
+ private String hostNamePropertyId = null;
+ private String componentNamePropertyId = null;
+
+ private Set<String> propertyIds = new HashSet<String>();
+
+ public HttpProxyPropertyProvider(
+ StreamProvider stream,
+ String clusterNamePropertyId,
+ String hostNamePropertyId,
+ String componentNamePropertyId) {
+ this.streamProvider = stream;
+ this.clusterNamePropertyId = clusterNamePropertyId;
+ this.hostNamePropertyId = hostNamePropertyId;
+ this.componentNamePropertyId = componentNamePropertyId;
+
+ propertyIds.addAll(MAPPINGS.values());
+ }
+
+ /**
+ * This method only checks if an HTTP-type property should be fulfilled. No
+ * modification is performed on the resources.
+ */
+ @Override
+ public Set<Resource> populateResources(Set<Resource> resources,
+ Request request, Predicate predicate) throws SystemException {
+
+ Set<String> ids = PropertyHelper.getRequestPropertyIds(propertyIds,
request, predicate);
+
+ if (0 == ids.size())
+ return resources;
+
+ for (Resource resource : resources) {
+
+ Object hostName = resource.getPropertyValue(hostNamePropertyId);
+ Object componentName =
resource.getPropertyValue(componentNamePropertyId);
+
+ if (null != hostName && null != componentName &&
+ MAPPINGS.containsKey(componentName.toString()) &&
+ URL_TEMPLATES.containsKey(componentName.toString())) {
+
+ String template = URL_TEMPLATES.get(componentName.toString());
+ String propertyId = MAPPINGS.get(componentName.toString());
+ String url = String.format(template, hostName);
+
+ getHttpResponse(resource, url, propertyId);
+ }
+ }
+
+ return resources;
+ }
+
+ @Override
+ public Set<String> getPropertyIds() {
+ return propertyIds;
+ }
+
+ @Override
+ public Set<String> checkPropertyIds(Set<String> propertyIds) {
+ if (!this.propertyIds.containsAll(propertyIds)) {
+ Set<String> unsupportedPropertyIds = new HashSet<String>(propertyIds);
+ unsupportedPropertyIds.removeAll(this.propertyIds);
+ return unsupportedPropertyIds;
+ }
+ return Collections.emptySet();
+ }
+
+ private void getHttpResponse(Resource r, String url, String propertyIdToSet)
{
+
+ InputStream in = null;
+ try {
+ in = streamProvider.readFrom(url);
+
+ String str = IOUtils.toString(in, "UTF-8");
+
+ r.setProperty(propertyIdToSet, str);
+ }
+ catch (IOException ioe) {
+ LOG.error("Error reading HTTP response from " + url);
+ }
+ finally {
+ if (null != in) {
+ try {
+ in.close();
+ }
+ catch (IOException ioe) {
+ //
+ }
+ }
+ }
+
+ }
+
+}
Modified:
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java?rev=1437859&r1=1437858&r2=1437859&view=diff
==============================================================================
---
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java
(original)
+++
incubator/ambari/trunk/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java
Thu Jan 24 05:14:25 2013
@@ -18,20 +18,38 @@
package org.apache.ambari.server.controller.internal;
-import org.apache.ambari.server.controller.utilities.StreamProvider;
-
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
+import org.apache.ambari.server.controller.utilities.StreamProvider;
+
/**
* URL based implementation of a stream provider.
*/
public class URLStreamProvider implements StreamProvider {
+
+ private int connTimeout = -1;
+
+ public URLStreamProvider() {
+ }
+
+ /**
+ * Provide the connection timeout for the underlying connection.
+ *
+ * @param connectionTimeout time, in milliseconds, to attempt a connection
+ */
+ public URLStreamProvider(int connectionTimeout) {
+ connTimeout = connectionTimeout;
+ }
+
@Override
public InputStream readFrom(String spec) throws IOException {
URLConnection connection = new URL(spec).openConnection();
+ if (connTimeout > 0) {
+ connection.setConnectTimeout(connTimeout);
+ }
connection.setDoOutput(true);
return connection.getInputStream();
}
Added:
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HttpPropertyProviderTest.java
URL:
http://svn.apache.org/viewvc/incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HttpPropertyProviderTest.java?rev=1437859&view=auto
==============================================================================
---
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HttpPropertyProviderTest.java
(added)
+++
incubator/ambari/trunk/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HttpPropertyProviderTest.java
Thu Jan 24 05:14:25 2013
@@ -0,0 +1,120 @@
+/**
+ * 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.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.controller.utilities.StreamProvider;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class HttpPropertyProviderTest {
+ private static final String PROPERTY_ID_CLUSTER_NAME =
PropertyHelper.getPropertyId("HostRoles", "cluster_name");
+ private static final String PROPERTY_ID_HOST_NAME =
PropertyHelper.getPropertyId("HostRoles", "host_name");
+ private static final String PROPERTY_ID_COMPONENT_NAME =
PropertyHelper.getPropertyId("HostRoles", "component_name");
+
+ private static final String PROPERTY_ID_NAGIOS_ALERTS =
PropertyHelper.getPropertyId("HostRoles", "nagios_alerts");
+
+ @Test
+ public void testReadNagiosServer() throws Exception {
+
+ Resource resource = doPopulate("NAGIOS_SERVER",
Collections.<String>emptySet());
+
+ Assert.assertNotNull("Expected non-null for 'nagios_alerts'",
+ resource.getPropertyValue(PROPERTY_ID_NAGIOS_ALERTS));
+ }
+
+ @Test
+ public void testReadNotRequested() throws Exception {
+
+ Set<String> propertyIds = new HashSet<String>();
+ propertyIds.add(PropertyHelper.getPropertyId("HostRoles", "state"));
+ propertyIds.add(PROPERTY_ID_COMPONENT_NAME);
+
+ Resource resource = doPopulate("NAGIOS_SERVER", propertyIds);
+
+ Assert.assertNull("Expected null for 'nagios_alerts'",
+ resource.getPropertyValue(PROPERTY_ID_NAGIOS_ALERTS));
+ }
+
+ @Test
+ public void testReadWithRequested() throws Exception {
+
+ Set<String> propertyIds = new HashSet<String>();
+ propertyIds.add(PropertyHelper.getPropertyId("HostRoles", "nagios_alerts"));
+ propertyIds.add(PROPERTY_ID_COMPONENT_NAME);
+
+ Resource resource = doPopulate("NAGIOS_SERVER", propertyIds);
+
+ Assert.assertNotNull("Expected non-null for 'nagios_alerts'",
+ resource.getPropertyValue(PROPERTY_ID_NAGIOS_ALERTS));
+ }
+
+
+ @Test
+ public void testReadGangliaServer() throws Exception {
+
+ Resource resource = doPopulate("GANGLIA_SERVER",
Collections.<String>emptySet());
+
+ // !!! GANGLIA_SERVER has no current http lookup
+ Assert.assertNull("Expected null, was: " +
+ resource.getPropertyValue(PROPERTY_ID_NAGIOS_ALERTS),
+ resource.getPropertyValue(PROPERTY_ID_NAGIOS_ALERTS));
+ }
+
+ private Resource doPopulate(String componentName, Set<String>
requestProperties) throws Exception {
+
+ HttpProxyPropertyProvider propProvider = new HttpProxyPropertyProvider(
+ new TestStreamProvider(),
+ PROPERTY_ID_CLUSTER_NAME,
+ PROPERTY_ID_HOST_NAME,
+ PROPERTY_ID_COMPONENT_NAME);
+
+ Resource resource = new ResourceImpl(Resource.Type.HostComponent);
+
+ resource.setProperty(PROPERTY_ID_HOST_NAME,
"ec2-54-234-33-50.compute-1.amazonaws.com");
+ resource.setProperty(PROPERTY_ID_COMPONENT_NAME, componentName);
+
+ Request request = PropertyHelper.getReadRequest(requestProperties);
+
+ propProvider.populateResources(Collections.singleton(resource), request,
null);
+
+ return resource;
+ }
+
+
+
+ private static class TestStreamProvider implements StreamProvider {
+
+ @Override
+ public InputStream readFrom(String spec) throws IOException {
+ return new ByteArrayInputStream("PROPERTY_TEST".getBytes());
+ }
+ }
+
+
+}