| /** |
| * 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.state.kerberos; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.TreeMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Represents information required to configure Kerberos for a particular service. |
| * <p/> |
| * The data map is expected to have the following properties: |
| * <ul> |
| * <li>name</li> |
| * <li>components</li> |
| * <li>identities</li> |
| * <li>configurations</li> |
| * </ul> |
| * Example: |
| * <pre> |
| * "name" => "SERVICE", |
| * "identities" => Collection<Map<String, Object>> |
| * "components" => Collection<Map<String, Object>> |
| * "configurations" => Collection<Map<String, Object>> |
| * </pre> |
| */ |
| |
| /** |
| * KerberosServiceDescriptor is an implementation of an AbstractKerberosDescriptorContainer that |
| * encapsulates an Ambari service and it components. |
| * <p/> |
| * A KerberosServiceDescriptor has the following properties: |
| * <ul> |
| * <li>name</li> |
| * <li>components</li> |
| * <li>identities ({@link org.apache.ambari.server.state.kerberos.AbstractKerberosDescriptorContainer})</li> |
| * <li>configurations ({@link org.apache.ambari.server.state.kerberos.AbstractKerberosDescriptorContainer})</li> |
| * </ul> |
| * <p/> |
| * The following (pseudo) JSON Schema will yield a valid KerberosServiceDescriptor |
| * <pre> |
| * { |
| * "$schema": "http://json-schema.org/draft-04/schema#", |
| * "title": "KerberosServiceDescriptor", |
| * "description": "Describes an Ambari service", |
| * "type": "object", |
| * "properties": { |
| * "name": { |
| * "description": "An identifying name for this service descriptor.", |
| * "type": "string" |
| * }, |
| * "components": { |
| * "description": "A list of Ambari component descriptors", |
| * "type": "array", |
| * "items": { |
| * "title": "KerberosComponentDescriptor" |
| * "type": "{@link org.apache.ambari.server.state.kerberos.KerberosComponentDescriptor}" |
| * } |
| * }, |
| * "identities": { |
| * "description": "A list of Kerberos identity descriptors", |
| * "type": "array", |
| * "items": { |
| * "title": "KerberosIdentityDescriptor" |
| * "type": "{@link org.apache.ambari.server.state.kerberos.KerberosIdentityDescriptor}" |
| * } |
| * }, |
| * "configurations": { |
| * "description": "A list of relevant configuration blocks", |
| * "type": "array", |
| * "items": { |
| * "title": "KerberosConfigurationDescriptor" |
| * "type": "{@link org.apache.ambari.server.state.kerberos.KerberosConfigurationDescriptor}" |
| * } |
| * } |
| * } |
| * } |
| * </pre> |
| * <p/> |
| * In this implementation, |
| * {@link org.apache.ambari.server.state.kerberos.AbstractKerberosDescriptor#name} will hold the |
| * KerberosServiceDescriptor#name value. |
| */ |
| public class KerberosServiceDescriptor extends AbstractKerberosDescriptorContainer { |
| |
| /** |
| * A Map of the components contained within this KerberosServiceDescriptor |
| */ |
| private Map<String, KerberosComponentDescriptor> components; |
| |
| /** |
| * Creates a new KerberosServiceDescriptor |
| * <p/> |
| * See {@link org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor} for the JSON |
| * Schema that may be used to generate this map. |
| * |
| * @param data a Map of values use to populate the data for the new instance |
| * @see org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor |
| */ |
| KerberosServiceDescriptor(Map<?, ?> data) { |
| // The name for this KerberosServiceDescriptor is stored in the "name" entry in the map |
| // This is not automatically set by the super classes. |
| this(getStringValue(data, "name"), data); |
| } |
| |
| @Override |
| public Collection<? extends AbstractKerberosDescriptorContainer> getChildContainers() { |
| return (components == null) ? null : Collections.unmodifiableCollection(components.values()); |
| } |
| |
| @Override |
| public AbstractKerberosDescriptorContainer getChildContainer(String name) { |
| return getComponent(name); |
| } |
| |
| /** |
| * Creates a new KerberosServiceDescriptor |
| * <p/> |
| * See {@link org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor} for the JSON |
| * Schema that may be used to generate this map. |
| * |
| * @param name a String declaring this service's name |
| * @param data a Map of values use to populate the data for the new instance |
| * @see org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor |
| */ |
| KerberosServiceDescriptor(String name, Map<?, ?> data) { |
| super(data); |
| |
| // This is not automatically set by the super classes. |
| setName(name); |
| |
| if (data != null) { |
| Object list = data.get(Type.COMPONENT.getDescriptorPluralName()); |
| if (list instanceof Collection) { |
| // Assume list is Collection<Map<String, Object>> |
| for (Object item : (Collection) list) { |
| if (item instanceof Map) { |
| putComponent(new KerberosComponentDescriptor((Map<?, ?>) item)); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Returns a Map of the KerberosComponentDescriptors related to this KerberosServiceDescriptor |
| * |
| * @return a Map of String to KerberosComponentDescriptor |
| */ |
| public Map<String, KerberosComponentDescriptor> getComponents() { |
| return components; |
| } |
| |
| /** |
| * Returns the KerberosComponentDescriptors with the specified name |
| * |
| * @param name the name of the component for which to retrieve a descriptor |
| * @return the KerberosComponentDescriptor for the requested component or null if not found |
| */ |
| public KerberosComponentDescriptor getComponent(String name) { |
| return ((name == null) || (components == null)) ? null : components.get(name); |
| } |
| |
| /** |
| * Adds or replaces a KerberosComponentDescriptor |
| * <p/> |
| * If a KerberosComponentDescriptor with the same name already exists in the components Map, it |
| * will be replaced; else a new entry will be made. |
| * |
| * @param component the KerberosComponentDescriptor to put |
| */ |
| public void putComponent(KerberosComponentDescriptor component) { |
| if (component != null) { |
| String name = component.getName(); |
| |
| if (name == null) { |
| throw new IllegalArgumentException("The component name must not be null"); |
| } |
| |
| if (components == null) { |
| components = new TreeMap<String, KerberosComponentDescriptor>(); |
| } |
| |
| components.put(name, component); |
| component.setParent(this); |
| } |
| } |
| |
| /** |
| * Updates this KerberosServiceDescriptor with data from another KerberosServiceDescriptor |
| * <p/> |
| * Properties will be updated if the relevant updated values are not null. |
| * |
| * @param updates the KerberosServiceDescriptor containing the updated values |
| */ |
| public void update(KerberosServiceDescriptor updates) { |
| if (updates != null) { |
| Map<String, KerberosComponentDescriptor> updatedComponents = updates.getComponents(); |
| if (updatedComponents != null) { |
| for (Map.Entry<String, KerberosComponentDescriptor> entry : updatedComponents.entrySet()) { |
| KerberosComponentDescriptor existing = getComponent(entry.getKey()); |
| if (existing == null) { |
| putComponent(entry.getValue()); |
| } else { |
| existing.update(entry.getValue()); |
| } |
| } |
| } |
| } |
| |
| super.update(updates); |
| } |
| |
| /** |
| * Gets the requested AbstractKerberosDescriptor implementation using a type name and a relevant |
| * descriptor name. |
| * <p/> |
| * This implementation handles component descriptors and relies on the |
| * AbstractKerberosDescriptorContainer implementation to handle other types. |
| * |
| * @param type a String indicating the type of the requested descriptor |
| * @param name a String indicating the name of the requested descriptor |
| * @return a AbstractKerberosDescriptor representing the requested descriptor or null if not found |
| */ |
| @Override |
| protected AbstractKerberosDescriptor getDescriptor(Type type, String name) { |
| if (Type.COMPONENT == type) { |
| return getComponent(name); |
| } else { |
| return super.getDescriptor(type, name); |
| } |
| } |
| |
| /** |
| * Creates a Map of values that can be used to create a copy of this KerberosServiceDescriptor |
| * or generate the JSON structure described in |
| * {@link org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor} |
| * |
| * @return a Map of values for this KerberosServiceDescriptor |
| * @see org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor |
| */ |
| @Override |
| public Map<String, Object> toMap() { |
| Map<String, Object> map = super.toMap(); |
| |
| if (components != null) { |
| List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); |
| for (KerberosComponentDescriptor component : components.values()) { |
| list.add(component.toMap()); |
| } |
| map.put(Type.COMPONENT.getDescriptorPluralName(), list); |
| } |
| |
| return map; |
| } |
| |
| @Override |
| public int hashCode() { |
| return super.hashCode() + |
| ((getComponents() == null) |
| ? 0 |
| : getComponents().hashCode()); |
| } |
| |
| @Override |
| public boolean equals(Object object) { |
| if (object == null) { |
| return false; |
| } else if (object == this) { |
| return true; |
| } else if (object.getClass() == KerberosServiceDescriptor.class) { |
| KerberosServiceDescriptor descriptor = (KerberosServiceDescriptor) object; |
| return super.equals(object) && |
| ( |
| (getComponents() == null) |
| ? (descriptor.getComponents() == null) |
| : getComponents().equals(descriptor.getComponents()) |
| ); |
| } else { |
| return false; |
| } |
| } |
| |
| } |
| |