package org.infinispan.cli.interpreter.statement; import static org.infinispan.cli.interpreter.logging.Messages.MSG; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.infinispan.Cache; import org.infinispan.cli.interpreter.logging.Log; import org.infinispan.cli.interpreter.result.Result; import org.infinispan.cli.interpreter.result.StatementException; import org.infinispan.cli.interpreter.result.StringResult; import org.infinispan.cli.interpreter.session.Session; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.upgrade.RollingUpgradeManager; import org.infinispan.util.logging.LogFactory; /** * Performs operation related to rolling upgrades * * @author Tristan Tarrant * @since 5.2 */ public class UpgradeStatement implements Statement { private static final Log log = LogFactory.getLog(UpgradeStatement.class, Log.class); private enum Options { ALL, DUMPKEYS, SYNCHRONIZE, DISCONNECTSOURCE }; final String cacheName; final private List<Option> options; public UpgradeStatement(List<Option> options, String cacheName) { this.options = options; this.cacheName = cacheName; } @Override public Result execute(Session session) throws StatementException { boolean all = false; UpgradeMode mode = UpgradeMode.NONE; String migratorName = null; for (Option opt : options) { switch (opt.toEnum(Options.class)) { case ALL: { all = true; break; } case DUMPKEYS: { mode = UpgradeMode.DUMPKEYS; break; } case SYNCHRONIZE: { mode = UpgradeMode.SYNCHRONIZE; migratorName = opt.getParameter(); if (migratorName == null) { throw log.missingMigrator(); } break; } case DISCONNECTSOURCE: { mode = UpgradeMode.DISCONNECTSOURCE; migratorName = opt.getParameter(); if (migratorName == null) { throw log.missingMigrator(); } } } } StringBuilder sb = new StringBuilder(); switch (mode) { case DUMPKEYS: { for (Cache<?, ?> cache : all ? getAllCaches(session) : Collections.singletonList(session.getCache(cacheName))) { RollingUpgradeManager upgradeManager = cache.getAdvancedCache().getComponentRegistry().getComponent(RollingUpgradeManager.class); upgradeManager.recordKnownGlobalKeyset(); sb.append(MSG.dumpedKeys(cache.getName())); sb.append("\n"); } break; } case SYNCHRONIZE: { for (Cache<?, ?> cache : all ? getAllCaches(session) : Collections.singletonList(session.getCache(cacheName))) { RollingUpgradeManager upgradeManager = cache.getAdvancedCache().getComponentRegistry().getComponent(RollingUpgradeManager.class); try { long count = upgradeManager.synchronizeData(migratorName); sb.append(MSG.synchronizedEntries(count, migratorName, cache.getName())); sb.append("\n"); } catch (Exception e) { throw log.dataSynchronizationError(e, cache.getName(), migratorName); } } break; } case DISCONNECTSOURCE: { for (Cache<?, ?> cache : all ? getAllCaches(session) : Collections.singletonList(session.getCache(cacheName))) { RollingUpgradeManager upgradeManager = cache.getAdvancedCache().getComponentRegistry().getComponent(RollingUpgradeManager.class); try { upgradeManager.disconnectSource(migratorName); sb.append(MSG.disonnectedSource(migratorName, cache.getName())); sb.append("\n"); } catch (Exception e) { throw log.sourceDisconnectionError(e, cache.getName(), migratorName); } } break; } default: { throw log.missingUpgradeAction(); } } return new StringResult(sb.toString()); } private List<Cache<?, ?>> getAllCaches(Session session) { List<Cache<?, ?>> caches = new ArrayList<Cache<?, ?>>(); EmbeddedCacheManager container = session.getCacheManager(); for (String cacheName : container.getCacheNames()) { if (container.isRunning(cacheName)) { caches.add(session.getCache(cacheName)); } } caches.add(container.getCache()); return caches; } private enum UpgradeMode { NONE, DUMPKEYS, SYNCHRONIZE, DISCONNECTSOURCE } }