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 com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
15 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
17 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
18 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
19 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil;
20 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
21 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy;
22 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction;
23 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
24 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
25 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.Interface;
26 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
27 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
28 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
29 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernet;
30 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernetKey;
31 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
32 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder;
33 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
34 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
35 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.Local;
36 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName;
37 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
38 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
39 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 import java.util.ArrayList;
44 import java.util.List;
46 public class PolicyWriter {
48 private static final Logger LOG = LoggerFactory.getLogger(PolicyWriter.class);
50 private final DataBroker mountpoint;
52 private final List<ClassMap> classMapEntries;
53 private final List<Class> policyMapEntries;
54 private final List<ServiceFfName> remoteForwarders;
55 private final List<ServiceChain> serviceChains;
56 private final NodeId nodeId;
57 private final String interfaceName;
58 private final String policyMapName;
59 private final String managementIpAddress;
60 private Local localForwarder;
62 public PolicyWriter(final DataBroker dataBroker, final String interfaceName, final String ipAddress,
63 final String policyMapName, final NodeId nodeId) {
64 classMapEntries = new ArrayList<>();
65 policyMapEntries = new ArrayList<>();
66 remoteForwarders = new ArrayList<>();
67 serviceChains = new ArrayList<>();
69 this.nodeId = Preconditions.checkNotNull(nodeId);
70 mountpoint = Preconditions.checkNotNull(dataBroker);
71 managementIpAddress = Preconditions.checkNotNull(ipAddress);
72 this.interfaceName = Preconditions.checkNotNull(interfaceName);
73 this.policyMapName = Preconditions.checkNotNull(policyMapName);
76 public void cache(ClassMap classMap) {
77 classMapEntries.add(classMap);
80 public void cache(List<Class> policyMapEntries) {
81 this.policyMapEntries.addAll(policyMapEntries);
84 public void cache(Local localForwarder) {
85 this.localForwarder = localForwarder;
88 public void cache(ServiceFfName remoteForwarder) {
89 remoteForwarders.add(remoteForwarder);
92 public void cache(ServiceChain serviceChain) {
93 serviceChains.add(serviceChain);
96 public void commitToDatastore() {
97 WriteTransaction wtx = mountpoint.newWriteOnlyTransaction();
100 for (ClassMap entry : classMapEntries) {
101 InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
102 wtx.merge(LogicalDatastoreType.CONFIGURATION, classMapIid, entry);
103 LOG.info("Created class-map {} on node {}", entry.getName(), nodeId.getValue());
107 PolicyMap policyMap = PolicyManagerUtil.createPolicyMap(policyMapName, policyMapEntries);
108 InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier();
109 wtx.merge(LogicalDatastoreType.CONFIGURATION, policyMapIid, policyMap);
110 LOG.info("Created policy-map {} on node {}", policyMap.getName(), nodeId.getValue());
113 ServicePolicy servicePolicy = PolicyManagerUtil.createServicePolicy(policyMapName, Direction.Input);
114 InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
115 wtx.merge(LogicalDatastoreType.CONFIGURATION, servicePolicyIid, servicePolicy);
116 LOG.info("Service-policy interface {}, bound to policy-map {} created on node {}",
117 interfaceName, policyMap.getName(), nodeId.getValue());
120 // Local forwarder (if some service chain exists, otherwise is useless)
121 if (!serviceChains.isEmpty()) {
122 InstanceIdentifier<Local> localIid = localSffInstanceIdentifier();
123 wtx.merge(LogicalDatastoreType.CONFIGURATION, localIid, localForwarder);
124 LOG.info("Local forwarder created on node {}", nodeId.getValue());
128 for (ServiceFfName forwarder : remoteForwarders) {
129 InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
130 wtx.merge(LogicalDatastoreType.CONFIGURATION, forwarderIid, forwarder);
131 LOG.info("Remote forwarder {} created on node {}", forwarder.getName(), nodeId.getValue());
135 for (ServiceChain serviceChain : serviceChains) {
136 for (ServicePath entry : serviceChain.getServicePath()) {
137 InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
138 wtx.merge(LogicalDatastoreType.CONFIGURATION, servicePathIid, entry);
139 LOG.info("Service path with Id {} created on node {}", entry.getServicePathId(), nodeId.getValue());
144 CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
145 submitFuture.checkedGet();
147 } catch (TransactionCommitFailedException e) {
148 LOG.error("Write transaction failed to {}", e.getMessage());
149 } catch (Exception e) {
150 LOG.error("Failed to .. {}", e.getMessage());
154 public void removeFromDatastore() {
155 ReadWriteTransaction wtx = mountpoint.newReadWriteTransaction();
158 InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
159 wtx.delete(LogicalDatastoreType.CONFIGURATION, servicePolicyIid);
160 LOG.info("Service-policy removed from interface {} on node {}", interfaceName, nodeId.getValue());
163 InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier();
164 wtx.delete(LogicalDatastoreType.CONFIGURATION, policyMapIid);
165 LOG.info("Policy-map removed from node node {}", nodeId.getValue());
168 for (ClassMap entry : classMapEntries) {
169 InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
170 wtx.delete(LogicalDatastoreType.CONFIGURATION, classMapIid);
171 LOG.info("Class-map {} removed from node {}", entry.getName(), nodeId.getValue());
176 for (ServiceChain serviceChain : serviceChains) {
177 for (ServicePath entry : serviceChain.getServicePath()) {
178 InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
179 wtx.delete(LogicalDatastoreType.CONFIGURATION, servicePathIid);
180 LOG.info("Service path with Id {} removed from node {}", entry.getServicePathId(), nodeId.getValue());
185 for (ServiceFfName forwarder : remoteForwarders) {
186 InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
187 wtx.delete(LogicalDatastoreType.CONFIGURATION, forwarderIid);
188 LOG.info("Remote forwarder {} removed from node {}", forwarder.getName(), nodeId.getValue());
191 // Local forwarder - remove only if there is no more service-paths on device. If paths removed above were last
192 // ones, remove local forwarder. If there are still some paths present, they were created by sfc and local
193 // forwarder cannot be removed (because it was created by sfc as well)
194 if (ServiceChainingUtil.checkServicePathPresence(mountpoint)) {
195 InstanceIdentifier<Local> localIid = localSffInstanceIdentifier();
196 wtx.delete(LogicalDatastoreType.CONFIGURATION, localIid);
197 LOG.info("Local forwarder removed from node {}", nodeId.getValue());
201 CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
202 submitFuture.checkedGet();
203 } catch (TransactionCommitFailedException e) {
204 LOG.error("Write transaction failed to {}", e.getMessage());
205 } catch (Exception e) {
206 LOG.error("Failed to .. {}", e.getMessage());
210 private InstanceIdentifier<ClassMap> classMapInstanceIdentifier(ClassMap classMap) {
211 return InstanceIdentifier.builder(Native.class)
212 .child(ClassMap.class, new ClassMapKey(classMap.getName())).build();
215 private InstanceIdentifier<PolicyMap> policyMapInstanceIdentifier() {
216 return InstanceIdentifier.builder(Native.class)
217 .child(PolicyMap.class, new PolicyMapKey(policyMapName)).build();
220 private InstanceIdentifier<ServicePolicy> interfaceInstanceIdentifier(String ethernetName) {
221 return InstanceIdentifier.builder(Native.class)
222 .child(Interface.class)
223 .child(GigabitEthernet.class, new GigabitEthernetKey(ethernetName))
224 .child(ServicePolicy.class)
228 private InstanceIdentifier<Local> localSffInstanceIdentifier() {
229 return InstanceIdentifier.builder(Native.class)
230 .child(ServiceChain.class)
231 .child(ServiceFunctionForwarder.class)
232 .child(Local.class).build();
235 private InstanceIdentifier<ServiceFfName> remoteSffInstanceIdentifier(ServiceFfName sffName) {
236 return InstanceIdentifier.builder(Native.class)
237 .child(ServiceChain.class)
238 .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder.class)
239 .child(ServiceFfName.class, new ServiceFfNameKey(sffName.getName())).build();
242 private InstanceIdentifier<ServicePath> servicePathInstanceIdentifier(ServicePathKey key) {
243 return InstanceIdentifier.builder(Native.class)
244 .child(ServiceChain.class)
245 .child(ServicePath.class, key).build();
248 public String getManagementIpAddress() {
249 return managementIpAddress;
252 public DataBroker getCurrentMountpoint() {
256 public NodeId getCurrentNodeId() {