/* * 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.net.intent.util; import org.onosproject.net.DeviceId; import org.onosproject.net.flow.DefaultFlowRule; import org.onosproject.net.flow.FlowEntry; import org.onosproject.net.flow.FlowRule; import org.onosproject.net.flow.FlowRuleService; import org.onosproject.net.flowobjective.DefaultForwardingObjective; import org.onosproject.net.flowobjective.DefaultNextObjective; import org.onosproject.net.flowobjective.ForwardingObjective; import org.onosproject.net.flowobjective.NextObjective; import org.onosproject.net.flowobjective.Objective; import org.onosproject.net.intent.FlowObjectiveIntent; import org.onosproject.net.intent.FlowRuleIntent; import org.onosproject.net.intent.Intent; import org.onosproject.net.intent.IntentService; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; /** * Utility to get flow entries corresponding to specified intent. */ public class IntentFilter { private final IntentService intentService; private final FlowRuleService flowRuleService; /** * Creates an intent filter. * * @param intentService intent service object * @param flowRuleService flow service object */ public IntentFilter(IntentService intentService, FlowRuleService flowRuleService) { this.intentService = intentService; this.flowRuleService = flowRuleService; } //checks whether the collection is empty or not. private boolean nonEmpty(Collection<?> c) { return c != null && !c.isEmpty(); } /** * Finds all path (flow entries) corresponding to intent installables. * * @param installables set of installables * @return set of flow entries */ public List<List<FlowEntry>> readIntentFlows(List<Intent> installables) { List<List<FlowEntry>> paths = new ArrayList<>(); for (Intent installable : installables) { if (installable instanceof FlowRuleIntent) { List<FlowEntry> flowEntries = getFlowEntries((FlowRuleIntent) installable); if (nonEmpty(flowEntries)) { paths.add(flowEntries); } } else if (installable instanceof FlowObjectiveIntent) { List<FlowEntry> flowEntries = getFlowEntries( (FlowObjectiveIntent) installable); if (nonEmpty(flowEntries)) { paths.add(flowEntries); } } } return paths; } /** * Finds all flow entries created by FlowRuleIntent. * * @param intent FlowRuleIntent Object * @return set of flow entries created by FlowRuleIntent */ private List<FlowEntry> getFlowEntries(FlowRuleIntent intent) { List<FlowEntry> flowEntries = new ArrayList<>(); Collection<FlowRule> flowRules = intent.flowRules(); FlowEntry flowEntry; for (FlowRule flowRule : flowRules) { flowEntry = getFlowEntry(flowRule); if (flowEntry != null) { flowEntries.add(flowEntry); } } return flowEntries; } /** * Finds all flow entries created by FlowObjectiveIntent. * * @param intent FlowObjectiveIntent Object * @return set of flow entries created by FlowObjectiveIntent */ private List<FlowEntry> getFlowEntries(FlowObjectiveIntent intent) { List<FlowEntry> flowEntries = new ArrayList<>(); Iterator<Objective> objectives = intent.objectives().iterator(); Iterator<DeviceId> devices = intent.devices().iterator(); DefaultNextObjective nextObjective = null; DefaultForwardingObjective forwardObjective; Objective objective; DeviceId deviceId; FlowEntry flowEntry; while (objectives.hasNext()) { objective = objectives.next(); deviceId = devices.next(); if (objective instanceof NextObjective) { nextObjective = (DefaultNextObjective) objective; continue; } else if (objective instanceof ForwardingObjective) { forwardObjective = (DefaultForwardingObjective) objective; FlowRule flowRule = DefaultFlowRule.builder() .forDevice(deviceId) .withSelector(forwardObjective.selector()) .withTreatment(nextObjective.next().iterator().next()) .withPriority(intent.priority()) .fromApp(intent.appId()) .makePermanent() .build(); flowEntry = getFlowEntry(flowRule); if (flowEntry != null) { flowEntries.add(flowEntry); } } } return flowEntries; } /** * Finds FlowEntry matching with the FlowRule. * * @param flowRule FlowRule object * @return flow entry matching to FlowRule */ private FlowEntry getFlowEntry(FlowRule flowRule) { Iterable<FlowEntry> flowEntries = flowRuleService.getFlowEntries(flowRule.deviceId()); if (flowEntries != null) { for (FlowEntry entry : flowEntries) { if (entry.exactMatch(flowRule)) { return entry; } } } return null; } }