org.apache.brooklyn.rest.transform.CatalogTransformer.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.brooklyn.rest.transform.CatalogTransformer.java

Source

/*
 * 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.brooklyn.rest.transform;

import java.net.URI;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.brooklyn.api.catalog.CatalogItem;
import org.apache.brooklyn.api.catalog.CatalogItem.CatalogItemType;
import org.apache.brooklyn.api.effector.Effector;
import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.entity.EntitySpec;
import org.apache.brooklyn.api.entity.EntityType;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.objs.SpecParameter;
import org.apache.brooklyn.api.policy.Policy;
import org.apache.brooklyn.api.policy.PolicySpec;
import org.apache.brooklyn.api.sensor.Sensor;
import org.apache.brooklyn.core.entity.EntityDynamicType;
import org.apache.brooklyn.core.mgmt.BrooklynTags;
import org.apache.brooklyn.core.objs.BrooklynTypes;
import org.apache.brooklyn.rest.domain.CatalogEntitySummary;
import org.apache.brooklyn.rest.domain.CatalogItemSummary;
import org.apache.brooklyn.rest.domain.CatalogLocationSummary;
import org.apache.brooklyn.rest.domain.CatalogPolicySummary;
import org.apache.brooklyn.rest.domain.EffectorSummary;
import org.apache.brooklyn.rest.domain.EntityConfigSummary;
import org.apache.brooklyn.rest.domain.LocationConfigSummary;
import org.apache.brooklyn.rest.domain.PolicyConfigSummary;
import org.apache.brooklyn.rest.domain.SensorSummary;
import org.apache.brooklyn.rest.domain.SummaryComparators;
import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.collections.MutableSet;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.javalang.Reflections;
import org.slf4j.LoggerFactory;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

public class CatalogTransformer {

    private static final org.slf4j.Logger log = LoggerFactory.getLogger(CatalogTransformer.class);

    public static <T extends Entity> CatalogEntitySummary catalogEntitySummary(BrooklynRestResourceUtils b,
            CatalogItem<T, EntitySpec<? extends T>> item) {
        Set<EntityConfigSummary> config = Sets.newLinkedHashSet();
        Set<SensorSummary> sensors = Sets.newTreeSet(SummaryComparators.nameComparator());
        Set<EffectorSummary> effectors = Sets.newTreeSet(SummaryComparators.nameComparator());

        EntitySpec<?> spec = null;
        try {
            @SuppressWarnings({ "unchecked", "rawtypes" })
            // the raw type isn't needed according to eclipse IDE, but jenkins maven fails without it;
            // must be a java version or compiler thing. don't remove even though it looks okay without it!
            EntitySpec<?> specRaw = (EntitySpec<?>) b.getCatalog().createSpec((CatalogItem) item);
            spec = specRaw;
            EntityDynamicType typeMap = BrooklynTypes.getDefinedEntityType(spec.getType());
            EntityType type = typeMap.getSnapshot();

            AtomicInteger paramPriorityCnt = new AtomicInteger();
            for (SpecParameter<?> input : spec.getParameters()) {
                config.add(EntityTransformer.entityConfigSummary(input, paramPriorityCnt));
                if (input.getSensor() != null)
                    sensors.add(SensorTransformer.sensorSummaryForCatalog(input.getSensor()));
            }
            for (Sensor<?> x : type.getSensors())
                sensors.add(SensorTransformer.sensorSummaryForCatalog(x));
            for (Effector<?> x : type.getEffectors())
                effectors.add(EffectorTransformer.effectorSummaryForCatalog(x));

        } catch (Exception e) {
            Exceptions.propagateIfFatal(e);

            // templates with multiple entities can't have spec created in the manner above; just ignore
            if (item.getCatalogItemType() == CatalogItemType.ENTITY) {
                log.warn("Unable to create spec for " + item + ": " + e, e);
            }
            if (log.isTraceEnabled()) {
                log.trace("Unable to create spec for " + item + ": " + e, e);
            }
        }

        return new CatalogEntitySummary(item.getSymbolicName(), item.getVersion(), item.getDisplayName(),
                item.getJavaType(), item.getPlanYaml(), item.getDescription(),
                tidyIconLink(b, item, item.getIconUrl()), makeTags(spec, item), config, sensors, effectors,
                item.isDeprecated(), makeLinks(item));
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static CatalogItemSummary catalogItemSummary(BrooklynRestResourceUtils b, CatalogItem item) {
        try {
            switch (item.getCatalogItemType()) {
            case TEMPLATE:
            case ENTITY:
                return catalogEntitySummary(b, item);
            case POLICY:
                return catalogPolicySummary(b, item);
            case LOCATION:
                return catalogLocationSummary(b, item);
            default:
                log.warn("Unexpected catalog item type when getting self link (supplying generic item): "
                        + item.getCatalogItemType() + " " + item);
            }
        } catch (Exception e) {
            Exceptions.propagateIfFatal(e);
            log.warn("Invalid item in catalog when converting REST summaries (supplying generic item), at " + item
                    + ": " + e, e);
        }
        return new CatalogItemSummary(item.getSymbolicName(), item.getVersion(), item.getDisplayName(),
                item.getJavaType(), item.getPlanYaml(), item.getDescription(),
                tidyIconLink(b, item, item.getIconUrl()), item.tags().getTags(), item.isDeprecated(),
                makeLinks(item));
    }

    public static CatalogPolicySummary catalogPolicySummary(BrooklynRestResourceUtils b,
            CatalogItem<? extends Policy, PolicySpec<?>> item) {
        Set<PolicyConfigSummary> config = ImmutableSet.of();
        return new CatalogPolicySummary(item.getSymbolicName(), item.getVersion(), item.getDisplayName(),
                item.getJavaType(), item.getPlanYaml(), item.getDescription(),
                tidyIconLink(b, item, item.getIconUrl()), config, item.tags().getTags(), item.isDeprecated(),
                makeLinks(item));
    }

    public static CatalogLocationSummary catalogLocationSummary(BrooklynRestResourceUtils b,
            CatalogItem<? extends Location, LocationSpec<?>> item) {
        Set<LocationConfigSummary> config = ImmutableSet.of();
        return new CatalogLocationSummary(item.getSymbolicName(), item.getVersion(), item.getDisplayName(),
                item.getJavaType(), item.getPlanYaml(), item.getDescription(),
                tidyIconLink(b, item, item.getIconUrl()), config, item.tags().getTags(), item.isDeprecated(),
                makeLinks(item));
    }

    protected static Map<String, URI> makeLinks(CatalogItem<?, ?> item) {
        return MutableMap.<String, URI>of().addIfNotNull("self", URI.create(getSelfLink(item)));
    }

    protected static String getSelfLink(CatalogItem<?, ?> item) {
        String itemId = item.getId();
        switch (item.getCatalogItemType()) {
        case TEMPLATE:
            return "/v1/applications/" + itemId + "/" + item.getVersion();
        case ENTITY:
            return "/v1/entities/" + itemId + "/" + item.getVersion();
        case POLICY:
            return "/v1/policies/" + itemId + "/" + item.getVersion();
        case LOCATION:
            return "/v1/locations/" + itemId + "/" + item.getVersion();
        default:
            log.warn("Unexpected catalog item type when getting self link (not supplying self link): "
                    + item.getCatalogItemType() + " " + item);
            return null;
        }
    }

    private static String tidyIconLink(BrooklynRestResourceUtils b, CatalogItem<?, ?> item, String iconUrl) {
        if (b.isUrlServerSideAndSafe(iconUrl))
            return "/v1/catalog/icon/" + item.getSymbolicName() + "/" + item.getVersion();
        return iconUrl;
    }

    private static Set<Object> makeTags(EntitySpec<?> spec, CatalogItem<?, ?> item) {
        // Combine tags on item with an InterfacesTag.
        Set<Object> tags = MutableSet.copyOf(item.tags().getTags());
        if (spec != null) {
            Class<?> type;
            if (spec.getImplementation() != null) {
                type = spec.getImplementation();
            } else {
                type = spec.getType();
            }
            if (type != null) {
                tags.add(new BrooklynTags.TraitsTag(Reflections.getAllInterfaces(type)));
            }
        }
        return tags;
    }

}