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 static java.util.Objects.requireNonNull;
12 import java.io.Externalizable;
13 import java.io.IOException;
14 import java.io.ObjectInput;
15 import java.io.ObjectOutput;
16 import java.util.concurrent.atomic.AtomicLong;
17 import org.opendaylight.yangtools.concepts.Identifier;
18 import org.opendaylight.yangtools.concepts.WritableObjects;
21 * Identifier for a message slice that is composed of a client-supplied Identifier and an internal counter value.
23 * @author Thomas Pantelis
25 final class MessageSliceIdentifier implements Identifier {
26 private static final long serialVersionUID = 1L;
27 private static final AtomicLong ID_COUNTER = new AtomicLong(1);
29 private final Identifier clientIdentifier;
30 private final long slicerId;
31 private final long messageId;
33 MessageSliceIdentifier(final Identifier clientIdentifier, final long slicerId) {
34 this(clientIdentifier, slicerId, ID_COUNTER.getAndIncrement());
37 private MessageSliceIdentifier(final Identifier clientIdentifier, final long slicerId, final long messageId) {
38 this.clientIdentifier = requireNonNull(clientIdentifier);
39 this.messageId = messageId;
40 this.slicerId = slicerId;
43 Identifier getClientIdentifier() {
44 return clientIdentifier;
52 public int hashCode() {
55 result = prime * result + clientIdentifier.hashCode();
56 result = prime * result + (int) (messageId ^ messageId >>> 32);
57 result = prime * result + (int) (slicerId ^ slicerId >>> 32);
62 public boolean equals(final Object obj) {
67 if (!(obj instanceof MessageSliceIdentifier)) {
71 MessageSliceIdentifier other = (MessageSliceIdentifier) obj;
72 return other.clientIdentifier.equals(clientIdentifier) && other.slicerId == slicerId
73 && other.messageId == messageId;
77 public String toString() {
78 return "MessageSliceIdentifier [clientIdentifier=" + clientIdentifier + ", slicerId=" + slicerId
79 + ", messageId=" + messageId + "]";
82 private Object writeReplace() {
83 return new Proxy(this);
86 private static class Proxy implements Externalizable {
87 private static final long serialVersionUID = 1L;
89 private MessageSliceIdentifier messageSliceId;
91 // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
92 // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
93 @SuppressWarnings("checkstyle:RedundantModifier")
97 Proxy(final MessageSliceIdentifier messageSliceId) {
98 this.messageSliceId = messageSliceId;
102 public void writeExternal(final ObjectOutput out) throws IOException {
103 out.writeObject(messageSliceId.clientIdentifier);
104 WritableObjects.writeLongs(out, messageSliceId.slicerId, messageSliceId.messageId);
108 public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
109 final Identifier clientIdentifier = (Identifier) in.readObject();
110 final byte header = WritableObjects.readLongHeader(in);
111 final long slicerId = WritableObjects.readFirstLong(in, header);
112 final long messageId = WritableObjects.readSecondLong(in, header);
113 messageSliceId = new MessageSliceIdentifier(clientIdentifier, slicerId, messageId);
116 private Object readResolve() {
117 return messageSliceId;