Package com.linkedin.databus2.schemas

Source Code of com.linkedin.databus2.schemas.FileSystemSchemaRegistryService$Config

package com.linkedin.databus2.schemas;
/*
*
* 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.io.File;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;

import org.apache.log4j.Logger;

import com.linkedin.databus.core.DatabusRuntimeException;
import com.linkedin.databus.core.util.ConfigBuilder;
import com.linkedin.databus.core.util.InvalidConfigException;
import com.linkedin.databus2.core.DatabusException;

/**
* Implements a simple {@link SchemaRegistryService} by reading schemas from a directory.
* @author cbotev
*/
public class FileSystemSchemaRegistryService extends VersionedSchemaSetBackedRegistryService
{
  public static final String MODULE = FileSystemSchemaRegistryService.class.getName();
  public static final Logger LOG = Logger.getLogger(MODULE);

  private final FileSystemVersionedSchemaSetProvider _fsSchemaSetProvider;
  private final ResourceVersionedSchemaSetProvider _resourceSchemaSetProvider;
  private final StaticConfig _config;
  private Thread _schemaSetRefreshThread;
  private final AtomicBoolean _stopRefreshThread = new AtomicBoolean();
  private long _lastRefreshTs = -1;

  public static FileSystemSchemaRegistryService build(Config config) throws InvalidConfigException
  {
    return build(config.build());
  }

  public static FileSystemSchemaRegistryService build(StaticConfig config)
  {
    FileSystemSchemaRegistryService service = new FileSystemSchemaRegistryService(config);
    service.initializeSchemaSet();
    if (0 == service.getCurSchemaSet().size())
    {
      throw new DatabusRuntimeException("no schemas loaded; please check the schemas directory: " +
                                        config.getSchemaDir().getAbsolutePath() );
    }

    if (config.getRefreshPeriodMs() > 0)
    {
      service.startSchemasRefreshThread();
    }
    return service;
  }

  private FileSystemSchemaRegistryService(StaticConfig config)
  {
    super();
    _curSchemaSet = new VersionedSchemaSet();
    _fsSchemaSetProvider = new FileSystemVersionedSchemaSetProvider(Arrays.asList(config.getSchemaDir()));
    _resourceSchemaSetProvider = new ResourceVersionedSchemaSetProvider(this.getClass().getClassLoader());
    _schemaSetRefreshThread = null;
    _config = config;
  }

  /**
   * Starts the thread that periodically ({@link Config#getRefreshPeriodMs()} refreshes the schema set.
   * @return true if started
   */
  public boolean startSchemasRefreshThread()
  {
    if (_config.getRefreshPeriodMs() <= 0 || null != _schemaSetRefreshThread)
    {
      return false;
    }
    LOG.info("Starting schema refresh thread");

    _stopRefreshThread.set(false);
    _schemaSetRefreshThread = new Thread(new SchemaSetRefreshThread(), "SchemaRefreshThread");
    _schemaSetRefreshThread.setDaemon(true);
    _schemaSetRefreshThread.start();

    return true;
  }

  public void stopSchemasRefreshThread()
  {
    if (null == _schemaSetRefreshThread) return;

    LOG.info("Stopping schema refresh thread");
    _stopRefreshThread.set(true);
    _schemaSetRefreshThread.interrupt();
    while (_schemaSetRefreshThread.isAlive())
    {
      try
      {
        _schemaSetRefreshThread.join();
      }
      catch (InterruptedException ie) {}
    }
  }

  /**
   * Registers a schema represented by its JSON schema definition. Note that the schema will not be
   * persisted on disk. If there is a schema registered with the same name, it's version will be
   * increased by one.
   *
   * IMPORTANT: If you don't {@link FileSystemSchemaRegistryService#stopSchemasRefreshThread()},
   * the schema will be overwritten.
   */
  @Override
  public void registerSchema(VersionedSchema schema) throws DatabusException
  {
    super.registerSchema(schema);
  }

  private void initializeSchemaSet()
  {
    LOG.info("initializing schema registry");
    refreshSchemaSet();
    if (0 > _lastRefreshTs)
    {
      LOG.info("loading schemas from resources ");
      _curSchemaSet = _resourceSchemaSetProvider.loadSchemas();
      LOG.info("schemas from resources loaded");
    }
  }

  private void refreshSchemaSet()
  {
    LOG.info("refreshing schema registry");
    File schemaDir = _config.getSchemaDir();
    if (!_config.isFallbackToResources() && ! schemaDir.exists())
    {
      LOG.warn("schema dir not found:" + _config.getSchemaDir());
      return;
    }

    if (schemaDir.exists())
    {
      _curSchemaSet = _fsSchemaSetProvider.loadSchemas();
      _lastRefreshTs = System.currentTimeMillis();
    }
    else LOG.info("skipping not existant schema directory: " + schemaDir.getAbsolutePath());
    LOG.info("schema registry refreshed");
  }

  private class SchemaSetRefreshThread implements Runnable
  {

    public SchemaSetRefreshThread()
    {
    }

    @Override
    public void run()
    {
      while (! _stopRefreshThread.get())
      {
        try
        {
          Thread.sleep(_config.getRefreshPeriodMs());
        }
        catch (InterruptedException ie)
        {//do nothing
        }
        refreshSchemaSet();
      }

      LOG.info("Quitting schema refresh thread");
    }

  }

  public static class StaticConfig
  {

    private final File _schemaDir;
    private final long _refreshPeriodMs;
    private final boolean _enabled;
    private final boolean _fallbackToResources;

    public StaticConfig(File schemaDir, long schemasRefreshPeriodMs, boolean enabled,
                        boolean fallbackToResources)
    {
      super();
      _schemaDir = schemaDir;
      _refreshPeriodMs = schemasRefreshPeriodMs;
      _enabled = enabled;
      _fallbackToResources = fallbackToResources;
    }

    public File getSchemaDir()
    {
      return _schemaDir;
    }

    public long getRefreshPeriodMs()
    {
      return _refreshPeriodMs;
    }

    public boolean isEnabled()
    {
      return _enabled;
    }

    /** Try to load schemas from resources if directory is not available. */
    public boolean isFallbackToResources()
    {
      return _fallbackToResources;
    }
  }

  public static class Config implements ConfigBuilder<StaticConfig>
  {
    public static final String DEFAULT_FS_SCHEMA_REGISTRY_PATH = "schemas_registry";
    public static final long DEFAULT_FS_SCHEMA_REGISTRY_REFRESH_MS = 3600000;

    private String _schemaDir;
    private long _refreshPeriodMs;
    private boolean _enabled;
    private boolean _fallbackToResources;

    /** Default constructor. Uses the system properties for initialization. */
    public Config()
    {
      _schemaDir = DEFAULT_FS_SCHEMA_REGISTRY_PATH;
      _refreshPeriodMs = DEFAULT_FS_SCHEMA_REGISTRY_REFRESH_MS;
      _enabled = true;
      _fallbackToResources = true;
    }

    /**
     * Obtains the directory where the schemas are stored.
     * @return the absolute path of the directory
     */
    public String getSchemaDir()
    {
      return _schemaDir;
    }

    /**
     * Changes setting with the directory where the schemas are stored.
     * @param schemaDir         the new setting value
     */
    public void setSchemaDir(String schemaDir)
    {
      _schemaDir = schemaDir;
    }

    /**
     * Obtains the interval at which the schema registry will be synced with the file system.
     * @return the interval in ms
     */
    public long getRefreshPeriodMs()
    {
      return _refreshPeriodMs;
    }

    /**
     * Changes the interval at which the schema registry will be synced with the file system
     * @param schemasRefreshPeriodMs        the interval in ms; a value <= 0 disables the refresh;
     */
    public void setRefreshPeriodMs(long schemasRefreshPeriodMs)
    {
      _refreshPeriodMs = schemasRefreshPeriodMs;
    }

    @Override
    public StaticConfig build() throws InvalidConfigException
    {
      File schemaDirFile = new File(_schemaDir);
      if (_enabled && !_fallbackToResources && ! schemaDirFile.exists())
      {
        throw new InvalidConfigException("Schemas dir not found: " + _schemaDir);
      }
      return new StaticConfig(schemaDirFile, _refreshPeriodMs, _enabled, _fallbackToResources);
    }

    public boolean isEnabled()
    {
      return _enabled;
    }

    public void setEnabled(boolean enabled)
    {
      _enabled = enabled;
    }

    public boolean isFallbackToResources()
    {
      return _fallbackToResources;
    }

    public void setFallbackToResources(boolean fallbackToResources)
    {
      _fallbackToResources = fallbackToResources;
    }
  }

}
TOP

Related Classes of com.linkedin.databus2.schemas.FileSystemSchemaRegistryService$Config

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.