You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by tb...@apache.org on 2014/01/29 20:40:15 UTC
[2/2] git commit: AMBARI-4461 - Application Views Infrastructure and
allowing new views and API extensibility - framework
AMBARI-4461 - Application Views Infrastructure and allowing new views and API extensibility - framework
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a0a10fc5
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a0a10fc5
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a0a10fc5
Branch: refs/heads/trunk
Commit: a0a10fc5a98e16b8aec4717dc28af32c9f860d0e
Parents: ea420ff
Author: tbeerbower <tb...@hortonworks.com>
Authored: Wed Jan 29 12:39:29 2014 -0500
Committer: tbeerbower <tb...@hortonworks.com>
Committed: Wed Jan 29 14:38:33 2014 -0500
----------------------------------------------------------------------
.../resources/ResourceInstanceFactoryImpl.java | 37 ++
.../ViewInstanceResourceDefinition.java | 63 +++
.../api/resources/ViewResourceDefinition.java | 58 +++
.../api/services/ViewInstanceService.java | 237 ++++++++++++
.../ambari/server/api/services/ViewService.java | 161 ++++++++
.../api/services/ViewSubResourceService.java | 86 +++++
.../server/configuration/Configuration.java | 12 +
.../ambari/server/controller/AmbariServer.java | 10 +-
.../internal/DefaultProviderModule.java | 4 +
.../internal/ViewInstanceResourceProvider.java | 153 ++++++++
.../internal/ViewResourceProvider.java | 150 ++++++++
.../ambari/server/controller/spi/Resource.java | 6 +-
.../utilities/ClusterControllerHelper.java | 3 +-
.../ambari/server/view/ViewContextImpl.java | 141 +++++++
.../ambari/server/view/ViewDefinition.java | 209 ++++++++++
.../server/view/ViewInstanceDefinition.java | 198 ++++++++++
.../ambari/server/view/ViewProviderModule.java | 100 +++++
.../apache/ambari/server/view/ViewRegistry.java | 384 +++++++++++++++++++
.../server/view/ViewSubResourceDefinition.java | 101 +++++
.../server/view/ViewSubResourceProvider.java | 338 ++++++++++++++++
.../ViewInstanceResourceDefinitionTest.java | 65 ++++
.../resources/ViewResourceDefinitionTest.java | 51 +++
.../ambari/server/view/ViewContextImplTest.java | 92 +++++
.../ambari/server/view/ViewDefinitionTest.java | 155 ++++++++
.../server/view/ViewInstanceDefinitionTest.java | 127 ++++++
.../ambari/server/view/ViewRegistryTest.java | 99 +++++
.../view/ViewSubResourceDefinitionTest.java | 68 ++++
.../apache/ambari/view/URLStreamProvider.java | 40 ++
.../org/apache/ambari/view/ViewContext.java | 7 +
29 files changed, 3149 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/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 de6307c..7dcaccb 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
@@ -22,14 +22,25 @@ package org.apache.ambari.server.api.resources;
import org.apache.ambari.server.api.query.QueryImpl;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.server.view.ViewRegistry;
+import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
/**
* Factory for creating resource instances.
*/
public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
+
+ /**
+ * Map of external resource definitions (added through views).
+ */
+ private final static Map<Resource.Type, ResourceDefinition> resourceDefinitions =
+ new HashMap<Resource.Type, ResourceDefinition>();
+
+
@Override
public ResourceInstance createResource(Resource.Type type, Map<Resource.Type, String> mapIds) {
@@ -42,6 +53,16 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
}
/**
+ * Associate an external resource definition with a type.
+ *
+ * @param type the resource type
+ * @param definition the resource definition
+ */
+ public static void addResourceDefinition(Resource.Type type, ResourceDefinition definition) {
+ resourceDefinitions.put(type, definition);
+ }
+
+ /**
* Get a resource definition for the given type.
*
* @param type the resource type
@@ -52,6 +73,11 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
public static ResourceDefinition getResourceDefinition(Resource.Type type, Map<Resource.Type, String> mapIds) {
ResourceDefinition resourceDefinition;
+ // Check to see if there is an external resource definition registered for the given type.
+ if (resourceDefinitions.containsKey(type)) {
+ return resourceDefinitions.get(type);
+ }
+
//todo: consider ResourceDependencyManager : Map<Resource.Type, ResourceDefinition>
switch (type.getInternalType()) {
case Cluster:
@@ -167,6 +193,17 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
resourceDefinition = new RequestScheduleResourceDefinition();
break;
+ case View:
+ resourceDefinition = new ViewResourceDefinition();
+ break;
+
+ case ViewInstance:
+ Set<SubResourceDefinition> subResourceDefinitions =
+ ViewRegistry.getInstance().getSubResourceDefinitions(mapIds.get(Resource.Type.View));
+
+ resourceDefinition = new ViewInstanceResourceDefinition(subResourceDefinitions);
+ break;
+
default:
throw new IllegalArgumentException("Unsupported resource type: " + type);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ViewInstanceResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ViewInstanceResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ViewInstanceResourceDefinition.java
new file mode 100644
index 0000000..00b4264
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ViewInstanceResourceDefinition.java
@@ -0,0 +1,63 @@
+/**
+ * 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;
+
+import java.util.Set;
+
+
+/**
+ * View instance resource definition.
+ */
+public class ViewInstanceResourceDefinition extends BaseResourceDefinition {
+
+ /**
+ * The parent view name.
+ */
+ private final Set<SubResourceDefinition> subResourceDefinitions;
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view instance resource definition.
+ */
+ public ViewInstanceResourceDefinition(Set<SubResourceDefinition> subResourceDefinitions) {
+ super(Resource.Type.ViewInstance);
+ this.subResourceDefinitions = subResourceDefinitions;
+ }
+
+
+ // ----- ResourceDefinition ------------------------------------------------
+
+ @Override
+ public String getPluralName() {
+ return "instances";
+ }
+
+ @Override
+ public String getSingularName() {
+ return "instance";
+ }
+
+ @Override
+ public Set<SubResourceDefinition> getSubResourceDefinitions() {
+ return subResourceDefinitions;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ViewResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ViewResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ViewResourceDefinition.java
new file mode 100644
index 0000000..a068183
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ViewResourceDefinition.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.api.resources;
+
+import org.apache.ambari.server.controller.spi.Resource;
+
+import java.util.Collections;
+import java.util.Set;
+
+
+/**
+ * View resource definition.
+ */
+public class ViewResourceDefinition extends BaseResourceDefinition {
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view resource definition.
+ */
+ public ViewResourceDefinition() {
+ super(Resource.Type.View);
+ }
+
+
+ // ----- ResourceDefinition ------------------------------------------------
+
+ @Override
+ public String getPluralName() {
+ return "views";
+ }
+
+ @Override
+ public String getSingularName() {
+ return "view";
+ }
+
+ @Override
+ public Set<SubResourceDefinition> getSubResourceDefinitions() {
+ return Collections.singleton(new SubResourceDefinition(Resource.Type.ViewInstance));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java
new file mode 100644
index 0000000..96bc863
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewInstanceService.java
@@ -0,0 +1,237 @@
+/**
+ * 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 org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.view.ViewInstanceDefinition;
+import org.apache.ambari.server.view.ViewRegistry;
+
+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.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Service responsible for instances resource requests.
+ */
+public class ViewInstanceService extends BaseService {
+ /**
+ * Parent view name.
+ */
+ private String m_viewName;
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view instance service.
+ *
+ * @param viewName the view id
+ */
+ public ViewInstanceService(String viewName) {
+ m_viewName = viewName;
+ }
+
+ /**
+ * Handles URL: /views/{viewID}/instances/{instanceID}
+ * Get a specific instance.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param instanceName instance id
+ *
+ * @return instance resource representation
+ */
+ @GET
+ @Path("{instanceName}")
+ @Produces("text/plain")
+ public Response getService(@Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("instanceName") String instanceName) {
+
+ return handleRequest(headers, null, ui, Request.Type.GET,
+ createServiceResource(m_viewName, instanceName));
+ }
+
+ /**
+ * Handles URL: /views/{viewID}/instances
+ * Get all instances for a view.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ *
+ * @return instance collection resource representation
+ */
+ @GET
+ @Produces("text/plain")
+ public Response getServices(@Context HttpHeaders headers, @Context UriInfo ui) {
+ return handleRequest(headers, null, ui, Request.Type.GET,
+ createServiceResource(m_viewName, null));
+ }
+
+ /**
+ * Handles: POST /views/{viewID}/instances/{instanceId}
+ * Create a specific instance.
+ *
+ * @param body http body
+ * @param headers http headers
+ * @param ui uri info
+ * @param instanceName instance id
+ *
+ * @return information regarding the created instance
+ */
+ @POST
+ @Path("{instanceName}")
+ @Produces("text/plain")
+ public Response createService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("instanceName") String instanceName) {
+
+ return handleRequest(headers, body, ui, Request.Type.POST,
+ createServiceResource(m_viewName, instanceName));
+ }
+
+ /**
+ * Handles: POST /views/{viewID}/instances
+ * Create multiple instances.
+ *
+ * @param body http body
+ * @param headers http headers
+ * @param ui uri info
+ *
+ * @return information regarding the created instances
+ */
+ @POST
+ @Produces("text/plain")
+ public Response createServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+
+ return handleRequest(headers, body, ui, Request.Type.POST,
+ createServiceResource(m_viewName, null));
+ }
+
+ /**
+ * Handles: PUT /views/{viewID}/instances/{instanceId}
+ * Update a specific instance.
+ *
+ * @param body http body
+ * @param headers http headers
+ * @param ui uri info
+ * @param instanceName instance id
+ *
+ * @return information regarding the updated instance
+ */
+ @PUT
+ @Path("{instanceName}")
+ @Produces("text/plain")
+ public Response updateService(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("instanceName") String instanceName) {
+
+ return handleRequest(headers, body, ui, Request.Type.PUT, createServiceResource(m_viewName, instanceName));
+ }
+
+ /**
+ * Handles: PUT /views/{viewID}/instances
+ * Update multiple instances.
+ *
+ * @param body http body
+ * @param headers http headers
+ * @param ui uri info
+ *
+ * @return information regarding the updated instance
+ */
+ @PUT
+ @Produces("text/plain")
+ public Response updateServices(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
+
+ return handleRequest(headers, body, ui, Request.Type.PUT, createServiceResource(m_viewName, null));
+ }
+
+ /**
+ * Handles: DELETE /views/{viewID}/instances/{instanceId}
+ * Delete a specific instance.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param instanceName instance id
+ *
+ * @return information regarding the deleted instance
+ */
+ @DELETE
+ @Path("{instanceName}")
+ @Produces("text/plain")
+ public Response deleteService(@Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("instanceName") String instanceName) {
+
+ return handleRequest(headers, null, ui, Request.Type.DELETE, createServiceResource(m_viewName, instanceName));
+ }
+
+ /**
+ * Get the sub-resource
+ *
+ * @param instanceName the instance id
+ *
+ * @return the service
+ */
+ @Path("{instanceName}/{resources}")
+ public Object getResourceHandler(@PathParam("instanceName") String instanceName,
+ @PathParam("resources") String resources) {
+
+ ViewInstanceDefinition instanceDefinition =
+ ViewRegistry.getInstance().getInstanceDefinition(m_viewName, instanceName);
+
+ if (instanceDefinition == null) {
+ throw new IllegalArgumentException("A view instance " +
+ m_viewName + "/" + instanceName + " can not be found.");
+ }
+
+ Object service = instanceDefinition.getService(resources);
+
+ if (service == null) {
+ throw new IllegalArgumentException("A resource type " + resources + " for view instance " +
+ m_viewName + "/" + instanceName + " can not be found.");
+ }
+ return service;
+ }
+
+
+ // ----- helper methods ----------------------------------------------------
+
+ /**
+ * Create an view instance resource.
+ *
+ * @param viewName view name
+ * @param instanceName instance name
+ *
+ * @return a view instance resource
+ */
+ private ResourceInstance createServiceResource(String viewName, String instanceName) {
+ Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>();
+ mapIds.put(Resource.Type.View, viewName);
+ mapIds.put(Resource.Type.ViewInstance, instanceName);
+ return createResource(Resource.Type.ViewInstance, mapIds);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewService.java
new file mode 100644
index 0000000..45d7d2f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewService.java
@@ -0,0 +1,161 @@
+/**
+ * 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 org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+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.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.Collections;
+
+
+/**
+ * Service responsible for view resource requests.
+ */
+@Path("/views/")
+public class ViewService extends BaseService {
+
+ /**
+ * Handles: GET /views/{viewID}
+ * Get a specific view.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param viewName view id
+ *
+ * @return view instance representation
+ */
+ @GET
+ @Path("{viewName}")
+ @Produces("text/plain")
+ public Response getView(@Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("viewName") String viewName) {
+
+ return handleRequest(headers, null, ui, Request.Type.GET, createViewResource(viewName));
+ }
+
+ /**
+ * Handles: GET /views
+ * Get all views.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ *
+ * @return view collection resource representation
+ */
+ @GET
+ @Produces("text/plain")
+ public Response getViews(@Context HttpHeaders headers, @Context UriInfo ui) {
+ return handleRequest(headers, null, ui, Request.Type.GET, createViewResource(null));
+ }
+
+ /**
+ * Handles: POST /views/{viewID}
+ * Create a specific view.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param viewName view id
+ *
+ * @return information regarding the created view
+ */
+ @POST
+ @Path("{viewName}")
+ @Produces("text/plain")
+ public Response createView(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("viewName") String viewName) {
+
+ return handleRequest(headers, body, ui, Request.Type.POST, createViewResource(viewName));
+ }
+
+ /**
+ * Handles: PUT /views/{viewID}
+ * Update a specific view.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param viewName view id
+ *
+ * @return information regarding the updated view
+ */
+ @PUT
+ @Path("{viewName}")
+ @Produces("text/plain")
+ public Response updateView(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("viewName") String viewName) {
+
+ return handleRequest(headers, body, ui, Request.Type.PUT, createViewResource(viewName));
+ }
+
+ /**
+ * Handles: DELETE /views/{viewID}
+ * Delete a specific view.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param viewName view id
+ *
+ * @return information regarding the deleted view
+ */
+ @DELETE
+ @Path("{viewName}")
+ @Produces("text/plain")
+ public Response deleteView(@Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("viewName") String viewName) {
+
+ return handleRequest(headers, null, ui, Request.Type.DELETE, createViewResource(viewName));
+ }
+
+ /**
+ * Get the instances sub-resource
+ *
+ * @param viewName view id
+ *
+ * @return the hosts service
+ */
+ @Path("{viewName}/instances")
+ public ViewInstanceService getInstanceHandler(@PathParam("viewName") String viewName) {
+ return new ViewInstanceService(viewName);
+ }
+
+
+ // ----- helper methods ----------------------------------------------------
+
+ /**
+ * Create a view resource.
+ *
+ * @param viewName view name
+ *
+ * @return a view resource instance
+ */
+ private ResourceInstance createViewResource(String viewName) {
+ return createResource(Resource.Type.View,
+ Collections.singletonMap(Resource.Type.View, viewName));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewSubResourceService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewSubResourceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewSubResourceService.java
new file mode 100644
index 0000000..52dd608
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ViewSubResourceService.java
@@ -0,0 +1,86 @@
+/**
+ * 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 org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.view.ViewResourceHandler;
+
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * View sub-resource service.
+ */
+public class ViewSubResourceService extends BaseService implements ViewResourceHandler {
+ /**
+ * The type of the sub-resource.
+ */
+ private final Resource.Type type;
+
+ /**
+ * The associated view name.
+ */
+ private final String viewName;
+
+ /**
+ * The associated view instance name.
+ */
+ private final String instanceName;
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view sub-resource service.
+ */
+ public ViewSubResourceService(Resource.Type type, String viewName, String instanceName) {
+ this.type = type;
+ this.viewName = viewName;
+ this.instanceName = instanceName;
+ }
+
+
+ // ----- ViewResourceHandler -----------------------------------------------
+
+ @Override
+ public Response handleRequest(HttpHeaders headers, UriInfo ui, String resourceId) {
+ return handleRequest(headers, null, ui, Request.Type.GET,
+ createResource(resourceId));
+ }
+
+
+ // ----- helper methods ----------------------------------------------------
+
+ // create a resource with the given id
+ private ResourceInstance createResource(String resourceId) {
+ Map<Resource.Type,String> mapIds = new HashMap<Resource.Type,String>();
+
+ mapIds.put(Resource.Type.View, viewName);
+ mapIds.put(Resource.Type.ViewInstance, instanceName);
+
+ if (resourceId != null) {
+ mapIds.put(type, resourceId);
+ }
+ return super.createResource(type, mapIds);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/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 b070d98..293792b 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
@@ -50,6 +50,8 @@ public class Configuration {
public static final String CONFIG_FILE = "ambari.properties";
public static final String BOOTSTRAP_DIR = "bootstrap.dir";
public static final String BOOTSTRAP_DIR_DEFAULT = "/var/run/ambari-server/bootstrap";
+ public static final String VIEWS_DIR = "views.dir";
+ public static final String VIEWS_DIR_DEFAULT = "/var/lib/ambari-server/resources/views";
public static final String WEBAPP_DIR = "webapp.dir";
public static final String BOOTSTRAP_SCRIPT = "bootstrap.script";
public static final String BOOTSTRAP_SCRIPT_DEFAULT = "/usr/bin/ambari_bootstrap";
@@ -460,6 +462,16 @@ public class Configuration {
return properties;
}
+ /**
+ * Get the views directory.
+ *
+ * @return the views directory
+ */
+ public File getViewsDir() {
+ String fileName = properties.getProperty(VIEWS_DIR, VIEWS_DIR_DEFAULT);
+ return new File(fileName);
+ }
+
public File getBootStrapDir() {
String fileName = properties.getProperty(BOOTSTRAP_DIR, BOOTSTRAP_DIR_DEFAULT);
return new File(fileName);
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/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 00f1b74..75b6cb1 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
@@ -58,11 +58,11 @@ import org.apache.ambari.server.security.authorization.AmbariLocalUserDetailsSer
import org.apache.ambari.server.security.authorization.Users;
import org.apache.ambari.server.security.authorization.internal.AmbariInternalAuthenticationProvider;
import org.apache.ambari.server.security.authorization.internal.InternalTokenAuthenticationFilter;
-import org.apache.ambari.server.security.authorization.internal.InternalTokenStorage;
import org.apache.ambari.server.security.unsecured.rest.CertificateDownload;
import org.apache.ambari.server.security.unsecured.rest.CertificateSign;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.utils.StageUtils;
+import org.apache.ambari.server.view.ViewRegistry;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
@@ -277,6 +277,8 @@ public class AmbariServer {
root.addServlet(sh, "/api/v1/*");
sh.setInitOrder(2);
+ ViewRegistry.readViewArchives(configs, root, springSecurityFilter);
+
ServletHolder agent = new ServletHolder(ServletContainer.class);
agent.setInitParameter("com.sun.jersey.config.property.resourceConfigClass",
"com.sun.jersey.api.core.PackagesResourceConfig");
@@ -317,8 +319,8 @@ public class AmbariServer {
if (configs.getApiSSLAuthentication()) {
String httpsKeystore = configsMap.get(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY) +
File.separator + configsMap.get(Configuration.CLIENT_API_SSL_KSTR_NAME_KEY);
- LOG.info("API SSL Authentication is turned on. Keystore - " + httpsKeystore);
-
+ LOG.info("API SSL Authentication is turned on. Keystore - " + httpsKeystore);
+
String httpsCrtPass = configsMap.get(Configuration.CLIENT_API_SSL_CRT_PASS_KEY);
SslSelectChannelConnector sapiConnector = new SslSelectChannelConnector();
@@ -332,7 +334,7 @@ public class AmbariServer {
sapiConnector.setTruststoreType("PKCS12");
sapiConnector.setMaxIdleTime(configs.getConnectionMaxIdleTime());
apiConnector = sapiConnector;
- }
+ }
else {
apiConnector = new SelectChannelConnector();
apiConnector.setPort(configs.getClientApiPort());
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
index a10835e..e8765e4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
@@ -61,6 +61,10 @@ public class DefaultProviderModule extends AbstractProviderModule {
return new JobResourceProvider(propertyIds, keyPropertyIds);
case TaskAttempt:
return new TaskAttemptResourceProvider(propertyIds, keyPropertyIds);
+ case View:
+ return new ViewResourceProvider();
+ case ViewInstance:
+ return new ViewInstanceResourceProvider();
default:
return AbstractControllerResourceProvider.getResourceProvider(type, propertyIds,
keyPropertyIds, managementController);
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
new file mode 100644
index 0000000..82f2224
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
@@ -0,0 +1,153 @@
+/**
+ * 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 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.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.view.ViewDefinition;
+import org.apache.ambari.server.view.ViewInstanceDefinition;
+import org.apache.ambari.server.view.ViewRegistry;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Resource provider for view instances.
+ */
+public class ViewInstanceResourceProvider extends AbstractResourceProvider {
+
+ /**
+ * View instance property id constants.
+ */
+ public static final String VIEW_NAME_PROPERTY_ID = "ViewInstanceInfo/view_name";
+ public static final String INSTANCE_NAME_PROPERTY_ID = "ViewInstanceInfo/instance_name";
+ public static final String SERVLET_MAPPINGS_PROPERTY_ID = "ViewInstanceInfo/servlet_mappings";
+
+ /**
+ * The key property ids for a view instance resource.
+ */
+ private static Map<Resource.Type, String> keyPropertyIds = new HashMap<Resource.Type, String>();
+ static {
+ keyPropertyIds.put(Resource.Type.View, VIEW_NAME_PROPERTY_ID);
+ keyPropertyIds.put(Resource.Type.ViewInstance, INSTANCE_NAME_PROPERTY_ID);
+ }
+
+ /**
+ * The property ids for a view instance resource.
+ */
+ private static Set<String> propertyIds = new HashSet<String>();
+ static {
+ propertyIds.add(VIEW_NAME_PROPERTY_ID);
+ propertyIds.add(INSTANCE_NAME_PROPERTY_ID);
+ propertyIds.add(SERVLET_MAPPINGS_PROPERTY_ID);
+ }
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view instance resource provider.
+ */
+ public ViewInstanceResourceProvider() {
+ super(propertyIds, keyPropertyIds);
+ }
+
+
+ // ----- ResourceProvider --------------------------------------------------
+
+ @Override
+ public RequestStatus createResources(Request request)
+ throws SystemException, UnsupportedPropertyException,
+ ResourceAlreadyExistsException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Not yet supported.");
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<Resource> resources = new HashSet<Resource>();
+ ViewRegistry viewRegistry = ViewRegistry.getInstance();
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+ Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
+ if (propertyMaps.isEmpty()) {
+ propertyMaps.add(Collections.<String, Object>emptyMap());
+ }
+
+ for (Map<String, Object> propertyMap : propertyMaps) {
+
+ String viewName = (String) propertyMap.get(VIEW_NAME_PROPERTY_ID);
+ String instanceName = (String) propertyMap.get(INSTANCE_NAME_PROPERTY_ID);
+
+ for (ViewDefinition viewDefinition : viewRegistry.getDefinitions()){
+ if (viewName == null || viewName.equals(viewDefinition.getName())) {
+ for (ViewInstanceDefinition viewInstanceDefinition : viewRegistry.getInstanceDefinitions(viewDefinition)) {
+ if (instanceName == null || instanceName.equals(viewInstanceDefinition.getName())) {
+ Resource resource = new ResourceImpl(Resource.Type.ViewInstance);
+
+ setResourceProperty(resource, VIEW_NAME_PROPERTY_ID, viewDefinition.getName(), requestedIds);
+ setResourceProperty(resource, INSTANCE_NAME_PROPERTY_ID, viewInstanceDefinition.getName(), requestedIds);
+ setResourceProperty(resource, SERVLET_MAPPINGS_PROPERTY_ID,
+ viewInstanceDefinition.getServletMappings(), requestedIds);
+
+ resources.add(resource);
+ }
+ }
+ }
+ }
+ }
+ return resources;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Not yet supported.");
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Not yet supported.");
+ }
+
+ @Override
+ public Map<Resource.Type, String> getKeyPropertyIds() {
+ return keyPropertyIds;
+ }
+
+
+ // ----- AbstractResourceProvider ------------------------------------------
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return new HashSet<String>(keyPropertyIds.values());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewResourceProvider.java
new file mode 100644
index 0000000..17d3b94
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewResourceProvider.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.controller.internal;
+
+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.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.view.ViewDefinition;
+import org.apache.ambari.server.view.ViewRegistry;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Resource provider for view instances.
+ */
+public class ViewResourceProvider extends AbstractResourceProvider {
+
+ /**
+ * View property id constants.
+ */
+ public static final String VIEW_NAME_PROPERTY_ID = "ViewInfo/view_name";
+ public static final String LABEL_PROPERTY_ID = "ViewInfo/label";
+ public static final String VERSION_PROPERTY_ID = "ViewInfo/version";
+ public static final String PARAMETERS_PROPERTY_ID = "ViewInfo/parameters";
+
+
+ /**
+ * The key property ids for a view resource.
+ */
+ private static Map<Resource.Type, String> keyPropertyIds = new HashMap<Resource.Type, String>();
+ static {
+ keyPropertyIds.put(Resource.Type.View, VIEW_NAME_PROPERTY_ID);
+ }
+
+ /**
+ * The property ids for a view resource.
+ */
+ private static Set<String> propertyIds = new HashSet<String>();
+ static {
+ propertyIds.add(VIEW_NAME_PROPERTY_ID);
+ propertyIds.add(LABEL_PROPERTY_ID);
+ propertyIds.add(VERSION_PROPERTY_ID);
+ propertyIds.add(PARAMETERS_PROPERTY_ID);
+ }
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view resource provider.
+ */
+ public ViewResourceProvider() {
+ super(propertyIds, keyPropertyIds);
+ }
+
+
+ // ----- ResourceProvider --------------------------------------------------
+
+ @Override
+ public RequestStatus createResources(Request request)
+ throws SystemException, UnsupportedPropertyException,
+ ResourceAlreadyExistsException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Not yet supported.");
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ Set<Resource> resources = new HashSet<Resource>();
+ ViewRegistry viewRegistry = ViewRegistry.getInstance();
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+
+ Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
+
+ if (propertyMaps.isEmpty()) {
+ propertyMaps.add(Collections.<String, Object>emptyMap());
+ }
+
+ for (Map<String, Object> propertyMap : propertyMaps) {
+
+ String viewName = (String) propertyMap.get(VIEW_NAME_PROPERTY_ID);
+
+ for (ViewDefinition viewDefinition : viewRegistry.getDefinitions()){
+ if (viewName == null || viewName.equals(viewDefinition.getName())) {
+ Resource resource = new ResourceImpl(Resource.Type.View);
+
+ setResourceProperty(resource, VIEW_NAME_PROPERTY_ID, viewDefinition.getName(), requestedIds);
+ setResourceProperty(resource, LABEL_PROPERTY_ID, viewDefinition.getLabel(), requestedIds);
+ setResourceProperty(resource, VERSION_PROPERTY_ID, viewDefinition.getVersion(), requestedIds);
+ setResourceProperty(resource, PARAMETERS_PROPERTY_ID,
+ viewDefinition.getConfiguration().getParameters(), requestedIds);
+
+ resources.add(resource);
+ }
+ }
+ }
+ return resources;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Not yet supported.");
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Not yet supported.");
+ }
+
+ @Override
+ public Map<Resource.Type, String> getKeyPropertyIds() {
+ return keyPropertyIds;
+ }
+
+
+ // ----- AbstractResourceProvider ------------------------------------------
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return new HashSet<String>(keyPropertyIds.values());
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/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 6a82e59..52f0cdf 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
@@ -101,7 +101,9 @@ public interface Resource {
TaskAttempt,
RootService,
RootServiceComponent,
- RootServiceHostComponent;
+ RootServiceHostComponent,
+ View,
+ ViewInstance;
/**
* Get the {@link Type} that corresponds to this InternalType.
@@ -164,6 +166,8 @@ public interface Resource {
public static final Type RootService = InternalType.RootService.getType();
public static final Type RootServiceComponent = InternalType.RootServiceComponent.getType();
public static final Type RootServiceHostComponent = InternalType.RootServiceHostComponent.getType();
+ public static final Type View = InternalType.View.getType();
+ public static final Type ViewInstance = InternalType.ViewInstance.getType();
/**
* The type name.
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java
index 3b0c12a..3086eb8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/ClusterControllerHelper.java
@@ -21,6 +21,7 @@ package org.apache.ambari.server.controller.utilities;
import org.apache.ambari.server.controller.spi.ProviderModule;
import org.apache.ambari.server.controller.internal.ClusterControllerImpl;
import org.apache.ambari.server.controller.spi.ClusterController;
+import org.apache.ambari.server.view.ViewProviderModule;
/**
* Temporary class to bootstrap a cluster controller. TODO : Replace this global state with injection.
@@ -36,7 +37,7 @@ public class ClusterControllerHelper {
if (controller == null) {
try {
Class<?> implClass = Class.forName(PROVIDER_MODULE_CLASS);
- ProviderModule providerModule = (ProviderModule) implClass.newInstance();
+ ProviderModule providerModule = ViewProviderModule.getViewProviderModule((ProviderModule) implClass.newInstance());
controller = new ClusterControllerImpl(providerModule);
} catch (Exception e) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
new file mode 100644
index 0000000..0106c1d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewContextImpl.java
@@ -0,0 +1,141 @@
+/**
+ * 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.ComponentSSLConfiguration;
+import org.apache.ambari.view.ResourceProvider;
+import org.apache.ambari.view.URLStreamProvider;
+import org.apache.ambari.view.ViewContext;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContext;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * View context implementation.
+ */
+public class ViewContextImpl implements ViewContext {
+
+ /**
+ * The associated view definition.
+ */
+ private final ViewInstanceDefinition viewInstanceDefinition;
+
+ /**
+ * The available stream provider.
+ */
+ private final URLStreamProvider streamProvider;
+
+
+ // ---- Constructors -------------------------------------------------------
+
+ /**
+ * Construct a view context from the given view definition.
+ *
+ * @param viewInstanceDefinition the view definition
+ */
+ public ViewContextImpl(ViewInstanceDefinition viewInstanceDefinition) {
+ this.viewInstanceDefinition = viewInstanceDefinition;
+ this.streamProvider = new ViewURLStreamProvider();
+ }
+
+
+ // ----- ViewContext -------------------------------------------------------
+
+ @Override
+ public String getViewName() {
+ return viewInstanceDefinition.getViewDefinition().getName();
+ }
+
+ @Override
+ public String getInstanceName() {
+ return viewInstanceDefinition.getName();
+ }
+
+ @Override
+ public Map<String, String> getProperties() {
+ return viewInstanceDefinition.getProperties();
+ }
+
+ @Override
+ public ResourceProvider<?> getResourceProvider(String type) {
+ return viewInstanceDefinition.getResourceProvider(type);
+ }
+
+ @Override
+ public String getUsername() {
+ SecurityContext ctx = SecurityContextHolder.getContext();
+ Authentication authentication = ctx == null ? null : ctx.getAuthentication();
+ Object principal = authentication == null ? null : authentication.getPrincipal();
+
+ String username;
+ if (principal instanceof UserDetails) {
+ username = ((UserDetails)principal).getUsername();
+ } else {
+ username = principal == null ? "" :principal.toString();
+ }
+ return username;
+ }
+
+ @Override
+ public URLStreamProvider getURLStreamProvider() {
+ return streamProvider;
+ }
+
+
+ // ----- Inner class : ViewURLStreamProvider -------------------------------
+
+ /**
+ * Wrapper around internal URL stream provider.
+ */
+ private static class ViewURLStreamProvider implements URLStreamProvider {
+ private static final int DEFAULT_REQUEST_CONNECT_TIMEOUT = 5000;
+ private static final int DEFAULT_REQUEST_READ_TIMEOUT = 10000;
+
+ /**
+ * Internal stream provider.
+ */
+ private final org.apache.ambari.server.controller.internal.URLStreamProvider streamProvider;
+
+
+ // ----- Constructor -----------------------------------------------------
+
+ private ViewURLStreamProvider() {
+ ComponentSSLConfiguration configuration = ComponentSSLConfiguration.instance();
+ streamProvider =
+ new org.apache.ambari.server.controller.internal.URLStreamProvider(
+ DEFAULT_REQUEST_CONNECT_TIMEOUT, DEFAULT_REQUEST_READ_TIMEOUT,
+ configuration.getTruststorePath(),
+ configuration.getTruststorePassword(),
+ configuration.getTruststoreType());
+ }
+
+
+ // ----- URLStreamProvider -----------------------------------------------
+
+ @Override
+ public InputStream readFrom(String spec, String requestMethod, String params) throws IOException {
+ return streamProvider.readFrom(spec, requestMethod, params);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/view/ViewDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewDefinition.java
new file mode 100644
index 0000000..80651ad
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewDefinition.java
@@ -0,0 +1,209 @@
+/**
+ * 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.api.resources.BaseResourceDefinition;
+import org.apache.ambari.server.view.configuration.ResourceConfig;
+import org.apache.ambari.server.view.configuration.ViewConfig;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Provides access to the attributes of a view.
+ */
+public class ViewDefinition {
+ /**
+ * The associated view configuration.
+ */
+ private final ViewConfig configuration;
+
+ /**
+ * The mapping of resource type to resource provider.
+ */
+ private final Map<Resource.Type, ResourceProvider> resourceProviders = new HashMap<Resource.Type, ResourceProvider>();
+
+ /**
+ * The mapping of resource type to resource definition.
+ */
+ private final Map<Resource.Type, BaseResourceDefinition> resourceDefinitions = new HashMap<Resource.Type, BaseResourceDefinition>();
+
+ /**
+ * The mapping of resource type to resource configuration.
+ */
+ private final Map<Resource.Type, ResourceConfig> resourceConfigurations = new HashMap<Resource.Type, ResourceConfig>();
+
+ /**
+ * The mapping of instance name to instance definition.
+ */
+ private final Map<String, ViewInstanceDefinition> instanceDefinitions = new HashMap<String, ViewInstanceDefinition>();
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view definition from the given configuration.
+ *
+ * @param configuration the view configuration
+ */
+ public ViewDefinition(ViewConfig configuration) {
+ this.configuration = configuration;
+ }
+
+
+ // ----- ViewDefinition ----------------------------------------------------
+
+ /**
+ * Get the view name.
+ *
+ * @return the view name
+ */
+ public String getName() {
+ return configuration.getName();
+ }
+
+ /**
+ * Get the view label.
+ *
+ * @return the view label
+ */
+ public String getLabel() {
+ return configuration.getLabel();
+ }
+
+ /**
+ * Get the view version.
+ *
+ * @return the version
+ */
+ public String getVersion() {
+ return configuration.getVersion();
+ }
+
+ /**
+ * Get the associated view configuration.
+ *
+ * @return the configuration
+ */
+ public ViewConfig getConfiguration() {
+ return configuration;
+ }
+
+ /**
+ * Add a resource provider for the given type.
+ *
+ * @param type the resource type
+ * @param provider the resource provider
+ */
+ public void addResourceProvider(Resource.Type type, ResourceProvider provider) {
+ resourceProviders.put(type, provider);
+ }
+
+ /**
+ * Get the resource provider for the given type.
+ *
+ * @param type the resource type
+ *
+ * @return the resource provider associated with the given type
+ */
+ public ResourceProvider getResourceProvider(Resource.Type type) {
+ return resourceProviders.get(type);
+ }
+
+ /**
+ * Add a resource definition.
+ *
+ * @param definition the resource definition
+ */
+ public void addResourceDefinition(BaseResourceDefinition definition) {
+ resourceDefinitions.put(definition.getType(), definition);
+ }
+
+ /**
+ * Get the resource definition for the given type
+ *
+ * @param type the resource type
+ *
+ * @return the resource definition associated with the given type
+ */
+ public BaseResourceDefinition getResourceDefinition(Resource.Type type) {
+ return resourceDefinitions.get(type);
+ }
+
+ /**
+ * Add a resource configuration for the given type.
+ *
+ * @param type the resource type
+ * @param config the configuration
+ */
+ public void addResourceConfiguration(Resource.Type type, ResourceConfig config) {
+ resourceConfigurations.put(type, config);
+ }
+
+ /**
+ * Get a mapping of resource type to resource configurations.
+ *
+ * @return the mapping of resource types to resource configurations
+ */
+ public Map<Resource.Type, ResourceConfig> getResourceConfigurations() {
+ return resourceConfigurations;
+ }
+
+ /**
+ * Get the set of resource types for this view.
+ *
+ * @return the set of resource type
+ */
+ public Set<Resource.Type> getViewResourceTypes() {
+ return resourceConfigurations.keySet();
+ }
+
+ /**
+ * Add an instance definition.
+ *
+ * @param viewInstanceDefinition the instance definition
+ */
+ public void addInstanceDefinition(ViewInstanceDefinition viewInstanceDefinition) {
+ instanceDefinitions.put(viewInstanceDefinition.getName(), viewInstanceDefinition);
+ }
+
+ /**
+ * Get the collection of all instance definitions for this view.
+ *
+ * @return the collection of instance definitions
+ */
+ public Collection<ViewInstanceDefinition> getInstanceDefinitions() {
+ return instanceDefinitions.values();
+ }
+
+ /**
+ * Get an instance definition for the given name.
+ *
+ * @param instanceName the instance name
+ *
+ * @return the instance definition
+ */
+ public ViewInstanceDefinition getInstanceDefinition(String instanceName) {
+ return instanceDefinitions.get(instanceName);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/view/ViewInstanceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewInstanceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewInstanceDefinition.java
new file mode 100644
index 0000000..7a7a5eb
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewInstanceDefinition.java
@@ -0,0 +1,198 @@
+/**
+ * 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.controller.spi.Resource;
+import org.apache.ambari.server.view.configuration.InstanceConfig;
+import org.apache.ambari.view.ResourceProvider;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provides access to the attributes of a view instance.
+ */
+public class ViewInstanceDefinition {
+ /**
+ * The associated configuration.
+ */
+ private final InstanceConfig instanceConfig;
+
+ /**
+ * The parent view definition.
+ */
+ private final ViewDefinition viewDefinition;
+
+ /**
+ * The view instance properties.
+ */
+ private final Map<String, String> properties = new HashMap<String, String>();
+
+ /**
+ * The mapping of resource type to resource provider.
+ */
+ private final Map<Resource.Type, ResourceProvider> resourceProviders = new HashMap<Resource.Type, ResourceProvider>();
+
+ /**
+ * The mapping of the resource plural name to service.
+ */
+ private final Map<String, Object> services = new HashMap<String, Object>();
+
+ /**
+ * The mapping of servlet name to servlet path spec.
+ */
+ private final Map<String, String> servletMappings = new HashMap<String, String>();
+
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view instance definition.
+ *
+ * @param viewDefinition the parent view definition
+ * @param instanceConfig the associated configuration
+ */
+ public ViewInstanceDefinition(ViewDefinition viewDefinition, InstanceConfig instanceConfig) {
+ this.instanceConfig = instanceConfig;
+ this.viewDefinition = viewDefinition;
+ }
+
+
+ // ----- ViewInstanceDefinition --------------------------------------------
+
+ /**
+ * Get the parent view definition.
+ *
+ * @return the parent view definition
+ */
+ public ViewDefinition getViewDefinition() {
+ return viewDefinition;
+ }
+
+ /**
+ * Get the associated configuration.
+ *
+ * @return the configuration
+ */
+ public InstanceConfig getConfiguration() {
+ return instanceConfig;
+ }
+
+ /**
+ * Get the view instance name.
+ *
+ * @return the instance name
+ */
+ public String getName() {
+ return instanceConfig.getName();
+ }
+
+ /**
+ * Add a mapping from servlet name to path spec.
+ *
+ * @param servletName the servlet name
+ * @param pathSpec the path
+ */
+ public void addServletMapping(String servletName, String pathSpec) {
+ servletMappings.put(servletName, pathSpec);
+ }
+
+ /**
+ * Get the servlet mappings.
+ *
+ * @return the servlet mappings
+ */
+ public Map<String, String> getServletMappings() {
+ return servletMappings;
+ }
+
+ /**
+ * Add a view instance property.
+ *
+ * @param key the property key
+ * @param value the property value
+ */
+ public void addProperty(String key, String value) {
+ properties.put(key, value);
+ }
+
+ /**
+ * Get the view instance properties.
+ *
+ * @return the view instance properties
+ */
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ /**
+ * Add a service for the given plural resource name.
+ *
+ * @param pluralName the plural resource name
+ * @param service the service
+ */
+ public void addService(String pluralName, Object service) {
+ services.put(pluralName, service);
+ }
+
+ /**
+ * Get the service associated with the given plural resource name.
+ *
+ * @param pluralName the plural resource name
+ *
+ * @return the service associated with the given name
+ */
+ public Object getService(String pluralName) {
+ return services.get(pluralName);
+ }
+
+ /**
+ * Add a resource provider for the given resource type.
+ *
+ * @param type the resource type
+ * @param provider the resource provider
+ */
+ public void addResourceProvider(Resource.Type type, ResourceProvider provider) {
+ resourceProviders.put(type, provider);
+ }
+
+ /**
+ * Get the resource provider for the given resource type.
+ *
+ * @param type the resource type
+ *
+ * @return the resource provider
+ */
+ public ResourceProvider getResourceProvider(Resource.Type type) {
+ return resourceProviders.get(type);
+ }
+
+ /**
+ * Get the resource provider for the given resource type name (scoped to this view).
+ *
+ * @param type the resource type name
+ *
+ * @return the resource provider
+ */
+ public ResourceProvider getResourceProvider(String type) {
+ String typeName = viewDefinition.getName() + "/" + type;
+ return resourceProviders.get(Resource.Type.valueOf(typeName));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/ambari-server/src/main/java/org/apache/ambari/server/view/ViewProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/view/ViewProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewProviderModule.java
new file mode 100644
index 0000000..9cb889a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewProviderModule.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.view;
+
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.ProviderModule;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Module which allows for discovery of view resource providers.
+ * This module wraps another module and delegates to it for
+ * any resource types not defined in a view.
+ */
+public class ViewProviderModule implements ProviderModule {
+ /**
+ * Mapping of view resource type to resource provider.
+ */
+ private final Map<Resource.Type, ResourceProvider> resourceProviders;
+
+ /**
+ * The delegate provider module.
+ */
+ private final ProviderModule providerModule;
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct a view provider module.
+ *
+ * @param providerModule the delegate provider module
+ * @param resourceProviders the map of view resource types to resource providers
+ */
+ private ViewProviderModule(ProviderModule providerModule,
+ Map<Resource.Type, ResourceProvider> resourceProviders) {
+ this.providerModule = providerModule;
+ this.resourceProviders = resourceProviders;
+ }
+
+
+ // ----- ProviderModule ----------------------------------------------------
+
+ @Override
+ public ResourceProvider getResourceProvider(Resource.Type type) {
+
+ if (resourceProviders.containsKey(type)) {
+ return resourceProviders.get(type);
+ }
+ return providerModule.getResourceProvider(type);
+ }
+
+ @Override
+ public List<PropertyProvider> getPropertyProviders(Resource.Type type) {
+ return providerModule.getPropertyProviders(type);
+ }
+
+
+ // ----- helper methods -----------------------------------------
+
+ /**
+ * Factory method to get a view provider module.
+ *
+ * @param module the delegate provider module
+ *
+ * @return a view provider module
+ */
+ public static ViewProviderModule getViewProviderModule(ProviderModule module) {
+ Map<Resource.Type, ResourceProvider> resourceProviders = new HashMap<Resource.Type, ResourceProvider>();
+
+ ViewRegistry registry = ViewRegistry.getInstance();
+ for (ViewDefinition definition : registry.getDefinitions()) {
+ for (Resource.Type type : definition.getViewResourceTypes()){
+ ResourceProvider provider = definition.getResourceProvider(type);
+ resourceProviders.put(type, provider);
+ }
+ }
+ return new ViewProviderModule(module, resourceProviders);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a0a10fc5/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
new file mode 100644
index 0000000..51fe2b6
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/view/ViewRegistry.java
@@ -0,0 +1,384 @@
+/**
+ * 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 com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.apache.ambari.server.api.resources.BaseResourceDefinition;
+import org.apache.ambari.server.api.resources.ResourceInstanceFactoryImpl;
+import org.apache.ambari.server.api.resources.SubResourceDefinition;
+import org.apache.ambari.server.api.services.ViewSubResourceService;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.view.configuration.InstanceConfig;
+import org.apache.ambari.server.view.configuration.PropertyConfig;
+import org.apache.ambari.server.view.configuration.ResourceConfig;
+import org.apache.ambari.server.view.configuration.ViewConfig;
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.web.filter.DelegatingFilterProxy;
+
+import javax.servlet.http.HttpServlet;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Unmarshaller;
+import java.beans.IntrospectionException;
+import java.io.File;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Registry for view and view instance definitions.
+ */
+public class ViewRegistry {
+
+ /**
+ * Constants
+ */
+ private static final String VIEW_XML = "view.xml";
+
+ /**
+ * Mapping of view names to view definitions.
+ */
+ private Map<String, ViewDefinition> viewDefinitions = new HashMap<String, ViewDefinition>();
+
+ /**
+ * Mapping of view instances to view definition and instance name.
+ */
+ private Map<ViewDefinition, Map<String, ViewInstanceDefinition>> viewInstanceDefinitions = new HashMap<ViewDefinition, Map<String, ViewInstanceDefinition>>();
+
+ /**
+ * Mapping of view names to sub-resources.
+ */
+ private final Map<String, Set<SubResourceDefinition>> subResourceDefinitionsMap = new HashMap<String, Set<SubResourceDefinition>>();
+
+ /**
+ * The singleton view registry instance.
+ */
+ private static final ViewRegistry singleton = new ViewRegistry();
+
+ /**
+ * The logger.
+ */
+ protected final static Logger LOG = LoggerFactory.getLogger(ViewRegistry.class);
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Hide the constructor for this singleton.
+ */
+ private ViewRegistry() {
+ }
+
+
+ // ----- ViewRegistry ------------------------------------------------------
+
+ /**
+ * Get the collection of all the view definitions.
+ *
+ * @return the collection of view definitions
+ */
+ public Collection<ViewDefinition> getDefinitions() {
+ return viewDefinitions.values();
+ }
+
+ /**
+ * Get a view definition for the given name.
+ *
+ * @param viewName the view name
+ *
+ * @return the view definition for the given name
+ */
+ public ViewDefinition getDefinition(String viewName) {
+ return viewDefinitions.get(viewName);
+ }
+
+ /**
+ * Add a view definition to the registry.
+ *
+ * @param definition the definition
+ */
+ public void addDefinition(ViewDefinition definition) {
+ viewDefinitions.put(definition.getName(), definition);
+ }
+
+ /**
+ * Get the collection of view instances for the given view definition.
+ *
+ * @param definition the view definition
+ *
+ * @return the collection of view instances for the view definition
+ */
+ public Collection<ViewInstanceDefinition> getInstanceDefinitions(ViewDefinition definition) {
+ return definition == null ? null : viewInstanceDefinitions.get(definition).values();
+ }
+
+ /**
+ * Get the instance definition for the given view nam,e and instance name.
+ *
+ * @param viewName the view name
+ * @param instanceName the instance name
+ *
+ * @return the view instance definition for the given view and instance name
+ */
+ public ViewInstanceDefinition getInstanceDefinition(String viewName, String instanceName) {
+ Map<String, ViewInstanceDefinition> viewInstanceDefinitionMap =
+ viewInstanceDefinitions.get(getDefinition(viewName));
+
+ return viewInstanceDefinitionMap == null ? null : viewInstanceDefinitionMap.get(instanceName);
+ }
+
+ /**
+ * Add an instance definition for the given view definition.
+ *
+ * @param definition the owning view definition
+ * @param instanceDefinition the instance definition
+ */
+ public void addInstanceDefinition(ViewDefinition definition, ViewInstanceDefinition instanceDefinition) {
+ Map<String, ViewInstanceDefinition> instanceDefinitions = viewInstanceDefinitions.get(definition);
+ if (instanceDefinitions == null) {
+ instanceDefinitions = new HashMap<String, ViewInstanceDefinition>();
+ viewInstanceDefinitions.put(definition, instanceDefinitions);
+ }
+ instanceDefinitions.put(instanceDefinition.getName(), instanceDefinition);
+ }
+
+ /**
+ * Get the view registry singleton.
+ *
+ * @return the view registry
+ */
+ public static ViewRegistry getInstance() {
+ return singleton;
+ }
+
+ /**
+ * Get the sub-resource definitions for the given view name.
+ *
+ * @param viewName the instance name
+ *
+ * @return the set of sub-resource definitions
+ */
+ public synchronized Set<SubResourceDefinition> getSubResourceDefinitions(String viewName) {
+
+ Set<SubResourceDefinition> subResourceDefinitions = subResourceDefinitionsMap.get(viewName);
+
+ if (subResourceDefinitions == null) {
+ subResourceDefinitions = new HashSet<SubResourceDefinition>();
+ ViewDefinition definition = getDefinition(viewName);
+ if (definition != null) {
+ for (Resource.Type type : definition.getViewResourceTypes()) {
+ subResourceDefinitions.add(new SubResourceDefinition(type));
+ }
+ }
+ subResourceDefinitionsMap.put(viewName, subResourceDefinitions);
+ }
+ return subResourceDefinitions;
+ }
+
+ /**
+ * Read the view archives.
+ *
+ * @param configuration Ambari configuration
+ * @param rootContextHandler the root servlet context handler
+ * @param filterProxy the security filter
+ */
+ public static void readViewArchives(Configuration configuration, ServletContextHandler rootContextHandler,
+ DelegatingFilterProxy filterProxy) {
+
+ File viewDir = configuration.getViewsDir();
+ File[] files = viewDir.listFiles();
+
+ if (files != null) {
+ for (final File fileEntry : files) {
+ if (!fileEntry.isDirectory()) {
+ try {
+ ClassLoader cl = URLClassLoader.newInstance(new URL[]{fileEntry.toURI().toURL()});
+
+ InputStream configStream = cl.getResourceAsStream(VIEW_XML);
+ JAXBContext jaxbContext = JAXBContext.newInstance(ViewConfig.class);
+ Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
+ ViewConfig viewConfig = (ViewConfig) jaxbUnmarshaller.unmarshal(configStream);
+ ViewDefinition viewDefinition = installView(viewConfig, cl);
+
+ List<InstanceConfig> instances = viewConfig.getInstances();
+
+ for (InstanceConfig instanceConfig : instances) {
+ installViewInstance(viewDefinition, instanceConfig, cl, rootContextHandler, filterProxy, configuration);
+ }
+ } catch (Exception e) {
+ LOG.error("Caught exception loading view from " + fileEntry.getAbsolutePath(), e);
+ }
+ }
+ }
+ }
+ }
+
+
+ // ----- helper methods ----------------------------------------------------
+
+ /**
+ * Clear the registry.
+ */
+ protected void clear() {
+ viewDefinitions.clear();
+ viewInstanceDefinitions.clear();
+ subResourceDefinitionsMap.clear();
+ }
+
+ // install a new view definition
+ private static ViewDefinition installView(ViewConfig viewConfig, ClassLoader cl)
+ throws ClassNotFoundException, IntrospectionException {
+
+ List<ResourceConfig> resourceConfigurations = viewConfig.getResources();
+
+ ViewDefinition viewDefinition = new ViewDefinition(viewConfig);
+
+ for (ResourceConfig resourceConfiguration : resourceConfigurations) {
+
+ BaseResourceDefinition resourceDefinition = new ViewSubResourceDefinition(viewDefinition, resourceConfiguration);
+ viewDefinition.addResourceDefinition(resourceDefinition);
+
+ Resource.Type type = resourceDefinition.getType();
+ ResourceInstanceFactoryImpl.addResourceDefinition(type, resourceDefinition);
+
+ viewDefinition.addResourceConfiguration(type, resourceConfiguration);
+
+ Class<?> clazz = resourceConfiguration.getResourceClass(cl);
+ String idProperty = resourceConfiguration.getIdProperty();
+
+ viewDefinition.addResourceProvider(type, new ViewSubResourceProvider(type, clazz, idProperty, viewDefinition));
+ }
+
+ ViewRegistry.getInstance().addDefinition(viewDefinition);
+ return viewDefinition;
+ }
+
+ // install a new view instance definition
+ private static void installViewInstance(ViewDefinition viewDefinition,
+ InstanceConfig instanceConfig,
+ ClassLoader cl,
+ ServletContextHandler root,
+ DelegatingFilterProxy springSecurityFilter,
+ Configuration configs) throws ClassNotFoundException {
+
+ ViewInstanceDefinition viewInstanceDefinition = new ViewInstanceDefinition(viewDefinition, instanceConfig);
+
+ List<PropertyConfig> propertyConfigs = instanceConfig.getProperties();
+
+ for (PropertyConfig propertyConfig : propertyConfigs) {
+ viewInstanceDefinition.addProperty(propertyConfig.getKey(), propertyConfig.getValue());
+ }
+
+ ViewContext viewInstanceContext = new ViewContextImpl(viewInstanceDefinition);
+
+ Map<Resource.Type, ResourceConfig> resourceConfigurations = viewDefinition.getResourceConfigurations();
+
+ for (Map.Entry<Resource.Type, ResourceConfig> entry : resourceConfigurations.entrySet()) {
+
+ Resource.Type type = entry.getKey();
+ ResourceConfig configuration = entry.getValue();
+
+ ViewResourceHandler viewResourceService =
+ new ViewSubResourceService(type, viewDefinition.getName(), instanceConfig.getName());
+ viewInstanceDefinition.addService(viewDefinition.getResourceDefinition(type).getPluralName(),
+ getService(configuration.getServiceClass(cl), viewResourceService, viewInstanceContext));
+
+ viewInstanceDefinition.addResourceProvider(type,
+ getProvider(configuration.getProviderClass(cl), viewInstanceContext));
+ }
+
+ ViewConfig viewConfig = viewDefinition.getConfiguration();
+
+ Map<String, Class<? extends HttpServlet>> servletPathMap = viewConfig.getServletPathMap(cl);
+ Map<String, String> servletURLPatternMap = viewConfig.getServletURLPatternMap();
+
+ for (Map.Entry<String, Class<? extends HttpServlet>> entry : servletPathMap.entrySet()) {
+ HttpServlet servlet = getServlet(entry.getValue(), viewInstanceContext);
+ ServletHolder sh = new ServletHolder(servlet);
+ String servletName = entry.getKey();
+ String pathSpec = "/views/" + viewDefinition.getName() + "/" +
+ viewInstanceDefinition.getName() + servletURLPatternMap.get(servletName);
+ root.addServlet(sh, pathSpec);
+ viewInstanceDefinition.addServletMapping(servletName, pathSpec);
+
+ if (configs.getApiAuthentication()) {
+ root.addFilter(new FilterHolder(springSecurityFilter), pathSpec, 1);
+ }
+ }
+ viewDefinition.addInstanceDefinition(viewInstanceDefinition);
+ ViewRegistry.getInstance().addInstanceDefinition(viewDefinition, viewInstanceDefinition);
+ }
+
+ // get the given service class from the given class loader; inject a handler and context
+ private static <T> T getService(Class<T> clazz,
+ final ViewResourceHandler viewResourceHandler,
+ final ViewContext viewInstanceContext) {
+ Injector viewInstanceInjector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(ViewResourceHandler.class)
+ .toInstance(viewResourceHandler);
+ bind(ViewContext.class)
+ .toInstance(viewInstanceContext);
+ }
+ });
+ return viewInstanceInjector.getInstance(clazz);
+ }
+
+ // get the given servlet class from the given class loader; inject a context
+ private static HttpServlet getServlet(Class<? extends HttpServlet> clazz,
+ final ViewContext viewInstanceContext) {
+ Injector viewInstanceInjector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(ViewContext.class)
+ .toInstance(viewInstanceContext);
+ }
+ });
+ return viewInstanceInjector.getInstance(clazz);
+ }
+
+ // get the given resource provider class from the given class loader; inject a context
+ private static org.apache.ambari.view.ResourceProvider getProvider(
+ Class<? extends org.apache.ambari.view.ResourceProvider> clazz,
+ final ViewContext viewInstanceContext) {
+ Injector viewInstanceInjector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(ViewContext.class)
+ .toInstance(viewInstanceContext);
+ }
+ });
+ return viewInstanceInjector.getInstance(clazz);
+ }
+}