Package com.linkedin.databus.util

Source Code of com.linkedin.databus.util.SchemaMetaDataManager

package com.linkedin.databus.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import com.linkedin.databus.core.data_model.LogicalSource;
import com.linkedin.databus.core.util.IdNamePair;
import com.linkedin.databus2.core.DatabusException;
import com.linkedin.databus2.schemas.SourceIdNameRegistry;


/**
*
* This Class manages 2 meta files and is responsible for generating SourceIds for new sources.
*
* physical_logical_src_map.json :
*    This is an json map containing mapping between schema name and the list of logical sources that are databusified
*    eg:   "slink" : [ "com.linkedin.events.slink.Shortlinks" ],
*
*
* idToName.map :
*    This file contains mapping from sourceId to logical source names
*     e.g : 2601:com.linkedin.events.slink.Shortlinks
*
*/
public class SchemaMetaDataManager
{
  private Short _maxSrcId = -1;
  private SourceIdNameRegistry _idNameRegistry = new SourceIdNameRegistry();
  private Map<String, TreeSet<String>> _physicalToLogicalSrcMap = null;

  private final String _idNameMapFile;
  private final String _physicalToLogicalSrcMapFile;

  public static final String SRC_ID_NAME_MAP_FILE =  "idToName.map";
  public static final String PHYSICAL_TO_LOGICAL_SRC_MAP_FILE =  "physical_logical_src_map.json";

  public SchemaMetaDataManager(String schemaRegistryLocation) throws IOException
  {
    _idNameMapFile = schemaRegistryLocation + "/" +  SRC_ID_NAME_MAP_FILE;
    _physicalToLogicalSrcMapFile = schemaRegistryLocation + "/" + PHYSICAL_TO_LOGICAL_SRC_MAP_FILE;
    populatePhysicalToLogicalSrcMap();
    populateSrcNameIdMap();
  }

  public void store() throws IOException
  {
    persistPhysicalToLogicalSrcMap();
    persistSrcNameIdMap();
  }

  private void populatePhysicalToLogicalSrcMap() throws IOException
  {
    FileInputStream fStream = null;
    try
    {
      fStream = new FileInputStream(new File(_physicalToLogicalSrcMapFile));

      ObjectMapper m = new ObjectMapper();
      _physicalToLogicalSrcMap = m.readValue(fStream,new TypeReference<TreeMap<String,TreeSet<String>>>(){});
    } finally {
      if ( null != fStream)
        fStream.close();
    }
  }

  private void persistPhysicalToLogicalSrcMap() throws IOException
  {
    ObjectMapper m = new ObjectMapper();
    String str = m.defaultPrettyPrintingWriter().writeValueAsString(_physicalToLogicalSrcMap);
    File tmpFile = File.createTempFile("phyToLogicalSrc", ".json.tmp");

    FileWriter oStream = null;
    try
    {
      oStream = new FileWriter(tmpFile);
      oStream.append(str);
    } finally {
      if ( null != oStream)
        oStream.close();
    }
    File destFile = new File(_physicalToLogicalSrcMapFile);
    boolean success = tmpFile.renameTo(destFile);

    if  ( ! success )
      throw new RuntimeException("Unable to persist the mapping json file !!");
  }

  private void populateSrcNameIdMap()
    throws IOException
  {
    int ln = 0;
    File file = new File(_idNameMapFile);
    BufferedReader reader = null;

    try
    {
      reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

      String line = null;
      List<IdNamePair> pairCollection = new ArrayList<IdNamePair>();
      Set<String> srcNames = new HashSet<String>();
      Set<Short> srcIds = new HashSet<Short>();

      while ( (line = reader.readLine()) != null)
      {
        line = line.trim();
        ln++;

        // omit  comments
        if (line.startsWith("#"))
          continue;

        // if line has comments elsewhere, omit comtents to the right of it.
        String[] parts = line.split("#");
        line = parts[0];

        String[] toks = line.split(":");

        if (toks.length != 2)
          throw new RuntimeException("SrcIdToName map file (" + file + ") is corrupted at line number :" + ln);

        short srcId = new Short(toks[0]);
        String srcName = toks[1];
        _maxSrcId = (short)Math.max(_maxSrcId, srcId);
        if (srcIds.contains(srcId))
        {
          throw new RuntimeException("Duplicate SrcId (" + srcId + ") present in the file :" + _idNameMapFile);
        } else if (srcNames.contains(srcName)) {
          throw new RuntimeException("Duplicate Source name (" + srcName + ") present in the file :" + _idNameMapFile);
        }
        srcIds.add(srcId);
        srcNames.add(srcName);
        pairCollection.add(new IdNamePair(Long.valueOf(srcId), srcName));
      }
      _idNameRegistry.updateFromIdNamePairs(pairCollection);
    } finally {
      if ( null != reader)
        reader.close();
    }
  }

  private void persistSrcNameIdMap() throws IOException
  {
    File tmpFile = File.createTempFile("srcIdToName", ".map.tmp");

    FileWriter oStream = null;

    try
    {
      oStream = new FileWriter(tmpFile);

      TreeSet<LogicalSource>  srcs = new TreeSet<LogicalSource>(new Comparator<LogicalSource>()
          {

        @Override
        public int compare(LogicalSource o1, LogicalSource o2)
        {
          return o1.getId().compareTo(o2.getId());
        }
          });

      srcs.addAll(_idNameRegistry.getAllSources());

      for(LogicalSource k : srcs)
      {
        oStream.append(k.getId().toString());
        oStream.append(":");
        oStream.append(k.getName());
        oStream.append("\n");
      }
    } finally {
      if (null != oStream)
        oStream.close();
    }
    File destFile = new File(_idNameMapFile);
    boolean success = tmpFile.renameTo(destFile);

    if  ( ! success )
      throw new RuntimeException("Unable to persist the mapping file !!");
  }

  public short updateAndGetNewSrcId(String dbName, String srcName)
     throws DatabusException
  {
    _maxSrcId++;

    dbName = dbName.toLowerCase(Locale.ENGLISH);

    if ( null != _idNameRegistry.getSource(srcName))
      throw new DatabusException("Source Name (" + srcName + ") already available in the schema registry !!");

    TreeSet<String> s = null;
    if (_physicalToLogicalSrcMap.containsKey(dbName))
    {
       s = _physicalToLogicalSrcMap.get(dbName);
    } else {
      s = new TreeSet<String>();
      _physicalToLogicalSrcMap.put(dbName,s);
    }

    s.add(srcName);
    IdNamePair pair = new IdNamePair(Long.valueOf(_maxSrcId), srcName);
    LogicalSource src = new LogicalSource(pair);
    List<LogicalSource> newSources = new ArrayList<LogicalSource>();
    newSources.add(src);
    _idNameRegistry.add(newSources);

    return _maxSrcId;
  }

  public List<String> getManagedSourcesForDB(String db)
  {
     Set<String> srcs =  _physicalToLogicalSrcMap.get(db);

     if ( null == srcs)
       return null;

     List<String> srcNames  = new ArrayList<String>(srcs);

     Collections.sort(srcNames, new Comparator<String>() {
         @Override
         public int compare(String o1, String o2)
         {
           Integer srcId1 = _idNameRegistry.getSourceId(o1);
           Integer srcId2 = _idNameRegistry.getSourceId(o2);

           return srcId1.compareTo(srcId2);
         }
       });

     return srcNames;
  }

  public short getSrcId(String srcName)
  {
    LogicalSource src = _idNameRegistry.getSource(srcName);

    if (src != null)
      return src.getId().shortValue();

    throw new RuntimeException("Unable to find the source id for the source name (" + srcName + ")");
  }

  public Map<String, TreeSet<String>> getDbToSrcMap()
  {
    return _physicalToLogicalSrcMap;
  }
}
TOP

Related Classes of com.linkedin.databus.util.SchemaMetaDataManager

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.