Implement REST API of policy
Change-Id: I46f5a3cd6d66cf7a3a90a5d153b3878fdf5cbd31
diff --git a/web/src/main/java/org/onosproject/segmentrouting/web/PolicyWebResource.java b/web/src/main/java/org/onosproject/segmentrouting/web/PolicyWebResource.java
index 08663e4..5a24ca5 100644
--- a/web/src/main/java/org/onosproject/segmentrouting/web/PolicyWebResource.java
+++ b/web/src/main/java/org/onosproject/segmentrouting/web/PolicyWebResource.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2015-present Open Networking Foundation
+ * Copyright 2021-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,92 +15,264 @@
*/
package org.onosproject.segmentrouting.web;
-import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
-
+import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.rest.AbstractWebResource;
-import org.onosproject.segmentrouting.Policy;
-import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.policy.api.DropPolicy;
+import org.onosproject.segmentrouting.policy.api.Policy;
+import org.onosproject.segmentrouting.policy.api.Policy.PolicyType;
+import org.onosproject.segmentrouting.policy.api.PolicyData;
+import org.onosproject.segmentrouting.policy.api.PolicyId;
+import org.onosproject.segmentrouting.policy.api.PolicyService;
+import org.onosproject.segmentrouting.policy.api.RedirectPolicy;
+import org.onosproject.segmentrouting.policy.api.TrafficMatch;
+import org.onosproject.segmentrouting.policy.api.TrafficMatchData;
+import org.onosproject.segmentrouting.policy.api.TrafficMatchId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
+import javax.ws.rs.Path;
import javax.ws.rs.POST;
+import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
-import java.util.List;
+import java.util.Set;
import static org.onlab.util.Tools.readTreeFromStream;
/**
- * Query, create and remove segment routing plicies.
+ * Query, create and remove Policies and Traffic Matches.
*/
-// @Path("policy")
+@Path("policy")
public class PolicyWebResource extends AbstractWebResource {
+ private static Logger log = LoggerFactory.getLogger(PolicyWebResource.class);
- private static final PolicyCodec POLICY_CODEC = new PolicyCodec();
+ private static final String EMPTY_TRAFFIC_SELECTOR =
+ "Empty traffic selector is not allowed";
+ private static final String POLICY = "policy";
+ private static final String POLICY_ID = "policy_id";
+ private static final String TRAFFIC_MATCH = "trafficMatch";
+ private static final String TRAFFIC_MATCH_ID = "traffic_match_id";
/**
- * Get all segment routing policies.
- * Returns an array of segment routing policies.
+ * Get all Policies.
*
- * @return status of OK
+ * @return 200 OK will a collection of Policies
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
- public Response getPolicy() {
- SegmentRoutingService srService = get(SegmentRoutingService.class);
- List<Policy> policies = srService.getPolicies();
- ObjectNode result = new ObjectMapper().createObjectNode();
- result.set("policy", new PolicyCodec().encode(policies, this));
+ public Response getPolicies() {
+ PolicyService policyService = get(PolicyService.class);
+ ObjectNode root = mapper().createObjectNode();
+ ArrayNode policiesArr = root.putArray(POLICY);
- return ok(result.toString()).build();
+ //Create a filter set contains all PolicyType
+ Set<PolicyType> policyTypes = Set.of(PolicyType.values());
+
+ for (PolicyData policyData : policyService.policies(policyTypes)) {
+ Policy policy = policyData.policy();
+ switch (policy.policyType()) {
+ case DROP:
+ policiesArr.add(codec(DropPolicy.class).encode((DropPolicy) policy, this));
+ break;
+ case REDIRECT:
+ policiesArr.add(codec(RedirectPolicy.class).encode((RedirectPolicy) policy, this));
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return Response.ok(root).build();
}
/**
- * Create a new segment routing policy.
+ * Get all Drop Policies.
*
- * @param input JSON stream for policy to create
- * @return status of the request - OK if the policy is created,
- * @throws IOException if JSON processing fails
+ * @return 200 OK will a collection of Dop Policies
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("drop")
+ public Response getDropPolicies() {
+ PolicyService policyService = get(PolicyService.class);
+ ObjectNode root = mapper().createObjectNode();
+ ArrayNode policiesArr = root.putArray(POLICY);
+
+ Set<PolicyType> policyTypes = Set.of(PolicyType.DROP);
+
+ for (PolicyData policyData : policyService.policies(policyTypes)) {
+ Policy policy = policyData.policy();
+ policiesArr.add(codec(DropPolicy.class).encode((DropPolicy) policy, this));
+ }
+
+ return Response.ok(root).build();
+ }
+
+ /**
+ * Create a new Drop Policy.
+ *
+ * @return 200 OK and policyId
*/
@POST
@Consumes(MediaType.APPLICATION_JSON)
- public Response createPolicy(InputStream input) throws IOException {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode policyJson = readTreeFromStream(mapper, input);
- SegmentRoutingService srService = get(SegmentRoutingService.class);
- Policy policyInfo = POLICY_CODEC.decode(policyJson, this);
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("drop")
+ public Response createDropPolicy() {
+ PolicyService policyService = get(PolicyService.class);
+ ObjectNode root = mapper().createObjectNode();
- if (policyInfo.type() == Policy.Type.TUNNEL_FLOW) {
- srService.createPolicy(policyInfo);
- return Response.ok().build();
- } else {
- return Response.serverError().build();
- }
+ DropPolicy dropPolicy = new DropPolicy();
+ policyService.addOrUpdatePolicy(dropPolicy);
+
+ root.put(POLICY_ID, dropPolicy.policyId().toString());
+
+ return Response.ok(root).build();
}
/**
- * Delete a segment routing policy.
+ * Get all Redirect Policies.
*
- * @param input JSON stream for policy to delete
- * @return 204 NO CONTENT if the policy is removed
- * @throws IOException if JSON is invalid
+ * @return 200 OK will a collection of Redirect Policies
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("redirect")
+ public Response getRedirectPolicies() {
+ PolicyService policyService = get(PolicyService.class);
+ ObjectNode root = mapper().createObjectNode();
+ ArrayNode policiesArr = root.putArray(POLICY);
+
+ Set<PolicyType> policyTypes = Set.of(PolicyType.REDIRECT);
+
+ for (PolicyData policyData : policyService.policies(policyTypes)) {
+ Policy policy = policyData.policy();
+ policiesArr.add(codec(RedirectPolicy.class).encode((RedirectPolicy) policy, this));
+ }
+
+ return Response.ok(root).build();
+ }
+
+ /**
+ * Create a new Redirect Policy.
+ *
+ * @param input Json for the Redirect Policy
+ * @return 200 OK and policyId
+ * @onos.rsModel RedirectPolicyCreate
+ */
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("redirect")
+ public Response createRedirectPolicy(InputStream input) {
+ PolicyService policyService = get(PolicyService.class);
+ ObjectNode root = mapper().createObjectNode();
+
+ try {
+ ObjectNode jsonTree = readTreeFromStream(mapper(), input);
+ RedirectPolicy redirectPolicy = codec(RedirectPolicy.class).
+ decode(jsonTree, this);
+ policyService.addOrUpdatePolicy(redirectPolicy);
+ root.put(POLICY_ID, redirectPolicy.policyId().toString());
+ } catch (IOException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+
+ return Response.ok(root).build();
+ }
+
+ /**
+ * Delete a Policy by policyId.
+ *
+ * @param policyId Policy identifier
+ * @return 204 NO CONTENT
*/
@DELETE
- @Consumes(MediaType.APPLICATION_JSON)
- public Response removePolicy(InputStream input) throws IOException {
- ObjectMapper mapper = new ObjectMapper();
- ObjectNode policyJson = readTreeFromStream(mapper, input);
- SegmentRoutingService srService = get(SegmentRoutingService.class);
- Policy policyInfo = POLICY_CODEC.decode(policyJson, this);
- // TODO: Check the result
- srService.removePolicy(policyInfo);
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("{policyId}")
+ public Response deletePolicy(@PathParam("policyId") String policyId) {
+ PolicyService policyService = get(PolicyService.class);
+
+ policyService.removePolicy(PolicyId.of(policyId));
return Response.noContent().build();
}
+ /**
+ * Get all Traffic Matches.
+ *
+ * @return 200 OK will a collection of Traffic Matches
+ */
+ @GET
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("trafficmatch")
+ public Response getTrafficMatches() {
+ PolicyService policyService = get(PolicyService.class);
+ ObjectNode root = mapper().createObjectNode();
+ ArrayNode trafficMatchArr = root.putArray(TRAFFIC_MATCH);
+
+ for (TrafficMatchData trafficMatchData : policyService.trafficMatches()) {
+ TrafficMatch trafficMatch = trafficMatchData.trafficMatch();
+ trafficMatchArr.add(codec(TrafficMatch.class).encode(trafficMatch, this));
+ }
+
+ return Response.ok(root).build();
+ }
+
+ /**
+ * Create a new Traffic Match.
+ *
+ * @param input Json for the Traffic Match
+ * @return status of the request - CREATED and TrafficMatchId if the JSON is correct,
+ * BAD_REQUEST if the JSON is invalid
+ * @onos.rsModel TrafficMatchCreate
+ */
+ @POST
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("trafficmatch")
+ public Response createTrafficMatch(InputStream input) {
+ PolicyService policyService = get(PolicyService.class);
+ ObjectNode root = mapper().createObjectNode();
+
+ try {
+ ObjectNode jsonTree = readTreeFromStream(mapper(), input);
+ TrafficMatch trafficMatch = codec(TrafficMatch.class).
+ decode(jsonTree, this);
+ if (trafficMatch.trafficSelector()
+ .equals(DefaultTrafficSelector.emptySelector())) {
+ throw new IllegalArgumentException(EMPTY_TRAFFIC_SELECTOR);
+ }
+ policyService.addOrUpdateTrafficMatch(trafficMatch);
+ root.put(TRAFFIC_MATCH_ID, trafficMatch.trafficMatchId().toString());
+ } catch (IOException ex) {
+ throw new IllegalArgumentException(ex);
+ }
+
+ return Response.ok(root).build();
+ }
+
+ /**
+ * Delete a Traffic Match by trafficMatchId.
+ *
+ * @param trafficMatchId Traffic Match identifier
+ * @return 204 NO CONTENT
+ */
+ @DELETE
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("trafficmatch/{trafficMatchId}")
+ public Response deleteTrafficMatch(@PathParam("trafficMatchId") String trafficMatchId) {
+ PolicyService policyService = get(PolicyService.class);
+
+ policyService.removeTrafficMatch(TrafficMatchId.of(trafficMatchId));
+
+ return Response.noContent().build();
+ }
}