package com.linkedin.databus.client.pub; /* * * 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.IOException; import java.util.List; import org.apache.log4j.Logger; import com.linkedin.databus.core.Checkpoint; import com.linkedin.databus.core.util.ConfigApplier; import com.linkedin.databus.core.util.ConfigBuilder; import com.linkedin.databus.core.util.InvalidConfigException; public class SharedCheckpointPersistenceProvider extends CheckpointPersistenceProviderAbstract { public static final String MODULE = SharedCheckpointPersistenceProvider.class.getName(); public static final Logger LOG = Logger.getLogger(MODULE); /** The static configuration */ private final StaticConfig _staticConfig; private final DatabusClientGroupMember _groupMember; private int _numWrites = 0; public SharedCheckpointPersistenceProvider(DatabusClientGroupMember node) throws InvalidConfigException { this (node,new Config()); } public StaticConfig getStaticConfig() { return _staticConfig; } public SharedCheckpointPersistenceProvider(DatabusClientGroupMember groupMember , Config config) throws InvalidConfigException { this(groupMember, config.build()); } public SharedCheckpointPersistenceProvider(DatabusClientGroupMember node, StaticConfig config) throws InvalidConfigException { _staticConfig = config; _groupMember = node; if (_groupMember==null) { throw new InvalidConfigException("Cannot initialize shared checkpoint with null cluster group member! Check if cluster node has been enabled"); } } @Override public void storeCheckpoint(List<String> sourceNames, Checkpoint checkpoint) throws IOException { String key = makeKey(sourceNames); _numWrites++; if (_numWrites > _staticConfig.getMaxNumWritesSkipped()) { _numWrites=0; if (!_groupMember.writeSharedData(key,checkpoint)) { LOG.info("Write failed in store checkpoint; Assuming no connection to zookeeper; throwing IO Exception: key=" + key); throw new IOException("Write failed in store checkpoint; Assuming no connection to zookeeper; throwing IO Exception: key=" + key); } } } protected String makeKey(List<String> srcs) { StringBuilder k = new StringBuilder(); for (String s: srcs) { k.append("_"); k.append(s); } return k.toString(); } @Override public Checkpoint loadCheckpoint(List<String> sourceNames) { String key = makeKey(sourceNames); return (Checkpoint) _groupMember.readSharedData(key); } @Override public void removeCheckpoint(List<String> sourceNames) { String key = makeKey(sourceNames); _groupMember.removeSharedData(key); } /** Static configuration for the shared checkpoint persistence provider. * * @see SharedCheckpointPersistenceProvider */ public static class StaticConfig { private final int _maxNumWritesSkipped; public StaticConfig(int maxNumWritesSkipped) { _maxNumWritesSkipped = maxNumWritesSkipped; } public int getMaxNumWritesSkipped() { return _maxNumWritesSkipped; } @Override public String toString() { return "StaticConfig [_maxNumWritesSkipped=" + _maxNumWritesSkipped + "]"; } } public static class Config implements ConfigBuilder<StaticConfig> { public Config() { } private int _maxNumWritesSkipped=0; @Override public StaticConfig build() throws InvalidConfigException { return new StaticConfig(_maxNumWritesSkipped); } public int getMaxNumWritesSkipped() { return _maxNumWritesSkipped; } public void setMaxNumWritesSkipped(int frequencyOfWritesInEvents) { _maxNumWritesSkipped = frequencyOfWritesInEvents; } } public static class RuntimeConfig implements ConfigApplier<RuntimeConfig> { @Override public void applyNewConfig(RuntimeConfig oldConfig) { // No shared state to change; runtime config settings are used on demand } @Override public boolean equalsConfig(RuntimeConfig otherConfig) { if (null == otherConfig) return false; return true; } } public static class RuntimeConfigBuilder implements ConfigBuilder<RuntimeConfig> { private SharedCheckpointPersistenceProvider _managedInstance = null; @Override public RuntimeConfig build() throws InvalidConfigException { if (null == _managedInstance) { throw new InvalidConfigException("No associated managed instance for runtime config"); } return new RuntimeConfig(); } public void setManagedInstance(SharedCheckpointPersistenceProvider persistenceProvider) { _managedInstance = persistenceProvider; } public Object getManagedInstance() { return _managedInstance; } } }