2 * Copyright (c) 2017 Inocybe Technologies and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.messaging;
10 import com.google.common.base.Preconditions;
11 import java.io.Externalizable;
12 import java.io.IOException;
13 import java.io.ObjectInput;
14 import java.io.ObjectOutput;
15 import java.util.concurrent.atomic.AtomicLong;
16 import org.opendaylight.yangtools.concepts.Identifier;
17 import org.opendaylight.yangtools.concepts.WritableObjects;
20 * Identifier for a message slice that is composed of a client-supplied Identifier and an internal counter value.
22 * @author Thomas Pantelis
24 final class MessageSliceIdentifier implements Identifier {
25 private static final long serialVersionUID = 1L;
26 private static final AtomicLong ID_COUNTER = new AtomicLong(1);
28 private final Identifier clientIdentifier;
29 private final long slicerId;
30 private final long messageId;
32 MessageSliceIdentifier(final Identifier clientIdentifier, final long slicerId) {
33 this(clientIdentifier, slicerId, ID_COUNTER.getAndIncrement());
36 private MessageSliceIdentifier(final Identifier clientIdentifier, final long slicerId, final long messageId) {
37 this.clientIdentifier = Preconditions.checkNotNull(clientIdentifier);
38 this.messageId = messageId;
39 this.slicerId = slicerId;
42 Identifier getClientIdentifier() {
43 return clientIdentifier;
51 public int hashCode() {
54 result = prime * result + clientIdentifier.hashCode();
55 result = prime * result + (int) (messageId ^ messageId >>> 32);
56 result = prime * result + (int) (slicerId ^ slicerId >>> 32);
61 public boolean equals(Object obj) {
66 if (!(obj instanceof MessageSliceIdentifier)) {
70 MessageSliceIdentifier other = (MessageSliceIdentifier) obj;
71 return other.clientIdentifier.equals(clientIdentifier) && other.slicerId == slicerId
72 && other.messageId == messageId;
76 public String toString() {
77 return "MessageSliceIdentifier [clientIdentifier=" + clientIdentifier + ", slicerId=" + slicerId
78 + ", messageId=" + messageId + "]";
81 private Object writeReplace() {
82 return new Proxy(this);
85 private static class Proxy implements Externalizable {
86 private static final long serialVersionUID = 1L;
88 private MessageSliceIdentifier messageSliceId;
90 // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
91 // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
92 @SuppressWarnings("checkstyle:RedundantModifier")
96 Proxy(MessageSliceIdentifier messageSliceId) {
97 this.messageSliceId = messageSliceId;
101 public void writeExternal(ObjectOutput out) throws IOException {
102 out.writeObject(messageSliceId.clientIdentifier);
103 WritableObjects.writeLongs(out, messageSliceId.slicerId, messageSliceId.messageId);
107 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
108 final Identifier clientIdentifier = (Identifier) in.readObject();
109 final byte header = WritableObjects.readLongHeader(in);
110 final long slicerId = WritableObjects.readFirstLong(in, header);
111 final long messageId = WritableObjects.readSecondLong(in, header);
112 messageSliceId = new MessageSliceIdentifier(clientIdentifier, slicerId, messageId);
115 private Object readResolve() {
116 return messageSliceId;