/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ambari.server.orm.entities; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinColumns; import javax.persistence.ManyToOne; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Transient; import org.apache.ambari.server.configuration.Configuration; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.view.ViewSubResourceDefinition; import org.apache.ambari.server.view.configuration.ParameterConfig; import org.apache.ambari.server.view.configuration.ResourceConfig; import org.apache.ambari.server.view.configuration.ViewConfig; import org.apache.ambari.view.View; import org.apache.ambari.view.ViewDefinition; import org.apache.ambari.view.validation.Validator; /** * Entity representing a View. */ @Table(name = "viewmain") @NamedQuery(name = "allViews", query = "SELECT view FROM ViewEntity view") @Entity public class ViewEntity implements ViewDefinition { public static final String AMBARI_ONLY = "AMBARI-ONLY"; /** * The unique view name. */ @Id @Column(name = "view_name", nullable = false, insertable = true, updatable = false, unique = true, length = 100) private String name; /** * The public view name. */ @Column @Basic private String label; /** * The view description. */ @Column @Basic private String description; /** * The icon path. */ @Column @Basic private String icon; /** * The big icon path. */ @Column @Basic private String icon64; /** * The view version. */ @Column @Basic private String version; /** * The view build number. */ @Column @Basic private String build; /** * The view archive. */ @Column @Basic private String archive; /** * The masker class for parameters. */ @Column @Basic private String mask; /** * Indicates whether or not this is a system view. */ @Column(name = "system_view") @Basic private Integer system; /** * The list of view parameters. */ @OneToMany(cascade = CascadeType.ALL, mappedBy = "view") private Collection<ViewParameterEntity> parameters = new HashSet<>(); /** * The list of view resources. */ @OneToMany(cascade = CascadeType.ALL, mappedBy = "view") private Collection<ViewResourceEntity> resources = new HashSet<>(); /** * The list of view instances. */ @OneToMany(cascade = CascadeType.ALL, mappedBy = "view") private Collection<ViewInstanceEntity> instances = new HashSet<>(); /** * The list of view permissions. */ @OneToMany(cascade = CascadeType.ALL) @JoinColumns({ @JoinColumn(name = "resource_type_id", referencedColumnName = "resource_type_id", nullable = false) }) private Collection<PermissionEntity> permissions = new HashSet<>(); /** * The resource type. */ @ManyToOne(cascade = CascadeType.ALL) @JoinColumns({ @JoinColumn(name = "resource_type_id", referencedColumnName = "resource_type_id", nullable = false) }) private ResourceTypeEntity resourceType; // ----- Transient data ---------------------------------------------------- /** * The associated view configuration. */ @Transient private ViewConfig configuration; /** * The Ambari configuration properties. */ @Transient private final Configuration ambariConfiguration; /** * The external resource type for the view. */ @Transient private final Resource.Type externalResourceType; /** * The classloader used to load the view. */ @Transient private ClassLoader classLoader = null; /** * The mapping of resource type to resource provider. */ @Transient private final Map<Resource.Type, ResourceProvider> resourceProviders = new HashMap<>(); /** * The mapping of resource type to resource definition. */ @Transient private final Map<Resource.Type, ViewSubResourceDefinition> resourceDefinitions = new HashMap<>(); /** * The mapping of resource type to resource configuration. */ @Transient private final Map<Resource.Type, ResourceConfig> resourceConfigurations = new HashMap<>(); /** * The name of the view shared across versions. */ @Transient private String commonName = null; /** * The view. */ @Transient private View view = null; /** * The view validator. */ @Transient private Validator validator = null; /** * The view status. */ @Transient private ViewStatus status = ViewStatus.PENDING; /** * The view status detail. */ @Transient private String statusDetail; /** * Indicates whether or not this view is configurable through cluster association. */ @Transient private boolean clusterConfigurable; // ----- Constructors ------------------------------------------------------ /** * Construct a view entity. */ public ViewEntity() { this.configuration = null; this.ambariConfiguration = null; this.archive = null; this.externalResourceType = null; this.system = 0; this.clusterConfigurable = false; } /** * Construct a view entity from the given configuration. * * @param configuration the view configuration * @param ambariConfiguration the Ambari configuration * @param archivePath the path of the view archive */ public ViewEntity(ViewConfig configuration, Configuration ambariConfiguration, String archivePath) { setConfiguration(configuration); this.ambariConfiguration = ambariConfiguration; this.archive = archivePath; String version = configuration.getVersion(); this.name = getViewName(configuration.getName(), version); this.label = configuration.getLabel(); this.description = configuration.getDescription(); this.version = version; this.build = configuration.getBuild(); this.mask = configuration.getMasker(); this.icon = configuration.getIcon(); this.icon64 = configuration.getIcon64(); this.system = configuration.isSystem() ? 1 : 0; this.externalResourceType = new Resource.Type(getQualifiedResourceTypeName(ResourceConfig.EXTERNAL_RESOURCE_PLURAL_NAME)); } // ----- ViewDefinition ---------------------------------------------------- @Override public String getViewName() { return getCommonName(); } @Override public String getLabel() { return label; } @Override public String getDescription() { return description; } @Override public String getVersion() { return version; } @Override public String getBuild() { return build; } @Override public ViewStatus getStatus() { return status; } @Override public String getStatusDetail() { return statusDetail; } @Override public String getMask() { return mask; } // ----- ViewEntity -------------------------------------------------------- /** * Get the view name. * * @return the view name */ public String getName() { return name; } /** * Set the view name. * * @param name the view name */ public void setName(String name) { this.name = name; } /** * Get the common name of the view. * This name is shared across versions of the view. * * @return the common name */ public synchronized String getCommonName() { if (commonName == null) { // Strip version from the internal name commonName = name.replaceAll("\\{(.+)\\}", ""); } return commonName; } /** * Set the view label (display name). * * @param label the view label */ public void setLabel(String label) { this.label = label; } /** * Set the view description. * * @param description the view description */ public void setDescription(String description) { this.description = description; } /** * Set the view version. * * @param version the version */ public void setVersion(String version) { this.version = version; } /** * Set the view build number. * * @param build the build */ public void setBuild(String build) { this.build = build; } /** * Get the icon path. * * @return the icon path */ public String getIcon() { return icon; } /** * Set the icon path. * * @param icon the icon path */ public void setIcon(String icon) { this.icon = icon; } /** * Get the big icon path. * * @return the big icon path */ public String getIcon64() { return icon64; } /** * Set the big icon path. * * @param icon64 the big icon path */ public void setIcon64(String icon64) { this.icon64 = icon64; } /** * Get the view parameters. * * @return the view parameters */ public Collection<ViewParameterEntity> getParameters() { return parameters; } /** * Set the view parameters. * * @param parameters the view parameters */ public void setParameters(Collection<ViewParameterEntity> parameters) { this.parameters = parameters; } /** * Get the view custom permissions. * * @return the view permissions */ public Collection<PermissionEntity> getPermissions() { return permissions; } /** * Set the custom view permissions. * * @param permissions the permissions */ public void setPermissions(Collection<PermissionEntity> permissions) { this.permissions = permissions; } /** * Get the permission entity for the given permission name. * * @param permissionName the permission name * * @return the matching permission entity or null */ public PermissionEntity getPermission(String permissionName) { for (PermissionEntity permissionEntity : permissions) { if (permissionEntity.getPermissionName().equals(permissionName)) { return permissionEntity; } } return null; } /** * Get the view resources. * * @return the view resources */ public Collection<ViewResourceEntity> getResources() { return resources; } /** * Set the view resources. * * @param resources the view resources */ public void setResources(Collection<ViewResourceEntity> resources) { this.resources = resources; } /** * Get the view instances. * * @return the view instances */ public Collection<ViewInstanceEntity> getInstances() { return instances; } /** * Set the view instances. * * @param instances the instances */ public void setInstances(Collection<ViewInstanceEntity> instances) { this.instances = instances; } /** * Add an instance definition. * * @param viewInstanceDefinition the instance definition */ public void addInstanceDefinition(ViewInstanceEntity viewInstanceDefinition) { removeInstanceDefinition(viewInstanceDefinition.getName()); instances.add(viewInstanceDefinition); } /** * Remove an instance definition. * * @param instanceName the instance name */ public void removeInstanceDefinition(String instanceName) { ViewInstanceEntity entity = getInstanceDefinition(instanceName); if (entity != null) { instances.remove(entity); } } /** * Get an instance definition for the given name. * * @param instanceName the instance name * * @return the instance definition */ public ViewInstanceEntity getInstanceDefinition(String instanceName) { for (ViewInstanceEntity viewInstanceEntity : instances) { if (viewInstanceEntity.getName().equals(instanceName)) { return viewInstanceEntity; } } return null; } /** * Get the path of the view archive. * * @return the path of the view archive */ public String getArchive() { return archive; } /** * Set the view archive path. * * @param archive the view archive path */ public void setArchive(String archive) { this.archive = archive; } /** * Get a property for the given key from the ambari configuration. * * @param key the property key * * @return the property value; null indicates that the configuration contains no mapping for the key */ public String getAmbariProperty(String key) { return ambariConfiguration.getProperty(key); } /** * Get the Ambari configuration. * * @return the Ambari configuration */ public Configuration getAmbariConfiguration() { return ambariConfiguration; } /** * Get a resource name qualified by the associated view name. * * @param resourceTypeName the resource type name * * @return the qualified resource name */ public String getQualifiedResourceTypeName(String resourceTypeName) { return getName() + "/" + resourceTypeName; } /** * Get the external resource type for the view. * * @return the external resource type */ public Resource.Type getExternalResourceType() { return externalResourceType; } /** * Get the class loader used to load the view classes. * * @return the class loader */ public ClassLoader getClassLoader() { return classLoader; } /** * Set the class loader. * * @param classLoader the class loader */ public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } /** * 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(ViewSubResourceDefinition 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 ViewSubResourceDefinition getResourceDefinition(Resource.Type type) { return resourceDefinitions.get(type); } /** * Get the mapping of resource type to resource definitions. * * @return the mapping of resource type to resource definitions */ public Map<Resource.Type, ViewSubResourceDefinition> getResourceDefinitions() { return resourceDefinitions; } /** * 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 the 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 resourceProviders.keySet(); } /** * Set the view configuration. * * @param configuration the view configuration */ public void setConfiguration(ViewConfig configuration) { this.configuration = configuration; this.clusterConfigurable = false; if(configuration.getClusterConfigOptions() != null && configuration.getClusterConfigOptions().equals(AMBARI_ONLY)){ this.clusterConfigurable = true; return; } // if any of the parameters contain a cluster config element then the view is cluster configurable for (ParameterConfig parameterConfig : configuration.getParameters()) { String clusterConfig = parameterConfig.getClusterConfig(); if (clusterConfig != null && !clusterConfig.isEmpty()) { this.clusterConfigurable = true; return; } } } /** * Get the associated view configuration. * * @return the configuration */ public ViewConfig getConfiguration() { return configuration; } /** * Set the view. * * @param view the view */ public void setView(View view) { this.view = view; } /** * Get the associated view. * * @return the view */ public View getView() { return view; } /** * Set the view validator. * * @param validator the view validator */ public void setValidator(Validator validator) { this.validator = validator; } /** * Get the associated view validator. * * @return the view validator */ public Validator getValidator() { return validator; } /** * Determine whether or not a validator has been specified for this view. * * @return true if this view has a validator */ public boolean hasValidator() { return validator != null; } /** * Set the mask class name. * * @param mask the mask class name */ public void setMask(String mask) { this.mask = mask; } /** * Determine whether or not the view is a system view. * * @return true if the view is a system view */ public boolean isSystem() { return system == 1; } /** * Set the flag which indicates whether or not the view is a system view. * * @param required the system flag; true if the view is a system view */ public void setSystem(boolean required) { this.system = required ? 1 : 0; } /** * Get the admin resource type entity. * * @return the resource type entity */ public ResourceTypeEntity getResourceType() { return resourceType; } /** * Set the admin resource type entity. * * @param resourceType the resource type entity */ public void setResourceType(ResourceTypeEntity resourceType) { this.resourceType = resourceType; } /** * Set the status of the view. * * @param status the view status */ public void setStatus(ViewStatus status) { this.status = status; } /** * Set the status detail for the view. * * @param statusDetail the status detail */ public void setStatusDetail(String statusDetail) { this.statusDetail = statusDetail; } /** * Determine whether or not this view is configurable through a cluster association. * * @return true if this view is cluster configurable */ public boolean isClusterConfigurable() { return clusterConfigurable; } /** * Determine whether or not the entity is deployed. * * @return true if the entity is deployed */ public boolean isDeployed() { return status.equals(ViewStatus.DEPLOYED); } /** * Get the internal view name from the given common name and version. * * @param name the view common name * @param version the version * * @return the view name */ public static String getViewName(String name, String version) { return name + "{" + version + "}"; } @Override public String toString() { return "ViewEntity{" + "name='" + name + '\'' + ", label='" + label + '\'' + ", description='" + description + '\'' + '}'; } }