/******************************************************************************* * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, and is * available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: Red Hat, Inc. ******************************************************************************/ package com.openshift.internal.restclient.model; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.internal.util.JBossDmrExtentions; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IResource; import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; /** * Resource is an abstract representation of a Kubernetes resource * * @author Jeff Cantrill */ public class KubernetesResource implements IResource, ResourcePropertyKeys { private ModelNode node; private IClient client; private Map<Class<? extends ICapability>, ICapability> capabilities = new HashMap<Class<? extends ICapability>, ICapability>(); private Map<String, String []> propertyKeys; private IProject project; /** * * @param node * @param client * @param overrideProperties the map of properties that override the defaults */ public KubernetesResource(ModelNode node, IClient client, Map<String, String []> overrideProperties){ if(overrideProperties == null) overrideProperties = new HashMap<String, String []>(); this.node = node; this.client = client; this.propertyKeys = overrideProperties; initializeCapabilities(capabilities, this, client); } @Override public String getResourceVersion() { return asString(METADATA_RESOURCE_VERSION); } @Override public Map<String, String> getMetadata() { return asMap(METADATA); } @SuppressWarnings("unchecked") @Override public <T extends ICapability> T getCapability(Class<T> capability) { return (T) capabilities.get(capability); } public Set<Class<? extends ICapability>> getCapabilities(){ return Collections.unmodifiableSet(capabilities.keySet()); } protected Map<Class<? extends ICapability>, ICapability> getModifiableCapabilities(){ return capabilities; } @Override public boolean supports(Class<? extends ICapability> capability) { return capabilities.containsKey(capability); } @SuppressWarnings("unchecked") @Override public <T extends ICapability, R> R accept(CapabilityVisitor<T, R> visitor, R unsupportedValue){ if(capabilities.containsKey(visitor.getCapabilityType())){ T capability = (T) capabilities.get(visitor.getCapabilityType()); return (R) visitor.visit(capability); } return unsupportedValue; } @Override public IProject getProject() { if(this.project == null) { this.project = client.get(ResourceKind.PROJECT, getNamespace(), ""); } return this.project; } @Override public Map<String, String> getAnnotations() { return asMap(ANNOTATIONS); } @Override public String getAnnotation(String key) { return getAnnotations().get(key); } @Override public void setAnnotation(String name, String value) { if(value == null) return; ModelNode annotations = get(ANNOTATIONS); annotations.get(name).set(value); } @Override public void removeAnnotation(String name) { ModelNode annotations = get(ANNOTATIONS); annotations.remove(name); } @Override public boolean isAnnotatedWith(String key) { Map<String, String> annotations = getAnnotations(); return annotations.containsKey(key); } public Map<String, String []> getPropertyKeys(){ return this.propertyKeys; } public IClient getClient(){ return client; } public void setNode(ModelNode node) { this.node = node.clone(); } public ModelNode getNode(){ return node; } public void refresh(){ //TODO find better way to bypass serialization/deserialization this.node = ModelNode.fromJSONString(client.get(getKind(), getName(), getNamespace()).toString()); } @Override public String getKind(){ return asString(KIND); } @Override public String getApiVersion(){ return asString(APIVERSION); } @Override public String getCreationTimeStamp(){ return asString(CREATION_TIMESTAMP); } @Override public String getName(){ return asString(METADATA_NAME); } public void setName(String name) { set(METADATA_NAME, name); } @Override public String getNamespace(){ return asString(METADATA_NAMESPACE); } public void setNamespace(String namespace){ set(METADATA_NAMESPACE, namespace); } @Override public void addLabel(String key, String value) { ModelNode labels = node.get(getPath(LABELS)); labels.get(key).set(value); } @Override public Map<String, String> getLabels() { return asMap(LABELS); } /*---------- utility methods ------*/ protected boolean has(String key) { return node.has(getPath(key)); } protected ModelNode get(String key){ return get(node, key); } protected ModelNode get(ModelNode node, String key){ return node.get(getPath(key)); } protected Map<String, String> getEnvMap(String key) { Map<String, String> values = new HashMap<String, String>(); ModelNode source = node.get(getPath(key)); if(source.getType() == ModelType.LIST){ for (ModelNode value : source.asList()) { values.put(value.get("name").asString(), value.get("value").asString()); } } return values; } protected void set(String key, Map<String, String> values) { JBossDmrExtentions.set(node, propertyKeys, key, values); } protected void set(String key, int value) { JBossDmrExtentions.set(node, propertyKeys, key, value); } protected void set(ModelNode node, String key, int value) { JBossDmrExtentions.set(node, propertyKeys, key, value); } protected void set(String key, String value){ JBossDmrExtentions.set(node, propertyKeys, key, value); } protected void set(ModelNode node, String key, String value){ JBossDmrExtentions.set(node, propertyKeys, key, value); } protected void set(String key, boolean value){ JBossDmrExtentions.set(node, propertyKeys, key, value); } protected void set(ModelNode node, String key, boolean value){ JBossDmrExtentions.set(node, propertyKeys, key, value); } protected void setEnvMap(String key, Map<String, String> values) { ModelNode mapNodeParent = node.get(getPath(key)); for(Map.Entry<String, String> value: values.entrySet()) { ModelNode mapNode = mapNodeParent.add(); mapNode.get("name").set(value.getKey()); mapNode.get("value").set(value.getValue()); } } protected String[] getPath(String key) { return JBossDmrExtentions.getPath(propertyKeys, key); } protected String asString(ModelNode node, String subKey) { return JBossDmrExtentions.asString(node, propertyKeys, subKey); } protected int asInt(String key){ return JBossDmrExtentions.asInt(node, propertyKeys, key); } protected int asInt(ModelNode node, String key){ return JBossDmrExtentions.asInt(node, propertyKeys, key); } protected Map<String, String> asMap(String property){ return JBossDmrExtentions.asMap(this.node, propertyKeys, property); } protected String asString(String property){ return JBossDmrExtentions.asString(node, propertyKeys, property); } protected boolean asBoolean(ModelNode node, String property) { return JBossDmrExtentions.asBoolean(node, propertyKeys, property); } protected boolean asBoolean(String property) { return JBossDmrExtentions.asBoolean(node, propertyKeys, property); } protected Set asSet(String property, ModelType type) { return JBossDmrExtentions.asSet(node, propertyKeys, property, type); } protected void set(String property, Set<String> values) { JBossDmrExtentions.set(node, propertyKeys, property, values); } protected void set(String property, String... values) { JBossDmrExtentions.set(node, propertyKeys, property, values); } @Override public String toString() { return toJson(true); } public String toPrettyString(){ return toJson(false); } @Override public int hashCode() { String namespace = getNamespace(); String name = getName(); String kind = getKind(); final int prime = 31; return prime * (namespace.hashCode() + name.hashCode() + kind.hashCode()); } @Override public boolean equals(Object obj) { if (this == obj) return true; else if (obj == null) return false; else if (getClass() != obj.getClass()) return false; else { KubernetesResource other = (KubernetesResource) obj; if (getKind() != null){ if (!getKind().equals(other.getKind())) { return false; } } else { if (other.getKind() != null) { return false; } } if (getNamespace() != null) { if(!getNamespace().equals(other.getNamespace())) { return false; } } else { if (other.getNamespace() != null) { return false; } } if (getName() != null) { if(!getName().equals(other.getName())) { return false; } } else { if (other.getName() != null) { return false; } } } return true; } @Override public String toJson() { return toJson(false); } @Override public String toJson(boolean compact) { return JBossDmrExtentions.toJsonString(node, compact); } }