Package com.cloudbees.clickstack.domain.metadata

Source Code of com.cloudbees.clickstack.domain.metadata.Metadata

/*
* Copyright 2010-2013, CloudBees Inc.
*
* Licensed 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 com.cloudbees.clickstack.domain.metadata;

import com.cloudbees.clickstack.util.Strings2;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;

/**
* It stores GenApp resources,
* environment variables (given by -P with the SDK), and runtime parameters (given by -R with the SDK).
* It also makes them accessible for other classes to (typically) write configuration files whithin ClickStacks.
*/

public class Metadata {
    public static final String DEFAULT_JAVA_VERSION = "1.7";

    private Map<String, Resource> resources;
    private Map<String, String> environment;
    private Map<String, RuntimeProperty> runtimeProperties;

    /**
     * This constructor is used by the Builder subclass to create a new Metadata instance
     *
     * @param resources         A map of the GenApp resources
     * @param environment       A map of the environment variables
     * @param runtimeProperties A map of RuntimeProperties
     */
    protected Metadata(Map<String, Resource> resources, Map<String, String> environment,
                       Map<String, RuntimeProperty> runtimeProperties) {
        this.resources = resources;
        this.environment = environment;
        this.runtimeProperties = runtimeProperties;
    }

    public Metadata() {
        this.resources = new HashMap<>();
        this.environment = new HashMap<>();
        this.runtimeProperties = new HashMap<>();
    }

    @Nonnull
    public <R extends Resource> R getResource(String resourceName) {
        return (R) resources.get(resourceName);
    }

    @Nonnull
    public Map<String, Resource> getResources() {
        return resources;
    }

    @Nonnull
    public <R extends Resource>  Collection<R> getResources(final Class<R> type) {

        return (Collection<R>) Collections2.filter(resources.values(), new Predicate<Resource>() {
            @Override
            public boolean apply(@Nullable Resource r) {
                return type.isAssignableFrom(r.getClass());
            }
        });
    }

    public String getEnvironmentVariable(String variableName) {
        return environment.get(variableName);
    }

    public Map<String, String> getEnvironment() {
        return environment;
    }

    /**
     * @throws NullPointerException if parent property does not exist
     */
    @Nullable
    public Map<String, String> getRuntimeProperty(String section) {
        RuntimeProperty runtimeProperty = runtimeProperties.get(section);
        if (runtimeProperty == null) {
            return null;
        }
        return runtimeProperty.getParameters();
    }

    @Nullable
    public String getRuntimeParameter(String parent, String propertyName) {
        RuntimeProperty runtimeProperty = runtimeProperties.get(parent);
        if (runtimeProperty == null) {
            return null;
        }
        return runtimeProperty.getParameter(propertyName);
    }

    public String getRuntimeParameter(String parent, String propertyName, String defaultValue) {
        RuntimeProperty runtimeProperty = runtimeProperties.get(parent);
        if (runtimeProperty == null) {
            return defaultValue;
        }
        String value = runtimeProperty.getParameter(propertyName);
        if (value == null) {
            return defaultValue;
        }
        return value;
    }

    public void setRuntimeParameter(String parameter, String value) {
        String section = Strings2.substringBeforeFirst(parameter, '.');
        String property = Strings2.substringAfterFirst(parameter, '.');
        if (section == null) {
            throw new IllegalArgumentException("no key found in '" + parameter + "'");
        }

        if (property == null)
            throw new IllegalArgumentException("no property found in '" + parameter + "'");

        setRuntimeParameter(section, property, value);
    }

    public void setRuntimeParameter(String section, String property, String value) {
        RuntimeProperty runtimeProperty = this.runtimeProperties.get(section);
        if (runtimeProperty == null) {
            runtimeProperty = new RuntimeProperty(section);
            runtimeProperties.put(section, runtimeProperty);
        }
        runtimeProperty.getParameters().put(property, value);
    }

    @Nonnull
    public Path getJavaExecutable() {
        Path javaPath = getJavaHome().resolve("bin/java");
        Preconditions.checkState(Files.exists(javaPath), "Java executable %s does not exist");
        Preconditions.checkState(!Files.isDirectory(javaPath), "Java executable %s is not a file");
        return javaPath;
    }

    @Nonnull
    public Path getJavaHome() {
        String javaVersion = getRuntimeParameter("java", "version", DEFAULT_JAVA_VERSION);
        Map<String, String> javaHomePerVersion = new HashMap<>();
        javaHomePerVersion.put("1.6", "/opt/java6");
        javaHomePerVersion.put("1.7", "/opt/java7");
        javaHomePerVersion.put("1.8", "/opt/java8");

        String javaHome = javaHomePerVersion.get(javaVersion);
        if (javaHome == null) {
            javaHome = javaHomePerVersion.get(DEFAULT_JAVA_VERSION);
        }
        Path javaHomePath = FileSystems.getDefault().getPath(javaHome);
        Preconditions.checkState(Files.exists(javaHomePath), "JavaHome %s does not exist");
        Preconditions.checkState(Files.isDirectory(javaHomePath), "JavaHome %s is not a directory");
        return javaHomePath;
    }



    /**
     * The Builder class creates a new Metadata instance from a metadata.json file.
     */

    public static class Builder {

        /**
         * This method parses a metadata.json file and returns a new Metadata instance containing the
         * metadata that has been parsed.
         *
         * @param metadataFile The absolute path to the metadata.json file to be parsed.
         * @return A new Metadata instance, containing the parameters from the metadata.json file.
         * @throws java.io.IOException
         */
        public static Metadata fromFile(File metadataFile) throws IOException {
            FileInputStream metadataInputStream = new FileInputStream(metadataFile);
            try {
                return fromStream(metadataInputStream);
            } finally {
                metadataInputStream.close();
            }
        }

        public static Metadata fromFile(@Nonnull Path metadataFile) throws IOException {
            if(!Files.exists(metadataFile))
                throw new IllegalArgumentException("Given metadata.json file does not exist: " + metadataFile);
            return fromStream(Files.newInputStream(metadataFile));
        }

        /**
         * This method is called from the fromFile method to parse json from a stream.
         *
         * @param metadataInputStream An InputStream to read the JSON metadata from.
         * @return A new Metadata instance, containing all resources parsed
         *         from the JSON metadata given as input.
         * @throws java.io.IOException
         */
        public static Metadata fromStream(InputStream metadataInputStream) throws IOException {
            ObjectMapper metadataObjectMapper = new ObjectMapper();

            JsonNode metadataRootNode = metadataObjectMapper.readTree(metadataInputStream);

            return fromJson(metadataRootNode);
        }

        /**
         * This method is called from the fromStream method to parse json from a stream.
         *
         * @param metadataRootNode the JSON metadata from.
         * @return A new Metadata instance, containing all resources parsed
         *         from the JSON metadata given as input.
         * @throws java.io.IOException
         */
        public static Metadata fromJson(JsonNode metadataRootNode) throws IOException {

            Builder metadataBuilder = new Builder();

            return metadataBuilder.buildResources(metadataRootNode);
        }

        /**
         * This method is called from the fromStream method to parse json from a stream.
         *
         * @param metadata the JSON metadata.
         * @return A new Metadata instance, containing all resources parsed
         *         from the JSON metadata given as input.
         * @throws java.io.IOException
         */
        public static Metadata fromJsonString(String metadata, boolean allowSingleQuotes) throws IOException {

            ObjectMapper metadataObjectMapper = new ObjectMapper();
            metadataObjectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

            JsonNode metadataRootNode = metadataObjectMapper.readTree(metadata);

            return fromJson(metadataRootNode);
        }

        /**
         * This method is called from the fromStream method to parse JSON metadata into a new Metadata instance.
         *
         * @param metadataRootNode The root node of the JSON metadata to be parsed.
         * @return A new Metadata instance containing all parsed metadata.
         */
        private Metadata buildResources(JsonNode metadataRootNode) {

            Map<String, Resource> resources = new TreeMap<>();
            Map<String, String> environment = new TreeMap<>();
            Map<String, RuntimeProperty> runtimeProperties = new TreeMap<>();

            /**
             *  We iterate over all children of the root node, determining if they're resources,
             *  runtime parameters or are part of the "app" section.
             */
            for (Iterator<Map.Entry<String, JsonNode>> fields = metadataRootNode.fields();
                 fields.hasNext(); ) {

                Map.Entry<String, JsonNode> entry = fields.next();
                JsonNode content = entry.getValue();
                String id = entry.getKey();
                Map<String, String> entryMetadata = new HashMap<>();

                // We then iterate over all the key-value pairs present in the children node, and store them.
                for (Iterator<Map.Entry<String, JsonNode>> properties = content.fields();
                     properties.hasNext(); ) {
                    Map.Entry<String, JsonNode> property = properties.next();
                    String entryName = property.getKey();
                    JsonNode entryValueNode = property.getValue();

                    // We check if the entry is well-formed (i.e can be output to a String meaningfully).
                    if (entryValueNode.isTextual() || entryValueNode.isInt()) {
                        String entryValue = entryValueNode.asText();
                        entryMetadata.put(entryName, entryValue);
                    }

                    // We get environment variables from the metadata when we iterate over app.env
                    if (id.equals("app") && entryName.equals("env")) {
                        for (Iterator<Map.Entry<String, JsonNode>> envVariables = entryValueNode.fields();
                             envVariables.hasNext(); ) {
                            Map.Entry<String, JsonNode> envVariable = envVariables.next();
                            String envName = envVariable.getKey();
                            JsonNode envValue = envVariable.getValue();
                            if (envValue.isTextual()) {
                                environment.put(envName, envValue.asText());
                            }
                        }
                    }
                }

                Resource resource = Resource.Builder.buildResource(entryMetadata);
                // We check if the children node we are currently iterating upon is a resource.
                if (resource != null) {
                    resources.put(resource.getName(), resource);
                    // Otherwise, if it wasn't a resource nor the "app" field, it is composed of runtime parameters.
                } else if (!id.equals("app")) {
                    runtimeProperties.put(id, new RuntimeProperty(id, entryMetadata));
                }
            }
            return new Metadata(resources, environment, runtimeProperties);
        }
    }
}
TOP

Related Classes of com.cloudbees.clickstack.domain.metadata.Metadata

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.