// 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();
}
}