All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fasterxml.clustermate.service.cfg.ServiceConfig Maven / Gradle / Ivy

The newest version!
package com.fasterxml.clustermate.service.cfg;

import java.io.File;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import org.skife.config.TimeSpan;

import com.fasterxml.clustermate.api.RequestPathStrategy;
import com.fasterxml.clustermate.service.store.StoredEntryConverter;
import com.fasterxml.storemate.store.StoreConfig;
import com.fasterxml.storemate.store.backend.StoreBackendBuilder;
import com.fasterxml.storemate.store.backend.StoreBackendConfig;
import com.fasterxml.storemate.store.lastaccess.LastAccessConfig;

/**
 * Configuration Object that ClusterMate-based service uses: either read from
 * a JSON or YAML file, or programmatically constructed.
 * Often aggregated in a container-specific wrapper object (like one used by
 * DropWizard).
 */
public abstract class ServiceConfig
{
    /*
    /**********************************************************************
    /* Service end point registration
    /**********************************************************************
     */

    /**
     * Root path used for registering all the end points of the system,
     * using configurable 
     */
    @NotNull
    public String[] servicePathRoot;

    /**
     * Method to find {@link RequestPathStrategy} used for matching
     * request paths to resources.
     */
    public abstract RequestPathStrategy getServicePathStrategy();
    
    /*
    /**********************************************************************
    /* Cluster configuration
    /**********************************************************************
     */

    /**
     * This is the mandatory definition for local cluster: at minimum, it needs to
     * specify enough information for local node to find out actual definition
     * via end points.
     */
    @NotNull
    @Valid
    public ClusterConfig cluster = new ClusterConfig();

    /**
     * Optional definition of zero or one "remote" cluster, with which nodes
     * of this cluster will synchronize content; but using different sync/pull
     * approach. If left as null or empty, no cluster-to-cluster synchronization
     * occurs; otherwise nodes of this cluster will try to synchronize data from
     * defined remote clusters.
     * Note that definitions between clusters may be asymmetric: that is, it is not
     * necessary for both sides to be pulling content. Leaving this empy on one side
     * will allow read-only, uni-directional synchronization.
     */
    @Valid
    public RemoteClusterConfig remoteCluster;

    /*
    /**********************************************************************
    /* Storage config: StoreMate (single-node storage subsystem) configs
    /**********************************************************************
     */

    /**
     * General configuration for the underlying entry metadata store.
     */
    public StoreConfig storeConfig = new StoreConfig();

    /**
     * Type of the store backend, specified using type of builder
     * for 
     */
    public Class> storeBackendType;
    
    /**
     * Configuration settings for the store backend: specific type depends on
     * backend type (class), and data-binding is done lazily.
     */
    public java.util.Map storeBackendConfig;

    /**
     * Alternatively, instead of "raw" JSON, it is possible to just give overrides
     * for backend. Used by some tests.
     */
    public StoreBackendConfig _storeBackendConfigOverride;
    
    /*
    /**********************************************************************
    /* Storage config: paths
    /**********************************************************************
     */

    /**
     * Directory used for storing service metadata, such as node
     * states, last-accessed timestamps.
     */
    @NotNull
    public File metadataDirectory;

    /*
    /**********************************************************************
    /* Storage config: last-access store
    /**********************************************************************
     */

    /**
     * Configuration of the last-accessed store, where optional
     * last-accessed information is stored (if used).
     */
    public LastAccessConfig lastAccess = new LastAccessConfig();

    /*
    /**********************************************************************
    /* Entry Store behavior
    /**********************************************************************
     */
    
    /**
     * Configuration setting that determines whether it is legal to
     * re-create a formerly deleted entry that still has a tombstone.
     * If allowed (true), entries can be recreated if (and only if)
     * content hashes match; if not allowed (false), 410 Gone
     * response will be returned if PUT is attempted on tombstone
     * entry (something DELETEd recently, not yet cleaned up).
     */
    public boolean cfgAllowUndelete = false;

    /**
     * Configuration setting that determines whether deleted entries
     * with tombstone are reported as empty entries (204, No Content)
     * or as missing (404, Not Found): if false, 404 returned,
     * if true, 204.
     *

* Default setting is false. */ public boolean cfgReportDeletedAsEmpty = false; /** * DELETE operations may be deferred; and if so, here's configuration * for details. */ public DeferredDeleteConfig deletes = new DeferredDeleteConfig(); /* /********************************************************************** /* Storage config: data expiration, deletion, cleanup /********************************************************************** */ /** * This value specifies absolute maximum time-to-live value for any * entry stored in system; this is a hard value which will not * take into account last-accessed timestamp. *

* By default this is set to 14 days (2 weeks) */ public TimeSpan cfgMaxMaxTTL = new TimeSpan("14d"); /** * This value specifies the default maximum time-to-live value for any * entry stored in system without specifying per-item maximum TTL. *

* Default value is 7 days (1 week) */ public TimeSpan cfgDefaultMaxTTL = new TimeSpan("14d"); /** * This value specifies the maximum value that can defined for * "TTL since last-access". *

* Default value is 2 days. */ public TimeSpan cfgMaxSinceAccessTTL = new TimeSpan("2d"); /** * This value specifies the default "time-to-live since last access" * value for any entry stored in system without specifying per-item value. * In cases where access-time is not tracked, this basically means * "time-to-live since creation", as creation is considered baseline * for "last-access". *

* Note that this setting can not override value of "maximum TTL", that is, * it can only make entries live to at most "maximum TTL". It does however * apply above and beyond "minimum TTL" (which would otherwise let 'old enough' * entries be expired) *

* Default value of 3 hours, then, means that by default no entry will expire * less than 3 hours after last access or creation. */ public TimeSpan cfgDefaultSinceAccessTTL = new TimeSpan("3h"); /** * By default we will not run cleanup more often than about once * an hour. * But the first cleanup will typically be run earlier than delay. *

* Let's use a value that is NOT neatly divisible, just to try to * avoid syncing up to some schedule. */ @NotNull public TimeSpan cfgDelayBetweenCleanup = new TimeSpan("40m"); /** * This value specifies time that tombstones (deletion markers) should * be kept in the metadata store before purging. Delay in deletion is * necessary to ensure proper deletion across instance during outages. *

* Current default value (45 minutes) is chosen to balance eventual consistency * (when some nodes fail) with additional storage cost. */ public TimeSpan cfgTombstoneTTL = new TimeSpan("45m"); /* /********************************************************************** /* Storage config: synchronization settings /********************************************************************** */ /** * What is the grace period for syncing: that is, how many seconds do we give * for servers to get content from clients before we try to synchronize. * This balances fast synchronization with overhead of doing sync: for now, * let's give 20 seconds. */ public TimeSpan cfgSyncGracePeriod = new TimeSpan("20s"); /** * How many entries can we request with each call sync-list call? * Responses are fully buffered in memory, so let's say... 500? */ public int cfgMaxEntriesPerSyncList = 500; /** * What is the maximum amount of time server may keep connection * for "Sync List" open before having to return empty result * set (non-empty result sets are to be returned right away without * further waiting). This means that servers may put request to sleep * for up to this amount of time, but only if it does not yet have * any results to return. *
* NOTE: should be kept relatively low; server will let client know * of additional sleep it may do before retrying sync list request. */ public TimeSpan cfgSyncMaxLongPollTime = new TimeSpan("3s"); /* /********************************************************************** /* Metrics settings /********************************************************************** */ /** * Setting that determines whether Yammer metrics information will be * updated or not. */ public boolean metricsEnabled = true; /** * Root name for metrics properties when reported via JMX. */ public String metricsJmxRoot = "com.fasterxml.clustermate.metrics"; /* /********************************************************************** /* Construction /********************************************************************** */ protected ServiceConfig(String[] root) { servicePathRoot = root; } /* /********************************************************************** /* Programmatic overrides /********************************************************************** */ public ServiceConfig overrideSyncGracePeriod(String periodDesc) { try { cfgSyncGracePeriod = new TimeSpan(periodDesc); } catch (Exception e) { throw new IllegalArgumentException("Invalid delay definition '"+periodDesc+"': "+e.getMessage()); } return this; } public ServiceConfig overrideMaxLongPollTime(String periodDesc) { try { cfgSyncMaxLongPollTime = new TimeSpan(periodDesc); } catch (Exception e) { throw new IllegalArgumentException("Invalid max setting definition '"+periodDesc+"': "+e.getMessage()); } return this; } public ServiceConfig overrideDefaultMaxTTL(String periodDesc) { try { cfgDefaultMaxTTL = new TimeSpan(periodDesc); } catch (Exception e) { throw new IllegalArgumentException("Invalid max TTL definition '"+periodDesc+"': "+e.getMessage()); } return this; } public ServiceConfig overrideDefaultSinceAccessTTL(String periodDesc) { try { cfgDefaultSinceAccessTTL = new TimeSpan(periodDesc); } catch (Exception e) { throw new IllegalArgumentException("Invalid min TTL definition '"+periodDesc+"': "+e.getMessage()); } return this; } public ServiceConfig overrideStoreBackendConfig(StoreBackendConfig cfg) { _storeBackendConfigOverride = cfg; return this; } /* /********************************************************************** /* Other access methods /********************************************************************** */ public abstract StoredEntryConverter getEntryConverter(); public StoreBackendBuilder instantiateBackendBuilder() { if (storeBackendType == null) { throw new IllegalStateException("Missing configuration for 'storeBackendType'"); } return _createInstance(storeBackendType, "storeBackendType", StoreBackendBuilder.class); } @SuppressWarnings("unchecked") protected T _createInstance(Class implCls, String desc, Class baseType) { // verify first; not 100% confident annotation verifications catch everything if (!baseType.isAssignableFrom(implCls)) { throw new IllegalStateException("Invalid value for '"+desc+"': " +implCls.getName()+" is not a sub-type of "+baseType.getName()); } try { // TODO: find the constructor, call 'setAccessible' if necessary? return (T) implCls.newInstance(); } catch (Exception e) { Throwable t = e; while (t.getCause() != null) { t = t.getCause(); } throw new IllegalStateException("Could not instantiate property '"+desc+"', of type " +implCls.getName()+". Problem ("+t.getClass().getName()+"): "+t.getMessage(), t); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy