/* * 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.rest.resources; import com.eclipsesource.json.Json; import com.eclipsesource.json.JsonArray; import com.eclipsesource.json.JsonObject; import com.google.common.collect.ImmutableSet; import org.glassfish.jersey.client.ClientProperties; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; import org.junit.Before; import org.junit.Test; import org.onlab.osgi.ServiceDirectory; import org.onlab.osgi.TestServiceDirectory; import org.onlab.packet.IpAddress; import org.onlab.rest.BaseResource; import org.onosproject.codec.CodecService; import org.onosproject.codec.impl.CodecManager; import org.onosproject.net.mcast.McastRoute; import org.onosproject.net.mcast.MulticastRouteService; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.InputStream; import java.net.HttpURLConnection; import java.util.Set; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expectLastCall; import static org.easymock.EasyMock.replay; import static org.easymock.EasyMock.verify; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; /** * Unit tests for multicast route REST APIs. */ public class MulticastRouteResourceTest extends ResourceTest { final MulticastRouteService mockMulticastRouteService = createMock(MulticastRouteService.class); private McastRoute route1; private McastRoute route2; private McastRoute route3; private void initMcastRouteMocks() { IpAddress source1 = IpAddress.valueOf("1.1.1.1"); IpAddress source2 = IpAddress.valueOf("2.2.2.2"); IpAddress source3 = IpAddress.valueOf("3.3.3.3"); IpAddress group = IpAddress.valueOf("224.0.0.1"); route1 = new McastRoute(source1, group, McastRoute.Type.PIM); route2 = new McastRoute(source2, group, McastRoute.Type.IGMP); route3 = new McastRoute(source3, group, McastRoute.Type.STATIC); } @Before public void setupTest() { final CodecManager codecService = new CodecManager(); codecService.activate(); ServiceDirectory testDirectory = new TestServiceDirectory() .add(MulticastRouteService.class, mockMulticastRouteService) .add(CodecService.class, codecService); BaseResource.setServiceDirectory(testDirectory); } /** * Hamcrest matcher to check that a mcast route representation in JSON matches * the actual mcast route. */ public static class McastRouteJsonMatcher extends TypeSafeMatcher<JsonObject> { private final McastRoute route; private String reason = ""; public McastRouteJsonMatcher(McastRoute mcastRoute) { this.route = mcastRoute; } @Override protected boolean matchesSafely(JsonObject jsonMcastRoute) { // check source String jsonSource = jsonMcastRoute.get("source").asString(); String source = route.source().toString(); if (!jsonSource.equals(source)) { reason = "Mcast route source was " + jsonSource; return false; } // check group String jsonGroup = jsonMcastRoute.get("group").asString(); String group = route.group().toString(); if (!jsonGroup.equals(group)) { reason = "Mcast route group was " + jsonSource; return false; } // check type String jsonType = jsonMcastRoute.get("type").asString(); String type = route.type().toString(); if (!jsonType.equals(type)) { reason = "Mcast route type was " + jsonSource; return false; } return true; } @Override public void describeTo(Description description) { description.appendText(reason); } } private static McastRouteJsonMatcher matchesMcastRoute(McastRoute route) { return new McastRouteJsonMatcher(route); } /** * Hamcrest matcher to check that a Mcast route is represented properly in * a JSON array of Mcastroutes. */ public static class McastRouteJsonArrayMatcher extends TypeSafeMatcher<JsonArray> { private final McastRoute route; private String reason = ""; public McastRouteJsonArrayMatcher(McastRoute mcastRoute) { this.route = mcastRoute; } @Override protected boolean matchesSafely(JsonArray json) { boolean found = false; for (int index = 0; index < json.size(); index++) { final JsonObject jsonMcastRoute = json.get(index).asObject(); final String source = route.source().toString(); final String group = route.group().toString(); final String type = route.type().toString(); final String jsonSource = jsonMcastRoute.get("source").asString(); final String jsonGroup = jsonMcastRoute.get("group").asString(); final String jsonType = jsonMcastRoute.get("type").asString(); if (jsonSource.equals(source) && jsonGroup.equals(group) && jsonType.equals(type)) { found = true; assertThat(jsonMcastRoute, matchesMcastRoute(route)); } } return found; } @Override public void describeTo(Description description) { description.appendText(reason); } } private static McastRouteJsonArrayMatcher hasMcastRoute(McastRoute route) { return new McastRouteJsonArrayMatcher(route); } /** * Tests the results of the REST API GET when there are active mcastroutes. */ @Test public void testMcastRoutePopulatedArray() { initMcastRouteMocks(); final Set<McastRoute> mcastRoutes = ImmutableSet.of(route1, route2, route3); expect(mockMulticastRouteService.getRoutes()).andReturn(mcastRoutes).anyTimes(); replay(mockMulticastRouteService); final WebTarget wt = target(); final String response = wt.path("mcast").request().get(String.class); final JsonObject result = Json.parse(response).asObject(); assertThat(result, notNullValue()); assertThat(result.names(), hasSize(1)); assertThat(result.names().get(0), is("routes")); final JsonArray jsonMcastRoutes = result.get("routes").asArray(); assertThat(jsonMcastRoutes, notNullValue()); assertThat(jsonMcastRoutes, hasMcastRoute(route1)); assertThat(jsonMcastRoutes, hasMcastRoute(route2)); assertThat(jsonMcastRoutes, hasMcastRoute(route3)); } /** * Tests creating a Mcast route with POST. */ @Test public void testMcastRoutePost() { mockMulticastRouteService.add(anyObject()); expectLastCall(); replay(mockMulticastRouteService); WebTarget wt = target(); InputStream jsonStream = MulticastRouteResourceTest.class .getResourceAsStream("mcastroute.json"); Response response = wt.path("mcast/") .request(MediaType.APPLICATION_JSON_TYPE) .post(Entity.json(jsonStream)); assertThat(response.getStatus(), is(HttpURLConnection.HTTP_CREATED)); verify(mockMulticastRouteService); } /** * Tests deletion a Mcast route with DELETE. */ @Test public void testMcastRouteDelete() { mockMulticastRouteService.remove(anyObject()); expectLastCall(); replay(mockMulticastRouteService); WebTarget wt = target().property( ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true); InputStream jsonStream = MulticastRouteResourceTest.class .getResourceAsStream("mcastroute.json"); wt.request().method("DELETE", Entity.json(jsonStream)); } }