ffcb8adbc3864e2f54813dc538fb662edba9755d
[netvirt.git] / vpnservice / policyservice / impl / src / main / java / org / opendaylight / netvirt / policyservice / listeners / UnderlayNetworkDpnListener.java
1 /*
2  * Copyright (c) 2017 Hewlett Packard Enterprise, Co. 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.netvirt.policyservice.listeners;
10
11 import java.math.BigInteger;
12 import java.util.List;
13 import java.util.Optional;
14
15 import javax.annotation.PostConstruct;
16 import javax.inject.Inject;
17 import javax.inject.Singleton;
18
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
22 import org.opendaylight.genius.mdsalutil.NwConstants;
23 import org.opendaylight.netvirt.policyservice.PolicyAceFlowProgrammer;
24 import org.opendaylight.netvirt.policyservice.util.PolicyServiceUtil;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.UnderlayNetworks;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.UnderlayNetwork;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.DpnToInterface;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.policy.rev170207.underlay.networks.underlay.network.PolicyProfile;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 /**
35  * Listen on {@link DpnToInterface} operational updates for each underlay
36  * network. When new DPN is added/removed, all policy pipeline associated flows
37  * and groups will be populated to the new DPN.<br>
38  * When new tunnel interfaces are added/removed from underlay network, the
39  * corresponding policy classifier group buckets would be updated accordingly.
40  */
41 @Singleton
42 public class UnderlayNetworkDpnListener
43         extends AsyncDataTreeChangeListenerBase<DpnToInterface, UnderlayNetworkDpnListener> {
44     private static final Logger LOG = LoggerFactory.getLogger(UnderlayNetworkDpnListener.class);
45
46     private final DataBroker dataBroker;
47     private final PolicyServiceUtil policyServiceUtil;
48     private final PolicyAceFlowProgrammer aceFlowProgrammer;
49
50     @Inject
51     public UnderlayNetworkDpnListener(final DataBroker dataBroker, final PolicyServiceUtil policyServiceUtil,
52             final PolicyAceFlowProgrammer aceFlowProgrammer) {
53         this.dataBroker = dataBroker;
54         this.policyServiceUtil = policyServiceUtil;
55         this.aceFlowProgrammer = aceFlowProgrammer;
56     }
57
58     @Override
59     @PostConstruct
60     public void init() {
61         LOG.info("init");
62         registerListener(LogicalDatastoreType.OPERATIONAL, dataBroker);
63     }
64
65     @Override
66     protected InstanceIdentifier<DpnToInterface> getWildCardPath() {
67         return InstanceIdentifier.create(UnderlayNetworks.class).child(UnderlayNetwork.class)
68                 .child(DpnToInterface.class);
69     }
70
71     @Override
72     protected UnderlayNetworkDpnListener getDataTreeChangeListener() {
73         return this;
74     }
75
76     @Override
77     protected void remove(InstanceIdentifier<DpnToInterface> key, DpnToInterface dpnToInterface) {
78     }
79
80     @Override
81     protected void update(InstanceIdentifier<DpnToInterface> key, DpnToInterface origDpnToInterface,
82             DpnToInterface updatedDpnToInterface) {
83     }
84
85     @Override
86     protected void add(InstanceIdentifier<DpnToInterface> key, DpnToInterface dpnToInterface) {
87         String underlayNetwork = key.firstKeyOf(UnderlayNetwork.class).getNetworkName();
88         BigInteger dpId = dpnToInterface.getDpId();
89         LOG.info("DPN {} added to underlay network {}", dpId, underlayNetwork);
90         populatePolicyRulesToDpn(underlayNetwork, dpId);
91
92     }
93
94     private void populatePolicyRulesToDpn(String underlayNetwork, BigInteger dpId) {
95         List<PolicyProfile> profiles = policyServiceUtil.getUnderlayNetworkPolicyProfiles(underlayNetwork);
96         if (profiles == null || profiles.isEmpty()) {
97             LOG.debug("No policy profiles found for underlay network {}", underlayNetwork);
98             return;
99         }
100
101         profiles.forEach(profile -> {
102             String policyClassifier = profile.getPolicyClassifier();
103
104             Optional.ofNullable(policyServiceUtil.getPolicyClassifierAclRules(policyClassifier)).ifPresent(aclRules -> {
105                 aclRules.forEach(aclRule -> {
106                     Optional.ofNullable(aclRule.getAceRule()).ifPresent(aceRules -> {
107                         aceRules.forEach(aceRule -> {
108                             com.google.common.base.Optional<Ace> policyAceOpt = policyServiceUtil
109                                     .getPolicyAce(aclRule.getAclName(), aceRule.getRuleName());
110                             if (policyAceOpt.isPresent()) {
111                                 aceFlowProgrammer.programAceFlows(policyAceOpt.get(), dpId, NwConstants.ADD_FLOW);
112                             } else {
113                                 LOG.warn("Failed to get ACL {} rule {}", aclRule.getAclName(), aceRule.getRuleName());
114                             }
115                         });
116                     });
117                 });
118             });
119         });
120     }
121
122 }