093c863e2fd61c2d4770c6d7d68b72167f091b8f
[vtn.git] /
1 /*
2  * Copyright (c) 2015 NEC Corporation
3  * All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this
7  * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.vtn.manager.internal.util.pathpolicy;
11
12 import java.util.ArrayList;
13 import java.util.Collections;
14 import java.util.List;
15
16 import org.opendaylight.vtn.manager.PathCost;
17 import org.opendaylight.vtn.manager.PathPolicy;
18 import org.opendaylight.vtn.manager.PortLocation;
19 import org.opendaylight.vtn.manager.VTNException;
20
21 import org.opendaylight.vtn.manager.internal.util.DataStoreUtils;
22 import org.opendaylight.vtn.manager.internal.util.MiscUtils;
23 import org.opendaylight.vtn.manager.internal.util.NodeUtils;
24 import org.opendaylight.vtn.manager.internal.util.rpc.RpcException;
25
26 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
27 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
28
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.VtnPathCostConfig;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.VtnPathPolicies;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.VtnPathPolicyConfig;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policies.VtnPathPolicy;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policies.VtnPathPolicyKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policy.config.VtnPathCost;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policy.config.VtnPathCostKey;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnPortDesc;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnUpdateOperationType;
40
41 /**
42  * {@code PathPolicyUtils} class is a collection of utility class methods
43  * for path policy.
44  */
45 public final class PathPolicyUtils {
46     /**
47      * Default link cost used when the path policy does not exist.
48      */
49     public static final Long  DEFAULT_LINK_COST = Long.valueOf(1L);
50
51     /**
52      * Private constructor that protects this class from instantiating.
53      */
54     private PathPolicyUtils() {}
55
56     /**
57      * Return a new {@link RpcException} that indicates the specified path
58      * policy is not present.
59      *
60      * @param id  The identifier of the path policy.
61      * @return  An {@link RpcException}.
62      */
63     public static RpcException getNotFoundException(int id) {
64         return getNotFoundException(id, null);
65     }
66
67     /**
68      * Return a new {@link RpcException} that indicates the specified path
69      * policy is not present.
70      *
71      * @param id     The identifier of the path policy.
72      * @param cause  A {@link Throwable} which indicates the cause of error.
73      * @return  An {@link RpcException}.
74      */
75     public static RpcException getNotFoundException(int id, Throwable cause) {
76         String msg = MiscUtils.joinColon(id, "Path policy does not exist.");
77         return RpcException.getNotFoundException(msg, cause);
78     }
79
80     /**
81      * Return a new {@link RpcException} that indicates the given path policy
82      * ID is invalid.
83      *
84      * @param id  The identifier of the path policy.
85      * @return  An {@link RpcException}.
86      */
87     public static RpcException getInvalidPolicyIdException(Integer id) {
88         String msg = MiscUtils.joinColon("Invalid path policy ID", id);
89         return RpcException.getBadArgumentException(msg);
90     }
91
92     /**
93      * Return a new {@link RpcException} that indicates the given default cost
94      * valud is invalid.
95      *
96      * @param cost  Value for default cost.
97      * @return  An {@link RpcException}.
98      */
99     public static RpcException getInvalidDefaultCostException(Long cost) {
100         String msg = MiscUtils.joinColon("Invalid default cost", cost);
101         return RpcException.getBadArgumentException(msg);
102     }
103
104     /**
105      * Return a new {@link RpcException} that indicates the given link cost
106      * valud is invalid.
107      *
108      * @param cost  Link cost.
109      * @return  An {@link RpcException}.
110      */
111     public static RpcException getInvalidCostException(Long cost) {
112         String msg = MiscUtils.joinColon("Invalid cost value", cost);
113         return RpcException.getBadArgumentException(msg);
114     }
115
116     /**
117      * Return a new {@link RpcException} that indicates the path policy ID
118      * is missing.
119      *
120      * @return  An {@link RpcException}.
121      */
122     public static RpcException getNullPolicyIdException() {
123         return MiscUtils.getNullArgumentException("Path policy ID");
124     }
125
126     /**
127      * Return a new {@link RpcException} that indicates the path cost
128      * configuration is null.
129      *
130      * @return  An {@link RpcException}.
131      */
132     public static RpcException getNullPathCostException() {
133         return MiscUtils.getNullArgumentException("Path cost");
134     }
135
136     /**
137      * Return a new {@link RpcException} that indicates the port descriptor
138      * is null.
139      *
140      * @return  An {@link RpcException}.
141      */
142     public static RpcException getNullPortDescException() {
143         return MiscUtils.getNullArgumentException("Port descriptor");
144     }
145
146     /**
147      * Return a new {@link RpcException} that indicates duplicate port
148      * descriptor is detected.
149      *
150      * @param loc  An object that represents the switch port location.
151      * @return  An {@link RpcException}.
152      */
153     public static RpcException getDuplicatePortException(Object loc) {
154         String msg = "Duplicate port descriptor: " + loc;
155         return RpcException.getBadArgumentException(msg);
156     }
157
158     /**
159      * Return a new {@link RpcException} that indicates no switch port is
160      * specified.
161      *
162      * @return  An {@link RpcException}.
163      */
164     public static RpcException getNoSwitchPortException() {
165         return RpcException.getMissingArgumentException(
166             "At least one switch port must be specified.");
167     }
168
169     /**
170      * Create the instance identifier for the specified path policy.
171      *
172      * @param id  The identifier of the path policy.
173      * @return  An {@link InstanceIdentifier} instance.
174      */
175     public static InstanceIdentifier<VtnPathPolicy> getIdentifier(Integer id) {
176         VtnPathPolicyKey key = new VtnPathPolicyKey(id);
177         return InstanceIdentifier.builder(VtnPathPolicies.class).
178             child(VtnPathPolicy.class, key).build();
179     }
180
181     /**
182      * Create the instance identifier for the given {@link VtnPathPolicyConfig}
183      * instance.
184      *
185      * @param vpp  A {@link VtnPathPolicyConfig} instance.
186      * @return  An {@link InstanceIdentifier} instance.
187      */
188     public static InstanceIdentifier<VtnPathPolicy> getIdentifier(
189         VtnPathPolicyConfig vpp) {
190         return getIdentifier(vpp.getId());
191     }
192
193     /**
194      * Create the instance identifier for the specified path cost
195      * configuration.
196      *
197      * @param id     The identifier of the path policy.
198      * @param vdesc  A {@link VtnPortDesc} instance.
199      * @return  An {@link InstanceIdentifier} instance.
200      */
201     public static InstanceIdentifier<VtnPathCost> getIdentifier(
202         Integer id, VtnPortDesc vdesc) {
203         VtnPathPolicyKey key = new VtnPathPolicyKey(id);
204         VtnPathCostKey ckey = new VtnPathCostKey(vdesc);
205         return InstanceIdentifier.builder(VtnPathPolicies.class).
206             child(VtnPathPolicy.class, key).
207             child(VtnPathCost.class, ckey).build();
208     }
209
210     /**
211      * Create the instance identifier for the specified path cost information.
212      *
213      * @param id   The identifier of the path policy.
214      * @param vpc  A {@link VtnPathCostConfig} instance.
215      * @return  An {@link InstanceIdentifier} instance.
216      */
217     public static InstanceIdentifier<VtnPathCost> getIdentifier(
218         int id, VtnPathCostConfig vpc) {
219         return getIdentifier(Integer.valueOf(id), vpc.getPortDesc());
220     }
221
222     /**
223      * Create a {@link PathCost} instance which describes the given
224      * {@link VtnPathCost} instance.
225      *
226      * @param vpc  A {@link VtnPathCost} instance.
227      * @return  A {@link PathCost} instance or {@code null}.
228      */
229     public static PathCost toPathCost(VtnPathCost vpc) {
230         Long c = vpc.getCost();
231         if (c == null) {
232             c = DEFAULT_LINK_COST;
233         }
234
235         PortLocation ploc = NodeUtils.toPortLocation(vpc.getPortDesc());
236         if (ploc == null) {
237             return null;
238         }
239
240         return new PathCost(ploc, c.longValue());
241     }
242
243     /**
244      * Create a {@link PathPolicy} instance which describes the given
245      * {@link VtnPathPolicy} instance.
246      *
247      * @param vpp  A {@link VtnPathPolicy} instance.
248      * @return  A {@link PathPolicy} instance.
249      */
250     public static PathPolicy toPathPolicy(VtnPathPolicy vpp) {
251         Long c = vpp.getDefaultCost();
252         long defc = (c == null) ? PathPolicy.COST_UNDEF : c.longValue();
253         List<PathCost> costs = new ArrayList<>();
254         List<VtnPathCost> vlist = vpp.getVtnPathCost();
255         if (vlist != null) {
256             for (VtnPathCost vpc: vlist) {
257                 PathCost pc = toPathCost(vpc);
258                 if (pc != null) {
259                     costs.add(pc);
260                 }
261             }
262         }
263
264         return new PathPolicy(vpp.getId(), defc, costs);
265     }
266
267     /**
268      * Read all the path policies from the MD-SAL datastore.
269      *
270      * @param rtx  A {@link ReadTransaction} instance.
271      * @return  A list of {@link VtnPathPolicy} instances.
272      * @throws VTNException  An error occurred.
273      */
274     public static List<VtnPathPolicy> readVtnPathPolicies(ReadTransaction rtx)
275         throws VTNException {
276         InstanceIdentifier<VtnPathPolicies> path =
277             InstanceIdentifier.create(VtnPathPolicies.class);
278         LogicalDatastoreType store = LogicalDatastoreType.OPERATIONAL;
279         VtnPathPolicies policies = DataStoreUtils.read(rtx, store, path).
280             orNull();
281         List<VtnPathPolicy> vlist = null;
282         if (policies != null) {
283             vlist = policies.getVtnPathPolicy();
284         }
285         if (vlist == null) {
286             vlist = Collections.<VtnPathPolicy>emptyList();
287         }
288
289         return vlist;
290     }
291
292     /**
293      * Read path policy configuration specified by the given ID.
294      *
295      * @param rtx  A {@link ReadTransaction} instance.
296      * @param id   The path policy identifier.
297      * @return  A {@link VtnPathPolicy} instance.
298      * @throws VTNException  An error occurred.
299      */
300     public static VtnPathPolicy readVtnPathPolicy(ReadTransaction rtx, int id)
301         throws VTNException {
302         InstanceIdentifier<VtnPathPolicy> path =
303             getIdentifier(Integer.valueOf(id));
304         LogicalDatastoreType store = LogicalDatastoreType.OPERATIONAL;
305         VtnPathPolicy vpp = DataStoreUtils.read(rtx, store, path).orNull();
306         if (vpp == null) {
307             throw getNotFoundException(id);
308         }
309
310         return vpp;
311     }
312
313     /**
314      * Read the cost information associated with the given port location
315      * in the given path policy.
316      *
317      * @param rtx    A {@link ReadTransaction} instance.
318      * @param id     The path policy identifier.
319      * @param vdesc  A {@link VtnPortDesc} instance if found.
320      *               {@code null} if not found.
321      * @return  A {@link VtnPathCost} instance.
322      * @throws VTNException  An error occurred.
323      */
324     public static VtnPathCost readVtnPathCost(ReadTransaction rtx, int id,
325                                               VtnPortDesc vdesc)
326         throws VTNException {
327         VtnPathCost vpc = null;
328         if (vdesc != null) {
329             InstanceIdentifier<VtnPathCost> path =
330                 getIdentifier(Integer.valueOf(id), vdesc);
331             LogicalDatastoreType store = LogicalDatastoreType.OPERATIONAL;
332             vpc = DataStoreUtils.read(rtx, store, path).orNull();
333         }
334         if (vpc == null) {
335             // Check to see if the path policy is present.
336             readVtnPathPolicy(rtx, id);
337         }
338
339         return vpc;
340     }
341
342     /**
343      * Create an RPC input builder used to update existing path policy
344      * configuration.
345      *
346      * @param id  The path policy ID.
347      * @return  Builder instance for RPC input.
348      * @throws RpcException
349      *    The given path policy ID is invalid.
350      */
351     public static PathPolicyConfigBuilder.Rpc createRpcInput(int id)
352         throws RpcException {
353         PathPolicyConfigBuilder.Rpc builder =
354             new PathPolicyConfigBuilder.Rpc();
355         Integer pid = Integer.valueOf(id);
356
357         try {
358             builder.setId(pid);
359         } catch (VTNException e) {
360             // Invalid path policy ID is specified.
361             throw getNotFoundException(id, e);
362         }
363
364         builder.getBuilder().setOperation(VtnUpdateOperationType.ADD).
365             setPresent(Boolean.TRUE);
366
367         return builder;
368     }
369 }