Bug 4724 added containers to tenant
[groupbasedpolicy.git] / ui-backend / src / main / java / org / opendaylight / groupbasedpolicy / ui / backend / UiBackendServiceImpl.java
1 /*\r
2  * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 \r
9 package org.opendaylight.groupbasedpolicy.ui.backend;\r
10 \r
11 import java.util.ArrayList;\r
12 import java.util.Collections;\r
13 import java.util.HashSet;\r
14 import java.util.List;\r
15 import java.util.Set;\r
16 import java.util.concurrent.Future;\r
17 \r
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
19 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
21 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;\r
22 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;\r
23 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;\r
24 import org.opendaylight.groupbasedpolicy.dto.EgKey;\r
25 import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;\r
26 import org.opendaylight.groupbasedpolicy.dto.Policy;\r
27 import org.opendaylight.groupbasedpolicy.dto.RuleGroup;\r
28 import org.opendaylight.groupbasedpolicy.util.PolicyResolverUtils;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantKey;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupInput;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupOutput;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupOutputBuilder;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsInput;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsOutput;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsOutputBuilder;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.UiBackendService;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.endpoints.from.endpoint.group.output.UiEndpoint;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.endpoints.from.endpoint.group.output.UiEndpointBuilder;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.input.FromOperData;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.EndpointGroupPairWithSubject;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.EndpointGroupPairWithSubjectBuilder;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.endpoint.group.pair.with.subject.UiSubject;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.endpoint.group.pair.with.subject.UiSubjectBuilder;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.endpoint.group.pair.with.subject.ui.subject.UiRule;\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.endpoint.group.pair.with.subject.ui.subject.UiRuleBuilder;\r
53 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
54 import org.opendaylight.yangtools.yang.common.RpcResult;\r
55 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;\r
56 import org.slf4j.Logger;\r
57 import org.slf4j.LoggerFactory;\r
58 \r
59 import com.google.common.base.Function;\r
60 import com.google.common.base.Optional;\r
61 import com.google.common.base.Preconditions;\r
62 import com.google.common.collect.ImmutableSet;\r
63 import com.google.common.collect.Table;\r
64 import com.google.common.collect.Table.Cell;\r
65 import com.google.common.util.concurrent.CheckedFuture;\r
66 import com.google.common.util.concurrent.Futures;\r
67 \r
68 public class UiBackendServiceImpl implements UiBackendService, AutoCloseable {\r
69 \r
70     private static final Logger LOG = LoggerFactory.getLogger(UiBackendServiceImpl.class);\r
71 \r
72     private final DataBroker dataProvider;\r
73     private final BindingAwareBroker.RpcRegistration<UiBackendService> rpcRegistration;\r
74     private final InstanceIdentifier<Endpoints> ENDPOINTS_IID = InstanceIdentifier.builder(Endpoints.class).build();\r
75 \r
76     public UiBackendServiceImpl(DataBroker dataBroker, RpcProviderRegistry rpcRegistry) {\r
77         Preconditions.checkNotNull(dataBroker);\r
78         Preconditions.checkNotNull(rpcRegistry);\r
79         this.dataProvider = dataBroker;\r
80         rpcRegistration = rpcRegistry.addRpcImplementation(UiBackendService.class, this);\r
81     }\r
82 \r
83     @Override\r
84     public Future<RpcResult<GetEndpointsFromEndpointGroupOutput>> getEndpointsFromEndpointGroup(\r
85             GetEndpointsFromEndpointGroupInput input) {\r
86         LOG.trace("getEndpointsFromEndpointGroup: {}", input);\r
87         final TenantId tenantId = input.getTenantId();\r
88         if (tenantId == null) {\r
89             throw new IllegalArgumentException("Missing tenant-Id in RPC input.");\r
90         }\r
91         final EndpointGroupId epgId = input.getEndpointGroupId();\r
92         if (epgId == null) {\r
93             throw new IllegalArgumentException("Missing endpoint-group-id in RPC input.");\r
94         }\r
95         ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();\r
96         CheckedFuture<Optional<Endpoints>, ReadFailedException> futureEndpoints = rTx.read(\r
97                 LogicalDatastoreType.OPERATIONAL, ENDPOINTS_IID);\r
98         return Futures.transform(futureEndpoints,\r
99                 new Function<Optional<Endpoints>, RpcResult<GetEndpointsFromEndpointGroupOutput>>() {\r
100 \r
101                     @Override\r
102                     public RpcResult<GetEndpointsFromEndpointGroupOutput> apply(Optional<Endpoints> potentialEndpoints) {\r
103                         GetEndpointsFromEndpointGroupOutputBuilder outputBuilder = new GetEndpointsFromEndpointGroupOutputBuilder();\r
104                         if (!potentialEndpoints.isPresent() || potentialEndpoints.get().getEndpoint() == null) {\r
105                             LOG.trace("No endpoint in datastore.");\r
106                             return RpcResultBuilder.success(outputBuilder.build()).build();\r
107                         }\r
108 \r
109                         List<Endpoint> endpoints = potentialEndpoints.get().getEndpoint();\r
110                         List<UiEndpoint> uiEndpoints = new ArrayList<>();\r
111                         for (Endpoint ep : endpoints) {\r
112                             if (tenantId.equals(ep.getTenant()) && isEpInEpg(ep, epgId)) {\r
113                                 uiEndpoints.add(new UiEndpointBuilder(ep).build());\r
114                             }\r
115                         }\r
116                         outputBuilder.setUiEndpoint(uiEndpoints);\r
117                         return RpcResultBuilder.success(outputBuilder.build()).build();\r
118                     }\r
119                 });\r
120     }\r
121 \r
122     private boolean isEpInEpg(Endpoint ep, EndpointGroupId epgId) {\r
123         if (epgId.equals(ep.getEndpointGroup())) {\r
124             return true;\r
125         }\r
126         if (ep.getEndpointGroups() != null) {\r
127             for (EndpointGroupId epgFromEp : ep.getEndpointGroups()) {\r
128                 if (epgId.equals(epgFromEp)) {\r
129                     return true;\r
130                 }\r
131             }\r
132         }\r
133         return false;\r
134     }\r
135 \r
136     @Override\r
137     public Future<RpcResult<GetSubjectsBetweenEndpointGroupsOutput>> getSubjectsBetweenEndpointGroups(\r
138             GetSubjectsBetweenEndpointGroupsInput input) {\r
139         LOG.trace("getSubjectsBetweenEndpointGroups: {}", input);\r
140         final TenantId tenantId = input.getTenantId();\r
141         if (tenantId == null) {\r
142             throw new IllegalArgumentException("Missing tenant-Id in RPC input.");\r
143         }\r
144         final FromOperData fromOperData = input.getFromOperData();\r
145         InstanceIdentifier<Tenant> tenantIid = InstanceIdentifier.builder(Tenants.class)\r
146             .child(Tenant.class, new TenantKey(tenantId))\r
147             .build();\r
148         CheckedFuture<Optional<Tenant>, ReadFailedException> futureTenant;\r
149         try (ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction()) {\r
150             if (fromOperData == null) {\r
151                 futureTenant = rTx.read(LogicalDatastoreType.CONFIGURATION, tenantIid);\r
152             } else {\r
153                 futureTenant = rTx.read(LogicalDatastoreType.OPERATIONAL, tenantIid);\r
154             }\r
155         }\r
156         return Futures.transform(futureTenant,\r
157                 new Function<Optional<Tenant>, RpcResult<GetSubjectsBetweenEndpointGroupsOutput>>() {\r
158 \r
159                     @Override\r
160                     public RpcResult<GetSubjectsBetweenEndpointGroupsOutput> apply(Optional<Tenant> potentialTenant) {\r
161                         GetSubjectsBetweenEndpointGroupsOutputBuilder outputBuilder = new GetSubjectsBetweenEndpointGroupsOutputBuilder();\r
162                         if (!potentialTenant.isPresent()) {\r
163                             LOG.trace(\r
164                                     "No tenant with id {} in {} datastore",\r
165                                     tenantId.getValue(),\r
166                                     fromOperData == null ? LogicalDatastoreType.CONFIGURATION : LogicalDatastoreType.OPERATIONAL);\r
167                             return RpcResultBuilder.success(outputBuilder.build()).build();\r
168                         }\r
169 \r
170                         Tenant tenant = potentialTenant.get();\r
171                         Table<EgKey, EgKey, Policy> resolvedPolicy = PolicyResolverUtils.resolvePolicy(ImmutableSet.of(new IndexedTenant(\r
172                                 tenant)));\r
173                         List<EndpointGroupPairWithSubject> epgPairsWithSubjects = new ArrayList<>();\r
174                         for (Cell<EgKey, EgKey, Policy> policyByConsProvEpg : resolvedPolicy.cellSet()) {\r
175                             Policy policy = policyByConsProvEpg.getValue();\r
176                             List<RuleGroup> subjects = getUniqueSortedSubjects(policy);\r
177                             List<UiSubject> uiSubjects = new ArrayList<>();\r
178                             for (RuleGroup subject : subjects) {\r
179                                 UiSubject uiSubject = new UiSubjectBuilder().setName(subject.getRelatedSubject())\r
180                                     .setOrder(subject.getOrder())\r
181                                     .setUiRule(getUiRules(subject.getRules()))\r
182                                     .build();\r
183                                 uiSubjects.add(uiSubject);\r
184                             }\r
185                             EgKey consEgKey = policyByConsProvEpg.getRowKey();\r
186                             EgKey provEgKey = policyByConsProvEpg.getColumnKey();\r
187                             LOG.trace(\r
188                                     "Resolved policies from {} datastore: \nConsumer EPG: {}\nProvider EPG: {}\nPolicy: {}",\r
189                                     fromOperData == null ? LogicalDatastoreType.CONFIGURATION : LogicalDatastoreType.OPERATIONAL,\r
190                                     consEgKey, provEgKey, policy);\r
191                             EndpointGroupPairWithSubject epgPairWithSubject = new EndpointGroupPairWithSubjectBuilder().setConsumerEndpointGroupId(\r
192                                     consEgKey.getEgId())\r
193                                 .setConsumerTenantId(consEgKey.getTenantId())\r
194                                 .setProviderEndpointGroupId(provEgKey.getEgId())\r
195                                 .setProviderTenantId(provEgKey.getTenantId())\r
196                                 .setUiSubject(uiSubjects)\r
197                                 .build();\r
198                             epgPairsWithSubjects.add(epgPairWithSubject);\r
199                         }\r
200                         GetSubjectsBetweenEndpointGroupsOutput result = outputBuilder.setEndpointGroupPairWithSubject(\r
201                                 epgPairsWithSubjects).build();\r
202                         return RpcResultBuilder.success(result).build();\r
203                     }\r
204                 });\r
205     }\r
206 \r
207     private List<RuleGroup> getUniqueSortedSubjects(Policy policy) {\r
208         Set<RuleGroup> uniqueSubjects = new HashSet<>();\r
209         for (List<RuleGroup> subjects : policy.getRuleMap().values()) {\r
210             for (RuleGroup subject : subjects) {\r
211                 uniqueSubjects.add(subject);\r
212             }\r
213         }\r
214         ArrayList<RuleGroup> sortedSubjects = new ArrayList<>(uniqueSubjects);\r
215         Collections.sort(sortedSubjects);\r
216         return sortedSubjects;\r
217     }\r
218 \r
219     private List<UiRule> getUiRules(List<Rule> rules) {\r
220         if (rules == null) {\r
221             return Collections.emptyList();\r
222         }\r
223         List<UiRule> uiRules = new ArrayList<>();\r
224         for (Rule rule : rules) {\r
225             UiRule uiRule = new UiRuleBuilder().setName(rule.getName())\r
226                 .setOrder(rule.getOrder())\r
227                 .setClassifierRef(rule.getClassifierRef())\r
228                 .setActionRef(rule.getActionRef())\r
229                 .build();\r
230             uiRules.add(uiRule);\r
231         }\r
232         return uiRules;\r
233     }\r
234 \r
235     /**\r
236      * @see java.lang.AutoCloseable#close()\r
237      */\r
238     @Override\r
239     public void close() throws Exception {\r
240         rpcRegistration.close();\r
241     }\r
242 \r
243 }\r