/*
* RHQ Management Platform
* Copyright (C) 2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.core.pc.drift.sync;
import static org.rhq.core.domain.drift.DriftDefinitionComparator.CompareMode.BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.clientapi.server.drift.DriftServerService;
import org.rhq.core.domain.drift.DriftDefinition;
import org.rhq.core.domain.drift.DriftDefinitionComparator;
import org.rhq.core.pc.drift.DriftManager;
import org.rhq.core.pc.inventory.InventoryManager;
/**
* This class handles syncing drift definitions and drift content during inventory sync.
* This class is intended to server as the public interface (so to speak) to
* {@link InventoryManager} for syncing drift definitions and content.
* <br/><br/>
* Please review the docs for each of the setter methods to determine which properties
* should be set before invoking any business logic methods.
*/
public class DriftSyncManager {
private final Log log = LogFactory.getLog(DriftSyncManager.class);
private DriftServerService driftServer;
private DriftManager driftMgr;
private InventoryManager inventoryMgr;
private File dataDir;
/**
* @param driftServer The interface to the remote server. This property must be set.
* It is injected to facilitate testing with stubs or mocks.
*/
public void setDriftServer(DriftServerService driftServer) {
this.driftServer = driftServer;
}
/**
* @param driftManager The drift manager singleton created by the plugin container.
* This property must be set even if drift manager is not yet initialized. It is
* injected to facilitate testing with stubs or mocks.
*/
public void setDriftManager(DriftManager driftManager) {
driftMgr = driftManager;
}
/**
* @param inventoryManager The inventory manager singleton created by the plugin
* container. This property must be set. It is injected to facilitate testing with stubs
* or mocks.
*/
public void setInventoryManager(InventoryManager inventoryManager) {
inventoryMgr = inventoryManager;
}
/**
* @param dataDirectory The plugin container data directory where inventory files are
* stored. This property must be set. It is injected to facilitate testing.
*/
public void setDataDirectory(File dataDirectory) {
dataDir = dataDirectory;
}
/**
* Synchronized both drift definitions and drift content with the server. The drift
* definition sync goes from server to agent in that the drift definitions in the
* local inventory are updated to match the drift definitions on the server
* inventory.
* <br/><br/>
* The content sync works as follows. Any change set content zip files found locally
* resent to the server under the assumption that the content has not been persisted on
* the server.
*
* @param resourceIds The ids of resources that need to be synced.
*/
public void syncWithServer(Set<Integer> resourceIds) {
DriftSynchronizerFactory synchronizerFactory = new DriftSynchronizerFactory();
DriftSynchronizer synchronizer;
if (isStartUpSync()) {
synchronizer = synchronizerFactory.getStartUpSynchronizer(inventoryMgr, dataDir);
} else {
synchronizer = synchronizerFactory.getRuntimeSynchronizer(driftMgr);
}
syncDriftDefinitions(synchronizer, resourceIds);
syncContent(synchronizer);
}
private void syncDriftDefinitions(DriftSynchronizer synchronizer, Set<Integer> resourceIds) {
log.info("Starting server sync for drift definitions...");
long startTime = System.currentTimeMillis();
Map<Integer, List<DriftDefinition>> driftDefs = driftServer.getDriftDefinitions(resourceIds);
DriftDefinitionComparator comparator = new DriftDefinitionComparator(
BOTH_BASE_INFO_AND_DIRECTORY_SPECIFICATIONS);
int totalDeleted = 0;
int totalAdded = 0;
for (Integer resourceId : driftDefs.keySet()) {
Set<DriftDefinition> driftDefinitionsOnServer = new TreeSet<DriftDefinition>(comparator);
driftDefinitionsOnServer.addAll(driftDefs.get(resourceId));
List<DriftDefinition> deletedDefs = synchronizer.getDeletedDefinitions(resourceId,
driftDefinitionsOnServer);
totalDeleted += deletedDefs.size();
synchronizer.purgeFromLocalInventory(resourceId, deletedDefs);
List<DriftDefinition> addedDefs = synchronizer.getAddedDefinitions(resourceId, driftDefinitionsOnServer);
totalAdded += addedDefs.size();
synchronizer.addToLocalInventory(resourceId, addedDefs);
}
long endTime = System.currentTimeMillis();
if (log.isInfoEnabled()) {
log.info("Finished server sync for drift definitions. " + totalAdded + " added and " + totalDeleted
+ " deleted in " + (endTime - startTime) + " ms");
}
}
private void syncContent(DriftSynchronizer synchronizer) {
log.info("Starting drift content sync...");
long startTime = System.currentTimeMillis();
synchronizer.syncChangeSetContent();
long endTime = System.currentTimeMillis();
if (log.isInfoEnabled()) {
log.info("Finished drift content sync in " + (endTime - startTime) + " ms");
}
}
/**
* This method determines whether or not this is a sync being done at start up (or
* more precisely during PC initialization). It does by checking to see if
* DriftManager is initialized. The only time DriftManager should not be initialized
* is during PC initialization which happens at start up or at runtime when the PC is
* rebooted.
*
* @return true if this is a sync being performed at start up or plugin container
* initialization.
*/
private boolean isStartUpSync() {
return driftMgr == null || !driftMgr.isInitialized();
}
}