blob: 259c3194cedfd2c5584401ccb9fceec4ef90bf02 [file] [log] [blame]
---
title: Resolving Conflicting Events
---
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
You can optionally create a `GatewayConflictResolver` cache plug-in to decide whether a potentially conflicting event that was delivered from another site should be applied to the local cache.
By default, all regions perform consistency checks when a member applies an update received either from another cluster member or from a remote cluster over the WAN. The default consistency checking for WAN events is described in [How Consistency Is Achieved in WAN Deployments](../distributed_regions/how_region_versioning_works_wan.html#topic_fpy_z3h_j5).
You can override the default consistency checking behavior by writing and configuring a custom `GatewayConflictResolver`. The `GatewayConflictResolver` implementation can use the timestamp and distributed system ID included in a WAN update event to determine whether or not to apply the update. For example, you may decide that updates from a particular cluster should always "win" a conflict when the timestamp difference between updates is less than some fixed period of time.
## <a id="topic_E97BB68748F14987916CD1A50E4B4542__section_E20B4A8A98FD4EDAAA8C14B8059AA7F7" class="no-quick-link"></a>Implementing a GatewayConflictResolver
**Note:**
A `GatewayConflictResolver` implementation is called only for update events that could cause a conflict in the region. This corresponds to update events that have a different distributed system ID than the distributed system that last updated the region entry. If the same distributed system ID makes consecutive updates to a region entry, no conflict is possible, and the `GatewayConflictResolver` is not called.
**Procedure**
1. Program the event handler:
1. Create a class that implements the `GatewayConflictResolver` interface.
2. If you want to declare the handler in `cache.xml`, implement the `org.apache.geode.cache.Declarable` interface as well.
3. Implement the handler's `onEvent()` method to determine whether the WAN event should be allowed. `onEvent()` receives both a `TimestampedEntryEvent` and a `GatewayConflictHelper` instance. `TimestampedEntryEvent` has methods for obtaining the timestamp and distributed system ID of both the update event and the current region entry. Use methods in the `GatewayConflictHelper` to either disallow the update event (retaining the existing region entry value) or provide an alternate value.
**Example:**
``` pre
public void onEvent(TimestampedEntryEvent event, GatewayConflictHelper helper) {
if (event.getOperation().isUpdate()) {
ShoppingCart oldCart = (ShoppingCart)event.getOldValue();
ShoppingCart newCart = (ShoppingCart)event.getNewValue();
oldCart.updateFromConflictingState(newCart);
helper.changeEventValue(oldCart);
}
}
```
**Note:**
In order to maintain consistency in the region, your conflict resolver must always resolve two events in the same way regardless of which event it receives first.
2. Install the conflict resolver for the cache, using either the `cache.xml` file or the Java API.
**cache.xml**
``` pre
<cache>
...
<gateway-conflict-resolver>
<class-name>myPackage.MyConflictResolver</class-name>
</gateway-conflict-resolver>
...
</cache>
```
**Java API**
``` pre
// Create or obtain the cache
Cache cache = new CacheFactory().create();
// Create and add a conflict resolver
cache.setGatewayConflictResolver(new MyConflictResolver);
```