org.apache.brooklyn.rest.resources.EntityConfigResource.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.brooklyn.rest.resources.EntityConfigResource.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.resources;

import static com.google.common.collect.Iterables.transform;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.config.BasicConfigKey;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.entity.EntityInternal;
import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
import org.apache.brooklyn.rest.api.EntityConfigApi;
import org.apache.brooklyn.rest.domain.EntityConfigSummary;
import org.apache.brooklyn.rest.filter.HaHotStateRequired;
import org.apache.brooklyn.rest.transform.EntityTransformer;
import org.apache.brooklyn.rest.util.WebResourceUtils;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.core.task.ValueResolver;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

@HaHotStateRequired
public class EntityConfigResource extends AbstractBrooklynRestResource implements EntityConfigApi {

    private static final Logger LOG = LoggerFactory.getLogger(EntityConfigResource.class);

    @Override
    public List<EntityConfigSummary> list(final String application, final String entityToken) {
        final Entity entity = brooklyn().getEntity(application, entityToken);
        // TODO merge with keys which have values
        return Lists.newArrayList(transform(entity.getEntityType().getConfigKeys(),
                new Function<ConfigKey<?>, EntityConfigSummary>() {
                    @Override
                    public EntityConfigSummary apply(ConfigKey<?> config) {
                        return EntityTransformer.entityConfigSummary(entity, config);
                    }
                }));
    }

    // TODO support parameters  ?show=value,summary&name=xxx &format={string,json,xml}
    // (and in sensors class)
    @Override
    public Map<String, Object> batchConfigRead(String application, String entityToken, Boolean raw) {
        // TODO: add test
        Entity entity = brooklyn().getEntity(application, entityToken);
        // wrap in a task for better runtime view
        return Entities.submit(entity, Tasks.<Map<String, Object>>builder()
                .displayName("REST API batch config read").body(new BatchConfigRead(this, entity, raw)).build())
                .getUnchecked();
    }

    private static class BatchConfigRead implements Callable<Map<String, Object>> {
        private EntityConfigResource resource;
        private Entity entity;
        private Boolean raw;

        public BatchConfigRead(EntityConfigResource resource, Entity entity, Boolean raw) {
            this.resource = resource;
            this.entity = entity;
            this.raw = raw;
        }

        @Override
        public Map<String, Object> call() throws Exception {
            Map<ConfigKey<?>, ?> source = ((EntityInternal) entity).config().getBag().getAllConfigAsConfigKeyMap();
            Map<String, Object> result = Maps.newLinkedHashMap();
            for (Map.Entry<ConfigKey<?>, ?> ek : source.entrySet()) {
                Object value = ek.getValue();
                result.put(ek.getKey().getName(),
                        resource.resolving(value).preferJson(true).asJerseyOutermostReturnValue(false).raw(raw)
                                .context(entity).timeout(Duration.ZERO).renderAs(ek.getKey()).resolve());
            }
            return result;
        }
    }

    @Override
    public Object get(String application, String entityToken, String configKeyName, Boolean raw) {
        return get(true, application, entityToken, configKeyName, raw);
    }

    @Override
    public String getPlain(String application, String entityToken, String configKeyName, Boolean raw) {
        return Strings.toString(get(false, application, entityToken, configKeyName, raw));
    }

    public Object get(boolean preferJson, String application, String entityToken, String configKeyName,
            Boolean raw) {
        Entity entity = brooklyn().getEntity(application, entityToken);
        ConfigKey<?> ck = findConfig(entity, configKeyName);
        Object value = ((EntityInternal) entity).config().getRaw(ck).orNull();
        return resolving(value).preferJson(preferJson).asJerseyOutermostReturnValue(true).raw(raw).context(entity)
                .timeout(ValueResolver.PRETTY_QUICK_WAIT).renderAs(ck).resolve();
    }

    private ConfigKey<?> findConfig(Entity entity, String configKeyName) {
        ConfigKey<?> ck = entity.getEntityType().getConfigKey(configKeyName);
        if (ck == null)
            ck = new BasicConfigKey<Object>(Object.class, configKeyName);
        return ck;
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public void setFromMap(String application, String entityToken, Boolean recurse, Map newValues) {
        final Entity entity = brooklyn().getEntity(application, entityToken);
        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
            throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify entity '%s'",
                    Entitlements.getEntitlementContext().user(), entity);
        }

        if (LOG.isDebugEnabled())
            LOG.debug("REST user " + Entitlements.getEntitlementContext() + " setting configs " + newValues);
        for (Object entry : newValues.entrySet()) {
            String configName = Strings.toString(((Map.Entry) entry).getKey());
            Object newValue = ((Map.Entry) entry).getValue();

            ConfigKey ck = findConfig(entity, configName);
            ((EntityInternal) entity).config().set(ck, TypeCoercions.coerce(newValue, ck.getTypeToken()));
            if (Boolean.TRUE.equals(recurse)) {
                for (Entity e2 : Entities.descendants(entity, Predicates.alwaysTrue(), false)) {
                    ((EntityInternal) e2).config().set(ck, newValue);
                }
            }
        }
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public void set(String application, String entityToken, String configName, Boolean recurse, Object newValue) {
        final Entity entity = brooklyn().getEntity(application, entityToken);
        if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
            throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify entity '%s'",
                    Entitlements.getEntitlementContext().user(), entity);
        }

        ConfigKey ck = findConfig(entity, configName);
        LOG.debug("REST setting config " + configName + " on " + entity + " to " + newValue);
        ((EntityInternal) entity).config().set(ck, TypeCoercions.coerce(newValue, ck.getTypeToken()));
        if (Boolean.TRUE.equals(recurse)) {
            for (Entity e2 : Entities.descendants(entity, Predicates.alwaysTrue(), false)) {
                ((EntityInternal) e2).config().set(ck, newValue);
            }
        }
    }
}