| /* |
| * 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. |
| * 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.segmentrouting.web; |
| |
| 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.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.Set; |
| |
| import static org.onlab.util.Tools.readTreeFromStream; |
| |
| /** |
| * Query, create and remove Policies and Traffic Matches. |
| */ |
| @Path("policy") |
| public class PolicyWebResource extends AbstractWebResource { |
| private static Logger log = LoggerFactory.getLogger(PolicyWebResource.class); |
| |
| 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 Policies. |
| * |
| * @return 200 OK will a collection of Policies |
| */ |
| @GET |
| @Produces(MediaType.APPLICATION_JSON) |
| public Response getPolicies() { |
| PolicyService policyService = get(PolicyService.class); |
| ObjectNode root = mapper().createObjectNode(); |
| ArrayNode policiesArr = root.putArray(POLICY); |
| |
| //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(); |
| } |
| |
| /** |
| * Get all Drop Policies. |
| * |
| * @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) |
| @Produces(MediaType.APPLICATION_JSON) |
| @Path("drop") |
| public Response createDropPolicy() { |
| PolicyService policyService = get(PolicyService.class); |
| ObjectNode root = mapper().createObjectNode(); |
| |
| DropPolicy dropPolicy = new DropPolicy(); |
| policyService.addOrUpdatePolicy(dropPolicy); |
| |
| root.put(POLICY_ID, dropPolicy.policyId().toString()); |
| |
| return Response.ok(root).build(); |
| } |
| |
| /** |
| * Get all Redirect Policies. |
| * |
| * @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 |
| @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(); |
| } |
| } |