/** * The contents of this file are subject to the OpenMRS Public License * Version 1.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://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.module.sync; import java.util.ArrayList; import java.util.List; import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.openmrs.api.context.Context; import org.openmrs.module.sync.api.SyncService; import org.openmrs.module.sync.server.RemoteServer; import org.openmrs.module.sync.server.RemoteServerType; import org.openmrs.module.sync.server.SyncServerRecord; /** * sync strategy that implements sync-ing via disconnected push/pull. */ public class SyncStrategyFile { //fields private final Log log = LogFactory.getLog(getClass()); //constructor public SyncStrategyFile() { } /** * Using the sourceChild sync source, create a sync transmission using JournalManager */ public SyncTransmission createSyncTransmission(SyncSource source) { SyncTransmission tx = new SyncTransmission(); List<SyncRecord> changeset = null; //retrieve value of the last sync timestamps SyncPoint lastSyncLocal = source.getLastSyncLocal(); //establish the 'new' sync point; this will be new sync local after transmission was 'exported' SyncPoint lastSyncLocalNew = source.moveSyncPoint(); //get changeset for sourceA changeset = this.getChangeset(source, lastSyncLocal, lastSyncLocalNew); String sourceUuid = source.getSyncSourceUuid(); //pack it into transmission, don't write temp file SyncTransmission syncTx = new SyncTransmission(sourceUuid, changeset); syncTx.create(false); //set new SyncPoint source.setLastSyncLocal(lastSyncLocalNew); return syncTx; } /** * Prepares a sync transmission containing sync records from source that are to be send to the * remote server. The records to be sent are determined as follows: <br/> * - select records from sync journal that are in the correct state (see * SyncConstants.SYNC_TO_PARENT_STATES) <br/> * - if a sync record from the journal reached state of FAILED_AND_STOPPED; do not attempt to * send it and records after it again <br/> * - filter out records that contain classes that are not accepted by the server * * @param source server from where changes are to be retrieved (local server) * @param writeFileToo flag to dump file or not * @param server server to send Tx to * @param maxSyncRecords The maximum number of sync records to include in the Sync Transmission * @return * @see org.openmrs.module.sync.SyncConstants#SYNC_TO_PARENT_STATES */ public SyncTransmission createStateBasedSyncTransmission(SyncSource source, boolean writeFileToo, RemoteServer server, boolean requestResponseWithTransmission, Integer maxSyncRecords) { SyncTransmission syncTx = null; boolean isMaxRetryReached = false; if (server != null) { List<SyncRecord> changeset = null; List<SyncRecord> filteredChangeset = new ArrayList<SyncRecord>(); //get changeset for sourceA changeset = this.getStateBasedChangeset(source, server, maxSyncRecords); // need to check each SyncRecord to see if it's eligible for sync'ing if (changeset != null) { for (SyncRecord record : changeset) { if (record.getState() == SyncRecordState.FAILED_AND_STOPPED) { isMaxRetryReached = true; SyncUtil.sendSyncErrorMessage(record, server, new SyncException("Reached maximum retry count")); break; } Set<String> containedClasses = record.getContainedClassSet(); if (server.shouldBeSentSyncRecord(record)) { filteredChangeset.add(record); } else { if (server.getServerType().equals(RemoteServerType.PARENT)) { record.setState(SyncRecordState.NOT_SUPPOSED_TO_SYNC); Context.getService(SyncService.class).updateSyncRecord(record); } else { SyncServerRecord serverRecord = record.getServerRecord(server); if (serverRecord != null) { serverRecord.setState(SyncRecordState.NOT_SUPPOSED_TO_SYNC); Context.getService(SyncService.class).updateSyncRecord(record); } } log.warn("NOT ADDING RECORD TO TRANSMISSION, SERVER IS NOT SET TO SEND ALL OF " + containedClasses + " TO SERVER " + server.getNickname()); } } } //pack it into transmission syncTx = new SyncTransmission(source.getSyncSourceUuid(), filteredChangeset, server.getUuid()); syncTx.setIsRequestingTransmission(requestResponseWithTransmission); syncTx.create(writeFileToo); syncTx.setSyncTargetUuid(server.getUuid()); if (isMaxRetryReached) { syncTx.setIsMaxRetryReached(true); } } return syncTx; } /** * Update status of a given sync transmission */ public void updateSyncTransmission(SyncTransmission Tx) { //TODO return; } /** * TODO: Review the 'exported' transmissions and return the list of the ones that did not * receive a confirmation from the server; these are in the 'pending' state. */ public List<String> getPendingTransmissions() { //TODO List<String> pending = new ArrayList<String>(); return pending; } /** * Apply given sync tx to source. */ public void applySyncTransmission(SyncSource source, SyncTransmission tx) { //TODO return; } private List<SyncRecord> getChangeset(SyncSource source, SyncPoint from, SyncPoint to) { List<SyncRecord> deleted = null; List<SyncRecord> changed = null; List<SyncRecord> changeset = null; //get all local deletes, inserts and updates deleted = source.getDeleted(from, to); changed = source.getChanged(from, to); //merge changeset = deleted; changeset.addAll(changed); return changeset; } private List<SyncRecord> getStateBasedChangesets(SyncSource source, Integer maxSyncRecords) { List<SyncRecord> deleted = null; List<SyncRecord> changed = null; List<SyncRecord> changeset = null; //get all local deletes, inserts and updates deleted = source.getDeleted(); changed = source.getChanged(maxSyncRecords); //merge changeset = deleted; changeset.addAll(changed); return changeset; } private List<SyncRecord> getStateBasedChangeset(SyncSource source, RemoteServer server, Integer maxResults) { List<SyncRecord> deleted = null; List<SyncRecord> changed = null; List<SyncRecord> changeset = null; //get all local deletes, inserts and updates deleted = source.getDeleted(); changed = source.getChanged(server, maxResults); //merge changeset = deleted; changeset.addAll(changed); return changeset; } //apply items to source private void applyChangeset(SyncSource source, List<SyncRecord> items) { //TODO return; } }