/** * 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.msi; import org.apache.ambari.server.controller.internal.RequestStatusImpl; import org.apache.ambari.server.controller.internal.ResourceImpl; 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.ResourceProvider; import org.apache.ambari.server.controller.spi.SystemException; import org.apache.ambari.server.controller.spi.UnsupportedPropertyException; import org.apache.ambari.server.controller.utilities.PredicateHelper; import org.apache.ambari.server.controller.utilities.PropertyHelper; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; /** * An abstract resource provider for a MSI defined cluster. */ public abstract class AbstractResourceProvider implements ResourceProvider { private final ClusterDefinition clusterDefinition; private final Resource.Type type; private final Set<String> propertyIds; // ----- Constructors ------------------------------------------------------ /** * Construct a resource provider based on the given cluster definition. * * @param clusterDefinition the cluster definition */ public AbstractResourceProvider(Resource.Type type, ClusterDefinition clusterDefinition) { this.type = type; this.clusterDefinition = clusterDefinition; Set<String> propertyIds = PropertyHelper.getPropertyIds(type); this.propertyIds = new HashSet<String>(propertyIds); this.propertyIds.addAll(PropertyHelper.getCategories(propertyIds)); } // ----- ResourceProvider -------------------------------------------------- @Override public RequestStatus createResources(Request request) throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException { throw new UnsupportedOperationException("Management operations are not supported"); } @Override public Set<Resource> getResources(Request request, Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { Set<Resource> resultSet = new HashSet<Resource>(); for (Resource resource : getResources()) { if (predicate == null || predicate.evaluate(resource)) { ResourceImpl newResource = new ResourceImpl(resource); updateProperties(newResource, request, predicate); resultSet.add(newResource); } } return resultSet; } @Override public RequestStatus updateResources(Request request, Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { Set<Resource> resources = getResources(request, predicate); Integer requestId = -1; Iterator<Map<String,Object>> iterator = request.getProperties().iterator(); if (iterator.hasNext()) { Map<String, Object> properties = iterator.next(); for (Resource resource : resources) { requestId = updateProperties(resource, properties); } } return getRequestStatus(requestId == -1 ? null : requestId); } @Override public RequestStatus deleteResources(Predicate predicate) throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException { throw new UnsupportedOperationException("Management operations are not supported"); } @Override public Map<Resource.Type, String> getKeyPropertyIds() { return PropertyHelper.getKeyPropertyIds(type); } @Override public Set<String> checkPropertyIds(Set<String> propertyIds) { propertyIds = new HashSet<String>(propertyIds); propertyIds.removeAll(this.propertyIds); return propertyIds; } // ----- AbstractResourceProvider ------------------------------------------ /** * Get the set of resources for this provider. * * @return the set of resources */ abstract protected Set<Resource> getResources(); /** * Update the resource with any properties handled by the resource provider. * * @param resource the resource to update * @param request the request * @param predicate the predicate */ public abstract void updateProperties(Resource resource, Request request, Predicate predicate); /** * Update the resource with the given properties. * * @param resource the resource to update * @param properties the properties * * @return the request id; -1 for none */ public abstract int updateProperties(Resource resource, Map<String, Object> properties); /** * Get a request status * * @return the request status */ protected RequestStatus getRequestStatus(Integer requestId) { if (requestId != null){ Resource requestResource = new ResourceImpl(Resource.Type.Request); requestResource.setProperty(PropertyHelper.getPropertyId("Requests", "id"), requestId); requestResource.setProperty(PropertyHelper.getPropertyId("Requests", "status"), "InProgress"); return new RequestStatusImpl(requestResource); } return new RequestStatusImpl(null); } // ----- accessors --------------------------------------------------------- /** * Get the configuration provider. * * @return the configuration provider */ protected ClusterDefinition getClusterDefinition() { return clusterDefinition; } /** * Get the resource provider type. * * @return the type */ public Resource.Type getType() { return type; } // ----- helper methods ---------------------------------------------------- /** * Get the set of property ids required to satisfy the given request. * * @param request the request * @param predicate the predicate * * @return the set of property ids needed to satisfy the request */ protected Set<String> getRequestPropertyIds(Request request, Predicate predicate) { Set<String> propertyIds = request.getPropertyIds(); // if no properties are specified, then return them all if (propertyIds == null || propertyIds.isEmpty()) { return new HashSet<String>(this.propertyIds); } propertyIds = new HashSet<String>(propertyIds); if (predicate != null) { propertyIds.addAll(PredicateHelper.getPropertyIds(predicate)); } return propertyIds; } /** * Check to see if the given set contains a property or category id that matches the given property id. * * @param ids the set of property/category ids * @param propertyId the property id * * @return true if the given set contains a property id or category that matches the given property id */ protected static boolean contains(Set<String> ids, String propertyId) { boolean contains = ids.contains(propertyId); if (!contains) { String category = PropertyHelper.getPropertyCategory(propertyId); while (category != null && !contains) { contains = ids.contains(category); category = PropertyHelper.getPropertyCategory(category); } } return contains; } /** * Factory method for obtaining a resource provider based on a given type. * * @param type the resource type * @param clusterDefinition the cluster definition * * @return a new resource provider */ public static ResourceProvider getResourceProvider(Resource.Type type, ClusterDefinition clusterDefinition) { if (type.equals(Resource.Type.Cluster)) { return new ClusterProvider(clusterDefinition); } else if (type.equals(Resource.Type.Service)) { return new ServiceProvider(clusterDefinition); } else if (type.equals(Resource.Type.Component)) { return new ComponentProvider(clusterDefinition); } else if (type.equals(Resource.Type.Host)) { return new HostProvider(clusterDefinition); } else if (type.equals(Resource.Type.HostComponent)) { return new HostComponentProvider(clusterDefinition); } else if (type.equals(Resource.Type.Request)) { return new RequestProvider(clusterDefinition); } else if (type.equals(Resource.Type.Task)) { return new TaskProvider(clusterDefinition); } else if (type.equals(Resource.Type.Configuration)) { return new ConfigurationProvider(clusterDefinition); } else { return new NoOpProvider(type, clusterDefinition); } } }