| /* |
| * 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. |
| */ |
| |
| package org.apache.geode.internal.cache; |
| |
| |
| import org.apache.geode.InternalGemFireError; |
| import org.apache.geode.internal.Assert; |
| |
| /** |
| * Indicates that the current partitioned region operation failed. It is only thrown in a context |
| * where the higher level operation needs to instigate a retry of some sort. |
| * |
| * @see org.apache.geode.internal.cache.partitioned.PartitionMessage |
| * @since GemFire 5.0 |
| */ |
| public class ForceReattemptException extends DataLocationException { |
| private static final long serialVersionUID = -595988965679204903L; |
| /** |
| * If true, this exception includes a hashCode for specified key |
| */ |
| private boolean hasHash = false; |
| |
| /** |
| * The hashCode for a specified key, if {@link #hasHash()} is true |
| */ |
| private int keyHash = 0; |
| |
| /** |
| * Used when constructing the error: sets the expected hash. |
| * |
| * @param h the hash to use |
| */ |
| public void setHash(int h) { |
| Assert.assertTrue(!this.hasHash, "setHash already called"); |
| this.hasHash = true; |
| this.keyHash = h; |
| } |
| |
| /** |
| * Fetch the hash for this exception |
| * |
| * @return the expected hash |
| */ |
| public boolean hasHash() { |
| return this.hasHash; |
| } |
| |
| public int getHash() { |
| if (!hasHash) { |
| throw new InternalGemFireError("getHash when no hash"); |
| } |
| return this.keyHash; |
| } |
| |
| /** |
| * If possible, validate the given key's hashCode against any that was returned by the peer. |
| * |
| * @param key the key on the current host. If null, no check is done. |
| * @throws PartitionedRegionException if the keys disagree. |
| */ |
| public void checkKey(Object key) throws PartitionedRegionException { |
| if (!hasHash) { |
| return; // none provided |
| } |
| if (key == null) { |
| return; // ??? |
| } |
| |
| int expected = key.hashCode(); |
| if (expected == keyHash) { |
| return; |
| } |
| throw new PartitionedRegionException("Object hashCode inconsistent between cache peers. Here = " |
| + expected + "; peer calculated = " + keyHash); |
| } |
| |
| /** |
| * Reattempt required due to an underlying error |
| * |
| * @param message describes the context |
| * @param cause the underlying cause |
| */ |
| public ForceReattemptException(String message, Throwable cause) { |
| super(message, cause); |
| } |
| |
| /** |
| * Reattempt required due to detected condition |
| * |
| * @param message describes the condition |
| */ |
| public ForceReattemptException(String message) { |
| super(message); |
| } |
| |
| @Override |
| public String toString() { |
| String result = super.toString(); |
| if (hasHash()) { |
| result = result + " (hash = " + keyHash + ")"; |
| } |
| return result; |
| } |
| } |