Merge "Fixed bug in update forwarding"
[groupbasedpolicy.git] / renderers / ios-xe / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ios_xe_provider / impl / manager / PolicyManagerImpl.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.manager;
10
11 import com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.Futures;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
16 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
17 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31
32 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
33 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
34
35 public class PolicyManagerImpl implements PolicyManager {
36
37     private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerImpl.class);
38     private static final String policyMapName = "service-chains";
39     private final DataBroker dataBroker;
40     private final NodeManager nodeManager;
41
42     public PolicyManagerImpl(final DataBroker dataBroker,
43                              final NodeManager nodeManager) {
44         this.dataBroker = Preconditions.checkNotNull(dataBroker);
45         this.nodeManager = Preconditions.checkNotNull(nodeManager);
46     }
47
48     @Override
49     public ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, final Configuration dataBefore) {
50         if (dataBefore == null && dataAfter != null) {
51             return createPolicy(dataAfter);
52         }
53         if (dataBefore != null && dataAfter != null) {
54             return updatePolicy(dataAfter, dataBefore);
55         }
56         if (dataBefore != null) {
57             return deletePolicy(dataBefore);
58         }
59         return Futures.immediateFuture(false);
60     }
61
62     private ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, DsAction action) {
63         if (dataAfter.getRendererEndpoints() == null
64                 || dataAfter.getRendererEndpoints().getRendererEndpoint() == null) {
65             LOG.debug("no configuration obtained - skipping");
66             return Futures.immediateFuture(true);
67         }
68         final Map<DataBroker, PolicyWriter> policyWriterPerDeviceCache = new HashMap<>();
69         for (RendererEndpoint rendererEndpoint : dataAfter.getRendererEndpoints().getRendererEndpoint()) {
70             if (dataAfter.getEndpoints() == null || dataAfter.getEndpoints().getAddressEndpointWithLocation() == null) {
71                 LOG.debug("renderer-endpoint: missing address-endpoint-with-location");
72                 continue;
73             }
74             final List<AddressEndpointWithLocation> endpointsWithLocation = dataAfter.getEndpoints()
75                     .getAddressEndpointWithLocation();
76             final InstanceIdentifier mountpointIid = PolicyManagerUtil.getAbsoluteLocationMountpoint(rendererEndpoint, endpointsWithLocation);
77             final DataBroker mountpoint = nodeManager.getNodeMountPoint(mountpointIid);
78             if (mountpoint == null) {
79                 LOG.debug("no data-broker for mount-point [{}] available", mountpointIid);
80                 continue;
81             }
82             // Find policy writer
83             PolicyWriter policyWriter = policyWriterPerDeviceCache.get(mountpoint);
84             if (policyWriter == null) {
85                 // Initialize new policy writer
86                 final String interfaceName = PolicyManagerUtil.getInterfaceNameForPolicyMap(rendererEndpoint, endpointsWithLocation);
87                 final NodeId nodeId = nodeManager.getNodeIdByMountpointIid(mountpointIid);
88                 final String managementIpAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
89                 if (interfaceName == null || managementIpAddress == null) {
90                     LOG.debug("can not create policyWriter: interface={}, managementIpAddress={}",
91                             interfaceName, managementIpAddress);
92                     continue;
93                 }
94                 policyWriter = new PolicyWriter(mountpoint, interfaceName, managementIpAddress, policyMapName, nodeId);
95                 policyWriterPerDeviceCache.put(mountpoint, policyWriter);
96             }
97
98             final Sgt sourceSgt = PolicyManagerUtil.findSgtTag(rendererEndpoint, dataAfter.getEndpoints()
99                     .getAddressEndpointWithLocation());
100             // Peer Endpoint
101             for (PeerEndpointWithPolicy peerEndpoint : rendererEndpoint.getPeerEndpointWithPolicy()) {
102                 final Sgt destinationSgt = PolicyManagerUtil.findSgtTag(peerEndpoint, dataAfter.getEndpoints()
103                         .getAddressEndpointWithLocation());
104                 if (sourceSgt == null || destinationSgt == null) {
105                     LOG.debug("endpoint-policy: missing sgt value(sourceSgt={}, destinationSgt={})",
106                             sourceSgt, destinationSgt);
107                     continue;
108                 }
109                 PolicyManagerUtil.syncPolicyEntities(sourceSgt, destinationSgt, policyWriter, dataAfter, peerEndpoint);
110             }
111         }
112         if (action.equals(Create)) {
113             policyWriterPerDeviceCache.values().forEach(PolicyWriter::commitToDatastore);
114             return Futures.immediateFuture(true);
115         } else if (action.equals(Delete)) {
116             policyWriterPerDeviceCache.values().forEach(PolicyWriter::removeFromDatastore);
117             return Futures.immediateFuture(true);
118         }
119         return Futures.immediateFuture(false);
120     }
121
122     private ListenableFuture<Boolean> createPolicy(Configuration data) {
123         return syncPolicy(data, Create);
124     }
125
126     private ListenableFuture<Boolean> deletePolicy(Configuration data) {
127         return syncPolicy(data, Delete);
128     }
129
130     private ListenableFuture<Boolean> updatePolicy(Configuration dataAfter, Configuration dataBefore) {
131         // TODO implement
132         return null;
133     }
134
135     @Override
136     public void close() {
137         //NOOP
138     }
139
140     enum DsAction {Create, Delete}
141
142     public enum ActionCase {ALLOW, CHAIN}
143 }