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) {
63 return this == obj || obj instanceof MessageSliceIdentifier other
64 && other.clientIdentifier.equals(clientIdentifier) && other.slicerId == slicerId
65 && other.messageId == messageId;
69 public String toString() {
70 return "MessageSliceIdentifier [clientIdentifier=" + clientIdentifier + ", slicerId=" + slicerId
71 + ", messageId=" + messageId + "]";
74 private Object writeReplace() {
75 return new Proxy(this);
78 private static class Proxy implements Externalizable {
79 private static final long serialVersionUID = 1L;
81 private MessageSliceIdentifier messageSliceId;
83 // checkstyle flags the public modifier as redundant which really doesn't make sense since it clearly isn't
84 // redundant. It is explicitly needed for Java serialization to be able to create instances via reflection.
85 @SuppressWarnings("checkstyle:RedundantModifier")
89 Proxy(final MessageSliceIdentifier messageSliceId) {
90 this.messageSliceId = messageSliceId;
94 public void writeExternal(final ObjectOutput out) throws IOException {
95 out.writeObject(messageSliceId.clientIdentifier);
96 WritableObjects.writeLongs(out, messageSliceId.slicerId, messageSliceId.messageId);
100 public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
101 final Identifier clientIdentifier = (Identifier) in.readObject();
102 final byte header = WritableObjects.readLongHeader(in);
103 final long slicerId = WritableObjects.readFirstLong(in, header);
104 final long messageId = WritableObjects.readSecondLong(in, header);
105 messageSliceId = new MessageSliceIdentifier(clientIdentifier, slicerId, messageId);
108 private Object readResolve() {
109 return messageSliceId;