mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-11-01 08:41:28 +01:00
[ONOS-4438] Add codecs for mastership REST API
Add codecs for RoleInfo, MastershipTerm and MastershipRole. Change-Id: I1135c7fc0ed591446d6268229b54fda70391fdb9
This commit is contained in:
parent
530cf46c1d
commit
b68a2b05f2
@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.Deactivate;
|
||||
import org.apache.felix.scr.annotations.Service;
|
||||
import org.onlab.packet.Ethernet;
|
||||
import org.onosproject.cluster.ControllerNode;
|
||||
import org.onosproject.cluster.RoleInfo;
|
||||
import org.onosproject.codec.CodecService;
|
||||
import org.onosproject.codec.JsonCodec;
|
||||
import org.onosproject.core.Application;
|
||||
@ -31,12 +32,14 @@ import org.onosproject.incubator.net.virtual.VirtualDevice;
|
||||
import org.onosproject.incubator.net.virtual.VirtualLink;
|
||||
import org.onosproject.incubator.net.virtual.VirtualNetwork;
|
||||
import org.onosproject.incubator.net.virtual.VirtualPort;
|
||||
import org.onosproject.mastership.MastershipTerm;
|
||||
import org.onosproject.net.Annotations;
|
||||
import org.onosproject.net.ConnectPoint;
|
||||
import org.onosproject.net.Device;
|
||||
import org.onosproject.net.Host;
|
||||
import org.onosproject.net.HostLocation;
|
||||
import org.onosproject.net.Link;
|
||||
import org.onosproject.net.MastershipRole;
|
||||
import org.onosproject.net.Path;
|
||||
import org.onosproject.net.Port;
|
||||
import org.onosproject.net.device.PortStatistics;
|
||||
@ -136,6 +139,9 @@ public class CodecManager implements CodecService {
|
||||
registerCodec(VirtualDevice.class, new VirtualDeviceCodec());
|
||||
registerCodec(VirtualPort.class, new VirtualPortCodec());
|
||||
registerCodec(VirtualLink.class, new VirtualLinkCodec());
|
||||
registerCodec(MastershipTerm.class, new MastershipTermCodec());
|
||||
registerCodec(MastershipRole.class, new MastershipRoleCodec());
|
||||
registerCodec(RoleInfo.class, new RoleInfoCodec());
|
||||
log.info("Started");
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed 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.onosproject.codec.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.onosproject.codec.CodecContext;
|
||||
import org.onosproject.codec.JsonCodec;
|
||||
import org.onosproject.net.MastershipRole;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.onlab.util.Tools.nullIsIllegal;
|
||||
import static org.onosproject.net.MastershipRole.MASTER;
|
||||
import static org.onosproject.net.MastershipRole.NONE;
|
||||
import static org.onosproject.net.MastershipRole.STANDBY;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
/**
|
||||
* Codec for mastership role.
|
||||
*/
|
||||
public final class MastershipRoleCodec extends JsonCodec<MastershipRole> {
|
||||
private final Logger log = getLogger(getClass());
|
||||
|
||||
// JSON field names
|
||||
private static final String ROLE = "role";
|
||||
|
||||
private static final String MISSING_MEMBER_MESSAGE = " member is required in MastershipRole";
|
||||
|
||||
@Override
|
||||
public ObjectNode encode(MastershipRole mastershipRole, CodecContext context) {
|
||||
checkNotNull(mastershipRole, "MastershipRole cannot be null");
|
||||
ObjectNode result = context.mapper().createObjectNode()
|
||||
.put(ROLE, mastershipRole.name());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MastershipRole decode(ObjectNode json, CodecContext context) {
|
||||
if (json == null || !json.isObject()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String roleJson = nullIsIllegal(json.get(ROLE),
|
||||
ROLE + MISSING_MEMBER_MESSAGE).asText();
|
||||
MastershipRole mastershipRole;
|
||||
switch (roleJson) {
|
||||
case "MASTER":
|
||||
mastershipRole = MASTER;
|
||||
break;
|
||||
case "STANDBY":
|
||||
mastershipRole = STANDBY;
|
||||
break;
|
||||
case "NONE":
|
||||
mastershipRole = NONE;
|
||||
break;
|
||||
default:
|
||||
log.warn("The mastership role {} is not defined.", roleJson);
|
||||
return null;
|
||||
}
|
||||
|
||||
return mastershipRole;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed 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.onosproject.codec.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.onosproject.cluster.NodeId;
|
||||
import org.onosproject.codec.CodecContext;
|
||||
import org.onosproject.codec.JsonCodec;
|
||||
import org.onosproject.mastership.MastershipTerm;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.onlab.util.Tools.nullIsIllegal;
|
||||
|
||||
/**
|
||||
* Codec for mastership term.
|
||||
*/
|
||||
public class MastershipTermCodec extends JsonCodec<MastershipTerm> {
|
||||
|
||||
// JSON field names
|
||||
private static final String MASTER = "master";
|
||||
private static final String TERM_NUMBER = "termNumber";
|
||||
|
||||
private static final String MISSING_MEMBER_MESSAGE = " member is required in MastershipTerm";
|
||||
|
||||
@Override
|
||||
public ObjectNode encode(MastershipTerm term, CodecContext context) {
|
||||
checkNotNull(term, "Mastership term cannot be null");
|
||||
ObjectNode result = context.mapper().createObjectNode()
|
||||
.put(MASTER, term.master().id())
|
||||
.put(TERM_NUMBER, term.termNumber());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MastershipTerm decode(ObjectNode json, CodecContext context) {
|
||||
if (json == null || !json.isObject()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// node identifier of master
|
||||
NodeId nodeId = NodeId.nodeId(nullIsIllegal(json.get(MASTER),
|
||||
MASTER + MISSING_MEMBER_MESSAGE).asText());
|
||||
|
||||
// term number
|
||||
long termNumber = nullIsIllegal(json.get(TERM_NUMBER),
|
||||
TERM_NUMBER + MISSING_MEMBER_MESSAGE).asLong();
|
||||
|
||||
return MastershipTerm.of(nodeId, termNumber);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed 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.onosproject.codec.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.onosproject.cluster.NodeId;
|
||||
import org.onosproject.cluster.RoleInfo;
|
||||
import org.onosproject.codec.CodecContext;
|
||||
import org.onosproject.codec.JsonCodec;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.onlab.util.Tools.nullIsIllegal;
|
||||
|
||||
/**
|
||||
* Codec for role info.
|
||||
*/
|
||||
public final class RoleInfoCodec extends JsonCodec<RoleInfo> {
|
||||
|
||||
// JSON field names
|
||||
private static final String MASTER = "master";
|
||||
private static final String BACKUPS = "backups";
|
||||
|
||||
private static final String MISSING_MEMBER_MESSAGE = " member is required in MastershipTerm";
|
||||
|
||||
@Override
|
||||
public ObjectNode encode(RoleInfo roleInfo, CodecContext context) {
|
||||
checkNotNull(roleInfo, "RoleInfo cannot be null");
|
||||
|
||||
ObjectNode result = context.mapper().createObjectNode();
|
||||
|
||||
if (roleInfo.master() != null) {
|
||||
result.put(MASTER, roleInfo.master().id());
|
||||
}
|
||||
|
||||
ArrayNode backups = context.mapper().createArrayNode();
|
||||
roleInfo.backups().forEach(backup -> backups.add(backup.id()));
|
||||
|
||||
if (roleInfo.backups().size() != 0) {
|
||||
result.set(BACKUPS, backups);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleInfo decode(ObjectNode json, CodecContext context) {
|
||||
if (json == null || !json.isObject()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// parse node identifier of master
|
||||
NodeId nodeId = json.get(MASTER) == null ?
|
||||
null : NodeId.nodeId(json.get(MASTER).asText());
|
||||
|
||||
// parse node identifier of backups
|
||||
List<NodeId> backups = new ArrayList<>();
|
||||
|
||||
ArrayNode backupsJson = (ArrayNode) nullIsIllegal(json.get(BACKUPS),
|
||||
BACKUPS + MISSING_MEMBER_MESSAGE);
|
||||
|
||||
IntStream.range(0, backupsJson.size()).forEach(i -> {
|
||||
JsonNode backupJson = nullIsIllegal(backupsJson.get(i),
|
||||
"Backup node id cannot be null");
|
||||
backups.add(NodeId.nodeId(backupJson.asText()));
|
||||
});
|
||||
|
||||
return new RoleInfo(nodeId, backups);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed 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.onosproject.codec.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.onosproject.codec.JsonCodec;
|
||||
import org.onosproject.net.MastershipRole;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
import static org.onosproject.net.MastershipRole.MASTER;
|
||||
|
||||
/**
|
||||
* Unit tests for mastership role codec.
|
||||
*/
|
||||
public final class MastershipRoleCodecTest {
|
||||
|
||||
MockCodecContext context;
|
||||
JsonCodec<MastershipRole> mastershipRoleCodec;
|
||||
|
||||
/**
|
||||
* Sets up for each test. Creates a context and fetches the mastership role
|
||||
* codec.
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
context = new MockCodecContext();
|
||||
mastershipRoleCodec = context.codec(MastershipRole.class);
|
||||
assertThat(mastershipRoleCodec, notNullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests encoding of a mastership role object.
|
||||
*/
|
||||
@Test
|
||||
public void testMastershipRoleEncode() {
|
||||
MastershipRole mastershipRole = MASTER;
|
||||
ObjectNode mastershipRoleJson = mastershipRoleCodec.encode(mastershipRole, context);
|
||||
assertThat(mastershipRoleJson, MastershipRoleJsonMatcher.matchesMastershipRole(mastershipRole));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests decoding of mastership role JSON object.
|
||||
*/
|
||||
@Test
|
||||
public void testMastershipRoleDecode() throws IOException {
|
||||
MastershipRole mastershipRole = getMastershipRole("MastershipRole.json");
|
||||
|
||||
assertThat(mastershipRole, is(MASTER));
|
||||
}
|
||||
|
||||
/**
|
||||
* Hamcrest matcher for mastership role.
|
||||
*/
|
||||
private static final class MastershipRoleJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
|
||||
|
||||
private final MastershipRole mastershipRole;
|
||||
|
||||
private MastershipRoleJsonMatcher(MastershipRole mastershipRole) {
|
||||
this.mastershipRole = mastershipRole;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(JsonNode jsonNode, Description description) {
|
||||
|
||||
// check mastership role
|
||||
String jsonRole = jsonNode.get("role").asText();
|
||||
String role = mastershipRole.name();
|
||||
if (!jsonRole.equals(role)) {
|
||||
description.appendText("mastership role was " + jsonRole);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText(mastershipRole.toString());
|
||||
}
|
||||
|
||||
static MastershipRoleJsonMatcher matchesMastershipRole(MastershipRole mastershipRole) {
|
||||
return new MastershipRoleJsonMatcher(mastershipRole);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a mastership role from the given resource and decodes it.
|
||||
*
|
||||
* @param resourceName resource to use to read the JSON for the rule
|
||||
* @return decoded mastership term object
|
||||
* @throws IOException if processing the resource fails
|
||||
*/
|
||||
private MastershipRole getMastershipRole(String resourceName) throws IOException {
|
||||
InputStream jsonStream = MastershipRoleCodecTest.class.getResourceAsStream(resourceName);
|
||||
JsonNode json = context.mapper().readTree(jsonStream);
|
||||
assertThat(json, notNullValue());
|
||||
MastershipRole mastershipRole = mastershipRoleCodec.decode((ObjectNode) json, context);
|
||||
assertThat(mastershipRole, notNullValue());
|
||||
return mastershipRole;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed 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.onosproject.codec.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.onosproject.cluster.NodeId;
|
||||
import org.onosproject.codec.JsonCodec;
|
||||
import org.onosproject.mastership.MastershipTerm;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
/**
|
||||
* Unit tests for mastership term codec.
|
||||
*/
|
||||
public class MastershipTermCodecTest {
|
||||
|
||||
MockCodecContext context;
|
||||
JsonCodec<MastershipTerm> mastershipTermCodec;
|
||||
|
||||
/**
|
||||
* Sets up for each test. Creates a context and fetches the mastership term
|
||||
* codec.
|
||||
*/
|
||||
@Before
|
||||
public void setUp() {
|
||||
context = new MockCodecContext();
|
||||
mastershipTermCodec = context.codec(MastershipTerm.class);
|
||||
assertThat(mastershipTermCodec, notNullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests encoding of a mastership term object.
|
||||
*/
|
||||
@Test
|
||||
public void testMastershipTermEncode() {
|
||||
NodeId masterNodeId = NodeId.nodeId("1");
|
||||
long termNumber = 10;
|
||||
|
||||
MastershipTerm mastershipTerm = MastershipTerm.of(masterNodeId, termNumber);
|
||||
ObjectNode mastershipTermJson = mastershipTermCodec.encode(mastershipTerm, context);
|
||||
assertThat(mastershipTermJson, MastershipTermJsonMatcher.matchesMastershipTerm(mastershipTerm));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests decoding of mastership term JSON object.
|
||||
*/
|
||||
@Test
|
||||
public void testMastershipTermDecode() throws IOException {
|
||||
MastershipTerm mastershipTerm = getMastershipTerm("MastershipTerm.json");
|
||||
|
||||
assertThat(mastershipTerm.master().id(), is("1"));
|
||||
assertThat(mastershipTerm.termNumber(), is(10L));
|
||||
}
|
||||
|
||||
/**
|
||||
* Hamcrest matcher for mastership term.
|
||||
*/
|
||||
private static final class MastershipTermJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
|
||||
|
||||
private final MastershipTerm mastershipTerm;
|
||||
|
||||
private MastershipTermJsonMatcher(MastershipTerm mastershipTerm) {
|
||||
this.mastershipTerm = mastershipTerm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(JsonNode jsonNode, Description description) {
|
||||
|
||||
// check node identifier of master
|
||||
String jsonNodeId = jsonNode.get("master").asText();
|
||||
String nodeId = mastershipTerm.master().id();
|
||||
if (!jsonNodeId.equals(nodeId)) {
|
||||
description.appendText("master's node id was " + jsonNodeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check term number
|
||||
long jsonTermNumber = jsonNode.get("termNumber").asLong();
|
||||
long termNumber = mastershipTerm.termNumber();
|
||||
if (jsonTermNumber != termNumber) {
|
||||
description.appendText("term number was " + jsonTermNumber);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText(mastershipTerm.toString());
|
||||
}
|
||||
|
||||
static MastershipTermJsonMatcher matchesMastershipTerm(MastershipTerm mastershipTerm) {
|
||||
return new MastershipTermJsonMatcher(mastershipTerm);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a mastership term from the given resource and decodes it.
|
||||
*
|
||||
* @param resourceName resource to use to read the JSON for the rule
|
||||
* @return decoded mastership term object
|
||||
* @throws IOException if processing the resource fails
|
||||
*/
|
||||
private MastershipTerm getMastershipTerm(String resourceName) throws IOException {
|
||||
InputStream jsonStream = MastershipTermCodecTest.class.getResourceAsStream(resourceName);
|
||||
JsonNode json = context.mapper().readTree(jsonStream);
|
||||
assertThat(json, notNullValue());
|
||||
MastershipTerm mastershipTerm = mastershipTermCodec.decode((ObjectNode) json, context);
|
||||
assertThat(mastershipTerm, notNullValue());
|
||||
return mastershipTerm;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright 2016-present Open Networking Laboratory
|
||||
*
|
||||
* Licensed 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.onosproject.codec.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hamcrest.Description;
|
||||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.onosproject.cluster.NodeId;
|
||||
import org.onosproject.cluster.RoleInfo;
|
||||
import org.onosproject.codec.JsonCodec;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.hamcrest.Matchers.notNullValue;
|
||||
|
||||
/**
|
||||
* Unit tests for role info codec.
|
||||
*/
|
||||
public final class RoleInfoCodecTest {
|
||||
|
||||
MockCodecContext context;
|
||||
JsonCodec<RoleInfo> roleInfoCodec;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
context = new MockCodecContext();
|
||||
roleInfoCodec = context.codec(RoleInfo.class);
|
||||
assertThat(roleInfoCodec, notNullValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests encoding of a role info object.
|
||||
*/
|
||||
@Test
|
||||
public void testRoleInfoEncode() {
|
||||
NodeId masterNodeId = NodeId.nodeId("1");
|
||||
NodeId backupNodeId1 = NodeId.nodeId("1");
|
||||
NodeId backupNodeId2 = NodeId.nodeId("2");
|
||||
NodeId backupNodeId3 = NodeId.nodeId("3");
|
||||
List<NodeId> backupNodeIds =
|
||||
ImmutableList.of(backupNodeId1, backupNodeId2, backupNodeId3);
|
||||
|
||||
RoleInfo roleInfo = new RoleInfo(masterNodeId, backupNodeIds);
|
||||
ObjectNode roleInfoJson = roleInfoCodec.encode(roleInfo, context);
|
||||
assertThat(roleInfoJson, RoleInfoJsonMatcher.matchesRoleInfo(roleInfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests decoding of a role info JSON object.
|
||||
*/
|
||||
@Test
|
||||
public void testRoleInfoDecode() throws IOException {
|
||||
RoleInfo roleInfo = getRoleInfo("RoleInfo.json");
|
||||
|
||||
assertThat(roleInfo.backups().size(), is(3));
|
||||
|
||||
assertThat(roleInfo.master().id(), is("1"));
|
||||
|
||||
List<NodeId> backups = roleInfo.backups();
|
||||
assertThat(backups.contains(NodeId.nodeId("2")), is(true));
|
||||
assertThat(backups.contains(NodeId.nodeId("3")), is(true));
|
||||
assertThat(backups.contains(NodeId.nodeId("4")), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Hamcrest matcher for role info.
|
||||
*/
|
||||
private static final class RoleInfoJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> {
|
||||
|
||||
private final RoleInfo roleInfo;
|
||||
|
||||
private RoleInfoJsonMatcher(RoleInfo roleInfo) {
|
||||
this.roleInfo = roleInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean matchesSafely(JsonNode jsonNode, Description description) {
|
||||
|
||||
// check master node identifier
|
||||
String jsonNodeId = jsonNode.get("master") != null ? jsonNode.get("master").asText() : null;
|
||||
String nodeId = roleInfo.master().id();
|
||||
if (!StringUtils.equals(jsonNodeId, nodeId)) {
|
||||
description.appendText("master's node id was " + jsonNodeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check backup nodes size
|
||||
JsonNode jsonBackupNodeIds = jsonNode.get("backups");
|
||||
if (jsonBackupNodeIds.size() != roleInfo.backups().size()) {
|
||||
description.appendText("backup nodes size was " + jsonBackupNodeIds.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// check backup nodes' identifier
|
||||
for (NodeId backupNodeId : roleInfo.backups()) {
|
||||
boolean backupFound = false;
|
||||
for (int idx = 0; idx < jsonBackupNodeIds.size(); idx++) {
|
||||
if (backupNodeId.id().equals(jsonBackupNodeIds.get(idx).asText())) {
|
||||
backupFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!backupFound) {
|
||||
description.appendText("backup not found " + backupNodeId.id());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void describeTo(Description description) {
|
||||
description.appendText(roleInfo.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory to allocate a role info.
|
||||
*
|
||||
* @param roleInfo role info object we are looking for
|
||||
* @return matcher
|
||||
*/
|
||||
static RoleInfoJsonMatcher matchesRoleInfo(RoleInfo roleInfo) {
|
||||
return new RoleInfoJsonMatcher(roleInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads in a role info from the given resource and decodes it.
|
||||
*
|
||||
* @param resourceName resource to use to read the JSON for the rule
|
||||
* @return decoded roleInfo
|
||||
* @throws IOException if processing the resource fails
|
||||
*/
|
||||
private RoleInfo getRoleInfo(String resourceName) throws IOException {
|
||||
InputStream jsonStream = RoleInfoCodecTest.class.getResourceAsStream(resourceName);
|
||||
JsonNode json = context.mapper().readTree(jsonStream);
|
||||
assertThat(json, notNullValue());
|
||||
RoleInfo roleInfo = roleInfoCodec.decode((ObjectNode) json, context);
|
||||
assertThat(roleInfo, notNullValue());
|
||||
return roleInfo;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,3 @@
|
||||
{
|
||||
"role": "MASTER"
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
{
|
||||
"master": "1",
|
||||
"termNumber": 10
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
{
|
||||
"master": "1",
|
||||
"backups": [
|
||||
"2",
|
||||
"3",
|
||||
"4"
|
||||
]
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user