610cab6c0b8d8e0bbcbc5a481d60fdd329673e7a
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / netvirt / openstack / netvirt / translator / iaware / impl / NeutronSecurityRuleDataChangeListener.java
1 /*
2  * Copyright (c) 2015 Brocade Communications 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 package org.opendaylight.netvirt.openstack.netvirt.translator.iaware.impl;
9
10 import java.util.Map.Entry;
11
12 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataChangeListener;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
16 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
17 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
18 import org.opendaylight.netvirt.openstack.netvirt.translator.iaware.INeutronSecurityRuleAware;
19 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityRule;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionBase;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionEgress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV6;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolBase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmp;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmpV6;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.SecurityRules;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
35 import org.opendaylight.yangtools.concepts.ListenerRegistration;
36 import org.opendaylight.yangtools.yang.binding.DataObject;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 import com.google.common.collect.ImmutableBiMap;
42
43 public class NeutronSecurityRuleDataChangeListener implements ClusteredDataChangeListener, AutoCloseable {
44
45     private static final Logger LOG = LoggerFactory.getLogger(NeutronSecurityRuleDataChangeListener.class);
46
47     private static final ImmutableBiMap<Class<? extends DirectionBase>, String> DIRECTION_MAP = ImmutableBiMap.of(
48             DirectionEgress.class, NeutronSecurityRule.DIRECTION_EGRESS,
49             DirectionIngress.class, NeutronSecurityRule.DIRECTION_INGRESS);
50     private static final ImmutableBiMap<Class<? extends ProtocolBase>, String> PROTOCOL_MAP = ImmutableBiMap.of(
51             ProtocolIcmp.class, NeutronSecurityRule.PROTOCOL_ICMP,
52             ProtocolTcp.class, NeutronSecurityRule.PROTOCOL_TCP,
53             ProtocolUdp.class, NeutronSecurityRule.PROTOCOL_UDP,
54             ProtocolIcmpV6.class, NeutronSecurityRule.PROTOCOL_ICMPV6);
55     private static final ImmutableBiMap<Class<? extends EthertypeBase>,String> ETHERTYPE_MAP = ImmutableBiMap.of(
56             EthertypeV4.class, NeutronSecurityRule.ETHERTYPE_IPV4,
57             EthertypeV6.class, NeutronSecurityRule.ETHERTYPE_IPV6);
58
59     private ListenerRegistration<DataChangeListener> registration;
60
61     public NeutronSecurityRuleDataChangeListener(DataBroker db) {
62         InstanceIdentifier<SecurityRule> path = InstanceIdentifier
63                 .create(Neutron.class).child(SecurityRules.class)
64                 .child(SecurityRule.class);
65         LOG.debug("Register listener for Neutron Secutiry rules model data changes");
66         registration = db.registerDataChangeListener(
67                 LogicalDatastoreType.CONFIGURATION, path, this,
68                 DataChangeScope.ONE);
69
70     }
71
72     @Override
73     public void onDataChanged(
74             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {
75         LOG.trace("Data changes : {}", changes);
76
77         Object[] subscribers = NeutronIAwareUtil.getInstances(
78                 INeutronSecurityRuleAware.class, this);
79         createSecurityRule(changes, subscribers);
80         updateSecurityRule(changes, subscribers);
81         deleteSecurityRule(changes, subscribers);
82     }
83
84     private void createSecurityRule(
85             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
86             Object[] subscribers) {
87         for (Entry<InstanceIdentifier<?>, DataObject> newSecutiryRule : changes
88                 .getCreatedData().entrySet()) {
89             if (newSecutiryRule.getValue() instanceof SecurityRule) {
90                 NeutronSecurityRule secutiryRule = fromMd((SecurityRule) newSecutiryRule
91                         .getValue());
92                 for (Object entry : subscribers) {
93                     INeutronSecurityRuleAware subscriber = (INeutronSecurityRuleAware) entry;
94                     subscriber.neutronSecurityRuleCreated(secutiryRule);
95                 }
96             }
97         }
98
99     }
100
101     private void updateSecurityRule(
102             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
103             Object[] subscribers) {
104         for (Entry<InstanceIdentifier<?>, DataObject> updateSecurityRule : changes
105                 .getUpdatedData().entrySet()) {
106             if (updateSecurityRule.getValue() instanceof SecurityRule) {
107                 NeutronSecurityRule securityRule = fromMd((SecurityRule) updateSecurityRule
108                         .getValue());
109                 for (Object entry : subscribers) {
110                     INeutronSecurityRuleAware subscriber = (INeutronSecurityRuleAware) entry;
111                     subscriber.neutronSecurityRuleUpdated(securityRule);
112                 }
113             }
114         }
115     }
116
117     private void deleteSecurityRule(
118             AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes,
119             Object[] subscribers) {
120         for (InstanceIdentifier<?> deletedSecurityRule : changes
121                 .getRemovedPaths()) {
122             if (deletedSecurityRule.getTargetType().equals(SecurityRule.class)) {
123                 NeutronSecurityRule securityRule = fromMd((SecurityRule) changes
124                         .getOriginalData().get(deletedSecurityRule));
125                 for (Object entry : subscribers) {
126                     INeutronSecurityRuleAware subscriber = (INeutronSecurityRuleAware) entry;
127                     subscriber.neutronSecurityRuleDeleted(securityRule);
128                 }
129             }
130         }
131     }
132
133     private NeutronSecurityRule fromMd(SecurityRule rule) {
134         NeutronSecurityRule answer = new NeutronSecurityRule();
135         if (rule.getTenantId() != null) {
136             answer.setSecurityRuleTenantID(rule.getTenantId().getValue()
137                     .replace("-", ""));
138         }
139         if (rule.getDirection() != null) {
140             answer.setSecurityRuleDirection(DIRECTION_MAP.get(rule
141                     .getDirection()));
142         }
143         if (rule.getSecurityGroupId() != null) {
144             answer.setSecurityRuleGroupID(rule.getSecurityGroupId().getValue());
145         }
146         if (rule.getRemoteGroupId() != null) {
147             answer.setSecurityRemoteGroupID(rule.getRemoteGroupId().getValue());
148         }
149         if (rule.getRemoteIpPrefix() != null) {
150             answer.setSecurityRuleRemoteIpPrefix(rule.getRemoteIpPrefix().getIpv4Prefix()!= null?
151                     rule.getRemoteIpPrefix().getIpv4Prefix().getValue():rule.getRemoteIpPrefix().getIpv6Prefix().getValue());
152         }
153         if (rule.getProtocol() != null) {
154             SecurityRuleAttributes.Protocol protocol = rule.getProtocol();
155             if (protocol.getUint8() != null) {
156                 // uint8
157                 answer.setSecurityRuleProtocol(protocol.getUint8().toString());
158             } else {
159                // symbolic protocol name
160                answer.setSecurityRuleProtocol(PROTOCOL_MAP.get(rule.getProtocol().getIdentityref()));
161             }
162         }
163         if (rule.getEthertype() != null) {
164             answer.setSecurityRuleEthertype(ETHERTYPE_MAP.get(rule
165                     .getEthertype()));
166         }
167         if (rule.getPortRangeMin() != null) {
168             answer.setSecurityRulePortMin(rule.getPortRangeMin());
169         }
170         if (rule.getPortRangeMax() != null) {
171             answer.setSecurityRulePortMax(rule.getPortRangeMax());
172         }
173         if (rule.getUuid() != null) {
174             answer.setID(rule.getUuid().getValue());
175         }
176         return answer;
177     }
178
179     @Override
180     public void close() throws Exception {
181         registration.close();
182     }
183 }