2 * Copyright (c) 2015 NEC Corporation. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.vtn.manager.internal.util.flow.cond;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
16 import com.google.common.base.Optional;
18 import org.opendaylight.vtn.manager.VTNException;
20 import org.opendaylight.vtn.manager.internal.util.DataStoreUtils;
21 import org.opendaylight.vtn.manager.internal.util.MiscUtils;
22 import org.opendaylight.vtn.manager.internal.util.rpc.RpcErrorTag;
23 import org.opendaylight.vtn.manager.internal.util.rpc.RpcException;
25 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.VtnFlowConditions;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.cond.config.VtnFlowMatch;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.cond.config.VtnFlowMatchBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.cond.config.VtnFlowMatchKey;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.conditions.VtnFlowCondition;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.flow.cond.rev150313.vtn.flow.conditions.VtnFlowConditionKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName;
39 * {@code FlowCondUtils} class is a collection of utility class methods
42 public final class FlowCondUtils {
44 * A brief description about flow condition.
46 private static final String DESC_FLOW_COND = "Flow condition";
49 * Private constructor that protects this class from instantiating.
51 private FlowCondUtils() {}
54 * Return a new {@link RpcException} that indicates the specified flow
55 * condition is not present.
57 * @param name The name of the flow condition.
58 * @return An {@link RpcException}.
60 public static RpcException getNotFoundException(String name) {
61 return getNotFoundException(name, null);
65 * Return a new {@link RpcException} that indicates the specified flow
66 * condition is not present.
68 * @param name The name of the flow condition.
69 * @param cause A {@link Throwable} which indicates the cause of error.
70 * @return An {@link RpcException}.
72 public static RpcException getNotFoundException(String name,
75 MiscUtils.joinColon(name, "Flow condition does not exist.");
76 return RpcException.getNotFoundException(msg, cause);
80 * Return a new {@link RpcException} that indicates the flow match index
83 * @return An {@link RpcException}.
85 public static RpcException getMatchIndexMissingException() {
86 return RpcException.getNullArgumentException("Match index");
90 * Verify the name of the flow condition.
92 * @param name The name of the flow condition.
93 * @return A {@link VnodeName} instance that contains the given name.
94 * @throws RpcException The specified name is invalid.
96 public static VnodeName checkName(String name) throws RpcException {
97 return MiscUtils.checkName(DESC_FLOW_COND, name);
101 * Verify the name of the flow condition.
103 * @param vname A {@link VnodeName} instance.
104 * @return Return the string in {@code vname}.
105 * @throws RpcException The specified name is invalid.
107 public static String checkName(VnodeName vname) throws RpcException {
108 return MiscUtils.checkName(DESC_FLOW_COND, vname);
112 * Ensure the given vnode-name is not null.
114 * @param vname A {@link VnodeName} instance.
115 * @throws RpcException {@code vname} is {@code null}.
117 public static void checkPresent(VnodeName vname) throws RpcException {
118 MiscUtils.checkPresent(DESC_FLOW_COND, vname);
122 * Create the instance identifier for the flow condition specified by the
126 * This method is used to retrieve existing flow condition.
129 * @param name The name of the flow condition.
130 * @return An {@link InstanceIdentifier} instance.
131 * @throws RpcException
132 * The given flow condition name is invalid.
134 public static InstanceIdentifier<VtnFlowCondition> getIdentifier(
135 String name) throws RpcException {
136 return getIdentifier(getVnodeName(name));
140 * Create the instance identifier for the flow condition specified by the
143 * @param vname A {@link VnodeName} instance that contains the name of
144 * the flow condition.
145 * @return An {@link InstanceIdentifier} instance.
147 public static InstanceIdentifier<VtnFlowCondition> getIdentifier(
149 return InstanceIdentifier.builder(VtnFlowConditions.class).
150 child(VtnFlowCondition.class, new VtnFlowConditionKey(vname)).
155 * Create the instance identifier for the flow match specified by the
156 * given flow condition name and match index.
159 * This method is used to retrieve flow match in existing flow condition.
162 * @param name The name of the flow condition.
163 * @param index The index assigned to the flow match in a flow condition.
164 * @return An {@link InstanceIdentifier} instance.
165 * @throws RpcException
166 * The given flow condition name or match index is invalid.
168 public static InstanceIdentifier<VtnFlowMatch> getIdentifier(
169 String name, Integer index) throws RpcException {
170 return getIdentifier(getVnodeName(name), index);
174 * Create the instance identifier for the flow match specified by the
175 * given flow condition name and match index.
178 * This method is used to retrieve flow match in existing flow condition.
181 * @param vname A {@link VnodeName} instance that contains the name of
182 * the flow condition.
183 * @param index The index assigned to the flow match in a flow condition.
184 * @return An {@link InstanceIdentifier} instance.
185 * @throws RpcException
186 * The given flow condition name or match index is invalid.
188 public static InstanceIdentifier<VtnFlowMatch> getIdentifier(
189 VnodeName vname, Integer index) throws RpcException {
191 throw getMatchIndexMissingException();
194 return InstanceIdentifier.builder(VtnFlowConditions.class).
195 child(VtnFlowCondition.class, new VtnFlowConditionKey(vname)).
196 child(VtnFlowMatch.class, new VtnFlowMatchKey(index)).build();
200 * Return a {@link VnodeName} instance that contains the given flow
204 * This method is used to retrieve existing flow condition.
207 * @param name The name of the flow condition.
208 * @return A {@link VnodeName} instance that contains the given name.
209 * @throws RpcException The specified name is invalid.
211 public static VnodeName getVnodeName(String name) throws RpcException {
213 return MiscUtils.checkName(DESC_FLOW_COND, name);
214 } catch (RpcException e) {
215 if (e.getErrorTag() == RpcErrorTag.BAD_ELEMENT) {
216 // The specified flow condition should not be present because
217 // the given name is invalid.
218 throw getNotFoundException(name, e);
225 * Return the name of the flow condition configured in the given
226 * instance identifier.
228 * @param path An {@link InstanceIdentifier} instance.
229 * @return The name of the flow condition if found.
230 * {@code null} if not found.
232 public static String getName(InstanceIdentifier<?> path) {
233 VtnFlowConditionKey key = path.firstKeyOf(VtnFlowCondition.class);
238 VnodeName vname = key.getName();
239 return (vname == null) ? null : vname.getValue();
243 * Ensure that there is no duplicate match index in the match list.
245 * @param set A set of match indices.
246 * @param index An index to be tested.
247 * @throws RpcException An error occurred.
249 public static void verifyMatchIndex(Set<Integer> set, Integer index)
250 throws RpcException {
251 if (!set.add(index)) {
252 String msg = "Duplicate match index: " + index;
253 throw RpcException.getBadArgumentException(msg);
258 * Verify the given index number for a flow match in a flow condition.
260 * @param index A match index to be verified.
261 * @throws RpcException
262 * The given match index is invalid.
264 public static void verifyMatchIndex(Integer index) throws RpcException {
266 throw getMatchIndexMissingException();
270 new VtnFlowMatchBuilder().setIndex(index);
271 } catch (RuntimeException e) {
272 String msg = "Invalid match index: " + index;
273 throw RpcException.getBadArgumentException(msg, e);
278 * Determine whether the given flow condition container is empty or not.
280 * @param root A {@link VtnFlowConditions} instance.
281 * @return {@code true} only if the given flow condition container is
284 public static boolean isEmpty(VtnFlowConditions root) {
289 List<VtnFlowCondition> vlist = root.getVtnFlowCondition();
290 return (vlist == null || vlist.isEmpty());
294 * Determine whether the specified flow condition is present or not.
296 * @param rtx A {@link ReadTransaction} instance associated with the
297 * read transaction for the MD-SAL datastore.
298 * @param vname A {@link VnodeName} instance that contains the name of the
299 * target flow condition.
300 * @throws RpcException
301 * The specified flow condition is not present.
302 * @throws VTNException
303 * Failed to read the MD-SAL datastore.
305 public static void checkPresent(ReadTransaction rtx, VnodeName vname)
306 throws VTNException {
307 InstanceIdentifier<VtnFlowCondition> path = getIdentifier(vname);
308 LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL;
309 Optional<VtnFlowCondition> opt = DataStoreUtils.read(rtx, oper, path);
310 if (!opt.isPresent()) {
311 throw getNotFoundException(vname.getValue());
316 * Read all the flow conditions from the MD-SAL datastore.
318 * @param rtx A {@link ReadTransaction} instance.
319 * @return A list of {@link VTNFlowCondition} instances.
320 * @throws VTNException An error occurred.
322 public static List<VTNFlowCondition> readFlowConditions(ReadTransaction rtx)
323 throws VTNException {
324 InstanceIdentifier<VtnFlowConditions> path =
325 InstanceIdentifier.create(VtnFlowConditions.class);
326 LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL;
327 Optional<VtnFlowConditions> opt = DataStoreUtils.read(rtx, oper, path);
328 List<VtnFlowCondition> vlist = null;
329 if (opt.isPresent()) {
330 vlist = opt.get().getVtnFlowCondition();
332 if (vlist == null || vlist.isEmpty()) {
333 return Collections.<VTNFlowCondition>emptyList();
336 List<VTNFlowCondition> list = new ArrayList<>(vlist.size());
337 for (VtnFlowCondition vfc: vlist) {
338 list.add(new VTNFlowCondition(vfc));
345 * Read the flow condition specified by the given name from the MD-SAL
348 * @param rtx A {@link ReadTransaction} instance.
349 * @param name The name of the flow condition.
350 * @return A {@link VTNFlowCondition} instance.
351 * @throws VTNException An error occurred.
353 public static VTNFlowCondition readFlowCondition(ReadTransaction rtx,
355 throws VTNException {
356 InstanceIdentifier<VtnFlowCondition> path = getIdentifier(name);
357 LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL;
358 Optional<VtnFlowCondition> opt = DataStoreUtils.read(rtx, oper, path);
359 if (opt.isPresent()) {
360 return new VTNFlowCondition(opt.get());
363 throw getNotFoundException(name);
367 * Read the flow match specified by the given index in the given flow
368 * condition from the MD-SAL datastore.
370 * @param rtx A {@link ReadTransaction} instance.
371 * @param name The name of the flow condition.
372 * @param idx The match index that specifies the flow match in the
374 * @return A {@link VTNFlowMatch} instance.
375 * {@code null} is returned if no flow match is associated
376 * with the given match index in the flow condition.
377 * @throws VTNException An error occurred.
379 public static VTNFlowMatch readFlowMatch(ReadTransaction rtx, String name,
380 int idx) throws VTNException {
381 VnodeName vname = getVnodeName(name);
382 InstanceIdentifier<VtnFlowMatch> path = getIdentifier(vname, idx);
383 LogicalDatastoreType oper = LogicalDatastoreType.OPERATIONAL;
384 Optional<VtnFlowMatch> opt = DataStoreUtils.read(rtx, oper, path);
385 if (opt.isPresent()) {
386 return new VTNFlowMatch(opt.get());
389 // Check to see if the flow condition is present.
390 checkPresent(rtx, vname);