Package com.netflix.paas.cassandra.provider.impl

Source Code of com.netflix.paas.cassandra.provider.impl.DefaultKeyspaceClientProvider$KeyspaceContextHolder

/*******************************************************************************
* /***
*  *
*  *  Copyright 2013 Netflix, 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.netflix.paas.cassandra.provider.impl;

import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

import org.apache.commons.configuration.AbstractConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
import com.netflix.astyanax.AstyanaxContext;
import com.netflix.astyanax.Keyspace;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.thrift.ThriftFamilyFactory;
import com.netflix.paas.cassandra.keys.KeyspaceKey;
import com.netflix.paas.cassandra.provider.AstyanaxConfigurationProvider;
import com.netflix.paas.cassandra.provider.AstyanaxConnectionPoolConfigurationProvider;
import com.netflix.paas.cassandra.provider.AstyanaxConnectionPoolMonitorProvider;
import com.netflix.paas.cassandra.provider.HostSupplierProvider;
import com.netflix.paas.cassandra.provider.KeyspaceClientProvider;

public class DefaultKeyspaceClientProvider implements KeyspaceClientProvider {
    private static final Logger LOG = LoggerFactory.getLogger(DefaultKeyspaceClientProvider.class);
   
    private static final String DISCOVERY_TYPE_FORMAT = "com.netflix.paas.schema.%s.discovery";
    private static final String CLUSTER_NAME_FORMAT   = "com.netflix.paas.schema.%s.cluster";
    private static final String KEYSPACE_NAME__FORMAT = "com.netflix.paas.schema.%s.keyspace";
    ImmutableMap<String, Object> defaultKsOptions = ImmutableMap.<String, Object>builder()
            .put("strategy_options", ImmutableMap.<String, Object>builder()
                    .put("replication_factor", "1")
                    .build())
            .put("strategy_class",     "SimpleStrategy")
            .build();

    public static class KeyspaceContextHolder {
        private AstyanaxContext<Keyspace> context;
        private AtomicLong refCount = new AtomicLong(0);
       
        public KeyspaceContextHolder(AstyanaxContext<Keyspace> context) {
            this.context = context;
        }
       
        public Keyspace getKeyspace() {
            return context.getClient();
        }
       
        public void start() {
            context.start();
        }
       
        public void shutdown() {
            context.shutdown();
        }
       
        public long addRef() {
            return refCount.incrementAndGet();
        }
       
        public long releaseRef() {
            return refCount.decrementAndGet();
        }
    }
   
    private final Map<String, KeyspaceContextHolder> contextMap = Maps.newHashMap();
   
    private final AstyanaxConfigurationProvider               configurationProvider;
    private final AstyanaxConnectionPoolConfigurationProvider cpProvider;
    private final AstyanaxConnectionPoolMonitorProvider       monitorProvider;
    private final Map<String, HostSupplierProvider>           hostSupplierProviders;
    private final AbstractConfiguration                       configuration;
   
    @Inject
    public DefaultKeyspaceClientProvider(
            AbstractConfiguration                       configuration,
            Map<String, HostSupplierProvider>           hostSupplierProviders,
            AstyanaxConfigurationProvider               configurationProvider,
            AstyanaxConnectionPoolConfigurationProvider cpProvider,
            AstyanaxConnectionPoolMonitorProvider       monitorProvider) {
        this.configurationProvider = configurationProvider;
        this.cpProvider            = cpProvider;
        this.monitorProvider       = monitorProvider;
        this.hostSupplierProviders = hostSupplierProviders;
        this.configuration         = configuration;
    }
   
    @Override
    public synchronized Keyspace acquireKeyspace(String schemaName) {
        schemaName = schemaName.toLowerCase();
       
        Preconditions.checkNotNull(schemaName, "Invalid schema name 'null'");
       
        KeyspaceContextHolder holder = contextMap.get(schemaName);
        if (holder == null) {
            LOG.info("Creating schema for '{}'", new Object[]{schemaName});
           
            String clusterName   = configuration.getString(String.format(CLUSTER_NAME_FORMAT,   schemaName));
            String keyspaceName  = configuration.getString(String.format(KEYSPACE_NAME__FORMAT, schemaName));
            String discoveryType = configuration.getString(String.format(DISCOVERY_TYPE_FORMAT, schemaName));
            if (clusterName==null || clusterName.equals("")) clusterName   = configuration.getString(String.format(CLUSTER_NAME_FORMAT,   "configuration"));
            if (keyspaceName == null || keyspaceName.equals("")) keyspaceName = schemaName;
            if (discoveryType==null || discoveryType.equals("")) discoveryType = configuration.getString(String.format(DISCOVERY_TYPE_FORMAT, "configuration"));
            Preconditions.checkNotNull(clusterName,   "Missing cluster name for schema " + schemaName + " " + String.format(CLUSTER_NAME_FORMAT,schemaName));
            Preconditions.checkNotNull(keyspaceName,  "Missing cluster name for schema " + schemaName + " " + String.format(KEYSPACE_NAME__FORMAT,schemaName));
            Preconditions.checkNotNull(discoveryType, "Missing cluster name for schema " + schemaName + " " + String.format(DISCOVERY_TYPE_FORMAT,schemaName));
           
            HostSupplierProvider hostSupplierProvider = hostSupplierProviders.get(discoveryType);
            Preconditions.checkNotNull(hostSupplierProvider,
                    String.format("Unknown host supplier provider '%s' for schema '%s'", discoveryType, schemaName));
           
            AstyanaxContext<Keyspace> context = new AstyanaxContext.Builder()
                .forCluster(clusterName)
                .forKeyspace(keyspaceName)
                .withAstyanaxConfiguration(configurationProvider.get(schemaName))
                .withConnectionPoolConfiguration(cpProvider.get(schemaName))
                .withConnectionPoolMonitor(monitorProvider.get(schemaName))
                .withHostSupplier(hostSupplierProvider.getSupplier(clusterName))
                .buildKeyspace(ThriftFamilyFactory.getInstance());
            context.start();
            try {
                context.getClient().createKeyspace(defaultKsOptions);
            } catch (ConnectionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            holder = new KeyspaceContextHolder(context);
            contextMap.put(schemaName, holder);
            holder.start();
        }
        holder.addRef();
       
        return holder.getKeyspace();
    }

    @Override
    public synchronized void releaseKeyspace(String schemaName) {
        KeyspaceContextHolder holder = contextMap.get(schemaName);
        if (holder.releaseRef() == 0) {
            contextMap.remove(schemaName);
            holder.shutdown();
        }
    }

    @Override
    public Keyspace acquireKeyspace(KeyspaceKey key) {
        String schemaName = key.getSchemaName().toLowerCase();
       
        Preconditions.checkNotNull(schemaName, "Invalid schema name 'null'");
       
        KeyspaceContextHolder holder = contextMap.get(schemaName);
        if (holder == null) {
            Preconditions.checkNotNull(key.getClusterName(),   "Missing cluster name for schema " + schemaName);
            Preconditions.checkNotNull(key.getKeyspaceName()"Missing cluster name for schema " + schemaName);
            Preconditions.checkNotNull(key.getDiscoveryType(), "Missing cluster name for schema " + schemaName);
           
            HostSupplierProvider hostSupplierProvider = hostSupplierProviders.get(key.getDiscoveryType());
            Preconditions.checkNotNull(hostSupplierProvider, "Unknown host supplier provider " + key.getDiscoveryType());
           
            AstyanaxContext<Keyspace> context = new AstyanaxContext.Builder()
                .forCluster(key.getClusterName())
                .forKeyspace(key.getKeyspaceName())
                .withAstyanaxConfiguration(configurationProvider.get(schemaName))
                .withConnectionPoolConfiguration(cpProvider.get(schemaName))
                .withConnectionPoolMonitor(monitorProvider.get(schemaName))
                .withHostSupplier(hostSupplierProvider.getSupplier(key.getClusterName()))
                .buildKeyspace(ThriftFamilyFactory.getInstance());
           
            holder = new KeyspaceContextHolder(context);
            contextMap.put(schemaName, holder);
            holder.start();
        }
        holder.addRef();
       
        return holder.getKeyspace();
    }
}
TOP

Related Classes of com.netflix.paas.cassandra.provider.impl.DefaultKeyspaceClientProvider$KeyspaceContextHolder

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.