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.manager;
11 import com.google.common.base.Function;
12 import com.google.common.base.Preconditions;
13 import com.google.common.util.concurrent.AsyncFunction;
14 import com.google.common.util.concurrent.CheckedFuture;
15 import com.google.common.util.concurrent.Futures;
16 import com.google.common.util.concurrent.ListenableFuture;
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
19 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
22 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
23 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
24 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NetconfTransactionCreator;
25 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
41 import javax.annotation.Nullable;
42 import java.util.ArrayList;
43 import java.util.HashMap;
44 import java.util.List;
46 import java.util.Optional;
48 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
49 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
51 public class PolicyManagerImpl implements PolicyManager {
53 private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerImpl.class);
54 private static final String policyMapName = "service-chains";
55 private final DataBroker dataBroker;
56 private final NodeManager nodeManager;
58 public PolicyManagerImpl(final DataBroker dataBroker,
59 final NodeManager nodeManager) {
60 this.dataBroker = Preconditions.checkNotNull(dataBroker);
61 this.nodeManager = Preconditions.checkNotNull(nodeManager);
65 public ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, final Configuration dataBefore,
67 final ListenableFuture<Boolean> result;
68 if (dataBefore == null && dataAfter != null) {
69 result = syncPolicy(dataAfter, Create);
70 } else if (dataBefore != null && dataAfter == null) {
71 result = syncPolicy(dataBefore, Delete);
73 syncPolicy(dataBefore, Delete);
74 syncPolicy(dataAfter, Create);
75 result = Futures.immediateFuture(false);
78 reportVersion(version);
80 // chain version update (TODO: status)
81 return Futures.transform(result, new AsyncFunction<Boolean, Boolean>() {
83 public ListenableFuture<Boolean> apply(final Boolean input) throws Exception {
84 if (input != null && input) {
85 return Futures.transform(reportVersion(version), new Function<Void, Boolean>() {
88 public Boolean apply(@Nullable final Void input) {
93 return Futures.immediateFuture(input);
99 private ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, DsAction action) {
100 if (dataAfter.getRendererEndpoints() == null
101 || dataAfter.getRendererEndpoints().getRendererEndpoint() == null) {
102 LOG.debug("no configuration obtained - skipping");
103 return Futures.immediateFuture(true);
105 final Map<DataBroker, PolicyWriter> policyWriterPerDeviceCache = new HashMap<>();
106 for (RendererEndpoint rendererEndpoint : dataAfter.getRendererEndpoints().getRendererEndpoint()) {
107 if (dataAfter.getEndpoints() == null || dataAfter.getEndpoints().getAddressEndpointWithLocation() == null) {
108 LOG.debug("renderer-endpoint: missing address-endpoint-with-location");
109 //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
112 final List<AddressEndpointWithLocation> endpointsWithLocation = dataAfter.getEndpoints()
113 .getAddressEndpointWithLocation();
114 final InstanceIdentifier mountpointIid = PolicyManagerUtil.getAbsoluteLocationMountpoint(rendererEndpoint, endpointsWithLocation);
115 final DataBroker mountpoint = nodeManager.getNodeMountPoint(mountpointIid);
116 if (mountpoint == null) {
117 LOG.debug("no data-broker for mount-point [{}] available", mountpointIid);
118 //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
122 // Find policy writer
123 PolicyWriter policyWriter = policyWriterPerDeviceCache.get(mountpoint);
124 if (policyWriter == null) {
125 // Initialize new policy writer
126 final String interfaceName = PolicyManagerUtil.getInterfaceNameForPolicyMap(rendererEndpoint, endpointsWithLocation);
127 final NodeId nodeId = nodeManager.getNodeIdByMountpointIid(mountpointIid);
128 final String managementIpAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
129 if (interfaceName == null || managementIpAddress == null) {
130 LOG.debug("can not create policyWriter: interface={}, managementIpAddress={}",
131 interfaceName, managementIpAddress);
132 //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
135 policyWriter = new PolicyWriter(mountpoint, interfaceName, managementIpAddress, policyMapName, nodeId);
136 policyWriterPerDeviceCache.put(mountpoint, policyWriter);
139 final Sgt sourceSgt = PolicyManagerUtil.findSgtTag(rendererEndpoint, dataAfter.getEndpoints()
140 .getAddressEndpointWithLocation());
142 for (PeerEndpointWithPolicy peerEndpoint : rendererEndpoint.getPeerEndpointWithPolicy()) {
143 final Sgt destinationSgt = PolicyManagerUtil.findSgtTag(peerEndpoint, dataAfter.getEndpoints()
144 .getAddressEndpointWithLocation());
145 if (sourceSgt == null || destinationSgt == null) {
146 LOG.debug("endpoint-policy: missing sgt value(sourceSgt={}, destinationSgt={})",
147 sourceSgt, destinationSgt);
148 //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
151 PolicyManagerUtil.syncPolicyEntities(sourceSgt, destinationSgt, policyWriter, dataAfter, peerEndpoint,
156 //TODO: return real (cumulated) future
157 final List<CheckedFuture<Boolean, TransactionCommitFailedException>> allFutureResults = new ArrayList<>();
158 if (action.equals(Create)) {
159 policyWriterPerDeviceCache.values().forEach(pw -> allFutureResults.add(pw.commitToDatastore()));
160 } else if (action.equals(Delete)) {
161 policyWriterPerDeviceCache.values().forEach(pw -> allFutureResults.add(pw.removeFromDatastore()));
163 LOG.info("unsupported policy manage action: {}", action);
165 final ListenableFuture<List<Boolean>> cumulativeResult = Futures.allAsList(allFutureResults);
167 return Futures.transform(cumulativeResult, new Function<List<Boolean>, Boolean>() {
170 public Boolean apply(@Nullable final List<Boolean> input) {
171 LOG.trace("considering all submits as successful - otherwise there will be exception");
177 private CheckedFuture<Void, TransactionCommitFailedException> reportVersion(long version) {
178 final Optional<ReadWriteTransaction> optionalReadWriteTransaction =
179 NetconfTransactionCreator.netconfReadWriteTransaction(dataBroker);
180 if (!optionalReadWriteTransaction.isPresent()) {
181 LOG.warn("Failed to create transaction, mountpoint: {}", dataBroker);
182 return Futures.immediateCheckedFuture(null);
184 final ReadWriteTransaction readWriteTransaction = optionalReadWriteTransaction.get();
185 final InstanceIdentifier<RendererPolicy> iid = InstanceIdentifier.create(Renderers.class)
186 .child(Renderer.class, new RendererKey(NodeManager.iosXeRenderer))
187 .child(RendererPolicy.class);
188 readWriteTransaction.merge(LogicalDatastoreType.OPERATIONAL, iid,
189 new RendererPolicyBuilder().setVersion(version).build());
190 return readWriteTransaction.submit();
194 public void close() {
198 public enum DsAction {Create, Delete}
200 public enum ActionCase {ALLOW, CHAIN}