Repository: ambari Updated Branches: refs/heads/trunk 66848d4d6 -> d4a037036
AMBARI-5929 - Views : Pass temporal request to view resource provider. Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d4a03703 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d4a03703 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d4a03703 Branch: refs/heads/trunk Commit: d4a037036687ac1f2c28a5d8869ef5152a01d1a8 Parents: 66848d4 Author: tbeerbower <[email protected]> Authored: Thu May 29 14:49:43 2014 -0400 Committer: tbeerbower <[email protected]> Committed: Thu May 29 15:30:30 2014 -0400 ---------------------------------------------------------------------- .../apache/ambari/server/view/ViewRegistry.java | 4 +- .../server/view/ViewSubResourceProvider.java | 65 ++++- .../ambari/server/view/ViewRegistryTest.java | 12 + .../view/ViewSubResourceProviderTest.java | 241 +++++++++++++++++++ .../org/apache/ambari/view/ReadRequest.java | 41 ++++ 5 files changed, 357 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/d4a03703/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java index 466ce5a..bc193a4 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java @@ -558,7 +558,7 @@ public class ViewRegistry { } // create a new view definition - private ViewEntity createViewDefinition(ViewConfig viewConfig, Configuration ambariConfig, + protected ViewEntity createViewDefinition(ViewConfig viewConfig, Configuration ambariConfig, ClassLoader cl, String archivePath) throws ClassNotFoundException, IntrospectionException { @@ -634,7 +634,7 @@ public class ViewRegistry { } // create a new view instance definition - private ViewInstanceEntity createViewInstanceDefinition(ViewEntity viewDefinition, InstanceConfig instanceConfig) + protected ViewInstanceEntity createViewInstanceDefinition(ViewEntity viewDefinition, InstanceConfig instanceConfig) throws ClassNotFoundException { ViewInstanceEntity viewInstanceDefinition = new ViewInstanceEntity(viewDefinition, instanceConfig); http://git-wip-us.apache.org/repos/asf/ambari/blob/d4a03703/ambari-server/src/main/java/org/apache/ambari/server/view/ViewSubResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewSubResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewSubResourceProvider.java index e9d2a4c..260fc3d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewSubResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewSubResourceProvider.java @@ -29,6 +29,7 @@ import org.apache.ambari.server.controller.spi.RequestStatus; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; import org.apache.ambari.server.controller.spi.SystemException; +import org.apache.ambari.server.controller.spi.TemporalInfo; import org.apache.ambari.server.controller.spi.UnsupportedPropertyException; import org.apache.ambari.server.controller.utilities.PropertyHelper; import org.apache.ambari.server.orm.entities.ViewEntity; @@ -157,7 +158,7 @@ public class ViewSubResourceProvider extends AbstractResourceProvider { } Set<Resource> results = new HashSet<Resource>(); - ReadRequest readRequest = new ViewReadRequest(requestedIds, predicate == null ? "" : predicate.toString()); + ReadRequest readRequest = new ViewReadRequest(request, requestedIds, predicate == null ? "" : predicate.toString()); for (ViewInstanceEntity instanceDefinition : instanceDefinitions) { Set<?> beans = instanceDefinition.getResourceProvider(type).getResources(readRequest); @@ -307,9 +308,17 @@ public class ViewSubResourceProvider extends AbstractResourceProvider { // ----- inner class : ViewReadRequest ------------------------------------- /** - * A read request to pass the the view resource provider. + * A read request to pass the the view resource provider. Serves + * as a bridge from the ambari-server API framework request to the + * view framework request. */ private static class ViewReadRequest implements ReadRequest { + + /** + * The original request. + */ + private final Request request; + /** * The property ids of the request. */ @@ -329,9 +338,10 @@ public class ViewSubResourceProvider extends AbstractResourceProvider { * @param propertyIds the property ids * @param predicate the predicate */ - private ViewReadRequest(Set<String> propertyIds, String predicate) { + private ViewReadRequest(Request request, Set<String> propertyIds, String predicate) { + this.request = request; this.propertyIds = propertyIds; - this.predicate = predicate; + this.predicate = predicate; } @@ -346,5 +356,52 @@ public class ViewSubResourceProvider extends AbstractResourceProvider { public String getPredicate() { return predicate; } + + @Override + public TemporalInfo getTemporalInfo(String id) { + + org.apache.ambari.server.controller.spi.TemporalInfo temporalInfo = + request.getTemporalInfo(id); + + return temporalInfo == null ? null : new ViewReadRequestTemporalInfo(temporalInfo); + } + } + + /** + * Temporal information to pass to the view resource provider. Serves as a + * bridge from the ambari-server API framework temporal info object to the + * view framework temporal info object. + */ + private static class ViewReadRequestTemporalInfo implements ReadRequest.TemporalInfo { + + /** + * The original temporal information object. + */ + private final org.apache.ambari.server.controller.spi.TemporalInfo temporalInfo; + + + // ----- Constructors ---------------------------------------------------- + + private ViewReadRequestTemporalInfo(TemporalInfo temporalInfo) { + this.temporalInfo = temporalInfo; + } + + + // ----- TemporalInfo ---------------------------------------------------- + + @Override + public Long getStartTime() { + return temporalInfo.getStartTime(); + } + + @Override + public Long getEndTime() { + return temporalInfo.getEndTime(); + } + + @Override + public Long getStep() { + return temporalInfo.getStep(); + } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/d4a03703/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java index 05947d5..fc493ab 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewRegistryTest.java @@ -491,4 +491,16 @@ public class ViewRegistryTest { } } + public static ViewEntity getViewEntity(ViewConfig viewConfig, Configuration ambariConfig, + ClassLoader cl, String archivePath) throws Exception{ + ViewRegistry registry = ViewRegistry.getInstance(); + + return registry.createViewDefinition(viewConfig, ambariConfig, cl, archivePath); + } + + public static ViewInstanceEntity getViewInstanceEntity(ViewEntity viewDefinition, InstanceConfig instanceConfig) throws Exception { + ViewRegistry registry = ViewRegistry.getInstance(); + + return registry.createViewInstanceDefinition(viewDefinition, instanceConfig); + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/d4a03703/ambari-server/src/test/java/org/apache/ambari/server/view/ViewSubResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/view/ViewSubResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewSubResourceProviderTest.java new file mode 100644 index 0000000..90854bd --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/view/ViewSubResourceProviderTest.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.view; + +import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.controller.internal.TemporalInfoImpl; +import org.apache.ambari.server.controller.predicate.AlwaysPredicate; +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.TemporalInfo; +import org.apache.ambari.server.controller.utilities.PredicateBuilder; +import org.apache.ambari.server.controller.utilities.PropertyHelper; +import org.apache.ambari.server.orm.entities.ViewEntity; +import org.apache.ambari.server.view.configuration.ViewConfig; +import org.apache.ambari.server.view.configuration.ViewConfigTest; +import org.apache.ambari.view.NoSuchResourceException; +import org.apache.ambari.view.ReadRequest; +import org.apache.ambari.view.ResourceAlreadyExistsException; +import org.apache.ambari.view.ResourceProvider; +import org.apache.ambari.view.SystemException; +import org.apache.ambari.view.UnsupportedPropertyException; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +/** + * ViewSubResourceProvider tests. + */ +public class ViewSubResourceProviderTest { + + + + private static String xml = "<view>\n" + + " <name>MY_VIEW</name>\n" + + " <label>My View!</label>\n" + + " <version>1.0.0</version>\n" + + " <resource>\n" + + " <name>resource</name>\n" + + " <plural-name>resources</plural-name>\n" + + " <id-property>id</id-property>\n" + + " <resource-class>org.apache.ambari.server.view.ViewSubResourceProviderTest$MyResource</resource-class>\n" + + " <provider-class>org.apache.ambari.server.view.ViewSubResourceProviderTest$MyResourceProvider</provider-class>\n" + + " <service-class>org.apache.ambari.server.view.ViewSubResourceProviderTest$MyResourceService</service-class>\n" + + " </resource>\n" + + " <instance>\n" + + " <name>INSTANCE1</name>\n" + + " </instance>\n" + + "</view>"; + + + @Test + public void testGetResources() throws Exception { + + Properties properties = new Properties(); + properties.put("p1", "v1"); + + Configuration ambariConfig = new Configuration(properties); + + ViewConfig config = ViewConfigTest.getConfig(xml); + ViewEntity viewEntity = ViewRegistryTest.getViewEntity(config, ambariConfig, getClass().getClassLoader(), ""); + ViewRegistryTest.getViewInstanceEntity(viewEntity, config.getInstances().get(0)); + + Map<Resource.Type, ViewSubResourceDefinition> resourceDefinitions = viewEntity.getResourceDefinitions(); + + Assert.assertEquals(1, resourceDefinitions.size()); + + Resource.Type type = resourceDefinitions.keySet().iterator().next(); + + ViewSubResourceProvider viewSubResourceProvider = new ViewSubResourceProvider(type, MyResource.class, "id", viewEntity); + + Request request = PropertyHelper.getReadRequest("id", "properties", "metrics/myMetric"); + Predicate predicate = new AlwaysPredicate(); + + Set<Resource> resources = viewSubResourceProvider.getResources(request, predicate); + + Assert.assertEquals(2, resources.size()); + + predicate = new PredicateBuilder().property("metrics/myMetric").greaterThan(1).toPredicate(); + + resources = viewSubResourceProvider.getResources(request, predicate); + + Assert.assertEquals(1, resources.size()); + + Assert.assertTrue(((Integer) resources.iterator().next().getPropertyValue("metrics/myMetric")) > 1); + } + + @Test + public void testGetResources_temporal() throws Exception { + + Properties properties = new Properties(); + properties.put("p1", "v1"); + + Configuration ambariConfig = new Configuration(properties); + + ViewConfig config = ViewConfigTest.getConfig(xml); + ViewEntity viewEntity = ViewRegistryTest.getViewEntity(config, ambariConfig, getClass().getClassLoader(), ""); + ViewRegistryTest.getViewInstanceEntity(viewEntity, config.getInstances().get(0)); + + Map<Resource.Type, ViewSubResourceDefinition> resourceDefinitions = viewEntity.getResourceDefinitions(); + + Assert.assertEquals(1, resourceDefinitions.size()); + + Resource.Type type = resourceDefinitions.keySet().iterator().next(); + + ViewSubResourceProvider viewSubResourceProvider = new ViewSubResourceProvider(type, MyResource.class, "id", viewEntity); + + Set<String> requestProperties = new HashSet<String>(); + requestProperties.add("metrics/myMetric"); + + Map<String, TemporalInfo> temporalInfoMap = new HashMap<String, TemporalInfo>(); + TemporalInfo temporalInfo = new TemporalInfoImpl(1000L, 1100L, 10L); + temporalInfoMap.put("metrics/myMetric", temporalInfo); + + Request request = PropertyHelper.getReadRequest(requestProperties, temporalInfoMap); + Predicate predicate = new AlwaysPredicate(); + + Set<Resource> resources = viewSubResourceProvider.getResources(request, predicate); + + Assert.assertEquals(2, resources.size()); + } + + public static class MyResource { + private String id; + private String property; + private Map<String, Object> metrics; + + public MyResource() { + } + + public MyResource(String id, String property, Map<String, Object> metrics) { + this.id = id; + this.property = property; + this.metrics = metrics; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getProperty() { + return property; + } + + public void setProperty(String property) { + this.property = property; + } + + public Map<String, Object> getMetrics() { + return metrics; + } + + public void setMetrics(Map<String, Object> metrics) { + this.metrics = metrics; + } + } + + public static class MyResourceProvider implements ResourceProvider<MyResource> { + + @Override + public MyResource getResource(String resourceId, Set<String> properties) + throws SystemException, NoSuchResourceException, UnsupportedPropertyException { + return null; + } + + @Override + public Set<MyResource> getResources(ReadRequest request) + throws SystemException, NoSuchResourceException, UnsupportedPropertyException { + + Set<MyResource> resources = new HashSet<MyResource>(); + resources.add(new MyResource("1", "foo", getMetricsValue(1, request, "myMetric"))); + resources.add(new MyResource("2", "bar", getMetricsValue(2, request, "myMetric"))); + + return resources; + } + + private Map<String, Object> getMetricsValue(Number value, ReadRequest request, String metricName) { + + ReadRequest.TemporalInfo temporalInfo = request.getTemporalInfo("metrics/" + metricName); + if (temporalInfo != null) { + int steps = (int) ((temporalInfo.getEndTime() - temporalInfo.getStartTime()) / temporalInfo.getStep()); + + Number[][] datapointsArray = new Number[steps][2]; + + for (int i = 0; i < steps; ++i) { + datapointsArray[i][0] = temporalInfo.getStartTime() + i * temporalInfo.getStep(); + datapointsArray[i][1] = value; + } + return Collections.<String, Object>singletonMap(metricName, datapointsArray); + } + return Collections.<String, Object>singletonMap(metricName, value); + } + + @Override + public void createResource(String resourceId, Map<String, Object> properties) + throws SystemException, ResourceAlreadyExistsException, NoSuchResourceException, UnsupportedPropertyException { + } + + @Override + public boolean updateResource(String resourceId, Map<String, Object> properties) + throws SystemException, NoSuchResourceException, UnsupportedPropertyException { + return false; + } + + @Override + public boolean deleteResource(String resourceId) + throws SystemException, NoSuchResourceException, UnsupportedPropertyException { + return false; + } + } + + public static class MyResourceService { + // nothing + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/d4a03703/ambari-views/src/main/java/org/apache/ambari/view/ReadRequest.java ---------------------------------------------------------------------- diff --git a/ambari-views/src/main/java/org/apache/ambari/view/ReadRequest.java b/ambari-views/src/main/java/org/apache/ambari/view/ReadRequest.java index ddadd42..c12e7f9 100644 --- a/ambari-views/src/main/java/org/apache/ambari/view/ReadRequest.java +++ b/ambari-views/src/main/java/org/apache/ambari/view/ReadRequest.java @@ -36,4 +36,45 @@ public interface ReadRequest { * @return the predicate; may be null */ public String getPredicate(); + + /** + * Get the temporal information for the given property id for this + * request, if any. + * + * @param id the property id + * + * @return the temporal information for the given property id; null if + * none exists + */ + public TemporalInfo getTemporalInfo(String id); + + + /** + * Temporal query data. + */ + public interface TemporalInfo { + /** + * Get the start of the requested time range. The time is given in + * seconds since the Unix epoch. + * + * @return the start time in seconds + */ + Long getStartTime(); + + /** + * Get the end of the requested time range. The time is given in + * seconds since the Unix epoch. + * + * @return the end time in seconds + */ + Long getEndTime(); + + /** + * Get the requested time between each data point of the temporal + * data. The time is given in seconds. + * + * @return the step time in seconds + */ + Long getStep(); + } }
