blob: 5327d48894da2728674df6677aaa1f3ba42d929b [file] [log] [blame]
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2014-present Open Networking Foundation
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.store.cluster.messaging;
tom1d416c52014-09-29 20:55:24 -070017
Madan Jampaniba472232015-03-04 13:00:50 -080018import java.nio.ByteBuffer;
19import java.util.Arrays;
20import java.util.Objects;
21
Jonathan Hart584d2f32015-01-27 19:46:14 -080022import org.onlab.util.ByteArraySizeHashPrinter;
23import org.onosproject.cluster.NodeId;
24
Madan Jampaniba472232015-03-04 13:00:50 -080025import com.google.common.base.Charsets;
26import com.google.common.base.MoreObjects;
tom1d416c52014-09-29 20:55:24 -070027
Yuta HIGUCHI971addc2014-10-07 23:23:17 -070028// TODO: Should payload type be ByteBuffer?
tom1d416c52014-09-29 20:55:24 -070029/**
30 * Base message for cluster-wide communications.
31 */
Madan Jampani890bc352014-10-01 22:35:29 -070032public class ClusterMessage {
tom1d416c52014-09-29 20:55:24 -070033
Madan Jampani890bc352014-10-01 22:35:29 -070034 private final NodeId sender;
tom1d416c52014-09-29 20:55:24 -070035 private final MessageSubject subject;
Madan Jampani53e44e62014-10-07 12:39:51 -070036 private final byte[] payload;
Madan Jampanic26eede2015-04-16 11:42:16 -070037 private transient byte[] response;
tom1d416c52014-09-29 20:55:24 -070038
39 /**
40 * Creates a cluster message.
41 *
Yuta HIGUCHI5c947272014-11-03 21:39:21 -080042 * @param sender message sender
tom1d416c52014-09-29 20:55:24 -070043 * @param subject message subject
Yuta HIGUCHI5c947272014-11-03 21:39:21 -080044 * @param payload message payload
tom1d416c52014-09-29 20:55:24 -070045 */
Madan Jampani53e44e62014-10-07 12:39:51 -070046 public ClusterMessage(NodeId sender, MessageSubject subject, byte[] payload) {
Madan Jampani890bc352014-10-01 22:35:29 -070047 this.sender = sender;
tom1d416c52014-09-29 20:55:24 -070048 this.subject = subject;
Madan Jampani890bc352014-10-01 22:35:29 -070049 this.payload = payload;
tom1d416c52014-09-29 20:55:24 -070050 }
51
52 /**
Madan Jampani890bc352014-10-01 22:35:29 -070053 * Returns the id of the controller sending this message.
54 *
55 * @return message sender id.
56 */
57 public NodeId sender() {
58 return sender;
59 }
60
61 /**
tom1d416c52014-09-29 20:55:24 -070062 * Returns the message subject indicator.
63 *
64 * @return message subject
65 */
66 public MessageSubject subject() {
67 return subject;
68 }
69
Madan Jampani890bc352014-10-01 22:35:29 -070070 /**
71 * Returns the message payload.
72 *
73 * @return message payload.
74 */
Madan Jampani53e44e62014-10-07 12:39:51 -070075 public byte[] payload() {
Madan Jampani890bc352014-10-01 22:35:29 -070076 return payload;
tom1d416c52014-09-29 20:55:24 -070077 }
Madan Jampani8a895092014-10-17 16:55:50 -070078
79 /**
Madan Jampanic26eede2015-04-16 11:42:16 -070080 * Records the response to be sent to the sender.
Madan Jampani8a895092014-10-17 16:55:50 -070081 *
Madan Jampanic26eede2015-04-16 11:42:16 -070082 * @param data response payload
Madan Jampani8a895092014-10-17 16:55:50 -070083 */
Madan Jampanic26eede2015-04-16 11:42:16 -070084 public void respond(byte[] data) {
85 response = data;
86 }
87
88 /**
89 * Returns the response to be sent to the sender.
90 *
91 * @return response bytes
92 */
93 public byte[] response() {
94 return response;
Madan Jampani8a895092014-10-17 16:55:50 -070095 }
Yuta HIGUCHI91768e32014-11-22 05:06:35 -080096
97 @Override
98 public String toString() {
99 return MoreObjects.toStringHelper(getClass())
100 .add("sender", sender)
101 .add("subject", subject)
102 .add("payload", ByteArraySizeHashPrinter.of(payload))
103 .toString();
104 }
Jonathan Hart584d2f32015-01-27 19:46:14 -0800105
106 @Override
107 public boolean equals(Object o) {
108 if (!(o instanceof ClusterMessage)) {
109 return false;
110 }
111
112 ClusterMessage that = (ClusterMessage) o;
113
114 return Objects.equals(this.sender, that.sender) &&
115 Objects.equals(this.subject, that.subject) &&
116 Arrays.equals(this.payload, that.payload);
117 }
118
Madan Jampaniba472232015-03-04 13:00:50 -0800119 /**
120 * Serializes this instance.
121 * @return bytes
122 */
123 public byte[] getBytes() {
124 byte[] senderBytes = sender.toString().getBytes(Charsets.UTF_8);
125 byte[] subjectBytes = subject.value().getBytes(Charsets.UTF_8);
126 int capacity = 12 + senderBytes.length + subjectBytes.length + payload.length;
127 ByteBuffer buffer = ByteBuffer.allocate(capacity);
128 buffer.putInt(senderBytes.length);
129 buffer.put(senderBytes);
130 buffer.putInt(subjectBytes.length);
131 buffer.put(subjectBytes);
132 buffer.putInt(payload.length);
133 buffer.put(payload);
134 return buffer.array();
135 }
136
137 /**
138 * Decodes a new ClusterMessage from raw bytes.
139 * @param bytes raw bytes
140 * @return cluster message
141 */
142 public static ClusterMessage fromBytes(byte[] bytes) {
143 ByteBuffer buffer = ByteBuffer.wrap(bytes);
144 byte[] senderBytes = new byte[buffer.getInt()];
145 buffer.get(senderBytes);
146 byte[] subjectBytes = new byte[buffer.getInt()];
147 buffer.get(subjectBytes);
148 byte[] payloadBytes = new byte[buffer.getInt()];
149 buffer.get(payloadBytes);
150
151 return new ClusterMessage(new NodeId(new String(senderBytes, Charsets.UTF_8)),
Thomas Vachuskaff965232015-03-17 14:10:52 -0700152 new MessageSubject(new String(subjectBytes, Charsets.UTF_8)),
Madan Jampaniba472232015-03-04 13:00:50 -0800153 payloadBytes);
154 }
155
Jonathan Hart584d2f32015-01-27 19:46:14 -0800156 @Override
157 public int hashCode() {
Yuta HIGUCHIfbd9ae92018-01-24 23:39:06 -0800158 return Objects.hash(sender, subject, Arrays.hashCode(payload));
Jonathan Hart584d2f32015-01-27 19:46:14 -0800159 }
tom1d416c52014-09-29 20:55:24 -0700160}