// This software is released into the Public Domain. See copying.txt for details. package org.openstreetmap.osmosis.replication.v0_6; import java.io.File; import java.util.HashMap; import java.util.Map; import org.openstreetmap.osmosis.core.container.v0_6.ChangeContainer; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSink; import org.openstreetmap.osmosis.core.task.v0_6.ChangeSinkChangeSource; import org.openstreetmap.osmosis.replication.common.ReplicationState; /** * This task allows a replication stream to be converted to a standard change * stream. It handles the state persistence required by a replication sink, and * then passes the replication data to a standard change sink destination. A * typical use case would be receiving a replication stream live from a * database, then applying those changes to another database where the change * applier task doesn't support the replication metadata extensions. * * @author Brett Henderson */ public class ReplicationToChangeWriter implements ChangeSinkChangeSource { /** * This handles and persists the replication metadata. */ private ReplicationStateWriter stateWriter; private ReplicationState state; private ChangeSink changeSink; /** * Creates a new instance. * * @param workingDirectory * The directory containing configuration and tracking files. */ public ReplicationToChangeWriter(File workingDirectory) { stateWriter = new ReplicationStateWriter(workingDirectory); } @Override public void setChangeSink(ChangeSink changeSink) { this.changeSink = changeSink; } @Override public void initialize(Map<String, Object> metaData) { // Initialise the replication meta data. stateWriter.initialize(metaData); // Get the replication state for this pipeline run. state = (ReplicationState) metaData.get(ReplicationState.META_DATA_KEY); // Initialise the downstream tasks passing everything except the // replication state. if (state.getSequenceNumber() > 0) { Map<String, Object> downstreamMetaData = new HashMap<String, Object>(metaData); downstreamMetaData.remove(ReplicationState.META_DATA_KEY); changeSink.initialize(downstreamMetaData); } } @Override public void process(ChangeContainer change) { // Perform replication checks. stateWriter.process(change); // Pass the change downstream. changeSink.process(change); } @Override public void complete() { // We must complete downstream before we complete the replication writer // so that we know the replication data has been committed before we // persist replication state. if (state.getSequenceNumber() > 0) { changeSink.complete(); } stateWriter.complete(); } @Override public void close() { changeSink.close(); stateWriter.close(); } }