Skip to content

Commit 92e328b

Browse files
rvansasebersole
authored andcommitted
HHH-10057 hibernate-infinispan incompatible with Infinispan 8.0.0.CR1
* ISPN-5609 changed InvalidateCommand constructors: used reflection to work around that; now should work with 8.0.0.CR1 * renamed BeginInvalidationCommand.getLockOwner to getSessionTransactionId() to prevent further conflicts * added commands tests (cherry picked from commit 64137c3)
1 parent e048b36 commit 92e328b

File tree

6 files changed

+203
-37
lines changed

6 files changed

+203
-37
lines changed

hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/NonTxInvalidationInterceptor.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,14 @@ private void invalidateAcrossCluster(FlagAffectedCommand command, Object[] keys)
125125
// increment invalidations counter if statistics maintained
126126
incrementInvalidations();
127127
InvalidateCommand invalidateCommand;
128-
Object lockOwner = putFromLoadValidator.registerRemoteInvalidations(keys);
128+
Object sessionTransactionId = putFromLoadValidator.registerRemoteInvalidations(keys);
129129
if (!isLocalModeForced(command)) {
130-
if (lockOwner == null) {
130+
if (sessionTransactionId == null) {
131131
invalidateCommand = commandsFactory.buildInvalidateCommand(InfinispanCollections.<Flag>emptySet(), keys);
132132
}
133133
else {
134134
invalidateCommand = commandInitializer.buildBeginInvalidationCommand(
135-
InfinispanCollections.<Flag>emptySet(), keys, lockOwner);
135+
InfinispanCollections.<Flag>emptySet(), keys, sessionTransactionId);
136136
}
137137
if (log.isDebugEnabled()) {
138138
log.debug("Cache [" + rpcManager.getAddress() + "] replicating " + invalidateCommand);

hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/access/NonTxPutFromLoadInterceptor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,16 @@ public void injectDependencies(CacheCommandInitializer commandInitializer, RpcMa
4545
public Object visitInvalidateCommand(InvocationContext ctx, InvalidateCommand command) throws Throwable {
4646
if (!ctx.isOriginLocal() && command instanceof BeginInvalidationCommand) {
4747
for (Object key : command.getKeys()) {
48-
putFromLoadValidator.beginInvalidatingKey(((BeginInvalidationCommand) command).getLockOwner(), key);
48+
putFromLoadValidator.beginInvalidatingKey(((BeginInvalidationCommand) command).getSessionTransactionId(), key);
4949
}
5050
}
5151
return invokeNextInterceptor(ctx, command);
5252
}
5353

54-
public void broadcastEndInvalidationCommand(Object[] keys, Object lockOwner) {
55-
assert lockOwner != null;
54+
public void broadcastEndInvalidationCommand(Object[] keys, Object sessionTransactionId) {
55+
assert sessionTransactionId != null;
5656
EndInvalidationCommand endInvalidationCommand = commandInitializer.buildEndInvalidationCommand(
57-
cacheName, keys, lockOwner);
57+
cacheName, keys, sessionTransactionId);
5858
rpcManager.invokeRemotely(null, endInvalidationCommand, rpcManager.getDefaultRpcOptions(false, DeliverOrder.NONE));
5959
}
6060
}

hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/BeginInvalidationCommand.java

Lines changed: 87 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,42 +7,101 @@
77
package org.hibernate.cache.infinispan.util;
88

99
import org.hibernate.internal.util.compare.EqualsHelper;
10+
import org.infinispan.commands.write.AbstractDataWriteCommand;
1011
import org.infinispan.commands.write.InvalidateCommand;
1112
import org.infinispan.context.Flag;
1213
import org.infinispan.notifications.cachelistener.CacheNotifier;
14+
import org.infinispan.remoting.transport.Address;
1315

16+
import java.lang.reflect.Field;
17+
import java.lang.reflect.InvocationTargetException;
18+
import java.lang.reflect.Method;
1419
import java.util.Arrays;
1520
import java.util.Set;
1621

1722
/**
1823
* @author Radim Vansa &lt;[email protected]&gt;
1924
*/
2025
public class BeginInvalidationCommand extends InvalidateCommand {
21-
private Object lockOwner;
26+
// this is a hack to keep compatibility with both Infinispan 7 and 8
27+
// TODO: remove this when rebasing on Infinispan 8
28+
private static final Field commandInvocationIdField;
29+
private static final Method generateIdMethod;
30+
31+
static {
32+
Field commandInvocationId = null;
33+
Method generateId = null;
34+
try {
35+
commandInvocationId = AbstractDataWriteCommand.class.getDeclaredField("commandInvocationId");
36+
commandInvocationId.setAccessible(true);
37+
Class commandInvocationIdClass = Class.forName("org.infinispan.commands.CommandInvocationId");
38+
generateId = commandInvocationIdClass.getMethod("generateId", Address.class);
39+
}
40+
catch (NoSuchFieldException e) {
41+
}
42+
catch (ClassNotFoundException e) {
43+
// already found field and not the class?
44+
throw new IllegalStateException(e);
45+
}
46+
catch (NoSuchMethodException e) {
47+
// already found field and not the method?
48+
throw new IllegalStateException(e);
49+
}
50+
commandInvocationIdField = commandInvocationId;
51+
generateIdMethod = generateId;
52+
}
53+
54+
private Object sessionTransactionId;
2255

2356
public BeginInvalidationCommand() {
2457
}
2558

26-
public BeginInvalidationCommand(CacheNotifier notifier, Set<Flag> flags, Object[] keys, Object lockOwner) {
27-
super(notifier, flags, keys);
28-
this.lockOwner = lockOwner;
59+
public BeginInvalidationCommand(CacheNotifier notifier, Set<Flag> flags, Object[] keys, Address address, Object sessionTransactionId) {
60+
super();
61+
this.notifier = notifier;
62+
this.flags = flags;
63+
this.keys = keys;
64+
this.sessionTransactionId = sessionTransactionId;
65+
if (commandInvocationIdField != null) {
66+
try {
67+
commandInvocationIdField.set(this, generateIdMethod.invoke(null, address));
68+
}
69+
catch (IllegalAccessException e) {
70+
throw new IllegalStateException(e);
71+
}
72+
catch (InvocationTargetException e) {
73+
throw new IllegalStateException(e);
74+
}
75+
}
2976
}
3077

31-
public Object getLockOwner() {
32-
return lockOwner;
78+
public Object getSessionTransactionId() {
79+
return sessionTransactionId;
3380
}
3481

3582
@Override
3683
public Object[] getParameters() {
84+
Object commandInvocationId = null;
85+
if (commandInvocationIdField != null) {
86+
try {
87+
commandInvocationId = commandInvocationIdField.get(this);
88+
}
89+
catch (IllegalAccessException e) {
90+
throw new IllegalStateException(e);
91+
}
92+
}
3793
if (keys == null || keys.length == 0) {
38-
return new Object[]{0, lockOwner};
94+
return new Object[]{flags, sessionTransactionId, commandInvocationId, 0};
3995
}
4096
if (keys.length == 1) {
41-
return new Object[]{1, keys[0], lockOwner};
97+
return new Object[]{flags, sessionTransactionId, commandInvocationId, 1, keys[0]};
4298
}
43-
Object[] retval = new Object[keys.length + 2];
44-
retval[0] = keys.length;
45-
System.arraycopy(keys, 0, retval, 1, keys.length);
99+
Object[] retval = new Object[keys.length + 4];
100+
retval[0] = flags;
101+
retval[1] = sessionTransactionId;
102+
retval[2] = commandInvocationId;
103+
retval[3] = keys.length;
104+
System.arraycopy(keys, 0, retval, 4, keys.length);
46105
return retval;
47106
}
48107

@@ -51,15 +110,25 @@ public void setParameters(int commandId, Object[] args) {
51110
if (commandId != CacheCommandIds.BEGIN_INVALIDATION) {
52111
throw new IllegalStateException("Invalid method id");
53112
}
54-
int size = (Integer) args[0];
113+
flags = (Set<Flag>) args[0];
114+
sessionTransactionId = args[1];
115+
Object commandInvocationId = args[2];
116+
if (commandInvocationIdField != null) {
117+
try {
118+
commandInvocationIdField.set(this, commandInvocationId);
119+
}
120+
catch (IllegalAccessException e) {
121+
throw new IllegalStateException(e);
122+
}
123+
}
124+
int size = (Integer) args[3];
55125
keys = new Object[size];
56126
if (size == 1) {
57-
keys[0] = args[1];
127+
keys[0] = args[4];
58128
}
59129
else if (size > 0) {
60-
System.arraycopy(args, 1, keys, 0, size);
130+
System.arraycopy(args, 4, keys, 0, size);
61131
}
62-
lockOwner = args[args.length - 1];
63132
}
64133

65134

@@ -75,7 +144,7 @@ public boolean equals(Object o) {
75144
}
76145
if (o instanceof BeginInvalidationCommand) {
77146
BeginInvalidationCommand bic = (BeginInvalidationCommand) o;
78-
return EqualsHelper.equals(lockOwner, bic.lockOwner);
147+
return EqualsHelper.equals(sessionTransactionId, bic.sessionTransactionId);
79148
}
80149
else {
81150
return false;
@@ -84,12 +153,12 @@ public boolean equals(Object o) {
84153

85154
@Override
86155
public int hashCode() {
87-
return super.hashCode() + (lockOwner == null ? 0 : lockOwner.hashCode());
156+
return super.hashCode() + (sessionTransactionId == null ? 0 : sessionTransactionId.hashCode());
88157
}
89158

90159
@Override
91160
public String toString() {
92161
return "BeginInvalidateCommand{keys=" + Arrays.toString(keys) +
93-
", lockOwner=" + lockOwner + '}';
162+
", sessionTransactionId=" + sessionTransactionId + '}';
94163
}
95164
}

hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/CacheCommandInitializer.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.infinispan.configuration.cache.Configuration;
1313
import org.infinispan.context.Flag;
1414
import org.infinispan.factories.annotations.Inject;
15+
import org.infinispan.interceptors.locking.ClusteringDependentLogic;
1516
import org.infinispan.notifications.cachelistener.CacheNotifier;
1617

1718
import java.util.Set;
@@ -29,11 +30,13 @@ public class CacheCommandInitializer implements ModuleCommandInitializer {
2930
= new ConcurrentHashMap<String, PutFromLoadValidator>();
3031
private CacheNotifier notifier;
3132
private Configuration configuration;
33+
private ClusteringDependentLogic clusteringDependentLogic;
3234

3335
@Inject
34-
public void injectDependencies(CacheNotifier notifier, Configuration configuration) {
36+
public void injectDependencies(CacheNotifier notifier, Configuration configuration, ClusteringDependentLogic clusteringDependentLogic) {
3537
this.notifier = notifier;
3638
this.configuration = configuration;
39+
this.clusteringDependentLogic = clusteringDependentLogic;
3740
}
3841

3942
public void addPutFromLoadValidator(String cacheName, PutFromLoadValidator putFromLoadValidator) {
@@ -62,12 +65,12 @@ public EvictAllCommand buildEvictAllCommand(String regionName) {
6265
return new EvictAllCommand( regionName );
6366
}
6467

65-
public BeginInvalidationCommand buildBeginInvalidationCommand(Set<Flag> flags, Object[] keys, Object lockOwner) {
66-
return new BeginInvalidationCommand(notifier, flags, keys, lockOwner);
68+
public BeginInvalidationCommand buildBeginInvalidationCommand(Set<Flag> flags, Object[] keys, Object sessionTransactionId) {
69+
return new BeginInvalidationCommand(notifier, flags, keys, clusteringDependentLogic.getAddress(), sessionTransactionId);
6770
}
6871

69-
public EndInvalidationCommand buildEndInvalidationCommand(String cacheName, Object[] keys, Object lockOwner) {
70-
return new EndInvalidationCommand( cacheName, keys, lockOwner );
72+
public EndInvalidationCommand buildEndInvalidationCommand(String cacheName, Object[] keys, Object sessionTransactionId) {
73+
return new EndInvalidationCommand( cacheName, keys, sessionTransactionId );
7174
}
7275

7376
@Override

hibernate-infinispan/src/main/java/org/hibernate/cache/infinispan/util/EndInvalidationCommand.java

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
public class EndInvalidationCommand extends BaseRpcCommand {
2222
private Object[] keys;
23-
private Object lockOwner;
23+
private Object sessionTransactionId;
2424
private PutFromLoadValidator putFromLoadValidator;
2525

2626
public EndInvalidationCommand(String cacheName) {
@@ -30,16 +30,16 @@ public EndInvalidationCommand(String cacheName) {
3030
/**
3131
* @param cacheName name of the cache to evict
3232
*/
33-
public EndInvalidationCommand(String cacheName, Object[] keys, Object lockOwner) {
33+
public EndInvalidationCommand(String cacheName, Object[] keys, Object sessionTransactionId) {
3434
super(cacheName);
3535
this.keys = keys;
36-
this.lockOwner = lockOwner;
36+
this.sessionTransactionId = sessionTransactionId;
3737
}
3838

3939
@Override
4040
public Object perform(InvocationContext ctx) throws Throwable {
4141
for (Object key : keys) {
42-
putFromLoadValidator.endInvalidatingKey(lockOwner, key);
42+
putFromLoadValidator.endInvalidatingKey(sessionTransactionId, key);
4343
}
4444
return null;
4545
}
@@ -51,13 +51,13 @@ public byte getCommandId() {
5151

5252
@Override
5353
public Object[] getParameters() {
54-
return new Object[] { keys, lockOwner };
54+
return new Object[] { keys, sessionTransactionId};
5555
}
5656

5757
@Override
5858
public void setParameters(int commandId, Object[] parameters) {
5959
keys = (Object[]) parameters[0];
60-
lockOwner = parameters[1];
60+
sessionTransactionId = parameters[1];
6161
}
6262

6363
@Override
@@ -74,12 +74,41 @@ public void setPutFromLoadValidator(PutFromLoadValidator putFromLoadValidator) {
7474
this.putFromLoadValidator = putFromLoadValidator;
7575
}
7676

77+
@Override
78+
public boolean equals(Object o) {
79+
if (this == o) {
80+
return true;
81+
}
82+
if (!(o instanceof EndInvalidationCommand)) {
83+
return false;
84+
}
85+
86+
EndInvalidationCommand that = (EndInvalidationCommand) o;
87+
88+
if (cacheName == null ? cacheName != null : !cacheName.equals(that.cacheName)) {
89+
return false;
90+
}
91+
if (!Arrays.equals(keys, that.keys)) {
92+
return false;
93+
}
94+
return !(sessionTransactionId != null ? !sessionTransactionId.equals(that.sessionTransactionId) : that.sessionTransactionId != null);
95+
96+
}
97+
98+
@Override
99+
public int hashCode() {
100+
int result = cacheName != null ? cacheName.hashCode() : 0;
101+
result = 31 * result + (keys != null ? Arrays.hashCode(keys) : 0);
102+
result = 31 * result + (sessionTransactionId != null ? sessionTransactionId.hashCode() : 0);
103+
return result;
104+
}
105+
77106
@Override
78107
public String toString() {
79108
final StringBuilder sb = new StringBuilder("EndInvalidationCommand{");
80109
sb.append("cacheName=").append(cacheName);
81110
sb.append(", keys=").append(Arrays.toString(keys));
82-
sb.append(", lockOwner=").append(lockOwner);
111+
sb.append(", sessionTransactionId=").append(sessionTransactionId);
83112
sb.append('}');
84113
return sb.toString();
85114
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package org.hibernate.test.cache.infinispan.util;
2+
3+
import org.hibernate.cache.infinispan.util.BeginInvalidationCommand;
4+
import org.hibernate.cache.infinispan.util.CacheCommandInitializer;
5+
import org.hibernate.cache.infinispan.util.EndInvalidationCommand;
6+
import org.infinispan.commands.ReplicableCommand;
7+
import org.infinispan.distribution.TestAddress;
8+
import org.infinispan.interceptors.locking.ClusteringDependentLogic;
9+
import org.junit.BeforeClass;
10+
import org.junit.Test;
11+
12+
import java.util.Collections;
13+
import java.util.UUID;
14+
import java.util.function.Supplier;
15+
16+
import static org.jgroups.util.Util.assertEquals;
17+
import static org.junit.Assert.assertArrayEquals;
18+
import static org.mockito.Mockito.mock;
19+
import static org.mockito.Mockito.when;
20+
21+
/**
22+
* @author Radim Vansa &lt;[email protected]&gt;
23+
*/
24+
public class CacheCommandsInitializerTest {
25+
private static CacheCommandInitializer initializer = new CacheCommandInitializer();
26+
27+
@BeforeClass
28+
public static void setUp() {
29+
ClusteringDependentLogic cdl = mock(ClusteringDependentLogic.class);
30+
when(cdl.getAddress()).thenReturn(new TestAddress(0));
31+
initializer.injectDependencies(null, null, cdl);
32+
}
33+
34+
@Test
35+
public void testBeginInvalidationCommand1() {
36+
BeginInvalidationCommand command = initializer.buildBeginInvalidationCommand(Collections.EMPTY_SET, new Object[]{}, UUID.randomUUID());
37+
checkParameters(command, () -> new BeginInvalidationCommand());
38+
}
39+
40+
@Test
41+
public void testBeginInvalidationCommand2() {
42+
BeginInvalidationCommand command = initializer.buildBeginInvalidationCommand(Collections.EMPTY_SET, new Object[]{ 1 }, UUID.randomUUID());
43+
checkParameters(command, () -> new BeginInvalidationCommand());
44+
}
45+
46+
@Test
47+
public void testBeginInvalidationCommand3() {
48+
BeginInvalidationCommand command = initializer.buildBeginInvalidationCommand(Collections.EMPTY_SET, new Object[]{ 2, 3 }, UUID.randomUUID());
49+
checkParameters(command, () -> new BeginInvalidationCommand());
50+
}
51+
52+
@Test
53+
public void testEndInvalidationCommmand() {
54+
EndInvalidationCommand command = initializer.buildEndInvalidationCommand("foo", new Object[] { 2, 3 }, UUID.randomUUID());
55+
checkParameters(command, () -> new EndInvalidationCommand("foo"));
56+
}
57+
58+
protected <T extends ReplicableCommand> void checkParameters(T command, Supplier<T> commandSupplier) {
59+
Object[] parameters = command.getParameters();
60+
ReplicableCommand newCommand = commandSupplier.get();
61+
newCommand.setParameters(command.getCommandId(), parameters);
62+
assertEquals(command, newCommand);
63+
assertArrayEquals(parameters, newCommand.getParameters());
64+
}
65+
}

0 commit comments

Comments
 (0)