org.apache.brooklyn.entity.machine.pool.ServerPoolLocationResolver.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.brooklyn.entity.machine.pool.ServerPoolLocationResolver.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.entity.machine.pool;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.api.location.Location;
import org.apache.brooklyn.api.location.LocationRegistry;
import org.apache.brooklyn.api.location.LocationSpec;
import org.apache.brooklyn.api.location.LocationResolver.EnableableLocationResolver;
import org.apache.brooklyn.api.mgmt.ManagementContext;
import org.apache.brooklyn.core.location.BasicLocationRegistry;
import org.apache.brooklyn.core.location.LocationPropertiesFromBrooklynProperties;
import org.apache.brooklyn.core.location.dynamic.DynamicLocation;
import org.apache.brooklyn.core.location.internal.LocationInternal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.text.KeyValueParser;
import org.apache.brooklyn.util.text.Strings;

public class ServerPoolLocationResolver implements EnableableLocationResolver {

    private static final Logger LOG = LoggerFactory.getLogger(ServerPoolLocationResolver.class);
    private static final String PREFIX = "pool";
    public static final String POOL_SPEC = PREFIX + ":%s";
    private static final Pattern PATTERN = Pattern
            .compile("(" + PREFIX + "|" + PREFIX.toUpperCase() + ")" + ":([a-zA-Z0-9]+)" + // pool Id
                    "(:\\((.*)\\))?$"); // arguments, e.g. displayName

    private static final Set<String> ACCEPTABLE_ARGS = ImmutableSet.of("name", "displayName");

    private ManagementContext managementContext;

    @Override
    public boolean isEnabled() {
        return true;
    }

    @Override
    public void init(ManagementContext managementContext) {
        this.managementContext = checkNotNull(managementContext, "managementContext");
    }

    @Override
    public String getPrefix() {
        return PREFIX;
    }

    @Override
    public boolean accepts(String spec, LocationRegistry registry) {
        return BasicLocationRegistry.isResolverPrefixForSpec(this, spec, true);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public Location newLocationFromString(Map locationFlags, String spec, LocationRegistry registry) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Resolving location '" + spec + "' with flags "
                    + Joiner.on(",").withKeyValueSeparator("=").join(locationFlags));
        }
        String namedLocation = (String) locationFlags.get(LocationInternal.NAMED_SPEC_NAME.getName());

        Matcher matcher = PATTERN.matcher(spec);
        if (!matcher.matches()) {
            String m = String.format(
                    "Invalid location '%s'; must specify either %s:entityId or %s:entityId:(key=argument)", spec,
                    PREFIX, PREFIX);
            throw new IllegalArgumentException(m);
        }

        String argsPart = matcher.group(4);
        Map<String, String> argsMap = (argsPart != null) ? KeyValueParser.parseMap(argsPart)
                : Collections.<String, String>emptyMap();
        String displayNamePart = argsMap.get("displayName");
        String namePart = argsMap.get("name");

        if (!ACCEPTABLE_ARGS.containsAll(argsMap.keySet())) {
            Set<String> illegalArgs = Sets.difference(argsMap.keySet(), ACCEPTABLE_ARGS);
            throw new IllegalArgumentException("Invalid location '" + spec + "'; illegal args " + illegalArgs
                    + "; acceptable args are " + ACCEPTABLE_ARGS);
        }
        if (argsMap.containsKey("displayName") && Strings.isEmpty(displayNamePart)) {
            throw new IllegalArgumentException(
                    "Invalid location '" + spec + "'; if displayName supplied then value must be non-empty");
        }
        if (argsMap.containsKey("name") && Strings.isEmpty(namePart)) {
            throw new IllegalArgumentException(
                    "Invalid location '" + spec + "'; if name supplied then value must be non-empty");
        }

        Map<String, Object> filteredProperties = new LocationPropertiesFromBrooklynProperties()
                .getLocationProperties(PREFIX, namedLocation, registry.getProperties());
        MutableMap<String, Object> flags = MutableMap.<String, Object>builder().putAll(filteredProperties)
                .putAll(locationFlags).build();

        String poolId = matcher.group(2);
        if (Strings.isBlank(poolId)) {
            throw new IllegalArgumentException(
                    "Invalid location '" + spec + "'; pool's entity id must be non-empty");
        }

        final String displayName = displayNamePart != null ? displayNamePart : "Server Pool " + poolId;
        final String locationName = namePart != null ? namePart : "serverpool-" + poolId;

        Entity pool = managementContext.getEntityManager().getEntity(poolId);
        LocationSpec<ServerPoolLocation> locationSpec = LocationSpec.create(ServerPoolLocation.class)
                .configure(flags).configure(DynamicLocation.OWNER, pool)
                .configure(LocationInternal.NAMED_SPEC_NAME, locationName).displayName(displayName);
        return managementContext.getLocationManager().createLocation(locationSpec);
    }

}