sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 1 | /* |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 2 | * Copyright 2021-present Open Networking Foundation |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 3 | * |
| 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 | */ |
| 16 | package org.onosproject.segmentrouting.web; |
| 17 | |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 18 | import com.fasterxml.jackson.databind.node.ArrayNode; |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 20 | import org.onosproject.net.flow.DefaultTrafficSelector; |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 21 | import org.onosproject.rest.AbstractWebResource; |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 22 | import org.onosproject.segmentrouting.policy.api.DropPolicy; |
| 23 | import org.onosproject.segmentrouting.policy.api.Policy; |
| 24 | import org.onosproject.segmentrouting.policy.api.Policy.PolicyType; |
| 25 | import org.onosproject.segmentrouting.policy.api.PolicyData; |
| 26 | import org.onosproject.segmentrouting.policy.api.PolicyId; |
| 27 | import org.onosproject.segmentrouting.policy.api.PolicyService; |
| 28 | import org.onosproject.segmentrouting.policy.api.RedirectPolicy; |
| 29 | import org.onosproject.segmentrouting.policy.api.TrafficMatch; |
| 30 | import org.onosproject.segmentrouting.policy.api.TrafficMatchData; |
| 31 | import org.onosproject.segmentrouting.policy.api.TrafficMatchId; |
| 32 | import org.slf4j.Logger; |
| 33 | import org.slf4j.LoggerFactory; |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 34 | |
| 35 | import javax.ws.rs.Consumes; |
| 36 | import javax.ws.rs.DELETE; |
| 37 | import javax.ws.rs.GET; |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 38 | import javax.ws.rs.Path; |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 39 | import javax.ws.rs.POST; |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 40 | import javax.ws.rs.PathParam; |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 41 | import javax.ws.rs.Produces; |
| 42 | import javax.ws.rs.core.MediaType; |
| 43 | import javax.ws.rs.core.Response; |
| 44 | import java.io.IOException; |
| 45 | import java.io.InputStream; |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 46 | import java.util.Set; |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 47 | |
Ray Milkey | c59ff08 | 2018-04-02 15:33:07 -0700 | [diff] [blame] | 48 | import static org.onlab.util.Tools.readTreeFromStream; |
| 49 | |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 50 | /** |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 51 | * Query, create and remove Policies and Traffic Matches. |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 52 | */ |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 53 | @Path("policy") |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 54 | public class PolicyWebResource extends AbstractWebResource { |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 55 | private static Logger log = LoggerFactory.getLogger(PolicyWebResource.class); |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 56 | |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 57 | private static final String EMPTY_TRAFFIC_SELECTOR = |
| 58 | "Empty traffic selector is not allowed"; |
| 59 | private static final String POLICY = "policy"; |
| 60 | private static final String POLICY_ID = "policy_id"; |
| 61 | private static final String TRAFFIC_MATCH = "trafficMatch"; |
| 62 | private static final String TRAFFIC_MATCH_ID = "traffic_match_id"; |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 63 | |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 64 | /** |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 65 | * Get all Policies. |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 66 | * |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 67 | * @return 200 OK will a collection of Policies |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 68 | */ |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 69 | @GET |
| 70 | @Produces(MediaType.APPLICATION_JSON) |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 71 | public Response getPolicies() { |
| 72 | PolicyService policyService = get(PolicyService.class); |
| 73 | ObjectNode root = mapper().createObjectNode(); |
| 74 | ArrayNode policiesArr = root.putArray(POLICY); |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 75 | |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 76 | //Create a filter set contains all PolicyType |
| 77 | Set<PolicyType> policyTypes = Set.of(PolicyType.values()); |
| 78 | |
| 79 | for (PolicyData policyData : policyService.policies(policyTypes)) { |
| 80 | Policy policy = policyData.policy(); |
| 81 | switch (policy.policyType()) { |
| 82 | case DROP: |
| 83 | policiesArr.add(codec(DropPolicy.class).encode((DropPolicy) policy, this)); |
| 84 | break; |
| 85 | case REDIRECT: |
| 86 | policiesArr.add(codec(RedirectPolicy.class).encode((RedirectPolicy) policy, this)); |
| 87 | break; |
| 88 | default: |
| 89 | continue; |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | return Response.ok(root).build(); |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 94 | } |
| 95 | |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 96 | /** |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 97 | * Get all Drop Policies. |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 98 | * |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 99 | * @return 200 OK will a collection of Dop Policies |
| 100 | */ |
| 101 | @GET |
| 102 | @Produces(MediaType.APPLICATION_JSON) |
| 103 | @Path("drop") |
| 104 | public Response getDropPolicies() { |
| 105 | PolicyService policyService = get(PolicyService.class); |
| 106 | ObjectNode root = mapper().createObjectNode(); |
| 107 | ArrayNode policiesArr = root.putArray(POLICY); |
| 108 | |
| 109 | Set<PolicyType> policyTypes = Set.of(PolicyType.DROP); |
| 110 | |
| 111 | for (PolicyData policyData : policyService.policies(policyTypes)) { |
| 112 | Policy policy = policyData.policy(); |
| 113 | policiesArr.add(codec(DropPolicy.class).encode((DropPolicy) policy, this)); |
| 114 | } |
| 115 | |
| 116 | return Response.ok(root).build(); |
| 117 | } |
| 118 | |
| 119 | /** |
| 120 | * Create a new Drop Policy. |
| 121 | * |
| 122 | * @return 200 OK and policyId |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 123 | */ |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 124 | @POST |
| 125 | @Consumes(MediaType.APPLICATION_JSON) |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 126 | @Produces(MediaType.APPLICATION_JSON) |
| 127 | @Path("drop") |
| 128 | public Response createDropPolicy() { |
| 129 | PolicyService policyService = get(PolicyService.class); |
| 130 | ObjectNode root = mapper().createObjectNode(); |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 131 | |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 132 | DropPolicy dropPolicy = new DropPolicy(); |
| 133 | policyService.addOrUpdatePolicy(dropPolicy); |
| 134 | |
| 135 | root.put(POLICY_ID, dropPolicy.policyId().toString()); |
| 136 | |
| 137 | return Response.ok(root).build(); |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 138 | } |
| 139 | |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 140 | /** |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 141 | * Get all Redirect Policies. |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 142 | * |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 143 | * @return 200 OK will a collection of Redirect Policies |
| 144 | */ |
| 145 | @GET |
| 146 | @Produces(MediaType.APPLICATION_JSON) |
| 147 | @Path("redirect") |
| 148 | public Response getRedirectPolicies() { |
| 149 | PolicyService policyService = get(PolicyService.class); |
| 150 | ObjectNode root = mapper().createObjectNode(); |
| 151 | ArrayNode policiesArr = root.putArray(POLICY); |
| 152 | |
| 153 | Set<PolicyType> policyTypes = Set.of(PolicyType.REDIRECT); |
| 154 | |
| 155 | for (PolicyData policyData : policyService.policies(policyTypes)) { |
| 156 | Policy policy = policyData.policy(); |
| 157 | policiesArr.add(codec(RedirectPolicy.class).encode((RedirectPolicy) policy, this)); |
| 158 | } |
| 159 | |
| 160 | return Response.ok(root).build(); |
| 161 | } |
| 162 | |
| 163 | /** |
| 164 | * Create a new Redirect Policy. |
| 165 | * |
| 166 | * @param input Json for the Redirect Policy |
| 167 | * @return 200 OK and policyId |
| 168 | * @onos.rsModel RedirectPolicyCreate |
| 169 | */ |
| 170 | @POST |
| 171 | @Consumes(MediaType.APPLICATION_JSON) |
| 172 | @Produces(MediaType.APPLICATION_JSON) |
| 173 | @Path("redirect") |
| 174 | public Response createRedirectPolicy(InputStream input) { |
| 175 | PolicyService policyService = get(PolicyService.class); |
| 176 | ObjectNode root = mapper().createObjectNode(); |
| 177 | |
| 178 | try { |
| 179 | ObjectNode jsonTree = readTreeFromStream(mapper(), input); |
| 180 | RedirectPolicy redirectPolicy = codec(RedirectPolicy.class). |
| 181 | decode(jsonTree, this); |
| 182 | policyService.addOrUpdatePolicy(redirectPolicy); |
| 183 | root.put(POLICY_ID, redirectPolicy.policyId().toString()); |
| 184 | } catch (IOException ex) { |
| 185 | throw new IllegalArgumentException(ex); |
| 186 | } |
| 187 | |
| 188 | return Response.ok(root).build(); |
| 189 | } |
| 190 | |
| 191 | /** |
| 192 | * Delete a Policy by policyId. |
| 193 | * |
| 194 | * @param policyId Policy identifier |
| 195 | * @return 204 NO CONTENT |
Ray Milkey | 9d9ff03 | 2015-08-20 14:25:51 -0700 | [diff] [blame] | 196 | */ |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 197 | @DELETE |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 198 | @Produces(MediaType.APPLICATION_JSON) |
| 199 | @Path("{policyId}") |
| 200 | public Response deletePolicy(@PathParam("policyId") String policyId) { |
| 201 | PolicyService policyService = get(PolicyService.class); |
| 202 | |
| 203 | policyService.removePolicy(PolicyId.of(policyId)); |
sangho | 4a5c42a | 2015-05-20 22:16:38 -0700 | [diff] [blame] | 204 | |
Jian Li | 6b377d1 | 2016-05-10 11:48:19 -0700 | [diff] [blame] | 205 | return Response.noContent().build(); |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 206 | } |
| 207 | |
Wailok Shum | ee90c13 | 2021-03-11 21:00:11 +0800 | [diff] [blame^] | 208 | /** |
| 209 | * Get all Traffic Matches. |
| 210 | * |
| 211 | * @return 200 OK will a collection of Traffic Matches |
| 212 | */ |
| 213 | @GET |
| 214 | @Produces(MediaType.APPLICATION_JSON) |
| 215 | @Path("trafficmatch") |
| 216 | public Response getTrafficMatches() { |
| 217 | PolicyService policyService = get(PolicyService.class); |
| 218 | ObjectNode root = mapper().createObjectNode(); |
| 219 | ArrayNode trafficMatchArr = root.putArray(TRAFFIC_MATCH); |
| 220 | |
| 221 | for (TrafficMatchData trafficMatchData : policyService.trafficMatches()) { |
| 222 | TrafficMatch trafficMatch = trafficMatchData.trafficMatch(); |
| 223 | trafficMatchArr.add(codec(TrafficMatch.class).encode(trafficMatch, this)); |
| 224 | } |
| 225 | |
| 226 | return Response.ok(root).build(); |
| 227 | } |
| 228 | |
| 229 | /** |
| 230 | * Create a new Traffic Match. |
| 231 | * |
| 232 | * @param input Json for the Traffic Match |
| 233 | * @return status of the request - CREATED and TrafficMatchId if the JSON is correct, |
| 234 | * BAD_REQUEST if the JSON is invalid |
| 235 | * @onos.rsModel TrafficMatchCreate |
| 236 | */ |
| 237 | @POST |
| 238 | @Consumes(MediaType.APPLICATION_JSON) |
| 239 | @Produces(MediaType.APPLICATION_JSON) |
| 240 | @Path("trafficmatch") |
| 241 | public Response createTrafficMatch(InputStream input) { |
| 242 | PolicyService policyService = get(PolicyService.class); |
| 243 | ObjectNode root = mapper().createObjectNode(); |
| 244 | |
| 245 | try { |
| 246 | ObjectNode jsonTree = readTreeFromStream(mapper(), input); |
| 247 | TrafficMatch trafficMatch = codec(TrafficMatch.class). |
| 248 | decode(jsonTree, this); |
| 249 | if (trafficMatch.trafficSelector() |
| 250 | .equals(DefaultTrafficSelector.emptySelector())) { |
| 251 | throw new IllegalArgumentException(EMPTY_TRAFFIC_SELECTOR); |
| 252 | } |
| 253 | policyService.addOrUpdateTrafficMatch(trafficMatch); |
| 254 | root.put(TRAFFIC_MATCH_ID, trafficMatch.trafficMatchId().toString()); |
| 255 | } catch (IOException ex) { |
| 256 | throw new IllegalArgumentException(ex); |
| 257 | } |
| 258 | |
| 259 | return Response.ok(root).build(); |
| 260 | } |
| 261 | |
| 262 | /** |
| 263 | * Delete a Traffic Match by trafficMatchId. |
| 264 | * |
| 265 | * @param trafficMatchId Traffic Match identifier |
| 266 | * @return 204 NO CONTENT |
| 267 | */ |
| 268 | @DELETE |
| 269 | @Produces(MediaType.APPLICATION_JSON) |
| 270 | @Path("trafficmatch/{trafficMatchId}") |
| 271 | public Response deleteTrafficMatch(@PathParam("trafficMatchId") String trafficMatchId) { |
| 272 | PolicyService policyService = get(PolicyService.class); |
| 273 | |
| 274 | policyService.removeTrafficMatch(TrafficMatchId.of(trafficMatchId)); |
| 275 | |
| 276 | return Response.noContent().build(); |
| 277 | } |
sangho | 27462c6 | 2015-05-14 00:39:53 -0700 | [diff] [blame] | 278 | } |