ios-xe-renderer policy-manager update
[groupbasedpolicy.git] / renderers / ios-xe / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ios_xe_provider / impl / writer / PolicyWriter.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer;
10
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;
42
43 import java.util.ArrayList;
44 import java.util.List;
45
46 public class PolicyWriter {
47
48     private static final Logger LOG = LoggerFactory.getLogger(PolicyWriter.class);
49
50     private final DataBroker mountpoint;
51     // Local cache
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;
61
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<>();
68
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);
74     }
75
76     public void cache(ClassMap classMap) {
77         classMapEntries.add(classMap);
78     }
79
80     public void cache(List<Class> policyMapEntries) {
81         this.policyMapEntries.addAll(policyMapEntries);
82     }
83
84     public void cache(Local localForwarder) {
85         this.localForwarder = localForwarder;
86     }
87
88     public void cache(ServiceFfName remoteForwarder) {
89         remoteForwarders.add(remoteForwarder);
90     }
91
92     public void cache(ServiceChain serviceChain) {
93         serviceChains.add(serviceChain);
94     }
95
96     public void commitToDatastore() {
97         WriteTransaction wtx = mountpoint.newWriteOnlyTransaction();
98         // GBP
99         // Class maps
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());
104         }
105
106         // Policy map
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());
111
112         // Interface
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());
118
119         //SFC
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());
125         }
126
127         // Remote forwarders
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());
132         }
133
134         // Service paths
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());
140             }
141         }
142
143         try {
144             CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
145             submitFuture.checkedGet();
146             // Clear cache
147         } catch (TransactionCommitFailedException e) {
148             LOG.error("Write transaction failed to {}", e.getMessage());
149         } catch (Exception e) {
150             LOG.error("Failed to .. {}", e.getMessage());
151         }
152     }
153
154     public void removeFromDatastore() {
155         ReadWriteTransaction wtx = mountpoint.newReadWriteTransaction();
156         //GBP
157         // Interface
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());
161
162         // Policy map
163         InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier();
164         wtx.delete(LogicalDatastoreType.CONFIGURATION, policyMapIid);
165         LOG.info("Policy-map removed from node node {}", nodeId.getValue());
166
167         // Class map
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());
172         }
173
174         //SFC
175         // Service paths
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());
181             }
182         }
183
184         // Remote forwarders
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());
189         }
190
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());
198         }
199
200         try {
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());
207         }
208     }
209
210     private InstanceIdentifier<ClassMap> classMapInstanceIdentifier(ClassMap classMap) {
211         return InstanceIdentifier.builder(Native.class)
212                 .child(ClassMap.class, new ClassMapKey(classMap.getName())).build();
213     }
214
215     private InstanceIdentifier<PolicyMap> policyMapInstanceIdentifier() {
216         return InstanceIdentifier.builder(Native.class)
217                 .child(PolicyMap.class, new PolicyMapKey(policyMapName)).build();
218     }
219
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)
225                 .build();
226     }
227
228     private InstanceIdentifier<Local> localSffInstanceIdentifier() {
229         return InstanceIdentifier.builder(Native.class)
230                 .child(ServiceChain.class)
231                 .child(ServiceFunctionForwarder.class)
232                 .child(Local.class).build();
233     }
234
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();
240     }
241
242     private InstanceIdentifier<ServicePath> servicePathInstanceIdentifier(ServicePathKey key) {
243         return InstanceIdentifier.builder(Native.class)
244                 .child(ServiceChain.class)
245                 .child(ServicePath.class, key).build();
246     }
247
248     public String getManagementIpAddress() {
249         return managementIpAddress;
250     }
251
252     public DataBroker getCurrentMountpoint() {
253         return mountpoint;
254     }
255
256     public NodeId getCurrentNodeId() {
257         return nodeId;
258     }
259 }