Package com.linkedin.databus.client.registration

Source Code of com.linkedin.databus.client.registration.RegistrationIdGenerator

package com.linkedin.databus.client.registration;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* 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.
*
*/


import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import org.apache.commons.codec.binary.Hex;
import org.apache.log4j.Logger;

import com.linkedin.databus.client.pub.RegistrationId;
import com.linkedin.databus.core.data_model.DatabusSubscription;

public class RegistrationIdGenerator
{
    public static final Logger LOG = Logger.getLogger(RegistrationIdGenerator.class);

  /**
   * Database of Ids for registrations created so far
   */
  private static Set<String> _registrationIdDatabase;
  static {
    _registrationIdDatabase = new HashSet<String>();
  }

  /**
   * Queries the existing database of registrations inside the client and generates a new id different from
   * any of them
   *
   * @param prefix : A String prefix which can be specified to precede the id to be generated. Typically this
   *                 is the name of the Consumer class
   * @param subsSources : List of subscriptions the consumer is interested in
   * @return RegistrationId : Generated based on the prefix _ 8 byte md5 hash ( subscriptions ) _ count
   */
  public static RegistrationId generateNewId(String prefix, Collection<DatabusSubscription> subsSources)
  {
    StringBuilder subscription = new StringBuilder();
    for (DatabusSubscription ds : subsSources)
    {
      if (ds != null)
        subscription.append(ds.generateSubscriptionString());
    }

    String id = generateUniqueString(prefix, subscription.toString());
    RegistrationId rid = new RegistrationId(id);
    return rid;
  }

  /**
   * For a given regId , this API queries the existing database of registrations inside the client.
   * If the id is available, it is returned as a registration id, otherwise a running counter
   * is appended to the suggested regId.
   *
   * @param id : A suggested name by the caller to be used as regId. If the id is not available, a running counter
   *             is appended
   * @return RegistrationId : Generated based on the id _count
   */
  public static RegistrationId generateNewId(String id)
  {
    String r = generateUniqueString(id);
    RegistrationId rid = new RegistrationId(r);
    return rid;
  }

  /**
   * Checks if the input rid can be used as a RegistrationId.
   * Specifically, checks to see if the underlying id is already in use
   * @return
   */
  public static boolean isIdValid(RegistrationId rid)
  {
    String id = rid.getId();
    synchronized (RegistrationIdGenerator.class)
    {
        if (_registrationIdDatabase.contains(id))
        {
          return false;
        }
        else
        {
          return true;
        }
    }
  }

  /**
   * Adds an id into the RegistrationId database.
   * This is useful for unit-testing / inserting an id out-of-band into the database, so that such an id
   * would not get generated again
   *
   * @param id
   */
  public static void insertId(RegistrationId rid)
  {
    String id = rid.getId();
    synchronized (RegistrationIdGenerator.class)
    {
      _registrationIdDatabase.add(id);
    }
  }

  /**
   * Creates a unique string given a prefix ( which must appear as is ), a subscription string ( which is converted
   * to an 8 byte string ) and a count if there are duplicates with the previous two
   */
  private static String generateUniqueString(String prefix, String subscription)
  {
    final String delimiter = "_";
    String baseId = prefix + delimiter + generateByteHash(subscription);
   
    return generateUniqueString(baseId);
  }
 
  /**
   * Creates a unique registration Id string given an id.
   * A running counter is appended if there are duplicates
   */
  private static String generateUniqueString(String id)
  {
    final String delimiter = "_";
    String baseId = id;
   
    boolean success = false;
    boolean debugEnabled = LOG.isDebugEnabled();
    synchronized (RegistrationIdGenerator.class)
        {
          int count = _registrationIdDatabase.size();
        while (! success)
        {
          if (_registrationIdDatabase.contains(id))
          {
            if (debugEnabled)
              LOG.debug("The generated id " + id + " already exists. Retrying ...");
                    id = baseId + delimiter + count;
            count++;
          }
          else
          {
            if (debugEnabled)
              LOG.debug("Obtained a new ID " + id);
            _registrationIdDatabase.add(id);
            success = true;
          }
        }
        }
    return id;
  }

  /**
   * Generate a hash out of the String id
   *
   * @param id
   * @return
   */
  private static String generateByteHash(String id)
  {
    try {
      final MessageDigest messageDigest = MessageDigest.getInstance("MD5");
      messageDigest.reset();
      messageDigest.update(id.getBytes(Charset.forName("UTF8")));
      final byte[] resultsByte = messageDigest.digest();
      String hash = new String(Hex.encodeHex(resultsByte));

      final int length = 8;
      if (hash.length() > length)
        hash = hash.substring(0, length);

      return hash;
    }
    catch (NoSuchAlgorithmException nse)
    {
      LOG.error("Unexpected error : Got NoSuchAlgorithm exception for MD5" );
      return "";
    }
  }

}
TOP

Related Classes of com.linkedin.databus.client.registration.RegistrationIdGenerator

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.