Bug 5409 - setting orders in single rule contract
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / infrastructure / NetworkService.java
1 /*
2  * Copyright (c) 2014 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.neutron.mapper.infrastructure;
10
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Set;
15
16 import javax.annotation.Nullable;
17
18 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
21 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
22 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
23 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
24 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
25 import org.opendaylight.groupbasedpolicy.util.IidFactory;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraints;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchers;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
69
70 import com.google.common.collect.ImmutableList;
71
72 public class NetworkService {
73
74     /**
75      * Unit tests {@link NetworkServiceTest}
76      */
77     // ########### DHCP
78     private static final long DHCP_IPV4_SERVER_PORT = 67;
79     private static final long DHCP_IPV4_CLIENT_PORT = 68;
80     private static final long DHCP_IPV6_SERVER_PORT = 547;
81     private static final long DHCP_IPV6_CLIENT_PORT = 546;
82     private static final ClassifierName DHCP_IPV4_CLIENT_SERVER_NAME =
83             new ClassifierName("DHCP_IPv4_FROM_CLIENT_TO_SERVER");
84     private static final ClassifierName DHCP_IPV4_SERVER_CLIENT_NAME =
85             new ClassifierName("DHCP_IPv4_FROM_SERVER_TO_CLIENT");
86     private static final ClassifierName DHCP_IPV6_CLIENT_SERVER_NAME =
87             new ClassifierName("DHCP_IPv6_FROM_CLIENT_TO_SERVER");
88     private static final ClassifierName DHCP_IPV6_SERVER_CLIENT_NAME =
89             new ClassifierName("DHCP_IPv6_FROM_SERVER_TO_CLIENT");
90     private static final SubjectName DHCP_SUBJECT_NAME = new SubjectName("ALLOW_DHCP");
91     private static final Description DHCP_CONTRACT_DESC =
92             new Description("Allow DHCP communication between client and server.");
93
94     /**
95      * Id of {@link #DHCP_CONTRACT}
96      */
97     public static final ContractId DHCP_CONTRACT_ID = new ContractId("11118d2e-dddd-11e5-885d-feff819cdc9f");
98     /**
99      * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching DHCP communication
100      * between Client and Server.
101      */
102     public static final Contract DHCP_CONTRACT;
103     /**
104      * {@link ConsumerNamedSelector} pointing to {@link #DHCP_CONTRACT}
105      */
106     public static final ConsumerNamedSelector DHCP_CONTRACT_CONSUMER_SELECTOR;
107
108     // ########### DNS
109     private static final long DNS_SERVER_PORT = 53;
110     private static final ClassifierName DNS_UDP_IPV4_CLIENT_SERVER_NAME =
111             new ClassifierName("DNS_UDP_IPv4_FROM_CLIENT_TO_SERVER");
112     private static final ClassifierName DNS_UDP_IPV4_SERVER_CLIENT_NAME =
113             new ClassifierName("DNS_UDP_IPv4_FROM_SERVER_TO_CLIENT");
114     private static final ClassifierName DNS_UDP_IPV6_CLIENT_SERVER_NAME =
115             new ClassifierName("DNS_UDP_IPv6_FROM_CLIENT_TO_SERVER");
116     private static final ClassifierName DNS_UDP_IPV6_SERVER_CLIENT_NAME =
117             new ClassifierName("DNS_UDP_IPv6_FROM_SERVER_TO_CLIENT");
118     private static final ClassifierName DNS_TCP_IPV4_CLIENT_SERVER_NAME =
119             new ClassifierName("DNS_TCP_IPv4_FROM_CLIENT_TO_SERVER");
120     private static final ClassifierName DNS_TCP_IPV4_SERVER_CLIENT_NAME =
121             new ClassifierName("DNS_TCP_IPv4_FROM_SERVER_TO_CLIENT");
122     private static final ClassifierName DNS_TCP_IPV6_CLIENT_SERVER_NAME =
123             new ClassifierName("DNS_TCP_IPv6_FROM_CLIENT_TO_SERVER");
124     private static final ClassifierName DNS_TCP_IPV6_SERVER_CLIENT_NAME =
125             new ClassifierName("DNS_TCP_IPv6_FROM_SERVER_TO_CLIENT");
126     private static final SubjectName DNS_SUBJECT_NAME = new SubjectName("ALLOW_DNS");
127     private static final Description DNS_CONTRACT_DESC =
128             new Description("Allow DNS communication between client and server.");
129     /**
130      * ID of {@link #DNS_CONTRACT}
131      */
132     public static final ContractId DNS_CONTRACT_ID = new ContractId("22218d2e-dddd-11e5-885d-feff819cdc9f");
133     /**
134      * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching DNS communication
135      * between Client and Server.
136      */
137     public static final Contract DNS_CONTRACT;
138     /**
139      * {@link ConsumerNamedSelector} pointing to {@link #DNS_CONTRACT}
140      */
141     public static final ConsumerNamedSelector DNS_CONTRACT_CONSUMER_SELECTOR;
142
143     // ########### SSH and ICMP management
144     private static final long SSH_TCP_PORT = 22;
145     private static final ClassifierName SSH_IPV4_SERVER_TO_CLIENT_NAME =
146             new ClassifierName("SSH_IPV4_FROM_SERVER_TO_CLIENT");
147     private static final ClassifierName SSH_IPV6_SERVER_TO_CLIENT_NAME =
148             new ClassifierName("SSH_IPV6_FROM_SERVER_TO_CLIENT");
149     private static final ClassifierName SSH_IPV4_CLIENT_TO_SERVER_NAME =
150             new ClassifierName("SSH_IPV4_FROM_CLIENT_TO_SERVER");
151     private static final ClassifierName SSH_IPV6_CLIENT_TO_SERVER_NAME =
152             new ClassifierName("SSH_IPV6_FROM_CLIENT_TO_SERVER");
153     private static final ClassifierName ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME =
154             new ClassifierName("ICMP_IPV4_BETWEEN_SERVER_CLIENT");
155     private static final ClassifierName ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME =
156             new ClassifierName("ICMP_IPV6_BETWEEN_SERVER_CLIENT");
157     private static final SubjectName MGMT_SUBJECT_NAME = new SubjectName("ALLOW_MGMT");
158     private static final Description MGMT_CONTRACT_DESC =
159             new Description("Allow ICMP and SSH management communication between server and client.");
160
161     /**
162      * Id of {@link #MGMT_CONTRACT}
163      */
164     public static final ContractId MGMT_CONTRACT_ID = new ContractId("33318d2e-dddd-11e5-885d-feff819cdc9f");
165     /**
166      * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching ICMP and SSH
167      * communication
168      * between Client and Server.
169      */
170     public static final Contract MGMT_CONTRACT;
171     /**
172      * {@link ConsumerNamedSelector} pointing to {@link #MGMT_CONTRACT}
173      */
174     public static final ConsumerNamedSelector MGMT_CONTRACT_CONSUMER_SELECTOR;
175
176     // ########### NETWORK-SERVICE ENDPOINT-GROUP
177     private static final Name NETWORK_SERVICE_EPG_NAME = new Name("NETWORK_SERVICE");
178     private static final Description NETWORK_SERVICE_EPG_DESC = new Description("Represents DHCP and DNS servers.");
179     /**
180      * ID of {@link #EPG}
181      */
182     public static final EndpointGroupId EPG_ID = new EndpointGroupId("ddd6cfe6-dfe5-11e4-8a00-1681e6b88ec1");
183     /**
184      * Network-service endpoint-group providing {@link #DHCP_CONTRACT} and {@link #DNS_CONTRACT}
185      */
186     public static final EndpointGroup EPG;
187
188     static {
189         DHCP_CONTRACT = createContractDhcp();
190         DHCP_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DHCP_CONTRACT);
191         DNS_CONTRACT = createContractDns();
192         DNS_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DNS_CONTRACT);
193         MGMT_CONTRACT = createContractMgmt();
194         MGMT_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(MGMT_CONTRACT);
195         EPG = createNetworkServiceEpg();
196     }
197
198     private static EndpointGroup createNetworkServiceEpg() {
199         ProviderNamedSelector dhcpProviderSelector = createProviderSelector(DHCP_CONTRACT);
200         ProviderNamedSelector dnsProviderSelector = createProviderSelector(DNS_CONTRACT);
201         ProviderNamedSelector mgmtProviderSelector = createProviderSelector(MGMT_CONTRACT);
202         return new EndpointGroupBuilder().setId(EPG_ID)
203             .setName(NETWORK_SERVICE_EPG_NAME)
204             .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector))
205             .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
206             .setDescription(NETWORK_SERVICE_EPG_DESC)
207             .build();
208     }
209
210     private static ProviderNamedSelector createProviderSelector(Contract contract) {
211         SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue());
212         return new ProviderNamedSelectorBuilder().setName(selectorName)
213             .setContract(ImmutableList.of(contract.getId()))
214             .build();
215     }
216
217     private static ConsumerNamedSelector createConsumerSelector(Contract contract) {
218         SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue());
219         return new ConsumerNamedSelectorBuilder().setName(selectorName)
220             .setContract(ImmutableList.of(contract.getId()))
221             .build();
222     }
223
224     private static Contract createContractDhcp() {
225         Rule clientServerIpv4Rule = createRuleAllow(DHCP_IPV4_CLIENT_SERVER_NAME, Direction.In);
226         Rule serverClientIpv4Rule = createRuleAllow(DHCP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
227         Rule clientServerIpv6Rule = createRuleAllow(DHCP_IPV6_CLIENT_SERVER_NAME, Direction.In);
228         Rule serverClientIpv6Rule = createRuleAllow(DHCP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
229         Subject subject = new SubjectBuilder().setName(DHCP_SUBJECT_NAME)
230             .setOrder(0)
231             .setRule(ImmutableList.of(clientServerIpv4Rule, serverClientIpv4Rule, clientServerIpv6Rule,
232                     serverClientIpv6Rule))
233             .build();
234         return new ContractBuilder().setId(DHCP_CONTRACT_ID)
235             .setSubject(ImmutableList.of(subject))
236             .setDescription(DHCP_CONTRACT_DESC)
237             .build();
238     }
239
240     private static Contract createContractDns() {
241         Rule clientServerUdpIpv4Rule = createRuleAllow(DNS_UDP_IPV4_CLIENT_SERVER_NAME, Direction.In);
242         Rule serverClientUdpIpv4Rule = createRuleAllow(DNS_UDP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
243         Rule clientServerUdpIpv6Rule = createRuleAllow(DNS_UDP_IPV6_CLIENT_SERVER_NAME, Direction.In);
244         Rule serverClientUdpIpv6Rule = createRuleAllow(DNS_UDP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
245         Rule clientServerTcpIpv4Rule = createRuleAllow(DNS_TCP_IPV4_CLIENT_SERVER_NAME, Direction.In);
246         Rule serverClientTcpIpv4Rule = createRuleAllow(DNS_TCP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
247         Rule clientServerTcpIpv6Rule = createRuleAllow(DNS_TCP_IPV6_CLIENT_SERVER_NAME, Direction.In);
248         Rule serverClientTcpIpv6Rule = createRuleAllow(DNS_TCP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
249         Subject subject = new SubjectBuilder().setName(DNS_SUBJECT_NAME)
250             .setOrder(0)
251             .setRule(ImmutableList.of(clientServerUdpIpv4Rule, serverClientUdpIpv4Rule, clientServerUdpIpv6Rule,
252                     serverClientUdpIpv6Rule, clientServerTcpIpv4Rule, serverClientTcpIpv4Rule, clientServerTcpIpv6Rule,
253                     serverClientTcpIpv6Rule))
254             .build();
255         return new ContractBuilder().setId(DNS_CONTRACT_ID)
256             .setSubject(ImmutableList.of(subject))
257             .setDescription(DNS_CONTRACT_DESC)
258             .build();
259     }
260
261     private static Contract createContractMgmt() {
262         Rule serverClientSshIpv4Rule = createRuleAllow(SSH_IPV4_SERVER_TO_CLIENT_NAME, Direction.Out);
263         Rule serverClientSshIpv6Rule = createRuleAllow(SSH_IPV6_SERVER_TO_CLIENT_NAME, Direction.Out);
264         Rule clientServerSshIpv4Rule = createRuleAllow(SSH_IPV4_CLIENT_TO_SERVER_NAME, Direction.In);
265         Rule clientServerSshIpv6Rule = createRuleAllow(SSH_IPV6_CLIENT_TO_SERVER_NAME, Direction.In);
266         Rule serverClientIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
267         Rule serverClientIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
268         Rule clientServerIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
269         Rule clientServerIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
270
271         Subject subject = new SubjectBuilder().setName(MGMT_SUBJECT_NAME)
272             .setOrder(0)
273             .setRule(ImmutableList.of(serverClientSshIpv4Rule, serverClientSshIpv6Rule, clientServerSshIpv4Rule,
274                     clientServerSshIpv6Rule, clientServerIcmpIpv4Rule, clientServerIcmpIpv6Rule,
275                     serverClientIcmpIpv4Rule, serverClientIcmpIpv6Rule))
276             .build();
277         return new ContractBuilder().setId(MGMT_CONTRACT_ID)
278             .setSubject(ImmutableList.of(subject))
279             .setDescription(MGMT_CONTRACT_DESC)
280             .build();
281     }
282
283     private static Rule createRuleAllow(ClassifierName classifierName, Direction direction) {
284         ClassifierName name =
285                 new ClassifierName(direction.name() + MappingUtils.NAME_DOUBLE_DELIMETER + classifierName.getValue());
286         ClassifierRef classifierRef = new ClassifierRefBuilder().setName(name)
287             .setInstanceName(classifierName)
288             .setDirection(direction)
289             .build();
290         return new RuleBuilder().setName(new RuleName(name))
291             .setActionRef(ImmutableList.<ActionRef>of(MappingUtils.ACTION_REF_ALLOW))
292             .setClassifierRef(ImmutableList.of(classifierRef))
293             .build();
294     }
295
296     /**
297      * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
298      * and {@link ProviderMatchers}. This clause points to subject in {@link #DHCP_CONTRACT}.
299      *
300      * @param tenantId location of {@link #DHCP_CONTRACT}
301      * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
302      * @param wTx transaction where entities are written
303      */
304     public static void writeDhcpClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
305             WriteTransaction wTx) {
306         Clause clause = createClauseWithConsProvEic(ipPrefix, DHCP_SUBJECT_NAME);
307         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, DHCP_CONTRACT_ID, clause.getName()),
308                 clause, true);
309     }
310
311     /**
312      * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
313      * and {@link ProviderMatchers}. This clause points to subject in {@link #DNS_CONTRACT}.
314      *
315      * @param tenantId location of {@link #DNS_CONTRACT}
316      * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
317      * @param wTx transaction where entities are written
318      */
319     public static void writeDnsClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
320             WriteTransaction wTx) {
321         Clause clause = createClauseWithConsProvEic(ipPrefix, DNS_SUBJECT_NAME);
322         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, DNS_CONTRACT_ID, clause.getName()),
323                 clause, true);
324     }
325
326     /**
327      * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
328      * and {@link ProviderMatchers}. This clause points to subject in {@link #MGMT_CONTRACT}.
329      *
330      * @param tenantId location of {@link #MGMT_CONTRACT}
331      * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
332      * @param wTx transaction where entities are written
333      */
334     public static void writeMgmtClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
335             WriteTransaction wTx) {
336         Clause clause = createClauseWithConsProvEic(ipPrefix, MGMT_SUBJECT_NAME);
337         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, MGMT_CONTRACT_ID, clause.getName()),
338                 clause, true);
339     }
340
341     private static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) {
342         ConsumerMatchers consumerMatchers = null;
343         ProviderMatchers providerMatchers = null;
344         StringBuilder clauseName = new StringBuilder();
345         clauseName.append(subjectName.getValue());
346         if (ipPrefix != null) {
347             clauseName.append(MappingUtils.NAME_DOUBLE_DELIMETER).append(Utils.getStringIpPrefix(ipPrefix));
348             consumerMatchers =
349                     new ConsumerMatchersBuilder()
350                         .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
351                             .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
352                                 .setPrefixConstraint(
353                                         ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
354                                 .build())
355                             .build())
356                         .build();
357             providerMatchers =
358                     new ProviderMatchersBuilder()
359                         .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
360                             .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
361                                 .setPrefixConstraint(
362                                         ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
363                                 .build())
364                             .build())
365                         .build();
366         }
367         return new ClauseBuilder().setName(new ClauseName(clauseName.toString()))
368             .setSubjectRefs(ImmutableList.of(subjectName))
369             .setConsumerMatchers(consumerMatchers)
370             .setProviderMatchers(providerMatchers)
371             .build();
372     }
373
374     /**
375      * Puts network service entities (classifier-instances, {@link #DHCP_CONTRACT},
376      * {@link #DNS_CONTRACT}, {@link #MGMT_CONTRACT} and {@link #EPG}) to
377      * {@link LogicalDatastoreType#CONFIGURATION}
378      *
379      * @param tenantId location of network-service entities
380      * @param wTx transaction where network-service entities are written
381      */
382     public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx) {
383         Set<ClassifierInstance> classifierInstances = getAllClassifierInstances();
384         for (ClassifierInstance ci : classifierInstances) {
385             wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci,
386                     true);
387         }
388         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, DHCP_CONTRACT_ID), DHCP_CONTRACT,
389                 true);
390         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, DNS_CONTRACT_ID), DNS_CONTRACT,
391                 true);
392         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, MGMT_CONTRACT_ID), MGMT_CONTRACT,
393                 true);
394         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true);
395     }
396
397     /**
398      * @return All classifier-instances used in {@link #DHCP_CONTRACT}, {@link #DNS_CONTRACT} and
399      *         {@link #MGMT_CONTRACT}
400      */
401     public static Set<ClassifierInstance> getAllClassifierInstances() {
402         HashSet<ClassifierInstance> cis = new HashSet<>();
403         cis.add(createDhcpIpv4ClientServer());
404         cis.add(createDhcpIpv4ServerClient());
405         cis.add(createDhcpIpv6ClientServer());
406         cis.add(createDhcpIpv6ServerClient());
407         cis.add(createDnsUdpIpv4ClientServer());
408         cis.add(createDnsUdpIpv4ServerClient());
409         cis.add(createDnsUdpIpv6ClientServer());
410         cis.add(createDnsUdpIpv6ServerClient());
411         cis.add(createDnsTcpIpv4ClientServer());
412         cis.add(createDnsTcpIpv4ServerClient());
413         cis.add(createDnsTcpIpv6ClientServer());
414         cis.add(createDnsTcpIpv6ServerClient());
415         // MGMT
416         cis.add(createSshTcpIpv4ServerClient());
417         cis.add(createSshTcpIpv6ServerClient());
418         cis.add(createSshTcpIpv4ClientServer());
419         cis.add(createSshTcpIpv6ClientServer());
420         cis.add(createIcmpIpv4());
421         cis.add(createIcmpIpv6());
422
423         return cis;
424     }
425
426     // ###################### DHCP
427     private static ClassifierInstance createDhcpIpv4ClientServer() {
428         return new ClassifierInstanceBuilder().setName(DHCP_IPV4_CLIENT_SERVER_NAME)
429             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
430             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
431                     DHCP_IPV4_CLIENT_PORT, DHCP_IPV4_SERVER_PORT))
432             .build();
433     }
434
435     private static ClassifierInstance createDhcpIpv4ServerClient() {
436         return new ClassifierInstanceBuilder().setName(DHCP_IPV4_SERVER_CLIENT_NAME)
437             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
438             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
439                     DHCP_IPV4_SERVER_PORT, DHCP_IPV4_CLIENT_PORT))
440             .build();
441     }
442
443     private static ClassifierInstance createDhcpIpv6ClientServer() {
444         return new ClassifierInstanceBuilder().setName(DHCP_IPV6_CLIENT_SERVER_NAME)
445             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
446             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
447                     DHCP_IPV6_CLIENT_PORT, DHCP_IPV6_SERVER_PORT))
448             .build();
449     }
450
451     private static ClassifierInstance createDhcpIpv6ServerClient() {
452         return new ClassifierInstanceBuilder().setName(DHCP_IPV6_SERVER_CLIENT_NAME)
453             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
454             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
455                     DHCP_IPV6_SERVER_PORT, DHCP_IPV6_CLIENT_PORT))
456             .build();
457     }
458
459     // ###################### DNS UDP
460     private static ClassifierInstance createDnsUdpIpv4ClientServer() {
461         return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_CLIENT_SERVER_NAME)
462             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
463             .setParameterValue(
464                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, DNS_SERVER_PORT))
465             .build();
466     }
467
468     private static ClassifierInstance createDnsUdpIpv4ServerClient() {
469         return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_SERVER_CLIENT_NAME)
470             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
471             .setParameterValue(
472                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, DNS_SERVER_PORT, null))
473             .build();
474     }
475
476     private static ClassifierInstance createDnsUdpIpv6ClientServer() {
477         return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_CLIENT_SERVER_NAME)
478             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
479             .setParameterValue(
480                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, DNS_SERVER_PORT))
481             .build();
482     }
483
484     private static ClassifierInstance createDnsUdpIpv6ServerClient() {
485         return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_SERVER_CLIENT_NAME)
486             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
487             .setParameterValue(
488                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, DNS_SERVER_PORT, null))
489             .build();
490     }
491
492     // ###################### DNS TCP
493     private static ClassifierInstance createDnsTcpIpv4ClientServer() {
494         return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_CLIENT_SERVER_NAME)
495             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
496             .setParameterValue(
497                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT))
498             .build();
499     }
500
501     private static ClassifierInstance createDnsTcpIpv4ServerClient() {
502         return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_SERVER_CLIENT_NAME)
503             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
504             .setParameterValue(
505                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null))
506             .build();
507     }
508
509     private static ClassifierInstance createDnsTcpIpv6ClientServer() {
510         return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_CLIENT_SERVER_NAME)
511             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
512             .setParameterValue(
513                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT))
514             .build();
515     }
516
517     private static ClassifierInstance createDnsTcpIpv6ServerClient() {
518         return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_SERVER_CLIENT_NAME)
519             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
520             .setParameterValue(
521                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null))
522             .build();
523     }
524
525     // ###################### SSH TCP
526     private static ClassifierInstance createSshTcpIpv4ClientServer() {
527         return new ClassifierInstanceBuilder().setName(SSH_IPV4_CLIENT_TO_SERVER_NAME)
528             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
529             .setParameterValue(
530                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null))
531             .build();
532     }
533
534     private static ClassifierInstance createSshTcpIpv4ServerClient() {
535         return new ClassifierInstanceBuilder().setName(SSH_IPV4_SERVER_TO_CLIENT_NAME)
536             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
537             .setParameterValue(
538                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT))
539             .build();
540     }
541
542     private static ClassifierInstance createSshTcpIpv6ClientServer() {
543         return new ClassifierInstanceBuilder().setName(SSH_IPV6_CLIENT_TO_SERVER_NAME)
544             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
545             .setParameterValue(
546                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null))
547             .build();
548     }
549
550     private static ClassifierInstance createSshTcpIpv6ServerClient() {
551         return new ClassifierInstanceBuilder().setName(SSH_IPV6_SERVER_TO_CLIENT_NAME)
552             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
553             .setParameterValue(
554                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT))
555             .build();
556     }
557
558     // ###################### ICMP
559     private static ClassifierInstance createIcmpIpv4() {
560         return new ClassifierInstanceBuilder().setName(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME)
561             .setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId())
562             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null))
563             .build();
564     }
565
566     private static ClassifierInstance createIcmpIpv6() {
567         return new ClassifierInstanceBuilder().setName(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME)
568             .setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId())
569             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null))
570             .build();
571     }
572
573     private static List<ParameterValue> createParams(long etherType, long proto, @Nullable Long srcPort,
574             @Nullable Long dstPort) {
575         List<ParameterValue> params = new ArrayList<>();
576         if (srcPort != null) {
577             params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.SRC_PORT_PARAM))
578                 .setIntValue(srcPort)
579                 .build());
580         }
581         if (dstPort != null) {
582             params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))
583                 .setIntValue(dstPort)
584                 .build());
585         }
586         params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))
587             .setIntValue(proto)
588             .build());
589         params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
590             .setIntValue(etherType)
591             .build());
592         return params;
593     }
594 }