2 * Copyright (c) 2016 Cisco Systems, Inc. and others. 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.groupbasedpolicy.renderer.ios_xe_provider.impl.writer;
11 import java.util.List;
13 import com.google.common.base.Optional;
14 import com.google.common.util.concurrent.CheckedFuture;
15 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
16 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
17 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
21 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
22 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType;
23 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
24 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy;
25 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction;
26 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
27 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
28 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.Interface;
29 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
30 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
31 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
32 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernet;
33 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernetKey;
34 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
35 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKey;
36 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
37 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
38 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName;
39 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
41 import org.opendaylight.yangtools.yang.binding.DataObject;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
47 * Purpose: Util class for every policy writer
49 class PolicyWriterUtil {
51 private static final Logger LOG = LoggerFactory.getLogger(PolicyWriterUtil.class);
53 static boolean writeClassMaps(final Set<ClassMap> classMapEntries, final NodeId nodeId, final DataBroker mountpoint) {
54 if (classMapEntries == null || classMapEntries.isEmpty()) {
57 for (ClassMap entry : classMapEntries) {
58 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
59 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
60 if (!optionalWriteTransaction.isPresent()) {
61 LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
64 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
65 final InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
66 writeMergeTransaction(writeTransaction, classMapIid, entry);
68 final java.util.Optional<ReadOnlyTransaction> optionalTransaction =
69 NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint);
70 if (!optionalTransaction.isPresent()) {
71 LOG.warn("Failed to create read-only transaction, mountpoint: {}", mountpoint);
74 final ReadOnlyTransaction readTransaction = optionalTransaction.get();
75 if (checkWritten(readTransaction, classMapIid) == null) {
78 LOG.trace("Created class-map {} on node {}", entry.getName(), nodeId.getValue());
83 static boolean removeClassMaps(final Set<ClassMap> classMapEntries, final NodeId nodeId, final DataBroker mountpoint) {
84 boolean result = true;
85 if (classMapEntries == null || classMapEntries.isEmpty()) {
88 for (ClassMap entry : classMapEntries) {
89 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
90 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
91 if (!optionalWriteTransaction.isPresent()) {
92 LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
95 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
96 final InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
97 deleteTransaction(writeTransaction, classMapIid);
99 final java.util.Optional<ReadOnlyTransaction> optionalReadTransaction =
100 NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint);
101 if (!optionalReadTransaction.isPresent()) {
102 LOG.warn("Failed to create read-only transaction, mountpoint: {}", mountpoint);
105 final ReadOnlyTransaction readTransaction = optionalReadTransaction.get();
106 result = checkRemoved(readTransaction, classMapIid);
107 LOG.trace("Class-map {} removed from node {}", entry.getName(), nodeId.getValue());
112 static boolean writePolicyMap(final String policyMapName, final Set<Class> policyMapEntries, NodeId nodeId,
113 final DataBroker mountpoint) {
114 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
115 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
116 if (!optionalWriteTransaction.isPresent()) {
117 LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
120 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
121 final PolicyMap policyMap = PolicyManagerUtil.createPolicyMap(policyMapName, policyMapEntries);
122 final InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier(policyMapName);
123 writeMergeTransaction(writeTransaction, policyMapIid, policyMap);
125 final java.util.Optional<ReadOnlyTransaction> optionalReadTransaction =
126 NetconfTransactionCreator.netconfReadOnlyTransaction(mountpoint);
127 if (!optionalReadTransaction.isPresent()) {
128 LOG.warn("Failed to create read-only transaction, mountpoint: {}", mountpoint);
131 final ReadOnlyTransaction readTransaction = optionalReadTransaction.get();
132 if (checkWritten(readTransaction, policyMapIid) == null) {
135 LOG.trace("Created policy-map {} on node {}", policyMap.getName(), nodeId.getValue());
139 static boolean removePolicyMapEntries(final String policyMapName, final Set<Class> policyMapEntries,
140 final NodeId nodeId, final DataBroker mountpoint) {
141 if (policyMapEntries == null || policyMapEntries.isEmpty()) {
144 for (Class entry : policyMapEntries) {
145 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
146 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
147 if (!optionalWriteTransaction.isPresent()) {
148 LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
151 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
152 final InstanceIdentifier policyMapEntryIid = policyMapEntryInstanceIdentifier(policyMapName, entry.getName());
153 if (deleteTransaction(writeTransaction, policyMapEntryIid)) {
154 LOG.trace("Policy map entry {} removed from node {}", entry.getName(), nodeId.getValue());
160 static boolean writeInterface(final String policyMapName, final String interfaceName, final NodeId nodeId,
161 final DataBroker mountpoint) {
162 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
163 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
164 if (!optionalWriteTransaction.isPresent()) {
165 LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
168 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
169 final ServicePolicy servicePolicy = PolicyManagerUtil.createServicePolicy(policyMapName, Direction.Input);
170 final InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
171 writeMergeTransaction(writeTransaction, servicePolicyIid, servicePolicy);
172 LOG.trace("Service-policy interface {}, bound to policy-map {} created on node {}",
173 interfaceName, policyMapName, nodeId.getValue());
177 static boolean writeRemote(final Set<ServiceFfName> remoteForwarders, final NodeId nodeId,
178 final DataBroker mountpoint) {
179 if (remoteForwarders == null || remoteForwarders.isEmpty()) {
182 for (ServiceFfName forwarder : remoteForwarders) {
183 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
184 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
185 if (!optionalWriteTransaction.isPresent()) {
186 LOG.warn("Failed to create transaction, mountpoint: {}", mountpoint);
189 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
190 final InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
191 writeMergeTransaction(writeTransaction, forwarderIid, forwarder);
192 LOG.trace("Remote forwarder {} created on node {}", forwarder.getName(), nodeId.getValue());
197 static boolean removeRemote(final Set<ServiceFfName> remoteForwarders, final NodeId nodeId,
198 final DataBroker mountpoint) {
199 if (remoteForwarders == null || remoteForwarders.isEmpty()) {
202 for (ServiceFfName forwarder : remoteForwarders) {
203 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
204 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
205 if (!optionalWriteTransaction.isPresent()) {
206 LOG.warn("Failed to create transaction, mountpoint: {}", mountpoint);
209 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
210 final InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
211 deleteTransaction(writeTransaction, forwarderIid);
212 LOG.trace("Remote forwarder {} removed from node {}", forwarder.getName(), nodeId.getValue());
217 static boolean writeServicePaths(final Set<ServiceChain> serviceChains, final NodeId nodeId,
218 final DataBroker mountpoint) {
219 for (org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain serviceChain : serviceChains) {
220 for (ServicePath entry : serviceChain.getServicePath()) {
221 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
222 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
223 if (!optionalWriteTransaction.isPresent()) {
224 LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
227 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
228 final InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
229 writeMergeTransaction(writeTransaction, servicePathIid, entry);
230 LOG.trace("Service path with ID: {} created on node {}", entry.getServicePathId(), nodeId.getValue());
236 static boolean removeServicePaths(final Set<ServiceChain> serviceChains, final NodeId nodeId,
237 final DataBroker mountpoint) {
238 if (serviceChains == null || serviceChains.isEmpty()) {
241 for (ServiceChain chain : serviceChains) {
242 List<ServicePath> servicePaths = chain.getServicePath();
243 if (servicePaths == null || servicePaths.isEmpty()) {
246 for (ServicePath servicePath : servicePaths) {
247 final java.util.Optional<WriteTransaction> optionalWriteTransaction =
248 NetconfTransactionCreator.netconfWriteOnlyTransaction(mountpoint);
249 if (!optionalWriteTransaction.isPresent()) {
250 LOG.warn("Failed to create write-only transaction, mountpoint: {}", mountpoint);
253 final WriteTransaction writeTransaction = optionalWriteTransaction.get();
254 final InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(servicePath.getKey());
255 if (deleteTransaction(writeTransaction, servicePathIid)) {
256 LOG.trace("Service-path with ID: {} removed from node {}", servicePath.getServicePathId(),
264 private static InstanceIdentifier<ClassMap> classMapInstanceIdentifier(final ClassMap classMap) {
265 return InstanceIdentifier.builder(Native.class)
266 .child(ClassMap.class, new ClassMapKey(classMap.getName())).build();
269 private static InstanceIdentifier<PolicyMap> policyMapInstanceIdentifier(final String policyMapName) {
270 return InstanceIdentifier.builder(Native.class)
271 .child(PolicyMap.class, new PolicyMapKey(policyMapName)).build();
274 private static InstanceIdentifier<Class> policyMapEntryInstanceIdentifier(final String policyMapName,
275 final ClassNameType classNameType) {
276 return InstanceIdentifier.builder(Native.class)
277 .child(PolicyMap.class, new PolicyMapKey(policyMapName))
278 .child(Class.class, new ClassKey(classNameType)).build();
281 private static InstanceIdentifier<ServicePolicy> interfaceInstanceIdentifier(final String ethernetName) {
282 return InstanceIdentifier.builder(Native.class)
283 .child(Interface.class)
284 .child(GigabitEthernet.class, new GigabitEthernetKey(ethernetName))
285 .child(ServicePolicy.class)
289 private static InstanceIdentifier<ServiceFfName> remoteSffInstanceIdentifier(final ServiceFfName sffName) {
290 return InstanceIdentifier.builder(Native.class)
291 .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain.class)
292 .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder.class)
293 .child(ServiceFfName.class, new ServiceFfNameKey(sffName.getName())).build();
296 private static InstanceIdentifier<ServicePath> servicePathInstanceIdentifier(final ServicePathKey key) {
297 return InstanceIdentifier.builder(Native.class)
298 .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain.class)
299 .child(ServicePath.class, key).build();
302 private static <U extends DataObject> void writeMergeTransaction(final WriteTransaction transaction,
303 final InstanceIdentifier<U> addIID,
306 transaction.merge(LogicalDatastoreType.CONFIGURATION, addIID, data);
307 final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = transaction.submit();
308 submitFuture.checkedGet();
309 } catch (TransactionCommitFailedException e) {
310 LOG.error("Write transaction failed to {}", e.getMessage());
311 } catch (Exception e) {
312 LOG.error("Failed to .. {}", e.getMessage());
316 private static <U extends DataObject> boolean deleteTransaction(final WriteTransaction transaction,
317 final InstanceIdentifier<U> addIID) {
319 transaction.delete(LogicalDatastoreType.CONFIGURATION, addIID);
320 final CheckedFuture<Void, TransactionCommitFailedException> submitFuture = transaction.submit();
321 submitFuture.checkedGet();
323 } catch (TransactionCommitFailedException e) {
324 LOG.error("Write transaction failed to {}", e.getMessage());
326 } catch (Exception e) {
327 LOG.error("Failed to .. {}", e.getMessage());
332 private static <U extends DataObject> U checkWritten(final ReadOnlyTransaction transaction,
333 final InstanceIdentifier<U> readIID) {
334 for (int attempt = 1; attempt <= 5; attempt++) {
336 final CheckedFuture<Optional<U>, ReadFailedException> submitFuture =
337 transaction.read(LogicalDatastoreType.CONFIGURATION, readIID);
338 final Optional<U> optional = submitFuture.checkedGet();
339 if (optional != null && optional.isPresent()) {
340 transaction.close(); // Release lock
341 return optional.get();
343 // Could take some time until specific configuration appears on device, try to read a few times
346 } catch (InterruptedException i) {
347 LOG.error("Thread interrupted while waiting ... {} ", i);
348 } catch (ReadFailedException e) {
349 LOG.warn("Read transaction failed to {} ", e);
350 } catch (Exception e) {
351 LOG.error("Failed to .. {}", e.getMessage());
357 private static <U extends DataObject> boolean checkRemoved(final ReadOnlyTransaction transaction,
358 final InstanceIdentifier<U> readIID) {
359 for (int attempt = 1; attempt <= 5; attempt++) {
361 final CheckedFuture<Optional<U>, ReadFailedException> submitFuture =
362 transaction.read(LogicalDatastoreType.CONFIGURATION, readIID);
363 final Optional<U> optional = submitFuture.checkedGet();
364 if (optional != null && optional.isPresent()) {
365 // Could take some time until specific configuration is removed from the device
368 transaction.close(); // Release lock
371 } catch (InterruptedException i) {
372 LOG.error("Thread interrupted while waiting ... {} ", i);
373 } catch (ReadFailedException e) {
374 LOG.warn("Read transaction failed to {} ", e);
375 } catch (Exception e) {
376 LOG.error("Failed to .. {}", e.getMessage());