Package com.couchbase.client.vbucket.config

Source Code of com.couchbase.client.vbucket.config.DefaultConfigFactory

/**
* Copyright (C) 2009-2013 Couchbase, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING
* IN THE SOFTWARE.
*/

package com.couchbase.client.vbucket.config;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import net.spy.memcached.HashAlgorithm;
import net.spy.memcached.HashAlgorithmRegistry;
import net.spy.memcached.compat.SpyObject;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

/**
* A DefaultConfigFactory.
*/
public class DefaultConfigFactory extends SpyObject implements ConfigFactory {

  @Override
  public Config create(File filename) {
    if (filename == null || "".equals(filename.getName())) {
      throw new IllegalArgumentException("Filename is empty.");
    }
    StringBuilder sb = new StringBuilder();
    try {
      FileInputStream fis = new FileInputStream(filename);
      BufferedReader reader = new BufferedReader(new InputStreamReader(fis));
      String str;
      while ((str = reader.readLine()) != null) {
        sb.append(str);
      }
    } catch (IOException e) {
      throw new ConfigParsingException("Exception reading input file: "
          + filename, e);
    }
    return create(sb.toString());
  }

  @Override
  public Config create(String data) {
    try {
      JSONObject jsonObject = new JSONObject(data);
      return parseJSON(jsonObject);
    } catch (JSONException e) {
      throw new ConfigParsingException("Exception parsing JSON data: " + data,
        e);
    }
  }

  @Override
  public Config create(JSONObject jsonObject) {
    try {
      return parseJSON(jsonObject);
    } catch (JSONException e) {
      throw new ConfigParsingException("Exception parsing JSON data: "
        + jsonObject, e);
    }
  }

  private Config parseJSON(JSONObject jsonObject) throws JSONException {
    // the incoming config could be cache or EP object types, JSON envelope
    // picked apart
    if (!jsonObject.has("vBucketServerMap")) {
      return parseCacheJSON(jsonObject);
    }
    return parseEpJSON(jsonObject);
  }

  private Config parseCacheJSON(JSONObject jsonObject) throws JSONException {

    JSONArray nodes = jsonObject.getJSONArray("nodes");
    if (nodes.length() <= 0) {
      throw new ConfigParsingException("Empty nodes list.");
    }
    int serversCount = nodes.length();

    CacheConfig config = new CacheConfig(serversCount);
    populateServers(config, nodes);

    return config;
  }

  /* ep is for ep-engine, a.k.a. couchbase */
  private Config parseEpJSON(JSONObject jsonObject) throws JSONException {
    JSONObject vbMap = jsonObject.getJSONObject("vBucketServerMap");
    String algorithm = vbMap.getString("hashAlgorithm");
    HashAlgorithm hashAlgorithm =
        HashAlgorithmRegistry.lookupHashAlgorithm(algorithm);
    if (hashAlgorithm == null) {
      throw new IllegalArgumentException("Unhandled hash algorithm type: "
          + algorithm);
    }
    int replicasCount = vbMap.getInt("numReplicas");
    if (replicasCount > VBucket.MAX_REPLICAS) {
      throw new ConfigParsingException("Expected number <= "
          + VBucket.MAX_REPLICAS + " for replicas.");
    }
    JSONArray servers = vbMap.getJSONArray("serverList");
    if (servers.length() <= 0) {
      throw new ConfigParsingException("Empty servers list.");
    }
    int serversCount = servers.length();
    JSONArray vbuckets = vbMap.getJSONArray("vBucketMap");
    int vbucketsCount = vbuckets.length();
    if (vbucketsCount == 0 || (vbucketsCount & (vbucketsCount - 1)) != 0) {
      throw new ConfigParsingException("Number of vBuckets must be a power of "
        + "two, > 0 and <= " + VBucket.MAX_BUCKETS);
    }
    List<String> populateServers = populateServers(servers);
    List<VBucket> populateVbuckets = populateVbuckets(vbuckets);

    List<URL> couchServers =
      populateCouchServers(jsonObject.getJSONArray("nodes"));

    DefaultConfig config = new DefaultConfig(hashAlgorithm, serversCount,
      replicasCount, vbucketsCount, populateServers, populateVbuckets,
      couchServers);

    return config;
  }

  private List<URL> populateCouchServers(JSONArray nodes) throws JSONException{
    List<URL> nodeNames = new ArrayList<URL>();
    for (int i = 0; i < nodes.length(); i++) {
      JSONObject node = nodes.getJSONObject(i);
      if (node.has("couchApiBase")) {
        try {
          nodeNames.add(new URL(node.getString("couchApiBase")));
        } catch (MalformedURLException e) {
          throw new JSONException("Got bad couchApiBase URL from config");
        }
      }
    }
    return nodeNames;
  }

  private List<String> populateServers(JSONArray servers) throws JSONException {
    List<String> serverNames = new ArrayList<String>();
    for (int i = 0; i < servers.length(); i++) {
      String server = servers.getString(i);
      serverNames.add(server);
    }
    return serverNames;
  }

  private void populateServers(CacheConfig config, JSONArray nodes)
    throws JSONException {
    List<String> serverNames = new ArrayList<String>();
    for (int i = 0; i < nodes.length(); i++) {
      JSONObject node = nodes.getJSONObject(i);
      String webHostPort = node.getString("hostname");
      String[] splitHostPort = webHostPort.split(":");
      JSONObject portsList = node.getJSONObject("ports");
      int port = portsList.getInt("direct");
      serverNames.add(splitHostPort[0] + ":" + port);
    }
    config.setServers(serverNames);
  }

  private List<VBucket> populateVbuckets(JSONArray jsonVbuckets)
    throws JSONException {
    List<VBucket> vBuckets = new ArrayList<VBucket>();
    for (int i = 0; i < jsonVbuckets.length(); i++) {
      JSONArray rows = jsonVbuckets.getJSONArray(i);
      int master = rows.getInt(0);
      int[] replicas = new int[VBucket.MAX_REPLICAS];
      for (int j = 1; j < rows.length(); j++) {
        replicas[j - 1] = rows.getInt(j);
      }
      vBuckets.add(new VBucket(master, replicas));
    }
    return vBuckets;
  }
}
TOP

Related Classes of com.couchbase.client.vbucket.config.DefaultConfigFactory

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.