From e0e8b855957f0335ce399dcacb4f645071e53f26 Mon Sep 17 00:00:00 2001 From: Mircea Markus Date: Tue, 25 Sep 2012 15:16:24 +0100 Subject: [PATCH 01/10] ISPN-2339 Upgrade to JGroups 3.2.0.Alpha2 --- parent/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parent/pom.xml b/parent/pom.xml index 43a92adefcf6..d0f4d26057f9 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -147,7 +147,7 @@ 1.4.1 6.1.25 1.0.5 - 3.2.0.Alpha1 + 3.2.0.Alpha2 0.16 2.1 20090211 From d34190c8eb4486835343137d4fbc4627381bfe9c Mon Sep 17 00:00:00 2001 From: Mircea Markus Date: Wed, 26 Sep 2012 10:37:36 +0100 Subject: [PATCH 02/10] ISPN-2343 Exception thrown to user from xsite ROC when failurePolicy is set to WARN --- .../remoting/transport/BackupResponse.java | 2 +- .../jgroups/JGroupsBackupResponse.java | 10 ++- .../infinispan/xsite/BackupSenderImpl.java | 4 +- .../xsite/BaseSiteUnreachableTest.java | 63 +++++++++++++++++++ .../xsite/NoFailureAsyncReplTest.java | 63 +++++++++++++++++++ .../backupfailure/NonTxBackupFailureTest.java | 17 ++++- 6 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java create mode 100644 core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java diff --git a/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java b/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java index b82b719ed7a7..7dc144fa2ddd 100644 --- a/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java +++ b/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java @@ -30,5 +30,5 @@ public interface BackupResponse { void waitForBackupToFinish() throws Exception; - Map getFailedBackups(); + Map getFailedBackups(); } diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java index 297096351e65..07848ffb20c5 100644 --- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java +++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -44,7 +45,7 @@ public class JGroupsBackupResponse implements BackupResponse { private static Log log = LogFactory.getLog(JGroupsBackupResponse.class); private final Map> syncBackupCalls; - private Map errors; + private Map errors; //there might be an significant difference in time between when the message is sent and when the actual wait // happens. Track that and adjust the timeouts accordingly. @@ -57,7 +58,7 @@ public JGroupsBackupResponse(Map> syncBackupCalls) { public void waitForBackupToFinish() throws Exception { long deductFromTimeout = NANOSECONDS.toMillis(System.nanoTime() - sendTimeNanos); - errors = new HashMap(syncBackupCalls.size()); + errors = new HashMap(syncBackupCalls.size()); long elapsedTime = 0; for (Map.Entry> entry : syncBackupCalls.entrySet()) { long timeout = entry.getKey().getTimeout(); @@ -75,6 +76,9 @@ public void waitForBackupToFinish() throws Exception { value = entry.getValue().get(timeout, MILLISECONDS); } catch (TimeoutException te) { errors.put(siteName, newTimeoutException(entry, entry.getKey().getTimeout())); + } catch (ExecutionException ue) { + log.tracef(ue.getCause(), "Communication error with site %s", siteName); + errors.put(siteName, ue.getCause()); } finally { elapsedTime += NANOSECONDS.toMillis(System.nanoTime() - startNanos); } @@ -90,7 +94,7 @@ public void waitForBackupToFinish() throws Exception { } @Override - public Map getFailedBackups() { + public Map getFailedBackups() { return errors; } diff --git a/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java b/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java index 7cbbdd00f369..14e357f6e222 100644 --- a/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java +++ b/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java @@ -125,8 +125,8 @@ public void processResponses(BackupResponse backupResponse, VisitableCommand com public void processResponses(BackupResponse backupResponse, VisitableCommand command, Transaction transaction) throws Throwable { backupResponse.waitForBackupToFinish(); SitesConfiguration sitesConfiguration = config.sites(); - Map failures = backupResponse.getFailedBackups(); - for (Map.Entry failure : failures.entrySet()) { + Map failures = backupResponse.getFailedBackups(); + for (Map.Entry failure : failures.entrySet()) { BackupFailurePolicy policy = sitesConfiguration.getFailurePolicy(failure.getKey()); if (policy == BackupFailurePolicy.CUSTOM) { CustomFailurePolicy customFailurePolicy = siteFailurePolicy.get(failure.getKey()); diff --git a/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java new file mode 100644 index 000000000000..889149f4be44 --- /dev/null +++ b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java @@ -0,0 +1,63 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.xsite; + +import org.infinispan.configuration.cache.BackupConfiguration; +import org.infinispan.configuration.cache.BackupFailurePolicy; +import org.infinispan.configuration.cache.CacheMode; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.configuration.global.GlobalConfigurationBuilder; +import org.testng.annotations.Test; + +/** + * @author Mircea Markus + * @since 5.2 + */ +@Test(groups = "xsite", testName = "xsite.BaseSiteUnreachableTest") +public class BaseSiteUnreachableTest extends AbstractXSiteTest { + + protected BackupFailurePolicy lonBackupFailurePolicy = BackupFailurePolicy.WARN; + protected BackupConfiguration.BackupStrategy lonBackupStrategy = BackupConfiguration.BackupStrategy.SYNC; + protected String lonCustomFailurePolicyClass = null; + + + @Override + protected void createSites() { + + GlobalConfigurationBuilder lonGc = GlobalConfigurationBuilder.defaultClusteredBuilder(); + lonGc + .sites().addSite().name("LON") + .sites().addSite().name("NYC") + .sites().localSite("LON"); + ConfigurationBuilder lon = getLonActiveConfig(); + lon.sites().addBackup() + .site("NYC") + .backupFailurePolicy(lonBackupFailurePolicy) + .strategy(lonBackupStrategy) + .failurePolicyClass(lonCustomFailurePolicyClass); + + createSite("LON", 2, lonGc, lon); + } + + protected ConfigurationBuilder getLonActiveConfig() { + return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, true); + } + +} diff --git a/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java new file mode 100644 index 000000000000..f5ae0964460a --- /dev/null +++ b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java @@ -0,0 +1,63 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.xsite; + +import org.infinispan.configuration.cache.BackupConfiguration; +import org.infinispan.configuration.cache.BackupFailurePolicy; +import org.infinispan.configuration.cache.CacheMode; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.xsite.BaseSiteUnreachableTest; +import org.testng.annotations.Test; + +import java.util.Collections; + +import static org.testng.Assert.assertNull; +import static org.testng.AssertJUnit.assertEquals; + +/** + * @author Mircea Markus + * @since 5.2 + */ +@Test (groups = "xsite", testName = "xsite.bridgemissing.NoFailureAsyncReplTest") +public class NoFailureAsyncReplTest extends BaseSiteUnreachableTest { + + public NoFailureAsyncReplTest() { + lonBackupStrategy = BackupConfiguration.BackupStrategy.SYNC; + lonBackupFailurePolicy = BackupFailurePolicy.WARN; + } + + public void testNoFailures() { + cache("LON", 0).put("k", "v"); + assertEquals(cache("LON", 0).get("k"), "v"); + assertEquals(cache("LON", 1).get("k"), "v"); + + cache("LON", 1).remove("k"); + assertNull(cache("LON", 0).get("k")); + assertNull(cache("LON", 1).get("k")); + + cache("LON", 0).putAll(Collections.singletonMap("k", "v")); + assertEquals(cache("LON", 0).get("k"), "v"); + assertEquals(cache("LON", 1).get("k"), "v"); + } + + protected ConfigurationBuilder getLonActiveConfig() { + return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); + } +} diff --git a/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java b/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java index 34d1b8943622..6a51c69fbce5 100644 --- a/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java +++ b/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java @@ -20,6 +20,9 @@ package org.infinispan.xsite.backupfailure; import org.infinispan.CacheException; +import org.infinispan.configuration.cache.CacheMode; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.testng.annotations.Test; import java.util.HashMap; import java.util.Map; @@ -30,11 +33,23 @@ * @author Mircea Markus * @since 5.2 */ -public abstract class NonTxBackupFailureTest extends BaseBackupFailureTest { +@Test (groups = "xsite", testName = "xsite.backupfailure.NonTxBackupFailureTest") +public class NonTxBackupFailureTest extends BaseBackupFailureTest { //todo - if I don't explicitly override the test methods then testNG won't execute them from superclass. //fix this once we move to JUnit + + @Override + protected ConfigurationBuilder getLonActiveConfig() { + return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); + } + + @Override + protected ConfigurationBuilder getNycActiveConfig() { + return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); + } + public void testPutFailure() { try { cache("LON", 0).put("k", "v"); From 8a7e3aae65e2c2f660788d632f4629aba61da8a5 Mon Sep 17 00:00:00 2001 From: Mircea Markus Date: Thu, 27 Sep 2012 12:41:45 +0100 Subject: [PATCH 03/10] ISPN-2319 Add ability to take a site offline into x-site implementation - ongoing work --- .../cache/BackupConfiguration.java | 9 +- .../cache/BackupConfigurationBuilder.java | 21 ++- .../cache/TakeOfflineConfiguration.java | 77 ++++++++++ .../TakeOfflineConfigurationBuilder.java | 98 ++++++++++++ .../configuration/parsing/Attribute.java | 4 +- .../configuration/parsing/Element.java | 1 + .../configuration/parsing/Parser52.java | 32 +++- .../schema/infinispan-config-5.2.xsd | 145 +++++++++++------- .../xsite/BaseSiteUnreachableTest.java | 2 - ...ailureAsyncReplWarnFailurePolicyTest.java} | 7 +- .../xsite/XSiteFileParsing2Test.java | 7 +- .../xsite/XSiteFileParsing3Test.java | 83 ++++++++++ .../configs/xsite/xsite-offline-test.xml | 82 ++++++++++ 13 files changed, 498 insertions(+), 70 deletions(-) create mode 100644 core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java create mode 100644 core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java rename core/src/test/java/org/infinispan/xsite/{NoFailureAsyncReplTest.java => NoFailureAsyncReplWarnFailurePolicyTest.java} (92%) create mode 100644 core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java create mode 100644 core/src/test/resources/configs/xsite/xsite-offline-test.xml diff --git a/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java b/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java index 85586cef27a4..720a63ddb261 100644 --- a/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java +++ b/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java @@ -30,13 +30,16 @@ public class BackupConfiguration { private long timeout; private final BackupFailurePolicy backupFailurePolicy; private final String failurePolicyClass; + private final TakeOfflineConfiguration takeOfflineConfiguration; - public BackupConfiguration(String site, BackupStrategy strategy, long timeout, BackupFailurePolicy backupFailurePolicy, String failurePolicyClass) { + public BackupConfiguration(String site, BackupStrategy strategy, long timeout, BackupFailurePolicy backupFailurePolicy, + String failurePolicyClass, TakeOfflineConfiguration takeOfflineConfiguration) { this.site = site; this.strategy = strategy; this.timeout = timeout; this.backupFailurePolicy = backupFailurePolicy; this.failurePolicyClass = failurePolicyClass; + this.takeOfflineConfiguration = takeOfflineConfiguration; } /** @@ -53,6 +56,10 @@ public BackupStrategy strategy() { return strategy; } + public TakeOfflineConfiguration takeOffline() { + return takeOfflineConfiguration; + } + /** * If the failure policy is set to {@link BackupFailurePolicy#CUSTOM} then the failurePolicyClass is required and * should return the fully qualified name of a class implementing {@link org.infinispan.xsite.CustomFailurePolicy} diff --git a/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java b/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java index 37aef81a26e8..f68094be8c35 100644 --- a/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java +++ b/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java @@ -38,8 +38,11 @@ public class BackupConfigurationBuilder extends AbstractConfigurationChildBuilde private String failurePolicyClass; + private TakeOfflineConfigurationBuilder takeOfflineBuilder; + public BackupConfigurationBuilder(ConfigurationBuilder builder) { super(builder); + takeOfflineBuilder = new TakeOfflineConfigurationBuilder(builder); } /** @@ -105,6 +108,10 @@ public BackupConfiguration.BackupStrategy strategy() { return strategy; } + public TakeOfflineConfigurationBuilder takeOffline() { + return takeOfflineBuilder; + } + /** * Configures how the system behaves when the backup call fails. Only applies to sync backus. * The default values is {@link BackupFailurePolicy.WARN} @@ -125,6 +132,7 @@ public BackupFailurePolicy backupFailurePolicy() { @Override public void validate() { + takeOfflineBuilder.validate(); if (site == null) throw new ConfigurationException("The 'site' must be specified!"); if (backupFailurePolicy == BackupFailurePolicy.CUSTOM && (failurePolicyClass == null)) { @@ -135,11 +143,13 @@ public void validate() { @Override public BackupConfiguration create() { - return new BackupConfiguration(site, strategy, replicationTimeout, backupFailurePolicy, failurePolicyClass); + return new BackupConfiguration(site, strategy, replicationTimeout, backupFailurePolicy, failurePolicyClass, + takeOfflineBuilder.create()); } @Override public Builder read(BackupConfiguration template) { + this.takeOfflineBuilder.read(template.takeOffline()); this.site = template.site(); this.strategy = template.strategy(); this.backupFailurePolicy = template.backupFailurePolicy(); @@ -157,9 +167,12 @@ public boolean equals(Object o) { if (replicationTimeout != that.replicationTimeout) return false; if (backupFailurePolicy != that.backupFailurePolicy) return false; + if (failurePolicyClass != null ? !failurePolicyClass.equals(that.failurePolicyClass) : that.failurePolicyClass != null) + return false; if (site != null ? !site.equals(that.site) : that.site != null) return false; - if (failurePolicyClass != null ? !failurePolicyClass.equals(that.failurePolicyClass) : that.failurePolicyClass != null) return false; if (strategy != that.strategy) return false; + if (takeOfflineBuilder != null ? !takeOfflineBuilder.equals(that.takeOfflineBuilder) : that.takeOfflineBuilder != null) + return false; return true; } @@ -171,6 +184,7 @@ public int hashCode() { result = 31 * result + (int) (replicationTimeout ^ (replicationTimeout >>> 32)); result = 31 * result + (backupFailurePolicy != null ? backupFailurePolicy.hashCode() : 0); result = 31 * result + (failurePolicyClass != null ? failurePolicyClass.hashCode() : 0); + result = 31 * result + (takeOfflineBuilder != null ? takeOfflineBuilder.hashCode() : 0); return result; } @@ -181,7 +195,8 @@ public String toString() { ", strategy=" + strategy + ", replicationTimeout=" + replicationTimeout + ", backupFailurePolicy=" + backupFailurePolicy + - ", failurePolicyClass=" + failurePolicyClass + + ", failurePolicyClass='" + failurePolicyClass + '\'' + + ", takeOfflineBuilder=" + takeOfflineBuilder + '}'; } } diff --git a/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java new file mode 100644 index 000000000000..c5fb0589fa73 --- /dev/null +++ b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java @@ -0,0 +1,77 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.configuration.cache; + +/** + * @author Mircea Markus + * @since 5.2 + */ +public class TakeOfflineConfiguration { + + private int afterFailures; + private long minTimeToWait; + + public TakeOfflineConfiguration(int afterFailures, long minTimeToWait) { + this.afterFailures = afterFailures; + this.minTimeToWait = minTimeToWait; + } + + /** + * @see TakeOfflineConfigurationBuilder#afterFailures(int) + */ + public int afterFailures() { + return afterFailures; + } + + /** + * @see TakeOfflineConfigurationBuilder#minTimeToWait(long) + */ + public long minTimeToWait() { + return minTimeToWait; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TakeOfflineConfiguration)) return false; + + TakeOfflineConfiguration that = (TakeOfflineConfiguration) o; + + if (afterFailures != that.afterFailures) return false; + if (minTimeToWait != that.minTimeToWait) return false; + + return true; + } + + @Override + public int hashCode() { + int result = afterFailures; + result = 31 * result + (int) (minTimeToWait ^ (minTimeToWait >>> 32)); + return result; + } + + @Override + public String toString() { + return "TakeOfflineConfiguration{" + + "afterFailures=" + afterFailures + + ", minTimeToWait=" + minTimeToWait + + '}'; + } +} diff --git a/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java new file mode 100644 index 000000000000..f9c2d660e282 --- /dev/null +++ b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java @@ -0,0 +1,98 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.configuration.cache; + +import org.infinispan.configuration.Builder; + +/** + * @author Mircea Markus + * @since 5.2 + */ +public class TakeOfflineConfigurationBuilder extends AbstractConfigurationChildBuilder { + + private int afterFailures = 0; + private long minTimeToWait = 0; + + public TakeOfflineConfigurationBuilder(ConfigurationBuilder builder) { + super(builder); + } + + @Override + public void validate() { + } + + @Override + public TakeOfflineConfiguration create() { + return new TakeOfflineConfiguration(afterFailures, minTimeToWait); + } + + @Override + public Builder read(TakeOfflineConfiguration template) { + this.afterFailures = template.afterFailures(); + this.minTimeToWait = template.minTimeToWait(); + return this; + } + + /** + * The minimal number of millis to wait before taking this site offline, even in the case 'afterFailures' is reached. + * If smaller or equal to 0, then only 'afterFailures' is considered. + */ + public TakeOfflineConfigurationBuilder minTimeToWait(long minTimeToWait) { + this.minTimeToWait = minTimeToWait; + return this; + } + + /** + * The number of failed request operations after which this site should be taken offline. Defaults to 0 (never). A + * negative value would mean that the site will be taken offline after 'minTimeToWait'. + */ + public TakeOfflineConfigurationBuilder afterFailures(int afterFailures) { + this.afterFailures = afterFailures; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TakeOfflineConfigurationBuilder)) return false; + + TakeOfflineConfigurationBuilder that = (TakeOfflineConfigurationBuilder) o; + + if (afterFailures != that.afterFailures) return false; + if (minTimeToWait != that.minTimeToWait) return false; + + return true; + } + + @Override + public int hashCode() { + int result = afterFailures; + result = 31 * result + (int) (minTimeToWait ^ (minTimeToWait >>> 32)); + return result; + } + + @Override + public String toString() { + return "TakeOfflineConfigurationBuilder{" + + "afterFailures=" + afterFailures + + ", minTimeToWait=" + minTimeToWait + + '}'; + } +} diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java b/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java index e03bb1842789..f39bce253536 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java @@ -140,7 +140,9 @@ public enum Attribute { BACKUP_FAILURE_POLICY("backupFailurePolicy"), REMOTE_SITE("remoteSite"), REMOTE_CACHE("remoteCache"), - FAILURE_POLICY_CLASS("failurePolicyClass") + FAILURE_POLICY_CLASS("failurePolicyClass"), + AFTER_FAILURES("afterFailures"), + MIN_TIME_TO_WAIT("minTimeToWait") ; private final String name; diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Element.java b/core/src/main/java/org/infinispan/configuration/parsing/Element.java index 5410a91f8354..f579d42bb631 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Element.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Element.java @@ -88,6 +88,7 @@ public enum Element { BACKUPS("backups"), BACKUP("backup"), BACKUP_FOR("backupFor"), + TAKE_OFFLINE("takeOffline") ; private final String name; diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java b/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java index 3deecbe455f1..ff6c97449ae4 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java @@ -308,7 +308,7 @@ private void parseBackups(XMLExtendedStreamReader reader, ConfigurationBuilder c while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) { Element element = Element.forName(reader.getLocalName()); switch (element) { - case BACKUP: + case BACKUP: { BackupConfigurationBuilder backup = ccb.sites().addBackup(); for (int i = 0; i < reader.getAttributeCount(); i++) { ParseUtils.requireNoNamespaceAttribute(reader, i); @@ -334,14 +334,42 @@ private void parseBackups(XMLExtendedStreamReader reader, ConfigurationBuilder c throw ParseUtils.unexpectedElement(reader); } } + if (parseTakeOffline(reader, backup)) { + ParseUtils.requireNoContent(reader); + } + } default: { ParseUtils.unexpectedElement(reader); } - ParseUtils.requireNoContent(reader); } } } + private boolean parseTakeOffline(XMLExtendedStreamReader reader, BackupConfigurationBuilder backup) throws XMLStreamException { + if (reader.nextTag() != XMLStreamConstants.END_ELEMENT) { + Element takeOffline = Element.forName(reader.getLocalName()); + for (int i = 0; i < reader.getAttributeCount(); i++) { + ParseUtils.requireNoNamespaceAttribute(reader, i); + String value = replaceProperties(reader.getAttributeValue(i)); + Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); + switch (attribute) { + case AFTER_FAILURES: + backup.takeOffline().afterFailures(Integer.parseInt(value)); + break; + case MIN_TIME_TO_WAIT: + backup.takeOffline().minTimeToWait(Long.parseLong(value)); + break; + default: + throw ParseUtils.unexpectedElement(reader); + } + } + ParseUtils.requireNoContent(reader); + return true; + } else { + return false; + } + } + private void parseTransaction(final XMLExtendedStreamReader reader, final ConfigurationBuilderHolder holder) throws XMLStreamException { ConfigurationBuilder builder = holder.getCurrentConfigurationBuilder(); boolean forceSetTransactional = false; diff --git a/core/src/main/resources/schema/infinispan-config-5.2.xsd b/core/src/main/resources/schema/infinispan-config-5.2.xsd index 89ad411f1a79..f1c09edb9757 100644 --- a/core/src/main/resources/schema/infinispan-config-5.2.xsd +++ b/core/src/main/resources/schema/infinispan-config-5.2.xsd @@ -428,65 +428,14 @@ - + - Configures a specific site where this cache backups data. The name of the backup must match + Configures a specific site where this cache backups data. The name of the backup + must match a site defined in the "global" section. - - - - - Name of the remote site where this cache backups data. - - - - - - - The strategy used for backing up data: "SYNC" or "ASYNC". Defaults to "ASYNC" - - - - - - - - - - - - - Decides what the system would do in case of failure during backup. Defaults to "FAIL" - - - - - - - - - - - - - - - The timeout(millis) to be used when backing up data remotely. Defaults to 10 secs. - - - - - - - If the 'backupFailurePolicy' is set to 'CUSTOM' then this attribute is required and should - contain the fully qualified name of a class implementing org.infinispan.xsite.CustomFailurePolicy. - - - - @@ -1168,6 +1117,94 @@ + + + + + + Determines whether this backup is taken offline (ignored) after a certain + number of tries. + + + + + + + The number of failed request operations after which this site + should be taken offline. Defaults to 0 (never). + A negative value would mean that the site will be taken offline + after 'minTimeToWait'. + + + + + + + The minimal number of millis to wait before taking this site + offline, even in the case 'afterFailures' is reached. + If smaller or equal to 0, then only 'afterFailures' is considered. + + + + + + + + + + Name of the remote site where this cache backups data. + + + + + + + The strategy used for backing up data: "SYNC" or "ASYNC". Defaults to "ASYNC" + + + + + + + + + + + + + Decides what the system would do in case of failure during backup. Defaults to + "FAIL" + + + + + + + + + + + + + + + The timeout(millis) to be used when backing up data remotely. Defaults to 10 + secs. + + + + + + + If the 'backupFailurePolicy' is set to 'CUSTOM' then this attribute is + required and should + contain the fully qualified name of a class implementing + org.infinispan.xsite.CustomFailurePolicy. + + + + + diff --git a/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java index 889149f4be44..e6480a8fbae3 100644 --- a/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java +++ b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java @@ -24,13 +24,11 @@ import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.global.GlobalConfigurationBuilder; -import org.testng.annotations.Test; /** * @author Mircea Markus * @since 5.2 */ -@Test(groups = "xsite", testName = "xsite.BaseSiteUnreachableTest") public class BaseSiteUnreachableTest extends AbstractXSiteTest { protected BackupFailurePolicy lonBackupFailurePolicy = BackupFailurePolicy.WARN; diff --git a/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java similarity index 92% rename from core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java rename to core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java index f5ae0964460a..df2dfa95a264 100644 --- a/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java +++ b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java @@ -23,7 +23,6 @@ import org.infinispan.configuration.cache.BackupFailurePolicy; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; -import org.infinispan.xsite.BaseSiteUnreachableTest; import org.testng.annotations.Test; import java.util.Collections; @@ -35,10 +34,10 @@ * @author Mircea Markus * @since 5.2 */ -@Test (groups = "xsite", testName = "xsite.bridgemissing.NoFailureAsyncReplTest") -public class NoFailureAsyncReplTest extends BaseSiteUnreachableTest { +@Test (groups = "xsite", testName = "xsite.bridgemissing.NoFailureAsyncReplWarnFailurePolicyTest") +public class NoFailureAsyncReplWarnFailurePolicyTest extends BaseSiteUnreachableTest { - public NoFailureAsyncReplTest() { + public NoFailureAsyncReplWarnFailurePolicyTest() { lonBackupStrategy = BackupConfiguration.BackupStrategy.SYNC; lonBackupFailurePolicy = BackupFailurePolicy.WARN; } diff --git a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java index a40270223f71..ddcee159a302 100644 --- a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java +++ b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java @@ -22,6 +22,7 @@ import org.infinispan.configuration.cache.BackupConfiguration; import org.infinispan.configuration.cache.BackupFailurePolicy; import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.TakeOfflineConfiguration; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.fwk.TestCacheManagerFactory; @@ -62,7 +63,7 @@ public void testNoBackupFor() { assertEquals(1, dcc.sites().backups().size()); assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003, BackupFailurePolicy.WARN, null))); + 12003, BackupFailurePolicy.WARN, null, new TakeOfflineConfiguration(0,0)))); assertNull(dcc.sites().backupFor().remoteSite()); assertNull(dcc.sites().backupFor().remoteCache()); } @@ -75,9 +76,9 @@ public void testNoBackupFor2() { private void testDefault(Configuration dcc) { assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003l, BackupFailurePolicy.IGNORE, null))); + 12003l, BackupFailurePolicy.IGNORE, null, new TakeOfflineConfiguration(0,0)))); assertTrue(dcc.sites().backups().contains(new BackupConfiguration("SFO", BackupConfiguration.BackupStrategy.ASYNC, - 10000l, BackupFailurePolicy.WARN, null))); + 10000l, BackupFailurePolicy.WARN, null,new TakeOfflineConfiguration(0,0)))); assertEquals("someCache", dcc.sites().backupFor().remoteCache()); assertEquals("SFO", dcc.sites().backupFor().remoteSite()); } diff --git a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java new file mode 100644 index 000000000000..48f8a760c6f7 --- /dev/null +++ b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java @@ -0,0 +1,83 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.xsite; + +import org.infinispan.configuration.cache.BackupConfiguration; +import org.infinispan.configuration.cache.BackupFailurePolicy; +import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.TakeOfflineConfiguration; +import org.infinispan.manager.EmbeddedCacheManager; +import org.infinispan.test.SingleCacheManagerTest; +import org.infinispan.test.fwk.TestCacheManagerFactory; +import org.testng.annotations.Test; + +import static org.testng.AssertJUnit.*; + +/** + * @author Mircea Markus + * @since 5.2 + */ +@Test (groups = "functional", testName = "xsite.XSiteFileParsing3Test") +public class XSiteFileParsing3Test extends SingleCacheManagerTest { + public static final String FILE_NAME = "configs/xsite/xsite-offline-test.xml"; + + @Override + protected EmbeddedCacheManager createCacheManager() throws Exception { + EmbeddedCacheManager embeddedCacheManager = TestCacheManagerFactory.fromXml(FILE_NAME); + return embeddedCacheManager; + } + + public void testDefaultCache() { + Configuration dcc = cacheManager.getDefaultCacheConfiguration(); + assertEquals(dcc.sites().backups().size(), 1); + testDefault(dcc); + } + + public void testInheritor() { + Configuration dcc = cacheManager.getCacheConfiguration("inheritor"); + testDefault(dcc); + } + + public void testNoTakeOffline() { + Configuration dcc = cacheManager.getCacheConfiguration("noTakeOffline"); + assertEquals(1, dcc.sites().backups().size()); + + assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, + 12003, BackupFailurePolicy.WARN, null, new TakeOfflineConfiguration(0,0)))); + assertNull(dcc.sites().backupFor().remoteSite()); + assertNull(dcc.sites().backupFor().remoteCache()); + } + public void testTakeOfflineDifferentConfig() { + Configuration dcc = cacheManager.getCacheConfiguration("takeOfflineDifferentConfig"); + assertEquals(1, dcc.sites().backups().size()); + TakeOfflineConfiguration toc = new TakeOfflineConfiguration(321, 3765); + assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, + 12003l, BackupFailurePolicy.IGNORE, null, toc))); + + } + + private void testDefault(Configuration dcc) { + TakeOfflineConfiguration toc = new TakeOfflineConfiguration(123, 5673); + assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, + 12003l, BackupFailurePolicy.IGNORE, null, toc))); + assertEquals("someCache", dcc.sites().backupFor().remoteCache()); + assertEquals("SFO", dcc.sites().backupFor().remoteSite()); + } +} diff --git a/core/src/test/resources/configs/xsite/xsite-offline-test.xml b/core/src/test/resources/configs/xsite/xsite-offline-test.xml new file mode 100644 index 000000000000..ee7c54d6536d --- /dev/null +++ b/core/src/test/resources/configs/xsite/xsite-offline-test.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From e1b5e21b01d3220640125fbd6c4c6548675365bd Mon Sep 17 00:00:00 2001 From: Bela Ban Date: Fri, 28 Sep 2012 11:32:03 +0200 Subject: [PATCH 04/10] - Catching exception in GUI demo (otherwise the hourglass icon doesn't disappear) - Added toString() to XSiteBackup (better legibility in log) - Suppressing UNREACHABLE exception (otherwise it is printed 2x) --- .../jgroups/JGroupsBackupResponse.java | 2 +- .../xsite/BackupFailureException.java | 2 +- .../org/infinispan/xsite/XSiteBackup.java | 4 +++ .../org/infinispan/demo/InfinispanDemo.java | 34 ++++++++++++------- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java index 07848ffb20c5..550f2fe81fd4 100644 --- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java +++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java @@ -77,7 +77,7 @@ public void waitForBackupToFinish() throws Exception { } catch (TimeoutException te) { errors.put(siteName, newTimeoutException(entry, entry.getKey().getTimeout())); } catch (ExecutionException ue) { - log.tracef(ue.getCause(), "Communication error with site %s", siteName); + log.tracef("Communication error with site %s: %s", siteName, ue.getCause()); errors.put(siteName, ue.getCause()); } finally { elapsedTime += NANOSECONDS.toMillis(System.nanoTime() - startNanos); diff --git a/core/src/main/java/org/infinispan/xsite/BackupFailureException.java b/core/src/main/java/org/infinispan/xsite/BackupFailureException.java index eae85f2c38cf..a3ee5ae151c8 100644 --- a/core/src/main/java/org/infinispan/xsite/BackupFailureException.java +++ b/core/src/main/java/org/infinispan/xsite/BackupFailureException.java @@ -33,7 +33,7 @@ public class BackupFailureException extends RpcException { private String localCacheName; public BackupFailureException(Throwable cause, String remoteSiteName, String localCacheName) { - super("The local cache" + localCacheName + " failed to backup data to the remote site " + remoteSiteName, cause); + super("The local cache " + localCacheName + " failed to backup data to the remote site " + remoteSiteName, cause); this.remoteSiteName = remoteSiteName; this.localCacheName = localCacheName; } diff --git a/core/src/main/java/org/infinispan/xsite/XSiteBackup.java b/core/src/main/java/org/infinispan/xsite/XSiteBackup.java index 650f9932ccea..9fe29e1353ff 100644 --- a/core/src/main/java/org/infinispan/xsite/XSiteBackup.java +++ b/core/src/main/java/org/infinispan/xsite/XSiteBackup.java @@ -46,4 +46,8 @@ public boolean isSync() { public long getTimeout() { return timeout; } + + public String toString() { + return siteName + " (" + (sync? "sync" : "async") + ", timeout=" + timeout + ")"; + } } diff --git a/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java b/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java index b12377188bd6..4e0507f53350 100644 --- a/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java +++ b/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java @@ -28,10 +28,13 @@ import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.notifications.Listener; -import org.infinispan.notifications.cachelistener.annotation.*; +import org.infinispan.notifications.cachelistener.annotation.CacheEntriesEvicted; +import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified; +import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved; import org.infinispan.notifications.cachelistener.event.Event; -import org.infinispan.notifications.cachemanagerlistener.annotation.*; -import org.infinispan.notifications.cachemanagerlistener.event.*; +import org.infinispan.notifications.cachemanagerlistener.annotation.Merged; +import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged; +import org.infinispan.notifications.cachemanagerlistener.event.ViewChangedEvent; import org.infinispan.remoting.transport.Address; import org.infinispan.util.LegacyKeySupportSystemProperties; import org.infinispan.util.Util; @@ -167,15 +170,22 @@ public void actionPerformed(ActionEvent e) { @Override public void run() { // based on the value of the radio button: - if (putEntryRadioButton.isSelected()) { - cache.put(keyTextField.getText(), valueTextField.getText(), lifespan(), TimeUnit.MILLISECONDS, maxIdle(), TimeUnit.MILLISECONDS); - } else if (removeEntryRadioButton.isSelected()) { - cache.remove(keyTextField.getText()); - } else if (getEntryRadioButton.isSelected()) { - cache.get(keyTextField.getText()); + try { + if (putEntryRadioButton.isSelected()) { + cache.put(keyTextField.getText(), valueTextField.getText(), lifespan(), TimeUnit.MILLISECONDS, maxIdle(), TimeUnit.MILLISECONDS); + } else if (removeEntryRadioButton.isSelected()) { + cache.remove(keyTextField.getText()); + } else if (getEntryRadioButton.isSelected()) { + cache.get(keyTextField.getText()); + } + } + catch(Throwable t) { + // log.error("failed to update cache", t); + } + finally { + dataViewTab.repaint(); + processAction(goButton, false); } - dataViewTab.repaint(); - processAction(goButton, false); // reset these values lifespanSpinner.setValue(cache.getCacheConfiguration().expiration().lifespan()); @@ -379,7 +389,7 @@ public void run() { Util.close(stream); } } - cache = cacheManager.getCache(); + cache = cacheManager.getCache(); cache.start(); // repaint the cfg file display From c3015c554eaacd8e2494f80a3940c2ae79deb72c Mon Sep 17 00:00:00 2001 From: Mircea Markus Date: Tue, 25 Sep 2012 15:16:24 +0100 Subject: [PATCH 05/10] ISPN-2339 Upgrade to JGroups 3.2.0.Alpha2 --- parent/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parent/pom.xml b/parent/pom.xml index 43a92adefcf6..d0f4d26057f9 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -147,7 +147,7 @@ 1.4.1 6.1.25 1.0.5 - 3.2.0.Alpha1 + 3.2.0.Alpha2 0.16 2.1 20090211 From d98eeddd484861178b3931f42552906ada2b0384 Mon Sep 17 00:00:00 2001 From: Mircea Markus Date: Wed, 26 Sep 2012 10:37:36 +0100 Subject: [PATCH 06/10] ISPN-2343 Exception thrown to user from xsite ROC when failurePolicy is set to WARN --- .../remoting/transport/BackupResponse.java | 2 +- .../jgroups/JGroupsBackupResponse.java | 10 ++- .../infinispan/xsite/BackupSenderImpl.java | 4 +- .../xsite/BaseSiteUnreachableTest.java | 63 +++++++++++++++++++ .../xsite/NoFailureAsyncReplTest.java | 63 +++++++++++++++++++ .../backupfailure/NonTxBackupFailureTest.java | 17 ++++- 6 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java create mode 100644 core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java diff --git a/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java b/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java index b82b719ed7a7..7dc144fa2ddd 100644 --- a/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java +++ b/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java @@ -30,5 +30,5 @@ public interface BackupResponse { void waitForBackupToFinish() throws Exception; - Map getFailedBackups(); + Map getFailedBackups(); } diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java index 297096351e65..07848ffb20c5 100644 --- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java +++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -44,7 +45,7 @@ public class JGroupsBackupResponse implements BackupResponse { private static Log log = LogFactory.getLog(JGroupsBackupResponse.class); private final Map> syncBackupCalls; - private Map errors; + private Map errors; //there might be an significant difference in time between when the message is sent and when the actual wait // happens. Track that and adjust the timeouts accordingly. @@ -57,7 +58,7 @@ public JGroupsBackupResponse(Map> syncBackupCalls) { public void waitForBackupToFinish() throws Exception { long deductFromTimeout = NANOSECONDS.toMillis(System.nanoTime() - sendTimeNanos); - errors = new HashMap(syncBackupCalls.size()); + errors = new HashMap(syncBackupCalls.size()); long elapsedTime = 0; for (Map.Entry> entry : syncBackupCalls.entrySet()) { long timeout = entry.getKey().getTimeout(); @@ -75,6 +76,9 @@ public void waitForBackupToFinish() throws Exception { value = entry.getValue().get(timeout, MILLISECONDS); } catch (TimeoutException te) { errors.put(siteName, newTimeoutException(entry, entry.getKey().getTimeout())); + } catch (ExecutionException ue) { + log.tracef(ue.getCause(), "Communication error with site %s", siteName); + errors.put(siteName, ue.getCause()); } finally { elapsedTime += NANOSECONDS.toMillis(System.nanoTime() - startNanos); } @@ -90,7 +94,7 @@ public void waitForBackupToFinish() throws Exception { } @Override - public Map getFailedBackups() { + public Map getFailedBackups() { return errors; } diff --git a/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java b/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java index 7cbbdd00f369..14e357f6e222 100644 --- a/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java +++ b/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java @@ -125,8 +125,8 @@ public void processResponses(BackupResponse backupResponse, VisitableCommand com public void processResponses(BackupResponse backupResponse, VisitableCommand command, Transaction transaction) throws Throwable { backupResponse.waitForBackupToFinish(); SitesConfiguration sitesConfiguration = config.sites(); - Map failures = backupResponse.getFailedBackups(); - for (Map.Entry failure : failures.entrySet()) { + Map failures = backupResponse.getFailedBackups(); + for (Map.Entry failure : failures.entrySet()) { BackupFailurePolicy policy = sitesConfiguration.getFailurePolicy(failure.getKey()); if (policy == BackupFailurePolicy.CUSTOM) { CustomFailurePolicy customFailurePolicy = siteFailurePolicy.get(failure.getKey()); diff --git a/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java new file mode 100644 index 000000000000..889149f4be44 --- /dev/null +++ b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java @@ -0,0 +1,63 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.xsite; + +import org.infinispan.configuration.cache.BackupConfiguration; +import org.infinispan.configuration.cache.BackupFailurePolicy; +import org.infinispan.configuration.cache.CacheMode; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.configuration.global.GlobalConfigurationBuilder; +import org.testng.annotations.Test; + +/** + * @author Mircea Markus + * @since 5.2 + */ +@Test(groups = "xsite", testName = "xsite.BaseSiteUnreachableTest") +public class BaseSiteUnreachableTest extends AbstractXSiteTest { + + protected BackupFailurePolicy lonBackupFailurePolicy = BackupFailurePolicy.WARN; + protected BackupConfiguration.BackupStrategy lonBackupStrategy = BackupConfiguration.BackupStrategy.SYNC; + protected String lonCustomFailurePolicyClass = null; + + + @Override + protected void createSites() { + + GlobalConfigurationBuilder lonGc = GlobalConfigurationBuilder.defaultClusteredBuilder(); + lonGc + .sites().addSite().name("LON") + .sites().addSite().name("NYC") + .sites().localSite("LON"); + ConfigurationBuilder lon = getLonActiveConfig(); + lon.sites().addBackup() + .site("NYC") + .backupFailurePolicy(lonBackupFailurePolicy) + .strategy(lonBackupStrategy) + .failurePolicyClass(lonCustomFailurePolicyClass); + + createSite("LON", 2, lonGc, lon); + } + + protected ConfigurationBuilder getLonActiveConfig() { + return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, true); + } + +} diff --git a/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java new file mode 100644 index 000000000000..f5ae0964460a --- /dev/null +++ b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java @@ -0,0 +1,63 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.xsite; + +import org.infinispan.configuration.cache.BackupConfiguration; +import org.infinispan.configuration.cache.BackupFailurePolicy; +import org.infinispan.configuration.cache.CacheMode; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.xsite.BaseSiteUnreachableTest; +import org.testng.annotations.Test; + +import java.util.Collections; + +import static org.testng.Assert.assertNull; +import static org.testng.AssertJUnit.assertEquals; + +/** + * @author Mircea Markus + * @since 5.2 + */ +@Test (groups = "xsite", testName = "xsite.bridgemissing.NoFailureAsyncReplTest") +public class NoFailureAsyncReplTest extends BaseSiteUnreachableTest { + + public NoFailureAsyncReplTest() { + lonBackupStrategy = BackupConfiguration.BackupStrategy.SYNC; + lonBackupFailurePolicy = BackupFailurePolicy.WARN; + } + + public void testNoFailures() { + cache("LON", 0).put("k", "v"); + assertEquals(cache("LON", 0).get("k"), "v"); + assertEquals(cache("LON", 1).get("k"), "v"); + + cache("LON", 1).remove("k"); + assertNull(cache("LON", 0).get("k")); + assertNull(cache("LON", 1).get("k")); + + cache("LON", 0).putAll(Collections.singletonMap("k", "v")); + assertEquals(cache("LON", 0).get("k"), "v"); + assertEquals(cache("LON", 1).get("k"), "v"); + } + + protected ConfigurationBuilder getLonActiveConfig() { + return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); + } +} diff --git a/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java b/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java index 34d1b8943622..6a51c69fbce5 100644 --- a/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java +++ b/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java @@ -20,6 +20,9 @@ package org.infinispan.xsite.backupfailure; import org.infinispan.CacheException; +import org.infinispan.configuration.cache.CacheMode; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.testng.annotations.Test; import java.util.HashMap; import java.util.Map; @@ -30,11 +33,23 @@ * @author Mircea Markus * @since 5.2 */ -public abstract class NonTxBackupFailureTest extends BaseBackupFailureTest { +@Test (groups = "xsite", testName = "xsite.backupfailure.NonTxBackupFailureTest") +public class NonTxBackupFailureTest extends BaseBackupFailureTest { //todo - if I don't explicitly override the test methods then testNG won't execute them from superclass. //fix this once we move to JUnit + + @Override + protected ConfigurationBuilder getLonActiveConfig() { + return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); + } + + @Override + protected ConfigurationBuilder getNycActiveConfig() { + return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); + } + public void testPutFailure() { try { cache("LON", 0).put("k", "v"); From a0401373f0de39b59a0a5f809da97dc7f2071cba Mon Sep 17 00:00:00 2001 From: Mircea Markus Date: Thu, 27 Sep 2012 12:41:45 +0100 Subject: [PATCH 07/10] ISPN-2319 Add ability to take a site offline into x-site implementation - ongoing work --- .../cache/BackupConfiguration.java | 9 +- .../cache/BackupConfigurationBuilder.java | 21 ++- .../cache/TakeOfflineConfiguration.java | 77 ++++++++++ .../TakeOfflineConfigurationBuilder.java | 98 ++++++++++++ .../configuration/parsing/Attribute.java | 4 +- .../configuration/parsing/Element.java | 1 + .../configuration/parsing/Parser52.java | 32 +++- .../schema/infinispan-config-5.2.xsd | 145 +++++++++++------- .../xsite/BaseSiteUnreachableTest.java | 2 - ...ailureAsyncReplWarnFailurePolicyTest.java} | 7 +- .../xsite/XSiteFileParsing2Test.java | 7 +- .../xsite/XSiteFileParsing3Test.java | 83 ++++++++++ .../configs/xsite/xsite-offline-test.xml | 82 ++++++++++ 13 files changed, 498 insertions(+), 70 deletions(-) create mode 100644 core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java create mode 100644 core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java rename core/src/test/java/org/infinispan/xsite/{NoFailureAsyncReplTest.java => NoFailureAsyncReplWarnFailurePolicyTest.java} (92%) create mode 100644 core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java create mode 100644 core/src/test/resources/configs/xsite/xsite-offline-test.xml diff --git a/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java b/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java index 85586cef27a4..720a63ddb261 100644 --- a/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java +++ b/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java @@ -30,13 +30,16 @@ public class BackupConfiguration { private long timeout; private final BackupFailurePolicy backupFailurePolicy; private final String failurePolicyClass; + private final TakeOfflineConfiguration takeOfflineConfiguration; - public BackupConfiguration(String site, BackupStrategy strategy, long timeout, BackupFailurePolicy backupFailurePolicy, String failurePolicyClass) { + public BackupConfiguration(String site, BackupStrategy strategy, long timeout, BackupFailurePolicy backupFailurePolicy, + String failurePolicyClass, TakeOfflineConfiguration takeOfflineConfiguration) { this.site = site; this.strategy = strategy; this.timeout = timeout; this.backupFailurePolicy = backupFailurePolicy; this.failurePolicyClass = failurePolicyClass; + this.takeOfflineConfiguration = takeOfflineConfiguration; } /** @@ -53,6 +56,10 @@ public BackupStrategy strategy() { return strategy; } + public TakeOfflineConfiguration takeOffline() { + return takeOfflineConfiguration; + } + /** * If the failure policy is set to {@link BackupFailurePolicy#CUSTOM} then the failurePolicyClass is required and * should return the fully qualified name of a class implementing {@link org.infinispan.xsite.CustomFailurePolicy} diff --git a/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java b/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java index 37aef81a26e8..f68094be8c35 100644 --- a/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java +++ b/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java @@ -38,8 +38,11 @@ public class BackupConfigurationBuilder extends AbstractConfigurationChildBuilde private String failurePolicyClass; + private TakeOfflineConfigurationBuilder takeOfflineBuilder; + public BackupConfigurationBuilder(ConfigurationBuilder builder) { super(builder); + takeOfflineBuilder = new TakeOfflineConfigurationBuilder(builder); } /** @@ -105,6 +108,10 @@ public BackupConfiguration.BackupStrategy strategy() { return strategy; } + public TakeOfflineConfigurationBuilder takeOffline() { + return takeOfflineBuilder; + } + /** * Configures how the system behaves when the backup call fails. Only applies to sync backus. * The default values is {@link BackupFailurePolicy.WARN} @@ -125,6 +132,7 @@ public BackupFailurePolicy backupFailurePolicy() { @Override public void validate() { + takeOfflineBuilder.validate(); if (site == null) throw new ConfigurationException("The 'site' must be specified!"); if (backupFailurePolicy == BackupFailurePolicy.CUSTOM && (failurePolicyClass == null)) { @@ -135,11 +143,13 @@ public void validate() { @Override public BackupConfiguration create() { - return new BackupConfiguration(site, strategy, replicationTimeout, backupFailurePolicy, failurePolicyClass); + return new BackupConfiguration(site, strategy, replicationTimeout, backupFailurePolicy, failurePolicyClass, + takeOfflineBuilder.create()); } @Override public Builder read(BackupConfiguration template) { + this.takeOfflineBuilder.read(template.takeOffline()); this.site = template.site(); this.strategy = template.strategy(); this.backupFailurePolicy = template.backupFailurePolicy(); @@ -157,9 +167,12 @@ public boolean equals(Object o) { if (replicationTimeout != that.replicationTimeout) return false; if (backupFailurePolicy != that.backupFailurePolicy) return false; + if (failurePolicyClass != null ? !failurePolicyClass.equals(that.failurePolicyClass) : that.failurePolicyClass != null) + return false; if (site != null ? !site.equals(that.site) : that.site != null) return false; - if (failurePolicyClass != null ? !failurePolicyClass.equals(that.failurePolicyClass) : that.failurePolicyClass != null) return false; if (strategy != that.strategy) return false; + if (takeOfflineBuilder != null ? !takeOfflineBuilder.equals(that.takeOfflineBuilder) : that.takeOfflineBuilder != null) + return false; return true; } @@ -171,6 +184,7 @@ public int hashCode() { result = 31 * result + (int) (replicationTimeout ^ (replicationTimeout >>> 32)); result = 31 * result + (backupFailurePolicy != null ? backupFailurePolicy.hashCode() : 0); result = 31 * result + (failurePolicyClass != null ? failurePolicyClass.hashCode() : 0); + result = 31 * result + (takeOfflineBuilder != null ? takeOfflineBuilder.hashCode() : 0); return result; } @@ -181,7 +195,8 @@ public String toString() { ", strategy=" + strategy + ", replicationTimeout=" + replicationTimeout + ", backupFailurePolicy=" + backupFailurePolicy + - ", failurePolicyClass=" + failurePolicyClass + + ", failurePolicyClass='" + failurePolicyClass + '\'' + + ", takeOfflineBuilder=" + takeOfflineBuilder + '}'; } } diff --git a/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java new file mode 100644 index 000000000000..c5fb0589fa73 --- /dev/null +++ b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java @@ -0,0 +1,77 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.configuration.cache; + +/** + * @author Mircea Markus + * @since 5.2 + */ +public class TakeOfflineConfiguration { + + private int afterFailures; + private long minTimeToWait; + + public TakeOfflineConfiguration(int afterFailures, long minTimeToWait) { + this.afterFailures = afterFailures; + this.minTimeToWait = minTimeToWait; + } + + /** + * @see TakeOfflineConfigurationBuilder#afterFailures(int) + */ + public int afterFailures() { + return afterFailures; + } + + /** + * @see TakeOfflineConfigurationBuilder#minTimeToWait(long) + */ + public long minTimeToWait() { + return minTimeToWait; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TakeOfflineConfiguration)) return false; + + TakeOfflineConfiguration that = (TakeOfflineConfiguration) o; + + if (afterFailures != that.afterFailures) return false; + if (minTimeToWait != that.minTimeToWait) return false; + + return true; + } + + @Override + public int hashCode() { + int result = afterFailures; + result = 31 * result + (int) (minTimeToWait ^ (minTimeToWait >>> 32)); + return result; + } + + @Override + public String toString() { + return "TakeOfflineConfiguration{" + + "afterFailures=" + afterFailures + + ", minTimeToWait=" + minTimeToWait + + '}'; + } +} diff --git a/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java new file mode 100644 index 000000000000..f9c2d660e282 --- /dev/null +++ b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java @@ -0,0 +1,98 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.configuration.cache; + +import org.infinispan.configuration.Builder; + +/** + * @author Mircea Markus + * @since 5.2 + */ +public class TakeOfflineConfigurationBuilder extends AbstractConfigurationChildBuilder { + + private int afterFailures = 0; + private long minTimeToWait = 0; + + public TakeOfflineConfigurationBuilder(ConfigurationBuilder builder) { + super(builder); + } + + @Override + public void validate() { + } + + @Override + public TakeOfflineConfiguration create() { + return new TakeOfflineConfiguration(afterFailures, minTimeToWait); + } + + @Override + public Builder read(TakeOfflineConfiguration template) { + this.afterFailures = template.afterFailures(); + this.minTimeToWait = template.minTimeToWait(); + return this; + } + + /** + * The minimal number of millis to wait before taking this site offline, even in the case 'afterFailures' is reached. + * If smaller or equal to 0, then only 'afterFailures' is considered. + */ + public TakeOfflineConfigurationBuilder minTimeToWait(long minTimeToWait) { + this.minTimeToWait = minTimeToWait; + return this; + } + + /** + * The number of failed request operations after which this site should be taken offline. Defaults to 0 (never). A + * negative value would mean that the site will be taken offline after 'minTimeToWait'. + */ + public TakeOfflineConfigurationBuilder afterFailures(int afterFailures) { + this.afterFailures = afterFailures; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TakeOfflineConfigurationBuilder)) return false; + + TakeOfflineConfigurationBuilder that = (TakeOfflineConfigurationBuilder) o; + + if (afterFailures != that.afterFailures) return false; + if (minTimeToWait != that.minTimeToWait) return false; + + return true; + } + + @Override + public int hashCode() { + int result = afterFailures; + result = 31 * result + (int) (minTimeToWait ^ (minTimeToWait >>> 32)); + return result; + } + + @Override + public String toString() { + return "TakeOfflineConfigurationBuilder{" + + "afterFailures=" + afterFailures + + ", minTimeToWait=" + minTimeToWait + + '}'; + } +} diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java b/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java index e03bb1842789..f39bce253536 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java @@ -140,7 +140,9 @@ public enum Attribute { BACKUP_FAILURE_POLICY("backupFailurePolicy"), REMOTE_SITE("remoteSite"), REMOTE_CACHE("remoteCache"), - FAILURE_POLICY_CLASS("failurePolicyClass") + FAILURE_POLICY_CLASS("failurePolicyClass"), + AFTER_FAILURES("afterFailures"), + MIN_TIME_TO_WAIT("minTimeToWait") ; private final String name; diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Element.java b/core/src/main/java/org/infinispan/configuration/parsing/Element.java index 5410a91f8354..f579d42bb631 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Element.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Element.java @@ -88,6 +88,7 @@ public enum Element { BACKUPS("backups"), BACKUP("backup"), BACKUP_FOR("backupFor"), + TAKE_OFFLINE("takeOffline") ; private final String name; diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java b/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java index 3deecbe455f1..ff6c97449ae4 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java @@ -308,7 +308,7 @@ private void parseBackups(XMLExtendedStreamReader reader, ConfigurationBuilder c while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) { Element element = Element.forName(reader.getLocalName()); switch (element) { - case BACKUP: + case BACKUP: { BackupConfigurationBuilder backup = ccb.sites().addBackup(); for (int i = 0; i < reader.getAttributeCount(); i++) { ParseUtils.requireNoNamespaceAttribute(reader, i); @@ -334,14 +334,42 @@ private void parseBackups(XMLExtendedStreamReader reader, ConfigurationBuilder c throw ParseUtils.unexpectedElement(reader); } } + if (parseTakeOffline(reader, backup)) { + ParseUtils.requireNoContent(reader); + } + } default: { ParseUtils.unexpectedElement(reader); } - ParseUtils.requireNoContent(reader); } } } + private boolean parseTakeOffline(XMLExtendedStreamReader reader, BackupConfigurationBuilder backup) throws XMLStreamException { + if (reader.nextTag() != XMLStreamConstants.END_ELEMENT) { + Element takeOffline = Element.forName(reader.getLocalName()); + for (int i = 0; i < reader.getAttributeCount(); i++) { + ParseUtils.requireNoNamespaceAttribute(reader, i); + String value = replaceProperties(reader.getAttributeValue(i)); + Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); + switch (attribute) { + case AFTER_FAILURES: + backup.takeOffline().afterFailures(Integer.parseInt(value)); + break; + case MIN_TIME_TO_WAIT: + backup.takeOffline().minTimeToWait(Long.parseLong(value)); + break; + default: + throw ParseUtils.unexpectedElement(reader); + } + } + ParseUtils.requireNoContent(reader); + return true; + } else { + return false; + } + } + private void parseTransaction(final XMLExtendedStreamReader reader, final ConfigurationBuilderHolder holder) throws XMLStreamException { ConfigurationBuilder builder = holder.getCurrentConfigurationBuilder(); boolean forceSetTransactional = false; diff --git a/core/src/main/resources/schema/infinispan-config-5.2.xsd b/core/src/main/resources/schema/infinispan-config-5.2.xsd index 89ad411f1a79..f1c09edb9757 100644 --- a/core/src/main/resources/schema/infinispan-config-5.2.xsd +++ b/core/src/main/resources/schema/infinispan-config-5.2.xsd @@ -428,65 +428,14 @@ - + - Configures a specific site where this cache backups data. The name of the backup must match + Configures a specific site where this cache backups data. The name of the backup + must match a site defined in the "global" section. - - - - - Name of the remote site where this cache backups data. - - - - - - - The strategy used for backing up data: "SYNC" or "ASYNC". Defaults to "ASYNC" - - - - - - - - - - - - - Decides what the system would do in case of failure during backup. Defaults to "FAIL" - - - - - - - - - - - - - - - The timeout(millis) to be used when backing up data remotely. Defaults to 10 secs. - - - - - - - If the 'backupFailurePolicy' is set to 'CUSTOM' then this attribute is required and should - contain the fully qualified name of a class implementing org.infinispan.xsite.CustomFailurePolicy. - - - - @@ -1168,6 +1117,94 @@ + + + + + + Determines whether this backup is taken offline (ignored) after a certain + number of tries. + + + + + + + The number of failed request operations after which this site + should be taken offline. Defaults to 0 (never). + A negative value would mean that the site will be taken offline + after 'minTimeToWait'. + + + + + + + The minimal number of millis to wait before taking this site + offline, even in the case 'afterFailures' is reached. + If smaller or equal to 0, then only 'afterFailures' is considered. + + + + + + + + + + Name of the remote site where this cache backups data. + + + + + + + The strategy used for backing up data: "SYNC" or "ASYNC". Defaults to "ASYNC" + + + + + + + + + + + + + Decides what the system would do in case of failure during backup. Defaults to + "FAIL" + + + + + + + + + + + + + + + The timeout(millis) to be used when backing up data remotely. Defaults to 10 + secs. + + + + + + + If the 'backupFailurePolicy' is set to 'CUSTOM' then this attribute is + required and should + contain the fully qualified name of a class implementing + org.infinispan.xsite.CustomFailurePolicy. + + + + + diff --git a/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java index 889149f4be44..e6480a8fbae3 100644 --- a/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java +++ b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java @@ -24,13 +24,11 @@ import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.global.GlobalConfigurationBuilder; -import org.testng.annotations.Test; /** * @author Mircea Markus * @since 5.2 */ -@Test(groups = "xsite", testName = "xsite.BaseSiteUnreachableTest") public class BaseSiteUnreachableTest extends AbstractXSiteTest { protected BackupFailurePolicy lonBackupFailurePolicy = BackupFailurePolicy.WARN; diff --git a/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java similarity index 92% rename from core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java rename to core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java index f5ae0964460a..df2dfa95a264 100644 --- a/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplTest.java +++ b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java @@ -23,7 +23,6 @@ import org.infinispan.configuration.cache.BackupFailurePolicy; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; -import org.infinispan.xsite.BaseSiteUnreachableTest; import org.testng.annotations.Test; import java.util.Collections; @@ -35,10 +34,10 @@ * @author Mircea Markus * @since 5.2 */ -@Test (groups = "xsite", testName = "xsite.bridgemissing.NoFailureAsyncReplTest") -public class NoFailureAsyncReplTest extends BaseSiteUnreachableTest { +@Test (groups = "xsite", testName = "xsite.bridgemissing.NoFailureAsyncReplWarnFailurePolicyTest") +public class NoFailureAsyncReplWarnFailurePolicyTest extends BaseSiteUnreachableTest { - public NoFailureAsyncReplTest() { + public NoFailureAsyncReplWarnFailurePolicyTest() { lonBackupStrategy = BackupConfiguration.BackupStrategy.SYNC; lonBackupFailurePolicy = BackupFailurePolicy.WARN; } diff --git a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java index a40270223f71..ddcee159a302 100644 --- a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java +++ b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java @@ -22,6 +22,7 @@ import org.infinispan.configuration.cache.BackupConfiguration; import org.infinispan.configuration.cache.BackupFailurePolicy; import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.TakeOfflineConfiguration; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.fwk.TestCacheManagerFactory; @@ -62,7 +63,7 @@ public void testNoBackupFor() { assertEquals(1, dcc.sites().backups().size()); assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003, BackupFailurePolicy.WARN, null))); + 12003, BackupFailurePolicy.WARN, null, new TakeOfflineConfiguration(0,0)))); assertNull(dcc.sites().backupFor().remoteSite()); assertNull(dcc.sites().backupFor().remoteCache()); } @@ -75,9 +76,9 @@ public void testNoBackupFor2() { private void testDefault(Configuration dcc) { assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003l, BackupFailurePolicy.IGNORE, null))); + 12003l, BackupFailurePolicy.IGNORE, null, new TakeOfflineConfiguration(0,0)))); assertTrue(dcc.sites().backups().contains(new BackupConfiguration("SFO", BackupConfiguration.BackupStrategy.ASYNC, - 10000l, BackupFailurePolicy.WARN, null))); + 10000l, BackupFailurePolicy.WARN, null,new TakeOfflineConfiguration(0,0)))); assertEquals("someCache", dcc.sites().backupFor().remoteCache()); assertEquals("SFO", dcc.sites().backupFor().remoteSite()); } diff --git a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java new file mode 100644 index 000000000000..48f8a760c6f7 --- /dev/null +++ b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java @@ -0,0 +1,83 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +package org.infinispan.xsite; + +import org.infinispan.configuration.cache.BackupConfiguration; +import org.infinispan.configuration.cache.BackupFailurePolicy; +import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.TakeOfflineConfiguration; +import org.infinispan.manager.EmbeddedCacheManager; +import org.infinispan.test.SingleCacheManagerTest; +import org.infinispan.test.fwk.TestCacheManagerFactory; +import org.testng.annotations.Test; + +import static org.testng.AssertJUnit.*; + +/** + * @author Mircea Markus + * @since 5.2 + */ +@Test (groups = "functional", testName = "xsite.XSiteFileParsing3Test") +public class XSiteFileParsing3Test extends SingleCacheManagerTest { + public static final String FILE_NAME = "configs/xsite/xsite-offline-test.xml"; + + @Override + protected EmbeddedCacheManager createCacheManager() throws Exception { + EmbeddedCacheManager embeddedCacheManager = TestCacheManagerFactory.fromXml(FILE_NAME); + return embeddedCacheManager; + } + + public void testDefaultCache() { + Configuration dcc = cacheManager.getDefaultCacheConfiguration(); + assertEquals(dcc.sites().backups().size(), 1); + testDefault(dcc); + } + + public void testInheritor() { + Configuration dcc = cacheManager.getCacheConfiguration("inheritor"); + testDefault(dcc); + } + + public void testNoTakeOffline() { + Configuration dcc = cacheManager.getCacheConfiguration("noTakeOffline"); + assertEquals(1, dcc.sites().backups().size()); + + assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, + 12003, BackupFailurePolicy.WARN, null, new TakeOfflineConfiguration(0,0)))); + assertNull(dcc.sites().backupFor().remoteSite()); + assertNull(dcc.sites().backupFor().remoteCache()); + } + public void testTakeOfflineDifferentConfig() { + Configuration dcc = cacheManager.getCacheConfiguration("takeOfflineDifferentConfig"); + assertEquals(1, dcc.sites().backups().size()); + TakeOfflineConfiguration toc = new TakeOfflineConfiguration(321, 3765); + assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, + 12003l, BackupFailurePolicy.IGNORE, null, toc))); + + } + + private void testDefault(Configuration dcc) { + TakeOfflineConfiguration toc = new TakeOfflineConfiguration(123, 5673); + assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, + 12003l, BackupFailurePolicy.IGNORE, null, toc))); + assertEquals("someCache", dcc.sites().backupFor().remoteCache()); + assertEquals("SFO", dcc.sites().backupFor().remoteSite()); + } +} diff --git a/core/src/test/resources/configs/xsite/xsite-offline-test.xml b/core/src/test/resources/configs/xsite/xsite-offline-test.xml new file mode 100644 index 000000000000..ee7c54d6536d --- /dev/null +++ b/core/src/test/resources/configs/xsite/xsite-offline-test.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5f54fd5d342ba6081141bdc11445af71df9e7d29 Mon Sep 17 00:00:00 2001 From: Bela Ban Date: Fri, 28 Sep 2012 11:32:03 +0200 Subject: [PATCH 08/10] - Catching exception in GUI demo (otherwise the hourglass icon doesn't disappear) - Added toString() to XSiteBackup (better legibility in log) - Suppressing UNREACHABLE exception (otherwise it is printed 2x) --- .../jgroups/JGroupsBackupResponse.java | 2 +- .../xsite/BackupFailureException.java | 2 +- .../org/infinispan/xsite/XSiteBackup.java | 4 +++ .../org/infinispan/demo/InfinispanDemo.java | 34 ++++++++++++------- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java index 07848ffb20c5..550f2fe81fd4 100644 --- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java +++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java @@ -77,7 +77,7 @@ public void waitForBackupToFinish() throws Exception { } catch (TimeoutException te) { errors.put(siteName, newTimeoutException(entry, entry.getKey().getTimeout())); } catch (ExecutionException ue) { - log.tracef(ue.getCause(), "Communication error with site %s", siteName); + log.tracef("Communication error with site %s: %s", siteName, ue.getCause()); errors.put(siteName, ue.getCause()); } finally { elapsedTime += NANOSECONDS.toMillis(System.nanoTime() - startNanos); diff --git a/core/src/main/java/org/infinispan/xsite/BackupFailureException.java b/core/src/main/java/org/infinispan/xsite/BackupFailureException.java index eae85f2c38cf..a3ee5ae151c8 100644 --- a/core/src/main/java/org/infinispan/xsite/BackupFailureException.java +++ b/core/src/main/java/org/infinispan/xsite/BackupFailureException.java @@ -33,7 +33,7 @@ public class BackupFailureException extends RpcException { private String localCacheName; public BackupFailureException(Throwable cause, String remoteSiteName, String localCacheName) { - super("The local cache" + localCacheName + " failed to backup data to the remote site " + remoteSiteName, cause); + super("The local cache " + localCacheName + " failed to backup data to the remote site " + remoteSiteName, cause); this.remoteSiteName = remoteSiteName; this.localCacheName = localCacheName; } diff --git a/core/src/main/java/org/infinispan/xsite/XSiteBackup.java b/core/src/main/java/org/infinispan/xsite/XSiteBackup.java index 650f9932ccea..9fe29e1353ff 100644 --- a/core/src/main/java/org/infinispan/xsite/XSiteBackup.java +++ b/core/src/main/java/org/infinispan/xsite/XSiteBackup.java @@ -46,4 +46,8 @@ public boolean isSync() { public long getTimeout() { return timeout; } + + public String toString() { + return siteName + " (" + (sync? "sync" : "async") + ", timeout=" + timeout + ")"; + } } diff --git a/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java b/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java index b12377188bd6..4e0507f53350 100644 --- a/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java +++ b/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java @@ -28,10 +28,13 @@ import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.notifications.Listener; -import org.infinispan.notifications.cachelistener.annotation.*; +import org.infinispan.notifications.cachelistener.annotation.CacheEntriesEvicted; +import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified; +import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved; import org.infinispan.notifications.cachelistener.event.Event; -import org.infinispan.notifications.cachemanagerlistener.annotation.*; -import org.infinispan.notifications.cachemanagerlistener.event.*; +import org.infinispan.notifications.cachemanagerlistener.annotation.Merged; +import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged; +import org.infinispan.notifications.cachemanagerlistener.event.ViewChangedEvent; import org.infinispan.remoting.transport.Address; import org.infinispan.util.LegacyKeySupportSystemProperties; import org.infinispan.util.Util; @@ -167,15 +170,22 @@ public void actionPerformed(ActionEvent e) { @Override public void run() { // based on the value of the radio button: - if (putEntryRadioButton.isSelected()) { - cache.put(keyTextField.getText(), valueTextField.getText(), lifespan(), TimeUnit.MILLISECONDS, maxIdle(), TimeUnit.MILLISECONDS); - } else if (removeEntryRadioButton.isSelected()) { - cache.remove(keyTextField.getText()); - } else if (getEntryRadioButton.isSelected()) { - cache.get(keyTextField.getText()); + try { + if (putEntryRadioButton.isSelected()) { + cache.put(keyTextField.getText(), valueTextField.getText(), lifespan(), TimeUnit.MILLISECONDS, maxIdle(), TimeUnit.MILLISECONDS); + } else if (removeEntryRadioButton.isSelected()) { + cache.remove(keyTextField.getText()); + } else if (getEntryRadioButton.isSelected()) { + cache.get(keyTextField.getText()); + } + } + catch(Throwable t) { + // log.error("failed to update cache", t); + } + finally { + dataViewTab.repaint(); + processAction(goButton, false); } - dataViewTab.repaint(); - processAction(goButton, false); // reset these values lifespanSpinner.setValue(cache.getCacheConfiguration().expiration().lifespan()); @@ -379,7 +389,7 @@ public void run() { Util.close(stream); } } - cache = cacheManager.getCache(); + cache = cacheManager.getCache(); cache.start(); // repaint the cfg file display From e498b0a3689904f3d0ae8d6afb7e0dc7070f8a9e Mon Sep 17 00:00:00 2001 From: Bela Ban Date: Fri, 28 Sep 2012 15:02:19 +0200 Subject: [PATCH 09/10] Pulled upstream/master --> master --- .../cache/BackupConfiguration.java | 9 +- .../cache/BackupConfigurationBuilder.java | 21 +-- .../cache/TakeOfflineConfiguration.java | 77 ---------- .../TakeOfflineConfigurationBuilder.java | 98 ------------ .../configuration/parsing/Attribute.java | 4 +- .../configuration/parsing/Element.java | 1 - .../configuration/parsing/Parser52.java | 32 +--- .../remoting/transport/BackupResponse.java | 2 +- .../jgroups/JGroupsBackupResponse.java | 10 +- .../xsite/BackupFailureException.java | 2 +- .../infinispan/xsite/BackupSenderImpl.java | 4 +- .../org/infinispan/xsite/XSiteBackup.java | 4 - .../schema/infinispan-config-5.2.xsd | 145 +++++++----------- .../xsite/BaseSiteUnreachableTest.java | 61 -------- ...FailureAsyncReplWarnFailurePolicyTest.java | 62 -------- .../xsite/XSiteFileParsing2Test.java | 7 +- .../xsite/XSiteFileParsing3Test.java | 83 ---------- .../backupfailure/NonTxBackupFailureTest.java | 17 +- .../configs/xsite/xsite-offline-test.xml | 82 ---------- .../org/infinispan/demo/InfinispanDemo.java | 34 ++-- parent/pom.xml | 2 +- 21 files changed, 85 insertions(+), 672 deletions(-) delete mode 100644 core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java delete mode 100644 core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java delete mode 100644 core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java delete mode 100644 core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java delete mode 100644 core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java delete mode 100644 core/src/test/resources/configs/xsite/xsite-offline-test.xml diff --git a/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java b/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java index 720a63ddb261..85586cef27a4 100644 --- a/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java +++ b/core/src/main/java/org/infinispan/configuration/cache/BackupConfiguration.java @@ -30,16 +30,13 @@ public class BackupConfiguration { private long timeout; private final BackupFailurePolicy backupFailurePolicy; private final String failurePolicyClass; - private final TakeOfflineConfiguration takeOfflineConfiguration; - public BackupConfiguration(String site, BackupStrategy strategy, long timeout, BackupFailurePolicy backupFailurePolicy, - String failurePolicyClass, TakeOfflineConfiguration takeOfflineConfiguration) { + public BackupConfiguration(String site, BackupStrategy strategy, long timeout, BackupFailurePolicy backupFailurePolicy, String failurePolicyClass) { this.site = site; this.strategy = strategy; this.timeout = timeout; this.backupFailurePolicy = backupFailurePolicy; this.failurePolicyClass = failurePolicyClass; - this.takeOfflineConfiguration = takeOfflineConfiguration; } /** @@ -56,10 +53,6 @@ public BackupStrategy strategy() { return strategy; } - public TakeOfflineConfiguration takeOffline() { - return takeOfflineConfiguration; - } - /** * If the failure policy is set to {@link BackupFailurePolicy#CUSTOM} then the failurePolicyClass is required and * should return the fully qualified name of a class implementing {@link org.infinispan.xsite.CustomFailurePolicy} diff --git a/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java b/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java index f68094be8c35..37aef81a26e8 100644 --- a/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java +++ b/core/src/main/java/org/infinispan/configuration/cache/BackupConfigurationBuilder.java @@ -38,11 +38,8 @@ public class BackupConfigurationBuilder extends AbstractConfigurationChildBuilde private String failurePolicyClass; - private TakeOfflineConfigurationBuilder takeOfflineBuilder; - public BackupConfigurationBuilder(ConfigurationBuilder builder) { super(builder); - takeOfflineBuilder = new TakeOfflineConfigurationBuilder(builder); } /** @@ -108,10 +105,6 @@ public BackupConfiguration.BackupStrategy strategy() { return strategy; } - public TakeOfflineConfigurationBuilder takeOffline() { - return takeOfflineBuilder; - } - /** * Configures how the system behaves when the backup call fails. Only applies to sync backus. * The default values is {@link BackupFailurePolicy.WARN} @@ -132,7 +125,6 @@ public BackupFailurePolicy backupFailurePolicy() { @Override public void validate() { - takeOfflineBuilder.validate(); if (site == null) throw new ConfigurationException("The 'site' must be specified!"); if (backupFailurePolicy == BackupFailurePolicy.CUSTOM && (failurePolicyClass == null)) { @@ -143,13 +135,11 @@ public void validate() { @Override public BackupConfiguration create() { - return new BackupConfiguration(site, strategy, replicationTimeout, backupFailurePolicy, failurePolicyClass, - takeOfflineBuilder.create()); + return new BackupConfiguration(site, strategy, replicationTimeout, backupFailurePolicy, failurePolicyClass); } @Override public Builder read(BackupConfiguration template) { - this.takeOfflineBuilder.read(template.takeOffline()); this.site = template.site(); this.strategy = template.strategy(); this.backupFailurePolicy = template.backupFailurePolicy(); @@ -167,12 +157,9 @@ public boolean equals(Object o) { if (replicationTimeout != that.replicationTimeout) return false; if (backupFailurePolicy != that.backupFailurePolicy) return false; - if (failurePolicyClass != null ? !failurePolicyClass.equals(that.failurePolicyClass) : that.failurePolicyClass != null) - return false; if (site != null ? !site.equals(that.site) : that.site != null) return false; + if (failurePolicyClass != null ? !failurePolicyClass.equals(that.failurePolicyClass) : that.failurePolicyClass != null) return false; if (strategy != that.strategy) return false; - if (takeOfflineBuilder != null ? !takeOfflineBuilder.equals(that.takeOfflineBuilder) : that.takeOfflineBuilder != null) - return false; return true; } @@ -184,7 +171,6 @@ public int hashCode() { result = 31 * result + (int) (replicationTimeout ^ (replicationTimeout >>> 32)); result = 31 * result + (backupFailurePolicy != null ? backupFailurePolicy.hashCode() : 0); result = 31 * result + (failurePolicyClass != null ? failurePolicyClass.hashCode() : 0); - result = 31 * result + (takeOfflineBuilder != null ? takeOfflineBuilder.hashCode() : 0); return result; } @@ -195,8 +181,7 @@ public String toString() { ", strategy=" + strategy + ", replicationTimeout=" + replicationTimeout + ", backupFailurePolicy=" + backupFailurePolicy + - ", failurePolicyClass='" + failurePolicyClass + '\'' + - ", takeOfflineBuilder=" + takeOfflineBuilder + + ", failurePolicyClass=" + failurePolicyClass + '}'; } } diff --git a/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java deleted file mode 100644 index c5fb0589fa73..000000000000 --- a/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfiguration.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @author tags. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU Lesser General Public License, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -package org.infinispan.configuration.cache; - -/** - * @author Mircea Markus - * @since 5.2 - */ -public class TakeOfflineConfiguration { - - private int afterFailures; - private long minTimeToWait; - - public TakeOfflineConfiguration(int afterFailures, long minTimeToWait) { - this.afterFailures = afterFailures; - this.minTimeToWait = minTimeToWait; - } - - /** - * @see TakeOfflineConfigurationBuilder#afterFailures(int) - */ - public int afterFailures() { - return afterFailures; - } - - /** - * @see TakeOfflineConfigurationBuilder#minTimeToWait(long) - */ - public long minTimeToWait() { - return minTimeToWait; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof TakeOfflineConfiguration)) return false; - - TakeOfflineConfiguration that = (TakeOfflineConfiguration) o; - - if (afterFailures != that.afterFailures) return false; - if (minTimeToWait != that.minTimeToWait) return false; - - return true; - } - - @Override - public int hashCode() { - int result = afterFailures; - result = 31 * result + (int) (minTimeToWait ^ (minTimeToWait >>> 32)); - return result; - } - - @Override - public String toString() { - return "TakeOfflineConfiguration{" + - "afterFailures=" + afterFailures + - ", minTimeToWait=" + minTimeToWait + - '}'; - } -} diff --git a/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java b/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java deleted file mode 100644 index f9c2d660e282..000000000000 --- a/core/src/main/java/org/infinispan/configuration/cache/TakeOfflineConfigurationBuilder.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @author tags. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU Lesser General Public License, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -package org.infinispan.configuration.cache; - -import org.infinispan.configuration.Builder; - -/** - * @author Mircea Markus - * @since 5.2 - */ -public class TakeOfflineConfigurationBuilder extends AbstractConfigurationChildBuilder { - - private int afterFailures = 0; - private long minTimeToWait = 0; - - public TakeOfflineConfigurationBuilder(ConfigurationBuilder builder) { - super(builder); - } - - @Override - public void validate() { - } - - @Override - public TakeOfflineConfiguration create() { - return new TakeOfflineConfiguration(afterFailures, minTimeToWait); - } - - @Override - public Builder read(TakeOfflineConfiguration template) { - this.afterFailures = template.afterFailures(); - this.minTimeToWait = template.minTimeToWait(); - return this; - } - - /** - * The minimal number of millis to wait before taking this site offline, even in the case 'afterFailures' is reached. - * If smaller or equal to 0, then only 'afterFailures' is considered. - */ - public TakeOfflineConfigurationBuilder minTimeToWait(long minTimeToWait) { - this.minTimeToWait = minTimeToWait; - return this; - } - - /** - * The number of failed request operations after which this site should be taken offline. Defaults to 0 (never). A - * negative value would mean that the site will be taken offline after 'minTimeToWait'. - */ - public TakeOfflineConfigurationBuilder afterFailures(int afterFailures) { - this.afterFailures = afterFailures; - return this; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof TakeOfflineConfigurationBuilder)) return false; - - TakeOfflineConfigurationBuilder that = (TakeOfflineConfigurationBuilder) o; - - if (afterFailures != that.afterFailures) return false; - if (minTimeToWait != that.minTimeToWait) return false; - - return true; - } - - @Override - public int hashCode() { - int result = afterFailures; - result = 31 * result + (int) (minTimeToWait ^ (minTimeToWait >>> 32)); - return result; - } - - @Override - public String toString() { - return "TakeOfflineConfigurationBuilder{" + - "afterFailures=" + afterFailures + - ", minTimeToWait=" + minTimeToWait + - '}'; - } -} diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java b/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java index f39bce253536..e03bb1842789 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Attribute.java @@ -140,9 +140,7 @@ public enum Attribute { BACKUP_FAILURE_POLICY("backupFailurePolicy"), REMOTE_SITE("remoteSite"), REMOTE_CACHE("remoteCache"), - FAILURE_POLICY_CLASS("failurePolicyClass"), - AFTER_FAILURES("afterFailures"), - MIN_TIME_TO_WAIT("minTimeToWait") + FAILURE_POLICY_CLASS("failurePolicyClass") ; private final String name; diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Element.java b/core/src/main/java/org/infinispan/configuration/parsing/Element.java index f579d42bb631..5410a91f8354 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Element.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Element.java @@ -88,7 +88,6 @@ public enum Element { BACKUPS("backups"), BACKUP("backup"), BACKUP_FOR("backupFor"), - TAKE_OFFLINE("takeOffline") ; private final String name; diff --git a/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java b/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java index ff6c97449ae4..3deecbe455f1 100644 --- a/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java +++ b/core/src/main/java/org/infinispan/configuration/parsing/Parser52.java @@ -308,7 +308,7 @@ private void parseBackups(XMLExtendedStreamReader reader, ConfigurationBuilder c while (reader.hasNext() && (reader.nextTag() != XMLStreamConstants.END_ELEMENT)) { Element element = Element.forName(reader.getLocalName()); switch (element) { - case BACKUP: { + case BACKUP: BackupConfigurationBuilder backup = ccb.sites().addBackup(); for (int i = 0; i < reader.getAttributeCount(); i++) { ParseUtils.requireNoNamespaceAttribute(reader, i); @@ -334,42 +334,14 @@ private void parseBackups(XMLExtendedStreamReader reader, ConfigurationBuilder c throw ParseUtils.unexpectedElement(reader); } } - if (parseTakeOffline(reader, backup)) { - ParseUtils.requireNoContent(reader); - } - } default: { ParseUtils.unexpectedElement(reader); } + ParseUtils.requireNoContent(reader); } } } - private boolean parseTakeOffline(XMLExtendedStreamReader reader, BackupConfigurationBuilder backup) throws XMLStreamException { - if (reader.nextTag() != XMLStreamConstants.END_ELEMENT) { - Element takeOffline = Element.forName(reader.getLocalName()); - for (int i = 0; i < reader.getAttributeCount(); i++) { - ParseUtils.requireNoNamespaceAttribute(reader, i); - String value = replaceProperties(reader.getAttributeValue(i)); - Attribute attribute = Attribute.forName(reader.getAttributeLocalName(i)); - switch (attribute) { - case AFTER_FAILURES: - backup.takeOffline().afterFailures(Integer.parseInt(value)); - break; - case MIN_TIME_TO_WAIT: - backup.takeOffline().minTimeToWait(Long.parseLong(value)); - break; - default: - throw ParseUtils.unexpectedElement(reader); - } - } - ParseUtils.requireNoContent(reader); - return true; - } else { - return false; - } - } - private void parseTransaction(final XMLExtendedStreamReader reader, final ConfigurationBuilderHolder holder) throws XMLStreamException { ConfigurationBuilder builder = holder.getCurrentConfigurationBuilder(); boolean forceSetTransactional = false; diff --git a/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java b/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java index 7dc144fa2ddd..b82b719ed7a7 100644 --- a/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java +++ b/core/src/main/java/org/infinispan/remoting/transport/BackupResponse.java @@ -30,5 +30,5 @@ public interface BackupResponse { void waitForBackupToFinish() throws Exception; - Map getFailedBackups(); + Map getFailedBackups(); } diff --git a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java index 550f2fe81fd4..297096351e65 100644 --- a/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java +++ b/core/src/main/java/org/infinispan/remoting/transport/jgroups/JGroupsBackupResponse.java @@ -28,7 +28,6 @@ import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -45,7 +44,7 @@ public class JGroupsBackupResponse implements BackupResponse { private static Log log = LogFactory.getLog(JGroupsBackupResponse.class); private final Map> syncBackupCalls; - private Map errors; + private Map errors; //there might be an significant difference in time between when the message is sent and when the actual wait // happens. Track that and adjust the timeouts accordingly. @@ -58,7 +57,7 @@ public JGroupsBackupResponse(Map> syncBackupCalls) { public void waitForBackupToFinish() throws Exception { long deductFromTimeout = NANOSECONDS.toMillis(System.nanoTime() - sendTimeNanos); - errors = new HashMap(syncBackupCalls.size()); + errors = new HashMap(syncBackupCalls.size()); long elapsedTime = 0; for (Map.Entry> entry : syncBackupCalls.entrySet()) { long timeout = entry.getKey().getTimeout(); @@ -76,9 +75,6 @@ public void waitForBackupToFinish() throws Exception { value = entry.getValue().get(timeout, MILLISECONDS); } catch (TimeoutException te) { errors.put(siteName, newTimeoutException(entry, entry.getKey().getTimeout())); - } catch (ExecutionException ue) { - log.tracef("Communication error with site %s: %s", siteName, ue.getCause()); - errors.put(siteName, ue.getCause()); } finally { elapsedTime += NANOSECONDS.toMillis(System.nanoTime() - startNanos); } @@ -94,7 +90,7 @@ public void waitForBackupToFinish() throws Exception { } @Override - public Map getFailedBackups() { + public Map getFailedBackups() { return errors; } diff --git a/core/src/main/java/org/infinispan/xsite/BackupFailureException.java b/core/src/main/java/org/infinispan/xsite/BackupFailureException.java index a3ee5ae151c8..eae85f2c38cf 100644 --- a/core/src/main/java/org/infinispan/xsite/BackupFailureException.java +++ b/core/src/main/java/org/infinispan/xsite/BackupFailureException.java @@ -33,7 +33,7 @@ public class BackupFailureException extends RpcException { private String localCacheName; public BackupFailureException(Throwable cause, String remoteSiteName, String localCacheName) { - super("The local cache " + localCacheName + " failed to backup data to the remote site " + remoteSiteName, cause); + super("The local cache" + localCacheName + " failed to backup data to the remote site " + remoteSiteName, cause); this.remoteSiteName = remoteSiteName; this.localCacheName = localCacheName; } diff --git a/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java b/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java index 14e357f6e222..7cbbdd00f369 100644 --- a/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java +++ b/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java @@ -125,8 +125,8 @@ public void processResponses(BackupResponse backupResponse, VisitableCommand com public void processResponses(BackupResponse backupResponse, VisitableCommand command, Transaction transaction) throws Throwable { backupResponse.waitForBackupToFinish(); SitesConfiguration sitesConfiguration = config.sites(); - Map failures = backupResponse.getFailedBackups(); - for (Map.Entry failure : failures.entrySet()) { + Map failures = backupResponse.getFailedBackups(); + for (Map.Entry failure : failures.entrySet()) { BackupFailurePolicy policy = sitesConfiguration.getFailurePolicy(failure.getKey()); if (policy == BackupFailurePolicy.CUSTOM) { CustomFailurePolicy customFailurePolicy = siteFailurePolicy.get(failure.getKey()); diff --git a/core/src/main/java/org/infinispan/xsite/XSiteBackup.java b/core/src/main/java/org/infinispan/xsite/XSiteBackup.java index 9fe29e1353ff..650f9932ccea 100644 --- a/core/src/main/java/org/infinispan/xsite/XSiteBackup.java +++ b/core/src/main/java/org/infinispan/xsite/XSiteBackup.java @@ -46,8 +46,4 @@ public boolean isSync() { public long getTimeout() { return timeout; } - - public String toString() { - return siteName + " (" + (sync? "sync" : "async") + ", timeout=" + timeout + ")"; - } } diff --git a/core/src/main/resources/schema/infinispan-config-5.2.xsd b/core/src/main/resources/schema/infinispan-config-5.2.xsd index f1c09edb9757..89ad411f1a79 100644 --- a/core/src/main/resources/schema/infinispan-config-5.2.xsd +++ b/core/src/main/resources/schema/infinispan-config-5.2.xsd @@ -428,14 +428,65 @@ - + - Configures a specific site where this cache backups data. The name of the backup - must match + Configures a specific site where this cache backups data. The name of the backup must match a site defined in the "global" section. + + + + + Name of the remote site where this cache backups data. + + + + + + + The strategy used for backing up data: "SYNC" or "ASYNC". Defaults to "ASYNC" + + + + + + + + + + + + + Decides what the system would do in case of failure during backup. Defaults to "FAIL" + + + + + + + + + + + + + + + The timeout(millis) to be used when backing up data remotely. Defaults to 10 secs. + + + + + + + If the 'backupFailurePolicy' is set to 'CUSTOM' then this attribute is required and should + contain the fully qualified name of a class implementing org.infinispan.xsite.CustomFailurePolicy. + + + + @@ -1117,94 +1168,6 @@ - - - - - - Determines whether this backup is taken offline (ignored) after a certain - number of tries. - - - - - - - The number of failed request operations after which this site - should be taken offline. Defaults to 0 (never). - A negative value would mean that the site will be taken offline - after 'minTimeToWait'. - - - - - - - The minimal number of millis to wait before taking this site - offline, even in the case 'afterFailures' is reached. - If smaller or equal to 0, then only 'afterFailures' is considered. - - - - - - - - - - Name of the remote site where this cache backups data. - - - - - - - The strategy used for backing up data: "SYNC" or "ASYNC". Defaults to "ASYNC" - - - - - - - - - - - - - Decides what the system would do in case of failure during backup. Defaults to - "FAIL" - - - - - - - - - - - - - - - The timeout(millis) to be used when backing up data remotely. Defaults to 10 - secs. - - - - - - - If the 'backupFailurePolicy' is set to 'CUSTOM' then this attribute is - required and should - contain the fully qualified name of a class implementing - org.infinispan.xsite.CustomFailurePolicy. - - - - - diff --git a/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java b/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java deleted file mode 100644 index e6480a8fbae3..000000000000 --- a/core/src/test/java/org/infinispan/xsite/BaseSiteUnreachableTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @author tags. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU Lesser General Public License, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -package org.infinispan.xsite; - -import org.infinispan.configuration.cache.BackupConfiguration; -import org.infinispan.configuration.cache.BackupFailurePolicy; -import org.infinispan.configuration.cache.CacheMode; -import org.infinispan.configuration.cache.ConfigurationBuilder; -import org.infinispan.configuration.global.GlobalConfigurationBuilder; - -/** - * @author Mircea Markus - * @since 5.2 - */ -public class BaseSiteUnreachableTest extends AbstractXSiteTest { - - protected BackupFailurePolicy lonBackupFailurePolicy = BackupFailurePolicy.WARN; - protected BackupConfiguration.BackupStrategy lonBackupStrategy = BackupConfiguration.BackupStrategy.SYNC; - protected String lonCustomFailurePolicyClass = null; - - - @Override - protected void createSites() { - - GlobalConfigurationBuilder lonGc = GlobalConfigurationBuilder.defaultClusteredBuilder(); - lonGc - .sites().addSite().name("LON") - .sites().addSite().name("NYC") - .sites().localSite("LON"); - ConfigurationBuilder lon = getLonActiveConfig(); - lon.sites().addBackup() - .site("NYC") - .backupFailurePolicy(lonBackupFailurePolicy) - .strategy(lonBackupStrategy) - .failurePolicyClass(lonCustomFailurePolicyClass); - - createSite("LON", 2, lonGc, lon); - } - - protected ConfigurationBuilder getLonActiveConfig() { - return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, true); - } - -} diff --git a/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java b/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java deleted file mode 100644 index df2dfa95a264..000000000000 --- a/core/src/test/java/org/infinispan/xsite/NoFailureAsyncReplWarnFailurePolicyTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @author tags. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU Lesser General Public License, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -package org.infinispan.xsite; - -import org.infinispan.configuration.cache.BackupConfiguration; -import org.infinispan.configuration.cache.BackupFailurePolicy; -import org.infinispan.configuration.cache.CacheMode; -import org.infinispan.configuration.cache.ConfigurationBuilder; -import org.testng.annotations.Test; - -import java.util.Collections; - -import static org.testng.Assert.assertNull; -import static org.testng.AssertJUnit.assertEquals; - -/** - * @author Mircea Markus - * @since 5.2 - */ -@Test (groups = "xsite", testName = "xsite.bridgemissing.NoFailureAsyncReplWarnFailurePolicyTest") -public class NoFailureAsyncReplWarnFailurePolicyTest extends BaseSiteUnreachableTest { - - public NoFailureAsyncReplWarnFailurePolicyTest() { - lonBackupStrategy = BackupConfiguration.BackupStrategy.SYNC; - lonBackupFailurePolicy = BackupFailurePolicy.WARN; - } - - public void testNoFailures() { - cache("LON", 0).put("k", "v"); - assertEquals(cache("LON", 0).get("k"), "v"); - assertEquals(cache("LON", 1).get("k"), "v"); - - cache("LON", 1).remove("k"); - assertNull(cache("LON", 0).get("k")); - assertNull(cache("LON", 1).get("k")); - - cache("LON", 0).putAll(Collections.singletonMap("k", "v")); - assertEquals(cache("LON", 0).get("k"), "v"); - assertEquals(cache("LON", 1).get("k"), "v"); - } - - protected ConfigurationBuilder getLonActiveConfig() { - return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); - } -} diff --git a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java index ddcee159a302..a40270223f71 100644 --- a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java +++ b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing2Test.java @@ -22,7 +22,6 @@ import org.infinispan.configuration.cache.BackupConfiguration; import org.infinispan.configuration.cache.BackupFailurePolicy; import org.infinispan.configuration.cache.Configuration; -import org.infinispan.configuration.cache.TakeOfflineConfiguration; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.fwk.TestCacheManagerFactory; @@ -63,7 +62,7 @@ public void testNoBackupFor() { assertEquals(1, dcc.sites().backups().size()); assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003, BackupFailurePolicy.WARN, null, new TakeOfflineConfiguration(0,0)))); + 12003, BackupFailurePolicy.WARN, null))); assertNull(dcc.sites().backupFor().remoteSite()); assertNull(dcc.sites().backupFor().remoteCache()); } @@ -76,9 +75,9 @@ public void testNoBackupFor2() { private void testDefault(Configuration dcc) { assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003l, BackupFailurePolicy.IGNORE, null, new TakeOfflineConfiguration(0,0)))); + 12003l, BackupFailurePolicy.IGNORE, null))); assertTrue(dcc.sites().backups().contains(new BackupConfiguration("SFO", BackupConfiguration.BackupStrategy.ASYNC, - 10000l, BackupFailurePolicy.WARN, null,new TakeOfflineConfiguration(0,0)))); + 10000l, BackupFailurePolicy.WARN, null))); assertEquals("someCache", dcc.sites().backupFor().remoteCache()); assertEquals("SFO", dcc.sites().backupFor().remoteSite()); } diff --git a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java b/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java deleted file mode 100644 index 48f8a760c6f7..000000000000 --- a/core/src/test/java/org/infinispan/xsite/XSiteFileParsing3Test.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2012 Red Hat Inc. and/or its affiliates and other contributors - * as indicated by the @author tags. All rights reserved. - * See the copyright.txt in the distribution for a - * full listing of individual contributors. - * - * This copyrighted material is made available to anyone wishing to use, - * modify, copy, or redistribute it subject to the terms and conditions - * of the GNU Lesser General Public License, v. 2.1. - * This program is distributed in the hope that it will be useful, but WITHOUT A - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - * You should have received a copy of the GNU Lesser General Public License, - * v.2.1 along with this distribution; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -package org.infinispan.xsite; - -import org.infinispan.configuration.cache.BackupConfiguration; -import org.infinispan.configuration.cache.BackupFailurePolicy; -import org.infinispan.configuration.cache.Configuration; -import org.infinispan.configuration.cache.TakeOfflineConfiguration; -import org.infinispan.manager.EmbeddedCacheManager; -import org.infinispan.test.SingleCacheManagerTest; -import org.infinispan.test.fwk.TestCacheManagerFactory; -import org.testng.annotations.Test; - -import static org.testng.AssertJUnit.*; - -/** - * @author Mircea Markus - * @since 5.2 - */ -@Test (groups = "functional", testName = "xsite.XSiteFileParsing3Test") -public class XSiteFileParsing3Test extends SingleCacheManagerTest { - public static final String FILE_NAME = "configs/xsite/xsite-offline-test.xml"; - - @Override - protected EmbeddedCacheManager createCacheManager() throws Exception { - EmbeddedCacheManager embeddedCacheManager = TestCacheManagerFactory.fromXml(FILE_NAME); - return embeddedCacheManager; - } - - public void testDefaultCache() { - Configuration dcc = cacheManager.getDefaultCacheConfiguration(); - assertEquals(dcc.sites().backups().size(), 1); - testDefault(dcc); - } - - public void testInheritor() { - Configuration dcc = cacheManager.getCacheConfiguration("inheritor"); - testDefault(dcc); - } - - public void testNoTakeOffline() { - Configuration dcc = cacheManager.getCacheConfiguration("noTakeOffline"); - assertEquals(1, dcc.sites().backups().size()); - - assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003, BackupFailurePolicy.WARN, null, new TakeOfflineConfiguration(0,0)))); - assertNull(dcc.sites().backupFor().remoteSite()); - assertNull(dcc.sites().backupFor().remoteCache()); - } - public void testTakeOfflineDifferentConfig() { - Configuration dcc = cacheManager.getCacheConfiguration("takeOfflineDifferentConfig"); - assertEquals(1, dcc.sites().backups().size()); - TakeOfflineConfiguration toc = new TakeOfflineConfiguration(321, 3765); - assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003l, BackupFailurePolicy.IGNORE, null, toc))); - - } - - private void testDefault(Configuration dcc) { - TakeOfflineConfiguration toc = new TakeOfflineConfiguration(123, 5673); - assertTrue(dcc.sites().backups().contains(new BackupConfiguration("NYC", BackupConfiguration.BackupStrategy.SYNC, - 12003l, BackupFailurePolicy.IGNORE, null, toc))); - assertEquals("someCache", dcc.sites().backupFor().remoteCache()); - assertEquals("SFO", dcc.sites().backupFor().remoteSite()); - } -} diff --git a/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java b/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java index 6a51c69fbce5..34d1b8943622 100644 --- a/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java +++ b/core/src/test/java/org/infinispan/xsite/backupfailure/NonTxBackupFailureTest.java @@ -20,9 +20,6 @@ package org.infinispan.xsite.backupfailure; import org.infinispan.CacheException; -import org.infinispan.configuration.cache.CacheMode; -import org.infinispan.configuration.cache.ConfigurationBuilder; -import org.testng.annotations.Test; import java.util.HashMap; import java.util.Map; @@ -33,23 +30,11 @@ * @author Mircea Markus * @since 5.2 */ -@Test (groups = "xsite", testName = "xsite.backupfailure.NonTxBackupFailureTest") -public class NonTxBackupFailureTest extends BaseBackupFailureTest { +public abstract class NonTxBackupFailureTest extends BaseBackupFailureTest { //todo - if I don't explicitly override the test methods then testNG won't execute them from superclass. //fix this once we move to JUnit - - @Override - protected ConfigurationBuilder getLonActiveConfig() { - return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); - } - - @Override - protected ConfigurationBuilder getNycActiveConfig() { - return getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); - } - public void testPutFailure() { try { cache("LON", 0).put("k", "v"); diff --git a/core/src/test/resources/configs/xsite/xsite-offline-test.xml b/core/src/test/resources/configs/xsite/xsite-offline-test.xml deleted file mode 100644 index ee7c54d6536d..000000000000 --- a/core/src/test/resources/configs/xsite/xsite-offline-test.xml +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java b/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java index 4e0507f53350..b12377188bd6 100644 --- a/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java +++ b/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java @@ -28,13 +28,10 @@ import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.notifications.Listener; -import org.infinispan.notifications.cachelistener.annotation.CacheEntriesEvicted; -import org.infinispan.notifications.cachelistener.annotation.CacheEntryModified; -import org.infinispan.notifications.cachelistener.annotation.CacheEntryRemoved; +import org.infinispan.notifications.cachelistener.annotation.*; import org.infinispan.notifications.cachelistener.event.Event; -import org.infinispan.notifications.cachemanagerlistener.annotation.Merged; -import org.infinispan.notifications.cachemanagerlistener.annotation.ViewChanged; -import org.infinispan.notifications.cachemanagerlistener.event.ViewChangedEvent; +import org.infinispan.notifications.cachemanagerlistener.annotation.*; +import org.infinispan.notifications.cachemanagerlistener.event.*; import org.infinispan.remoting.transport.Address; import org.infinispan.util.LegacyKeySupportSystemProperties; import org.infinispan.util.Util; @@ -170,22 +167,15 @@ public void actionPerformed(ActionEvent e) { @Override public void run() { // based on the value of the radio button: - try { - if (putEntryRadioButton.isSelected()) { - cache.put(keyTextField.getText(), valueTextField.getText(), lifespan(), TimeUnit.MILLISECONDS, maxIdle(), TimeUnit.MILLISECONDS); - } else if (removeEntryRadioButton.isSelected()) { - cache.remove(keyTextField.getText()); - } else if (getEntryRadioButton.isSelected()) { - cache.get(keyTextField.getText()); - } - } - catch(Throwable t) { - // log.error("failed to update cache", t); - } - finally { - dataViewTab.repaint(); - processAction(goButton, false); + if (putEntryRadioButton.isSelected()) { + cache.put(keyTextField.getText(), valueTextField.getText(), lifespan(), TimeUnit.MILLISECONDS, maxIdle(), TimeUnit.MILLISECONDS); + } else if (removeEntryRadioButton.isSelected()) { + cache.remove(keyTextField.getText()); + } else if (getEntryRadioButton.isSelected()) { + cache.get(keyTextField.getText()); } + dataViewTab.repaint(); + processAction(goButton, false); // reset these values lifespanSpinner.setValue(cache.getCacheConfiguration().expiration().lifespan()); @@ -389,7 +379,7 @@ public void run() { Util.close(stream); } } - cache = cacheManager.getCache(); + cache = cacheManager.getCache(); cache.start(); // repaint the cfg file display diff --git a/parent/pom.xml b/parent/pom.xml index 00c3517c53f4..2fee2359fd63 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -147,7 +147,7 @@ 1.4.1 6.1.25 1.0.5 - 3.2.0.Alpha2 + 3.2.0.Alpha1 0.16 2.1 20090211 From 75fe3ca6c748dd55aed11a660c44f9e2075d6f95 Mon Sep 17 00:00:00 2001 From: Bela Ban Date: Sat, 29 Sep 2012 14:44:38 +0200 Subject: [PATCH 10/10] - Catching exception in InfinispanDemo - Packaging multiple failures in one exception (https://issues.jboss.org/browse/ISPN-2356) --- .../xsite/BackupFailureException.java | 36 ++++++++++++++----- .../infinispan/xsite/BackupSenderImpl.java | 7 +++- .../org/infinispan/xsite/XSiteBackup.java | 4 +++ .../org/infinispan/demo/InfinispanDemo.java | 25 ++++++++----- 4 files changed, 54 insertions(+), 18 deletions(-) diff --git a/core/src/main/java/org/infinispan/xsite/BackupFailureException.java b/core/src/main/java/org/infinispan/xsite/BackupFailureException.java index eae85f2c38cf..cf9031427e1a 100644 --- a/core/src/main/java/org/infinispan/xsite/BackupFailureException.java +++ b/core/src/main/java/org/infinispan/xsite/BackupFailureException.java @@ -21,6 +21,9 @@ import org.infinispan.remoting.RpcException; +import java.util.HashMap; +import java.util.Map; + /** * Exception to be used to signal failures to backup to remote sites. * @@ -29,23 +32,40 @@ */ public class BackupFailureException extends RpcException { - private String remoteSiteName; - private String localCacheName; + private Map failures; + private String localCacheName; + - public BackupFailureException(Throwable cause, String remoteSiteName, String localCacheName) { - super("The local cache" + localCacheName + " failed to backup data to the remote site " + remoteSiteName, cause); - this.remoteSiteName = remoteSiteName; - this.localCacheName = localCacheName; + public BackupFailureException(String localCacheName) { + this.localCacheName = localCacheName; } public BackupFailureException() { } - public String getRemoteSiteName() { - return remoteSiteName; + public void addFailure(String site, Throwable t) { + if(site != null && t != null) { + if(failures == null) + failures = new HashMap(3); + failures.put(site, t); + } + } + + public String getRemoteSiteNames() { + return failures != null? failures.keySet().toString() : null; } public String getLocalCacheName() { return localCacheName; } + + @Override + public String toString() { + if(failures == null || failures.isEmpty()) + return super.toString(); + StringBuilder sb=new StringBuilder("The local cache " + localCacheName + " failed to backup data to the remote sites:\n"); + for(Map.Entry entry: failures.entrySet()) + sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); + return sb.toString(); + } } diff --git a/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java b/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java index 7cbbdd00f369..36c6a0407d38 100644 --- a/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java +++ b/core/src/main/java/org/infinispan/xsite/BackupSenderImpl.java @@ -126,6 +126,7 @@ public void processResponses(BackupResponse backupResponse, VisitableCommand com backupResponse.waitForBackupToFinish(); SitesConfiguration sitesConfiguration = config.sites(); Map failures = backupResponse.getFailedBackups(); + BackupFailureException backupException = null; for (Map.Entry failure : failures.entrySet()) { BackupFailurePolicy policy = sitesConfiguration.getFailurePolicy(failure.getKey()); if (policy == BackupFailurePolicy.CUSTOM) { @@ -135,9 +136,13 @@ public void processResponses(BackupResponse backupResponse, VisitableCommand com if (policy == BackupFailurePolicy.WARN) { log.warnXsiteBackupFailed(cacheName, failure.getKey(), failure.getValue()); } else if (policy == BackupFailurePolicy.FAIL) { - throw new BackupFailureException(failure.getValue(),failure.getKey(), cacheName); + if(backupException == null) + backupException = new BackupFailureException(cacheName); + backupException.addFailure(failure.getKey(), failure.getValue()); } } + if(backupException != null) + throw backupException; } @Override diff --git a/core/src/main/java/org/infinispan/xsite/XSiteBackup.java b/core/src/main/java/org/infinispan/xsite/XSiteBackup.java index 650f9932ccea..9fe29e1353ff 100644 --- a/core/src/main/java/org/infinispan/xsite/XSiteBackup.java +++ b/core/src/main/java/org/infinispan/xsite/XSiteBackup.java @@ -46,4 +46,8 @@ public boolean isSync() { public long getTimeout() { return timeout; } + + public String toString() { + return siteName + " (" + (sync? "sync" : "async") + ", timeout=" + timeout + ")"; + } } diff --git a/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java b/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java index b12377188bd6..466b50bfb409 100644 --- a/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java +++ b/demos/gui/src/main/java/org/infinispan/demo/InfinispanDemo.java @@ -167,15 +167,22 @@ public void actionPerformed(ActionEvent e) { @Override public void run() { // based on the value of the radio button: - if (putEntryRadioButton.isSelected()) { - cache.put(keyTextField.getText(), valueTextField.getText(), lifespan(), TimeUnit.MILLISECONDS, maxIdle(), TimeUnit.MILLISECONDS); - } else if (removeEntryRadioButton.isSelected()) { - cache.remove(keyTextField.getText()); - } else if (getEntryRadioButton.isSelected()) { - cache.get(keyTextField.getText()); + try { + if (putEntryRadioButton.isSelected()) { + cache.put(keyTextField.getText(), valueTextField.getText(), lifespan(), TimeUnit.MILLISECONDS, maxIdle(), TimeUnit.MILLISECONDS); + } else if (removeEntryRadioButton.isSelected()) { + cache.remove(keyTextField.getText()); + } else if (getEntryRadioButton.isSelected()) { + cache.get(keyTextField.getText()); + } + } + catch(Throwable t) { + // log.error("failed to update cache", t); + } + finally { + dataViewTab.repaint(); + processAction(goButton, false); } - dataViewTab.repaint(); - processAction(goButton, false); // reset these values lifespanSpinner.setValue(cache.getCacheConfiguration().expiration().lifespan()); @@ -379,7 +386,7 @@ public void run() { Util.close(stream); } } - cache = cacheManager.getCache(); + cache = cacheManager.getCache(); cache.start(); // repaint the cfg file display