<generated.yang.docs>${project.build.directory}/site/models</generated.yang.docs>
<config.version>0.3.0-SNAPSHOT</config.version>
<mdsal.version>1.2.0-SNAPSHOT</mdsal.version>
+ <restconf.version>1.2.0-SNAPSHOT</restconf.version>
<yangtools.version>0.7.0-SNAPSHOT</yangtools.version>
<openflowplugin.version>0.1.0-SNAPSHOT</openflowplugin.version>
<neutron.version>0.5.0-SNAPSHOT</neutron.version>
<artifactId>neutron-mapper</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>ui-backend</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- Yangtools and Controller infrastructure -->
<dependency>
<config.groupbasedpolicy.opflexconfigfile>15-groupbasedpolicy-opflex.xml</config.groupbasedpolicy.opflexconfigfile>
<config.groupbasedpolicy.openstackendpointconfigfile>15-groupbasedpolicy-openstackendpoint.xml</config.groupbasedpolicy.openstackendpointconfigfile>
<config.groupbasedpolicy.neutronmapperconfigfile>15-neutron-mapper.xml</config.groupbasedpolicy.neutronmapperconfigfile>
+ <config.groupbasedpolicy.uibackendconfigfile>15-ui-backend.xml</config.groupbasedpolicy.uibackendconfigfile>
</properties>
<dependencies>
<groupId>org.opendaylight.groupbasedpolicy</groupId>
<artifactId>neutron-mapper</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>ui-backend</artifactId>
+ </dependency>
<!-- gbp configuration dependencies -->
<dependency>
<type>xml</type>
<classifier>config</classifier>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>ui-backend-config</artifactId>
+ <version>${project.version}</version>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </dependency>
<!-- testing dependencies -->
<dependency>
<!-- Repos needed by the Neutron Mapper -->
<repository>mvn:org.opendaylight.neutron/features-neutron/${neutron.version}/xml/features</repository>
+ <!-- Repos needed by the UI Backend -->
+ <repository>mvn:org.opendaylight.controller/features-restconf/${restconf.version}/xml/features</repository>
+
<!-- The common GBP components -->
<feature name='odl-groupbasedpolicy-base' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: Base Copmonents'>
<feature version="${mdsal.version}">odl-mdsal-broker</feature>
<configfile finalname="${config.configfile.directory}/${config.groupbasedpolicy.openstackendpointconfigfile}">mvn:org.opendaylight.groupbasedpolicy/groupbasedpolicy-openstackendpoint-config/${project.version}/xml/config</configfile>
</feature>
-
<!--
The Neutron provider
-->
<bundle>mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/${project.version}</bundle>
<configfile finalname="${config.configfile.directory}/${config.groupbasedpolicy.neutronmapperconfigfile}">mvn:org.opendaylight.groupbasedpolicy/neutron-mapper-config/${project.version}/xml/config</configfile>
</feature>
+
+ <!--
+ The UI Backend
+ -->
+ <feature name='odl-groupbasedpolicy-uibackend' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: UI Backend provides APIs for UI '>
+ <feature version="${mdsal.version}">odl-mdsal-broker</feature>
+ <feature version="${project.version}">odl-groupbasedpolicy-base</feature>
+ <feature version="${restconf.version}">odl-restconf</feature>
+ <bundle>mvn:org.opendaylight.groupbasedpolicy/ui-backend/${project.version}</bundle>
+ <configfile finalname="${config.configfile.directory}/${config.groupbasedpolicy.uibackendconfigfile}">mvn:org.opendaylight.groupbasedpolicy/ui-backend-config/${project.version}/xml/config</configfile>
+ </feature>
</features>
--- /dev/null
+package org.opendaylight.groupbasedpolicy.resolver;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import javax.annotation.concurrent.Immutable;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ConsumerSelectionRelator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ProviderSelectionRelator;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.target.selector.QualityMatcher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Target;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerTargetSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelector;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderTargetSelector;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
+
+
+public class ContractResolverUtils {
+
+ private ContractResolverUtils() {
+ throw new UnsupportedOperationException("Cannot create an instance");
+ }
+
+ /**
+ * Choose the contracts that are in scope for each pair of endpoint groups,
+ * then perform subject selection for the pair
+ */
+ protected static Table<EgKey, EgKey, List<ContractMatch>> selectContracts(Set<IndexedTenant> tenants) {
+ Table<TenantId, ContractId, List<ConsumerContractMatch>> consumerMatches = HashBasedTable.create();
+ Table<EgKey, EgKey, List<ContractMatch>> contractMatches = HashBasedTable.create();
+
+ for (IndexedTenant tenant : tenants) {
+ selectContracts(consumerMatches, contractMatches, tenant.getTenant());
+ }
+ return contractMatches;
+ }
+
+ protected static void selectContracts(Table<TenantId, ContractId, List<ConsumerContractMatch>> consumerMatches,
+ Table<EgKey, EgKey, List<ContractMatch>> contractMatches, Tenant tenant) {
+ // For each endpoint group, match consumer selectors
+ // against contracts to get a set of matching consumer selectors
+ if (tenant.getEndpointGroup() == null)
+ return;
+ for (EndpointGroup group : tenant.getEndpointGroup()) {
+ List<ConsumerContractMatch> r = matchConsumerContracts(tenant, group);
+ for (ConsumerContractMatch ccm : r) {
+ List<ConsumerContractMatch> cms = consumerMatches.get(tenant.getId(), ccm.contract.getId());
+ if (cms == null) {
+ cms = new ArrayList<>();
+ consumerMatches.put(tenant.getId(), ccm.contract.getId(), cms);
+ }
+ cms.add(ccm);
+ }
+ }
+
+ // Match provider selectors, and check each match for a corresponding
+ // consumer selector match.
+ for (EndpointGroup group : tenant.getEndpointGroup()) {
+ List<ContractMatch> matches = matchProviderContracts(tenant, group, consumerMatches);
+ for (ContractMatch cm : matches) {
+ EgKey consumerKey = new EgKey(cm.consumerTenant.getId(), cm.consumer.getId());
+ EgKey providerKey = new EgKey(cm.providerTenant.getId(), cm.provider.getId());
+ List<ContractMatch> egPairMatches = contractMatches.get(consumerKey, providerKey);
+ if (egPairMatches == null) {
+ egPairMatches = new ArrayList<>();
+ contractMatches.put(consumerKey, providerKey, egPairMatches);
+ }
+
+ egPairMatches.add(cm);
+ }
+ }
+ }
+
+ private static List<ConsumerContractMatch> matchConsumerContracts(Tenant tenant,
+ EndpointGroup consumer) {
+ List<ConsumerContractMatch> matches = new ArrayList<>();
+ if (consumer.getConsumerNamedSelector() != null) {
+ for (ConsumerNamedSelector cns : consumer.getConsumerNamedSelector()) {
+ if (cns.getContract() == null)
+ continue;
+ for (ContractId contractId : cns.getContract()) {
+ Contract contract =
+ TenantUtils.findContract(tenant, contractId);
+ if (contract == null)
+ continue;
+ matches.add(new ConsumerContractMatch(tenant, contract,
+ tenant, consumer,
+ cns));
+ }
+ }
+ }
+ if (consumer.getConsumerTargetSelector() != null) {
+ for (ConsumerTargetSelector cts : consumer.getConsumerTargetSelector()) {
+ if (tenant.getContract() == null)
+ continue;
+ for (Contract contract : tenant.getContract()) {
+ if (contract.getTarget() == null)
+ continue;
+ for (Target t : contract.getTarget()) {
+ boolean match = true;
+ if (cts.getQualityMatcher() != null) {
+ for (QualityMatcher m : cts.getQualityMatcher()) {
+ if (!MatcherUtils.applyQualityMatcher(m, t)) {
+ match = false;
+ break;
+ }
+ }
+ }
+ if (match) {
+ matches.add(new ConsumerContractMatch(tenant,
+ contract,
+ tenant,
+ consumer,
+ cts));
+ }
+ }
+ }
+ }
+ }
+ // TODO match selectors also against contract references
+ // for (ConsumerTargetSelector cts :
+ // consumer.getConsumerTargetSelector()) {
+ // if (tenant.getContractRef() == null) continue;
+ // for (ContractRef c : tenant.getContractRef()) {
+ //
+ // }
+ // }
+ return matches;
+ }
+
+ private static List<ContractMatch> matchProviderContracts(Tenant tenant, EndpointGroup provider,
+ Table<TenantId, ContractId, List<ConsumerContractMatch>> consumerMatches) {
+ List<ContractMatch> matches = new ArrayList<>();
+ if (provider.getProviderNamedSelector() != null) {
+ for (ProviderNamedSelector pns : provider.getProviderNamedSelector()) {
+ if (pns.getContract() == null)
+ continue;
+ for (ContractId contractId : pns.getContract()) {
+ Contract c = TenantUtils.findContract(tenant, contractId);
+ if (c == null)
+ continue;
+ List<ConsumerContractMatch> cMatches = consumerMatches.get(tenant.getId(), c.getId());
+ amendContractMatches(matches, cMatches, tenant, provider, pns);
+ }
+ }
+ }
+ if (provider.getProviderTargetSelector() != null) {
+ for (ProviderTargetSelector pts : provider.getProviderTargetSelector()) {
+ if (tenant.getContract() == null)
+ continue;
+ for (Contract c : tenant.getContract()) {
+ if (c.getTarget() == null)
+ continue;
+ for (Target t : c.getTarget()) {
+ boolean match = true;
+ if (pts.getQualityMatcher() != null) {
+ for (QualityMatcher m : pts.getQualityMatcher()) {
+ if (!MatcherUtils.applyQualityMatcher(m, t)) {
+ match = false;
+ break;
+ }
+ }
+ }
+ if (match) {
+ List<ConsumerContractMatch> cMatches = consumerMatches.get(tenant.getId(), c.getId());
+ amendContractMatches(matches, cMatches, tenant, provider, pts);
+
+ }
+ }
+ }
+ }
+ }
+ return matches;
+ }
+
+ private static void amendContractMatches(List<ContractMatch> matches,
+ List<ConsumerContractMatch> cMatches,
+ Tenant tenant, EndpointGroup provider,
+ ProviderSelectionRelator relator) {
+ if (cMatches == null)
+ return;
+ for (ConsumerContractMatch cMatch : cMatches) {
+ matches.add(new ContractMatch(cMatch, tenant, provider, relator));
+ }
+ }
+
+ /**
+ * Represents a selected contract made by endpoint groups matching it using
+ * selection relators. This is the result of the contract selection phase.
+ *
+ * @author readams
+ */
+ @Immutable
+ protected static class ContractMatch extends ConsumerContractMatch {
+
+ /**
+ * The tenant ID of the provider endpoint group
+ */
+ final Tenant providerTenant;
+
+ /**
+ * The provider endpoint group
+ */
+ final EndpointGroup provider;
+
+ /**
+ * The provider selection relator that was used to match the contract
+ */
+ final ProviderSelectionRelator providerRelator;
+
+ public ContractMatch(ConsumerContractMatch consumerMatch, Tenant providerTenant, EndpointGroup provider,
+ ProviderSelectionRelator providerRelator) {
+ super(consumerMatch.contractTenant, consumerMatch.contract, consumerMatch.consumerTenant,
+ consumerMatch.consumer, consumerMatch.consumerRelator);
+ this.providerTenant = providerTenant;
+ this.provider = provider;
+ this.providerRelator = providerRelator;
+ }
+ }
+
+ @Immutable
+ protected static class ConsumerContractMatch {
+
+ /**
+ * The tenant of the matching contract
+ */
+ final Tenant contractTenant;
+
+ /**
+ * The matching contract
+ */
+ final Contract contract;
+
+ /**
+ * The tenant for the endpoint group
+ */
+ final Tenant consumerTenant;
+
+ /**
+ * The consumer endpoint group
+ */
+ final EndpointGroup consumer;
+
+ /**
+ * The consumer selection relator that was used to match the contract
+ */
+ final ConsumerSelectionRelator consumerRelator;
+
+ public ConsumerContractMatch(Tenant contractTenant, Contract contract, Tenant consumerTenant,
+ EndpointGroup consumer, ConsumerSelectionRelator consumerRelator) {
+ super();
+ this.contractTenant = contractTenant;
+ this.contract = contract;
+ this.consumerTenant = consumerTenant;
+ this.consumer = consumer;
+ this.consumerRelator = consumerRelator;
+ }
+ }
+
+}
package org.opendaylight.groupbasedpolicy.resolver;
-import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ConsumerSelectionRelator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.ProviderSelectionRelator;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.target.selector.QualityMatcher;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Target;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.GroupIdentificationConstraints;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.group.identification.constraints.GroupRequirementConstraintCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.group.identification.constraints.group.requirement.constraint._case.RequirementMatcher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.group.identification.constraints.GroupCapabilityConstraintCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.group.identification.constraints.group.capability.constraint._case.CapabilityMatcher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerNamedSelector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ConsumerTargetSelector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderNamedSelector;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.endpoint.group.ProviderTargetSelector;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Ordering;
import com.google.common.collect.Sets;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;
protected void updatePolicy() {
try {
Map<EgKey, Set<ConditionSet>> egConditions = new HashMap<>();
- Table<EgKey, EgKey, Policy> policyMap =
- resolvePolicy(resolvedTenants.values(),
- egConditions);
- Set<EgKey> updatedGroups =
- updatePolicy(policyMap,
- egConditions,
- policyListenerScopes);
+ Set<IndexedTenant> indexedTenants = getIndexedTenants(resolvedTenants.values());
+ Table<EgKey, EgKey, Policy> policyMap = PolicyResolverUtils.resolvePolicy(indexedTenants, egConditions);
+ Set<EgKey> updatedGroups = updatePolicy(policyMap, egConditions, policyListenerScopes);
notifyListeners(updatedGroups);
} catch (Exception e) {
}
}
- /**
- * Resolve the policy in three phases: (1) select contracts that in scope
- * based on contract selectors. (2) select subjects that are in scope for
- * each contract based on matchers in clauses (3) resolve the set of
- * in-scope contracts into a list of subjects that apply for each pair of
- * endpoint groups and the conditions that can apply for for each endpoint
- * in those groups.
- */
- protected Table<EgKey, EgKey, Policy>
- resolvePolicy(Collection<TenantContext> tenants,
- Map<EgKey, Set<ConditionSet>> egConditions) {
- // select contracts that apply for the given tenant
- Table<EgKey, EgKey, List<ContractMatch>> contractMatches =
- selectContracts(tenants);
-
- // select subjects for the matching contracts and resolve the policy
- // for endpoint group pairs. This does phase (2) and (3) as one step
- return selectSubjects(contractMatches, egConditions);
- }
-
- /**
- * Choose the contracts that are in scope for each pair of endpoint groups,
- * then perform subject selection for the pair
- */
- protected Table<EgKey, EgKey, List<ContractMatch>>
- selectContracts(Collection<TenantContext> tenants) {
- Table<TenantId, ContractId, List<ConsumerContractMatch>> consumerMatches =
- HashBasedTable.create();
- Table<EgKey, EgKey, List<ContractMatch>> contractMatches =
- HashBasedTable.create();
-
- for (TenantContext tenant : tenants) {
+ private Set<IndexedTenant> getIndexedTenants(Collection<TenantContext> tenantCtxs) {
+ Set<IndexedTenant> result = new HashSet<>();
+ for (TenantContext tenant : tenantCtxs) {
IndexedTenant t = tenant.tenant.get();
- if (t == null)
- continue;
- selectContracts(consumerMatches,
- contractMatches,
- t.getTenant());
- }
- return contractMatches;
- }
-
- protected void selectContracts(Table<TenantId,
- ContractId,
- List<ConsumerContractMatch>> consumerMatches,
- Table<EgKey, EgKey,
- List<ContractMatch>> contractMatches,
- Tenant tenant) {
- // For each endpoint group, match consumer selectors
- // against contracts to get a set of matching consumer selectors
- if (tenant.getEndpointGroup() == null)
- return;
- for (EndpointGroup group : tenant.getEndpointGroup()) {
- List<ConsumerContractMatch> r =
- matchConsumerContracts(tenant, group);
- for (ConsumerContractMatch ccm : r) {
- List<ConsumerContractMatch> cms =
- consumerMatches.get(tenant.getId(),
- ccm.contract.getId());
- if (cms == null) {
- cms = new ArrayList<>();
- consumerMatches.put(tenant.getId(),
- ccm.contract.getId(), cms);
- }
- cms.add(ccm);
- }
- }
-
- // Match provider selectors, and check each match for a corresponding
- // consumer selector match.
- for (EndpointGroup group : tenant.getEndpointGroup()) {
- List<ContractMatch> matches =
- matchProviderContracts(tenant, group, consumerMatches);
- for (ContractMatch cm : matches) {
- EgKey consumerKey = new EgKey(cm.consumerTenant.getId(),
- cm.consumer.getId());
- EgKey providerKey = new EgKey(cm.providerTenant.getId(),
- cm.provider.getId());
- List<ContractMatch> egPairMatches =
- contractMatches.get(consumerKey, providerKey);
- if (egPairMatches == null) {
- egPairMatches = new ArrayList<>();
- contractMatches.put(consumerKey, providerKey,
- egPairMatches);
- }
-
- egPairMatches.add(cm);
- }
- }
- }
-
- private boolean clauseMatchesByGroupReqAndCapConstraints(Clause clause, ContractMatch match) {
- if (clause.getConsumerMatchers() != null) {
- GroupIdentificationConstraints groupIdentificationConstraintsConsumer = clause.getConsumerMatchers()
- .getGroupIdentificationConstraints();
- if (groupIdentificationConstraintsConsumer instanceof GroupRequirementConstraintCase) {
- List<RequirementMatcher> reqMatchers = ((GroupRequirementConstraintCase) groupIdentificationConstraintsConsumer)
- .getRequirementMatcher();
- if (reqMatchers != null) {
- for (RequirementMatcher reqMatcher : reqMatchers) {
- if (!MatcherUtils.applyReqMatcher(reqMatcher,
- match.consumerRelator)) {
- return false;
- }
- }
- }
- }
- }
- if (clause.getProviderMatchers() != null) {
- org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.GroupIdentificationConstraints groupIdentificationConstraintsProvider = clause
- .getProviderMatchers().getGroupIdentificationConstraints();
- if (groupIdentificationConstraintsProvider instanceof GroupCapabilityConstraintCase) {
- List<CapabilityMatcher> capMatchers = ((GroupCapabilityConstraintCase) groupIdentificationConstraintsProvider)
- .getCapabilityMatcher();
-
- if (capMatchers != null) {
- for (CapabilityMatcher capMatcher : capMatchers) {
- if (!MatcherUtils.applyCapMatcher(capMatcher,
- match.providerRelator)) {
- return false;
- }
- }
- }
- }
+ if (t != null)
+ result.add(t);
}
- return true;
- }
-
- private ConditionSet buildConditionSet(List<ConditionMatcher> condMatchers) {
- if (condMatchers == null)
- return ConditionSet.EMPTY;
-
- ImmutableSet.Builder<ConditionName> allb = ImmutableSet.builder();
- ImmutableSet.Builder<ConditionName> noneb = ImmutableSet.builder();
- ImmutableSet.Builder<Set<ConditionName>> anyb =
- ImmutableSet.builder();
- for (ConditionMatcher condMatcher : condMatchers) {
- if (condMatcher.getCondition() == null)
- continue;
- MatchType type = condMatcher.getMatchType();
- if (type == null)
- type = MatchType.All;
- if (type.equals(MatchType.Any)) {
- ImmutableSet.Builder<ConditionName> a =
- ImmutableSet.builder();
- for (Condition c : condMatcher.getCondition()) {
- a.add(c.getName());
- }
- anyb.add(a.build());
- } else {
- for (Condition c : condMatcher.getCondition()) {
- switch (type) {
- case Any:
- break;
- case None:
- noneb.add(c.getName());
- break;
- case All:
- default:
- allb.add(c.getName());
- break;
- }
- }
- }
- }
- return new ConditionSet(allb.build(), noneb.build(), anyb.build());
- }
-
- private ConditionSet buildConsConditionSet(Clause clause) {
- if (clause.getConsumerMatchers() != null) {
- List<ConditionMatcher> condMatchers =
- clause.getConsumerMatchers().getConditionMatcher();
- return buildConditionSet(condMatchers);
- }
- return ConditionSet.EMPTY;
- }
-
- private ConditionSet buildProvConditionSet(Clause clause) {
- if (clause.getProviderMatchers() != null) {
- List<ConditionMatcher> condMatchers =
- clause.getProviderMatchers().getConditionMatcher();
- return buildConditionSet(condMatchers);
- }
- return ConditionSet.EMPTY;
- }
-
- private Policy resolvePolicy(Tenant contractTenant,
- Contract contract,
- Policy merge,
- Table<ConditionSet, ConditionSet,
- List<Subject>> subjectMap) {
- Table<ConditionSet, ConditionSet, List<RuleGroup>> ruleMap =
- HashBasedTable.create();
- if (merge != null) {
- ruleMap.putAll(merge.getRuleMap());
- }
- for (Cell<ConditionSet, ConditionSet, List<Subject>> entry : subjectMap.cellSet()) {
- List<RuleGroup> rules = new ArrayList<>();
- ConditionSet consConds = entry.getRowKey();
- ConditionSet provConds = entry.getColumnKey();
- List<RuleGroup> oldrules = ruleMap.get(consConds, provConds);
- if (oldrules != null) {
- rules.addAll(oldrules);
- }
- for (Subject s : entry.getValue()) {
- if (s.getRule() == null)
- continue;
-
- RuleGroup rg = new RuleGroup(s.getRule(), s.getOrder(),
- contractTenant, contract,
- s.getName());
- rules.add(rg);
- }
- Collections.sort(rules);
- ruleMap.put(consConds, provConds, Collections.unmodifiableList(rules));
- }
- return new Policy(ruleMap);
- }
-
- /**
- * Get the "natural" direction for the policy for the given pair of endpoint
- * groups.
- *
- * @param one
- * The first endpoint group
- * @param two
- * The second endpoint group
- * @return true if the order should be reversed in the index
- */
- protected static boolean shouldReverse(EgKey one, EgKey two) {
- if (one.compareTo(two) < 0) {
- return true;
- }
- return false;
- }
-
- private void addConditionSet(EgKey eg, ConditionSet cs,
- Map<EgKey, Set<ConditionSet>> egConditions) {
- if (egConditions == null)
- return;
- Set<ConditionSet> cset = egConditions.get(eg);
- if (cset == null) {
- egConditions.put(eg, cset = new HashSet<>());
- }
- cset.add(cs);
- }
-
- /**
- * Choose the set of subjects that in scope for each possible set of
- * endpoint conditions
- */
- // TODO Li msunal do we really need contractMatches to be a type Table<EgKey, EgKey, List<ContractMatch>>
- // it should be sufficient to be just List<ContractMatch>
- protected Table<EgKey, EgKey, Policy>
- selectSubjects(Table<EgKey, EgKey,
- List<ContractMatch>> contractMatches,
- Map<EgKey, Set<ConditionSet>> egConditions) {
- // TODO: Note that it's possible to further simplify the resulting
- // policy
- // in the case of things like repeated rules, condition sets that
- // cover other condition sets, etc. This would be a good thing to do
- // at some point
- Table<EgKey, EgKey, Policy> policy = HashBasedTable.create();
-
- for (List<ContractMatch> matches : contractMatches.values()) {
- for (ContractMatch match : matches) {
- List<Clause> clauses = match.contract.getClause();
- if (clauses == null)
- continue;
-
- List<Subject> subjectList = match.contract.getSubject();
- if (subjectList == null)
- continue;
-
- EgKey ckey = new EgKey(match.consumerTenant.getId(),
- match.consumer.getId());
- EgKey pkey = new EgKey(match.providerTenant.getId(),
- match.provider.getId());
- Policy existing = policy.get(ckey, pkey);
-
- HashMap<SubjectName, Subject> subjects = new HashMap<>();
- for (Subject s : subjectList) {
- subjects.put(s.getName(), s);
- }
-
- Table<ConditionSet, ConditionSet, List<Subject>> subjectMap =
- HashBasedTable.create();
-
- for (Clause clause : clauses) {
- if (clause.getSubjectRefs() != null &&
- clauseMatchesByGroupReqAndCapConstraints(clause, match)) {
- ConditionSet consCSet = buildConsConditionSet(clause);
- addConditionSet(ckey, consCSet, egConditions);
- ConditionSet provCSet = buildProvConditionSet(clause);
- addConditionSet(pkey, provCSet, egConditions);
- List<Subject> clauseSubjects =
- subjectMap.get(consCSet, provCSet);
- if (clauseSubjects == null) {
- clauseSubjects = new ArrayList<>();
- subjectMap.put(consCSet, provCSet, clauseSubjects);
- }
- for (SubjectName sn : clause.getSubjectRefs()) {
- Subject s = subjects.get(sn);
- if (s != null)
- clauseSubjects.add(s);
- }
- }
- }
-
- policy.put(ckey, pkey,
- resolvePolicy(match.contractTenant,
- match.contract,
- existing,
- subjectMap));
- }
- }
-
- return policy;
- }
-
- private List<ConsumerContractMatch> matchConsumerContracts(Tenant tenant,
- EndpointGroup consumer) {
- List<ConsumerContractMatch> matches = new ArrayList<>();
- if (consumer.getConsumerNamedSelector() != null) {
- for (ConsumerNamedSelector cns : consumer.getConsumerNamedSelector()) {
- if (cns.getContract() == null)
- continue;
- for (ContractId contractId : cns.getContract()) {
- Contract contract =
- TenantUtils.findContract(tenant, contractId);
- if (contract == null)
- continue;
- matches.add(new ConsumerContractMatch(tenant, contract,
- tenant, consumer,
- cns));
- }
- }
- }
- if (consumer.getConsumerTargetSelector() != null) {
- for (ConsumerTargetSelector cts : consumer.getConsumerTargetSelector()) {
- if (tenant.getContract() == null)
- continue;
- for (Contract contract : tenant.getContract()) {
- if (contract.getTarget() == null)
- continue;
- for (Target t : contract.getTarget()) {
- boolean match = true;
- if (cts.getQualityMatcher() != null) {
- for (QualityMatcher m : cts.getQualityMatcher()) {
- if (!MatcherUtils.applyQualityMatcher(m, t)) {
- match = false;
- break;
- }
- }
- }
- if (match) {
- matches.add(new ConsumerContractMatch(tenant,
- contract,
- tenant,
- consumer,
- cts));
- }
- }
- }
- }
- }
- // TODO match selectors also against contract references
- // for (ConsumerTargetSelector cts :
- // consumer.getConsumerTargetSelector()) {
- // if (tenant.getContractRef() == null) continue;
- // for (ContractRef c : tenant.getContractRef()) {
- //
- // }
- // }
- return matches;
- }
-
- private void amendContractMatches(List<ContractMatch> matches,
- List<ConsumerContractMatch> cMatches,
- Tenant tenant, EndpointGroup provider,
- ProviderSelectionRelator relator) {
- if (cMatches == null)
- return;
- for (ConsumerContractMatch cMatch : cMatches) {
- matches.add(new ContractMatch(cMatch, tenant, provider, relator));
- }
- }
-
- private List<ContractMatch>
- matchProviderContracts(Tenant tenant, EndpointGroup provider,
- Table<TenantId,
- ContractId,
- List<ConsumerContractMatch>> consumerMatches) {
- List<ContractMatch> matches = new ArrayList<>();
- if (provider.getProviderNamedSelector() != null) {
- for (ProviderNamedSelector pns : provider.getProviderNamedSelector()) {
- if (pns.getContract() == null)
- continue;
- for (ContractId contractId : pns.getContract()) {
- Contract c = TenantUtils.findContract(tenant, contractId);
- if (c == null)
- continue;
- List<ConsumerContractMatch> cMatches =
- consumerMatches.get(tenant.getId(), c.getId());
- amendContractMatches(matches, cMatches, tenant, provider, pns);
- }
- }
- }
- if (provider.getProviderTargetSelector() != null) {
- for (ProviderTargetSelector pts : provider.getProviderTargetSelector()) {
- if (tenant.getContract() == null)
- continue;
- for (Contract c : tenant.getContract()) {
- if (c.getTarget() == null)
- continue;
- for (Target t : c.getTarget()) {
- boolean match = true;
- if (pts.getQualityMatcher() != null) {
- for (QualityMatcher m : pts.getQualityMatcher()) {
- if (!MatcherUtils.applyQualityMatcher(m, t)) {
- match = false;
- break;
- }
- }
- }
- if (match) {
- List<ConsumerContractMatch> cMatches =
- consumerMatches.get(tenant.getId(),
- c.getId());
- amendContractMatches(matches, cMatches, tenant,
- provider, pts);
-
- }
- }
- }
- }
- }
- return matches;
+ return result;
}
protected static class TenantContext {
}
}
- /**
- * Represents a selected contract made by endpoint groups matching it using
- * selection relators. This is the result of the contract selection phase.
- *
- * @author readams
- *
- */
- @Immutable
- protected static class ContractMatch extends ConsumerContractMatch {
- /**
- * The tenant ID of the provider endpoint group
- */
- final Tenant providerTenant;
-
- /**
- * The provider endpoint group
- */
- final EndpointGroup provider;
-
- /**
- * The provider selection relator that was used to match the contract
- */
- final ProviderSelectionRelator providerRelator;
-
- public ContractMatch(ConsumerContractMatch consumerMatch,
- Tenant providerTenant, EndpointGroup provider,
- ProviderSelectionRelator providerRelator) {
- super(consumerMatch.contractTenant,
- consumerMatch.contract,
- consumerMatch.consumerTenant,
- consumerMatch.consumer,
- consumerMatch.consumerRelator);
- this.providerTenant = providerTenant;
- this.provider = provider;
- this.providerRelator = providerRelator;
- }
- }
-
- @Immutable
- private static class ConsumerContractMatch {
- /**
- * The tenant of the matching contract
- */
- final Tenant contractTenant;
-
- /**
- * The matching contract
- */
- final Contract contract;
-
- /**
- * The tenant for the endpoint group
- */
- final Tenant consumerTenant;
-
- /**
- * The consumer endpoint group
- */
- final EndpointGroup consumer;
-
- /**
- * The consumer selection relator that was used to match the contract
- */
- final ConsumerSelectionRelator consumerRelator;
-
- public ConsumerContractMatch(Tenant contractTenant,
- Contract contract,
- Tenant consumerTenant,
- EndpointGroup consumer,
- ConsumerSelectionRelator consumerRelator) {
- super();
- this.contractTenant = contractTenant;
- this.contract = contract;
- this.consumerTenant = consumerTenant;
- this.consumer = consumer;
- this.consumerRelator = consumerRelator;
- }
- }
-
@Immutable
private class PolicyChangeListener implements DataChangeListener {
final TenantId tenantId;
--- /dev/null
+package org.opendaylight.groupbasedpolicy.resolver;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.groupbasedpolicy.resolver.ContractResolverUtils.ContractMatch;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Table;
+
+public class PolicyResolverUtils {
+
+ private PolicyResolverUtils() {
+ throw new UnsupportedOperationException("Cannot create an instance");
+ }
+
+ /**
+ * Resolve the policy in three phases: <br>
+ * (1) select contracts that in scope based on contract selectors. <br>
+ * (2) select subjects that are in scope for each contract based on matchers in clauses <br>
+ * (3) resolve the set of in-scope contracts into a list of subjects that apply for each pair of
+ * endpoint groups and the conditions that can apply for for each endpoint in those groups.
+ */
+ public static Table<EgKey, EgKey, Policy> resolvePolicy(Set<IndexedTenant> tenants) {
+ return resolvePolicy(tenants, new HashMap<EgKey, Set<ConditionSet>>());
+ }
+
+ /**
+ * Resolve the policy in three phases: <br>
+ * (1) select contracts that in scope based on contract selectors. <br>
+ * (2) select subjects that are in scope for each contract based on matchers in clauses <br>
+ * (3) resolve the set of in-scope contracts into a list of subjects that apply for each pair of
+ * endpoint groups and the conditions that can apply for for each endpoint in those groups.
+ */
+ protected static Table<EgKey, EgKey, Policy> resolvePolicy(Set<IndexedTenant> tenants,
+ Map<EgKey, Set<ConditionSet>> egConditions) {
+ Preconditions.checkNotNull(tenants);
+ Preconditions.checkNotNull(egConditions);
+ // select contracts that apply for the given tenant
+ Table<EgKey, EgKey, List<ContractMatch>> contractMatches = ContractResolverUtils.selectContracts(tenants);
+
+ // select subjects for the matching contracts and resolve the policy
+ // for endpoint group pairs. This does phase (2) and (3) as one step
+ return SubjectResolverUtils.selectSubjects(contractMatches, egConditions);
+ }
+
+}
--- /dev/null
+package org.opendaylight.groupbasedpolicy.resolver;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.groupbasedpolicy.resolver.ContractResolverUtils.ContractMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher.MatchType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.condition.matchers.ConditionMatcher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.conditions.Condition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Subject;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.GroupIdentificationConstraints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.group.identification.constraints.GroupRequirementConstraintCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.consumer.matchers.group.identification.constraints.group.requirement.constraint._case.RequirementMatcher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.group.identification.constraints.GroupCapabilityConstraintCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.group.identification.constraints.group.capability.constraint._case.CapabilityMatcher;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Table;
+import com.google.common.collect.Table.Cell;
+
+
+public class SubjectResolverUtils {
+
+ private SubjectResolverUtils() {
+ throw new UnsupportedOperationException("Cannot create an instance");
+ }
+
+ /**
+ * Choose the set of subjects that in scope for each possible set of
+ * endpoint conditions
+ */
+ // TODO Li msunal do we really need contractMatches to be a type Table<EgKey, EgKey, List<ContractMatch>>
+ // it should be sufficient to be just List<ContractMatch>
+ protected static Table<EgKey, EgKey, Policy> selectSubjects(
+ Table<EgKey, EgKey, List<ContractMatch>> contractMatches, Map<EgKey, Set<ConditionSet>> egConditions) {
+ // TODO: Note that it's possible to further simplify the resulting
+ // policy
+ // in the case of things like repeated rules, condition sets that
+ // cover other condition sets, etc. This would be a good thing to do
+ // at some point
+ Table<EgKey, EgKey, Policy> policy = HashBasedTable.create();
+
+ for (List<ContractMatch> matches : contractMatches.values()) {
+ for (ContractMatch match : matches) {
+ List<Clause> clauses = match.contract.getClause();
+ if (clauses == null)
+ continue;
+
+ List<Subject> subjectList = match.contract.getSubject();
+ if (subjectList == null)
+ continue;
+
+ EgKey ckey = new EgKey(match.consumerTenant.getId(),
+ match.consumer.getId());
+ EgKey pkey = new EgKey(match.providerTenant.getId(),
+ match.provider.getId());
+ Policy existing = policy.get(ckey, pkey);
+
+ HashMap<SubjectName, Subject> subjects = new HashMap<>();
+ for (Subject s : subjectList) {
+ subjects.put(s.getName(), s);
+ }
+
+ Table<ConditionSet, ConditionSet, List<Subject>> subjectMap =
+ HashBasedTable.create();
+
+ for (Clause clause : clauses) {
+ if (clause.getSubjectRefs() != null &&
+ clauseMatchesByGroupReqAndCapConstraints(clause, match)) {
+ ConditionSet consCSet = buildConsConditionSet(clause);
+ addConditionSet(ckey, consCSet, egConditions);
+ ConditionSet provCSet = buildProvConditionSet(clause);
+ addConditionSet(pkey, provCSet, egConditions);
+ List<Subject> clauseSubjects =
+ subjectMap.get(consCSet, provCSet);
+ if (clauseSubjects == null) {
+ clauseSubjects = new ArrayList<>();
+ subjectMap.put(consCSet, provCSet, clauseSubjects);
+ }
+ for (SubjectName sn : clause.getSubjectRefs()) {
+ Subject s = subjects.get(sn);
+ if (s != null)
+ clauseSubjects.add(s);
+ }
+ }
+ }
+
+ policy.put(ckey, pkey,
+ resolvePolicy(match.contractTenant,
+ match.contract,
+ existing,
+ subjectMap));
+ }
+ }
+
+ return policy;
+ }
+
+ private static boolean clauseMatchesByGroupReqAndCapConstraints(Clause clause, ContractMatch match) {
+ if (clause.getConsumerMatchers() != null) {
+ GroupIdentificationConstraints groupIdentificationConstraintsConsumer = clause.getConsumerMatchers()
+ .getGroupIdentificationConstraints();
+ if (groupIdentificationConstraintsConsumer instanceof GroupRequirementConstraintCase) {
+ List<RequirementMatcher> reqMatchers = ((GroupRequirementConstraintCase) groupIdentificationConstraintsConsumer)
+ .getRequirementMatcher();
+ if (reqMatchers != null) {
+ for (RequirementMatcher reqMatcher : reqMatchers) {
+ if (!MatcherUtils.applyReqMatcher(reqMatcher,
+ match.consumerRelator)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ if (clause.getProviderMatchers() != null) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.provider.matchers.GroupIdentificationConstraints groupIdentificationConstraintsProvider = clause
+ .getProviderMatchers().getGroupIdentificationConstraints();
+ if (groupIdentificationConstraintsProvider instanceof GroupCapabilityConstraintCase) {
+ List<CapabilityMatcher> capMatchers = ((GroupCapabilityConstraintCase) groupIdentificationConstraintsProvider)
+ .getCapabilityMatcher();
+
+ if (capMatchers != null) {
+ for (CapabilityMatcher capMatcher : capMatchers) {
+ if (!MatcherUtils.applyCapMatcher(capMatcher,
+ match.providerRelator)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ private static void addConditionSet(EgKey eg, ConditionSet cs,
+ Map<EgKey, Set<ConditionSet>> egConditions) {
+ if (egConditions == null)
+ return;
+ Set<ConditionSet> cset = egConditions.get(eg);
+ if (cset == null) {
+ egConditions.put(eg, cset = new HashSet<>());
+ }
+ cset.add(cs);
+ }
+
+ private static ConditionSet buildConsConditionSet(Clause clause) {
+ if (clause.getConsumerMatchers() != null) {
+ List<ConditionMatcher> condMatchers =
+ clause.getConsumerMatchers().getConditionMatcher();
+ return buildConditionSet(condMatchers);
+ }
+ return ConditionSet.EMPTY;
+ }
+
+ private static ConditionSet buildProvConditionSet(Clause clause) {
+ if (clause.getProviderMatchers() != null) {
+ List<ConditionMatcher> condMatchers =
+ clause.getProviderMatchers().getConditionMatcher();
+ return buildConditionSet(condMatchers);
+ }
+ return ConditionSet.EMPTY;
+ }
+
+ private static ConditionSet buildConditionSet(List<ConditionMatcher> condMatchers) {
+ if (condMatchers == null)
+ return ConditionSet.EMPTY;
+
+ ImmutableSet.Builder<ConditionName> allb = ImmutableSet.builder();
+ ImmutableSet.Builder<ConditionName> noneb = ImmutableSet.builder();
+ ImmutableSet.Builder<Set<ConditionName>> anyb =
+ ImmutableSet.builder();
+ for (ConditionMatcher condMatcher : condMatchers) {
+ if (condMatcher.getCondition() == null)
+ continue;
+ MatchType type = condMatcher.getMatchType();
+ if (type == null)
+ type = MatchType.All;
+ if (type.equals(MatchType.Any)) {
+ ImmutableSet.Builder<ConditionName> a =
+ ImmutableSet.builder();
+ for (Condition c : condMatcher.getCondition()) {
+ a.add(c.getName());
+ }
+ anyb.add(a.build());
+ } else {
+ for (Condition c : condMatcher.getCondition()) {
+ switch (type) {
+ case Any:
+ break;
+ case None:
+ noneb.add(c.getName());
+ break;
+ case All:
+ default:
+ allb.add(c.getName());
+ break;
+ }
+ }
+ }
+ }
+ return new ConditionSet(allb.build(), noneb.build(), anyb.build());
+ }
+
+ private static Policy resolvePolicy(Tenant contractTenant,
+ Contract contract,
+ Policy merge,
+ Table<ConditionSet, ConditionSet,
+ List<Subject>> subjectMap) {
+ Table<ConditionSet, ConditionSet, List<RuleGroup>> ruleMap =
+ HashBasedTable.create();
+ if (merge != null) {
+ ruleMap.putAll(merge.getRuleMap());
+ }
+ for (Cell<ConditionSet, ConditionSet, List<Subject>> entry : subjectMap.cellSet()) {
+ List<RuleGroup> rules = new ArrayList<>();
+ ConditionSet consConds = entry.getRowKey();
+ ConditionSet provConds = entry.getColumnKey();
+ List<RuleGroup> oldrules = ruleMap.get(consConds, provConds);
+ if (oldrules != null) {
+ rules.addAll(oldrules);
+ }
+ for (Subject s : entry.getValue()) {
+ if (s.getRule() == null)
+ continue;
+
+ RuleGroup rg = new RuleGroup(s.getRule(), s.getOrder(),
+ contractTenant, contract,
+ s.getName());
+ rules.add(rg);
+ }
+ Collections.sort(rules);
+ ruleMap.put(consConds, provConds, Collections.unmodifiableList(rules));
+ }
+ return new Policy(ruleMap);
+ }
+}
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver.ContractMatch;
+import org.opendaylight.groupbasedpolicy.resolver.ContractResolverUtils.ContractMatch;
import org.opendaylight.groupbasedpolicy.resolver.PolicyResolver.TenantContext;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.CapabilityMatcherName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.CapabilityName;
public void testContractSelection() throws Exception {
// named selectors
TenantContext tc = new TenantContext(null);
- Collection<TenantContext> tCol = Collections.singleton(tc);
tc.tenant.set(new IndexedTenant(tenant1));
Table<EgKey, EgKey, List<ContractMatch>> contractMatches =
- resolver.selectContracts(tCol);
+ ContractResolverUtils.selectContracts(ImmutableSet.of(tc.tenant.get()));
assertEquals(1, contractMatches.size());
List<ContractMatch> matches =
contractMatches.get(new EgKey(tenant1.getId(), eg1.getId()),
tc.tenant.set(new IndexedTenant(tenant2));
- contractMatches = resolver.selectContracts(tCol);
+ contractMatches = ContractResolverUtils.selectContracts(ImmutableSet.of(tc.tenant.get()));
assertEquals(2, contractMatches.size());
matches = contractMatches.get(new EgKey(tenant2.getId(), eg1.getId()),
new EgKey(tenant2.getId(), eg2.getId()));
// target selectors
tc.tenant.set(new IndexedTenant(tenant3));
- contractMatches = resolver.selectContracts(tCol);
+ contractMatches = ContractResolverUtils.selectContracts(ImmutableSet.of(tc.tenant.get()));
assertEquals(1, contractMatches.size());
matches = contractMatches.get(new EgKey(tenant3.getId(), eg4.getId()),
new EgKey(tenant3.getId(), eg5.getId()));
// empty matches
tc.tenant.set(new IndexedTenant(tenant0));
- contractMatches = resolver.selectContracts(tCol);
+ contractMatches = ContractResolverUtils.selectContracts(ImmutableSet.of(tc.tenant.get()));
assertEquals(0, contractMatches.size());
tc.tenant.set(new IndexedTenant(tenant00));
- contractMatches = resolver.selectContracts(tCol);
+ contractMatches = ContractResolverUtils.selectContracts(ImmutableSet.of(tc.tenant.get()));
assertEquals(0, contractMatches.size());
}
ImmutableSet.of(ImmutableSet.of(cond1.getName(),
cond2.getName())));
TenantContext tc = new TenantContext(null);
- Collection<TenantContext> tCol = Collections.singleton(tc);
tc.tenant.set(new IndexedTenant(tenant1));
Table<EgKey, EgKey, List<ContractMatch>> contractMatches =
- resolver.selectContracts(tCol);
+ ContractResolverUtils.selectContracts(ImmutableSet.of(tc.tenant.get()));
Map<EgKey, Set<ConditionSet>> egConditions = new HashMap<>();
Table<EgKey, EgKey, Policy> policy =
- resolver.selectSubjects(contractMatches, egConditions);
+ SubjectResolverUtils.selectSubjects(contractMatches, egConditions);
assertEquals(1, policy.size());
Policy p = policy.get(new EgKey(tenant1.getId(), eg1.getId()), new EgKey(tenant1.getId(), eg2.getId()));
List<RuleGroup> rules = p.getRuleMap().get(cs, ConditionSet.EMPTY);
assertEquals(rule1.getName(), rg.rules.get(0).getName());
tc.tenant.set(new IndexedTenant(tenant2));
- contractMatches = resolver.selectContracts(tCol);
+ contractMatches = ContractResolverUtils.selectContracts(ImmutableSet.of(tc.tenant.get()));
egConditions = new HashMap<>();
- policy = resolver.selectSubjects(contractMatches, egConditions);
+ policy = SubjectResolverUtils.selectSubjects(contractMatches, egConditions);
assertEquals(2, policy.size());
p = policy.get(new EgKey(tenant2.getId(), eg3.getId()),
assertEquals(rule1.getName(), rg.rules.get(0).getName());
tc.tenant.set(new IndexedTenant(tenant3));
- contractMatches = resolver.selectContracts(tCol);
+ contractMatches = ContractResolverUtils.selectContracts(ImmutableSet.of(tc.tenant.get()));
egConditions = new HashMap<>();
- policy = resolver.selectSubjects(contractMatches, egConditions);
+ policy = SubjectResolverUtils.selectSubjects(contractMatches, egConditions);
assertEquals(1, policy.size());
p = policy.get(new EgKey(tenant3.getId(), eg4.getId()),
<!-- Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ and is available at http://www.eclipse.org/legal/epl-v10.html --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<module>groupbasedpolicy-openstackendpoint-config</module>
<module>neutron-mapper</module>
<module>neutron-mapper-config</module>
+ <module>ui-backend</module>
+ <module>ui-backend-config</module>
<module>distribution-karaf</module>
<module>features</module>
</modules>
<tag>HEAD</tag>
<url>https://wiki.opendaylight.org/view/Group_Policy:Main</url>
</scm>
-</project>
+</project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>commons.groupbasedpolicy</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ <relativePath>../commons/parent</relativePath>
+ </parent>
+
+ <artifactId>ui-backend-config</artifactId>
+ <description>Controller Configuration files for ui-backend</description>
+ <packaging>jar</packaging>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/initial/15-ui-backend.xml</file>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.\r
+\r
+ This program and the accompanying materials are made available under the\r
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ and is available at http://www.eclipse.org/legal/epl-v10.html\r
+-->\r
+<snapshot>\r
+ <configuration>\r
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\r
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">\r
+ <module>\r
+ <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:config:ui-backend:impl">\r
+ binding-impl:ui-backend-impl\r
+ </type>\r
+ <name>ui-backend-impl</name>\r
+\r
+ <data-broker>\r
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">\r
+ binding:binding-async-data-broker\r
+ </type>\r
+ <name>binding-data-broker</name>\r
+ </data-broker>\r
+\r
+ <rpc-registry>\r
+ <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">\r
+ binding:binding-rpc-registry\r
+ </type>\r
+ <name>binding-rpc-broker</name>\r
+ </rpc-registry>\r
+ </module>\r
+ </modules>\r
+ </data>\r
+ </configuration>\r
+\r
+ <required-capabilities>\r
+ <capability>urn:opendaylight:params:xml:ns:yang:controller:config:ui-backend:impl?module=ui-backend-impl&revision=2015-05-11\r
+ </capability>\r
+ </required-capabilities>\r
+</snapshot>\r
--- /dev/null
+<?xml version="1.0"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>groupbasedpolicy.project</artifactId>
+ <version>0.2.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>ui-backend</artifactId>
+ <packaging>bundle</packaging>
+
+ <!-- project build -->
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Export-Package>
+ </Export-Package>
+ </instructions>
+ <manifestLocation>${project.basedir}/META-INF</manifestLocation>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <redirectTestOutputToFile>true</redirectTestOutputToFile>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.groupbasedpolicy</groupId>
+ <artifactId>groupbasedpolicy</artifactId>
+ </dependency>
+
+ <!-- controller dependencies -->
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-config</artifactId>
+ </dependency>
+ </dependencies>
+</project>
--- /dev/null
+package org.opendaylight.controller.config.yang.config.ui_backend.impl;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.groupbasedpolicy.ui.backend.UiBackendServiceImpl;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Preconditions;
+
+public class UiBackendModule extends org.opendaylight.controller.config.yang.config.ui_backend.impl.AbstractUiBackendModule {
+
+ private static final Logger LOG = LoggerFactory.getLogger(UiBackendModule.class);
+
+ public UiBackendModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public UiBackendModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.ui_backend.impl.UiBackendModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public void customValidation() {
+ // add custom validation form module attributes here.
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ DataBroker dataProvider = Preconditions.checkNotNull(getDataBrokerDependency());
+ final UiBackendServiceImpl pgnApplicationService = new UiBackendServiceImpl(dataProvider,
+ getRpcRegistryDependency());
+ LOG.info("ui-backend started.");
+
+ return new AutoCloseable() {
+
+ @Override
+ public void close() throws Exception {
+ pgnApplicationService.close();
+ }
+ };
+ }
+
+}
--- /dev/null
+/*
+* Generated file
+*
+* Generated from: yang module name: ui-backend-impl yang module local name: ui-backend-impl
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Mon May 11 01:23:43 CEST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.controller.config.yang.config.ui_backend.impl;
+public class UiBackendModuleFactory extends org.opendaylight.controller.config.yang.config.ui_backend.impl.AbstractUiBackendModuleFactory {
+
+}
--- /dev/null
+/*\r
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.ui.backend;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.concurrent.Future;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;\r
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;\r
+import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;\r
+import org.opendaylight.groupbasedpolicy.resolver.EgKey;\r
+import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;\r
+import org.opendaylight.groupbasedpolicy.resolver.Policy;\r
+import org.opendaylight.groupbasedpolicy.resolver.PolicyResolverUtils;\r
+import org.opendaylight.groupbasedpolicy.resolver.RuleGroup;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupOutput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupOutputBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsOutput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsOutputBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.UiBackendService;\r
+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
+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
+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
+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
+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
+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
+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
+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
+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
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.yangtools.yang.common.RpcResult;\r
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.base.Function;\r
+import com.google.common.base.Optional;\r
+import com.google.common.base.Preconditions;\r
+import com.google.common.collect.ImmutableSet;\r
+import com.google.common.collect.Table;\r
+import com.google.common.collect.Table.Cell;\r
+import com.google.common.util.concurrent.CheckedFuture;\r
+import com.google.common.util.concurrent.Futures;\r
+\r
+public class UiBackendServiceImpl implements UiBackendService, AutoCloseable {\r
+\r
+ private static final Logger LOG = LoggerFactory.getLogger(UiBackendServiceImpl.class);\r
+\r
+ private final DataBroker dataProvider;\r
+ private final BindingAwareBroker.RpcRegistration<UiBackendService> rpcRegistration;\r
+ private final InstanceIdentifier<Endpoints> ENDPOINTS_IID = InstanceIdentifier.builder(Endpoints.class).build();\r
+\r
+ public UiBackendServiceImpl(DataBroker dataBroker, RpcProviderRegistry rpcRegistry) {\r
+ Preconditions.checkNotNull(dataBroker);\r
+ Preconditions.checkNotNull(rpcRegistry);\r
+ this.dataProvider = dataBroker;\r
+ rpcRegistration = rpcRegistry.addRpcImplementation(UiBackendService.class, this);\r
+ }\r
+\r
+ @Override\r
+ public Future<RpcResult<GetEndpointsFromEndpointGroupOutput>> getEndpointsFromEndpointGroup(\r
+ GetEndpointsFromEndpointGroupInput input) {\r
+ LOG.trace("getEndpointsFromEndpointGroup: {}", input);\r
+ final TenantId tenantId = input.getTenantId();\r
+ if (tenantId == null) {\r
+ throw new IllegalArgumentException("Missing tenant-Id in RPC input.");\r
+ }\r
+ final EndpointGroupId epgId = input.getEndpointGroupId();\r
+ if (epgId == null) {\r
+ throw new IllegalArgumentException("Missing endpoint-group-id in RPC input.");\r
+ }\r
+ ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();\r
+ CheckedFuture<Optional<Endpoints>, ReadFailedException> futureEndpoints = rTx.read(\r
+ LogicalDatastoreType.OPERATIONAL, ENDPOINTS_IID);\r
+ return Futures.transform(futureEndpoints,\r
+ new Function<Optional<Endpoints>, RpcResult<GetEndpointsFromEndpointGroupOutput>>() {\r
+\r
+ @Override\r
+ public RpcResult<GetEndpointsFromEndpointGroupOutput> apply(Optional<Endpoints> potentialEndpoints) {\r
+ GetEndpointsFromEndpointGroupOutputBuilder outputBuilder = new GetEndpointsFromEndpointGroupOutputBuilder();\r
+ if (!potentialEndpoints.isPresent() || potentialEndpoints.get().getEndpoint() == null) {\r
+ LOG.trace("No endpoint in datastore.");\r
+ return RpcResultBuilder.success(outputBuilder.build()).build();\r
+ }\r
+\r
+ List<Endpoint> endpoints = potentialEndpoints.get().getEndpoint();\r
+ List<UiEndpoint> uiEndpoints = new ArrayList<>();\r
+ for (Endpoint ep : endpoints) {\r
+ if (tenantId.equals(ep.getTenant()) && isEpInEpg(ep, epgId)) {\r
+ uiEndpoints.add(new UiEndpointBuilder(ep).build());\r
+ }\r
+ }\r
+ outputBuilder.setUiEndpoint(uiEndpoints);\r
+ return RpcResultBuilder.success(outputBuilder.build()).build();\r
+ }\r
+ });\r
+ }\r
+\r
+ private boolean isEpInEpg(Endpoint ep, EndpointGroupId epgId) {\r
+ if (epgId.equals(ep.getEndpointGroup())) {\r
+ return true;\r
+ }\r
+ if (ep.getEndpointGroups() != null) {\r
+ for (EndpointGroupId epgFromEp : ep.getEndpointGroups()) {\r
+ if (epgId.equals(epgFromEp)) {\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ return false;\r
+ }\r
+\r
+ @Override\r
+ public Future<RpcResult<GetSubjectsBetweenEndpointGroupsOutput>> getSubjectsBetweenEndpointGroups(\r
+ GetSubjectsBetweenEndpointGroupsInput input) {\r
+ LOG.trace("getSubjectsBetweenEndpointGroups: {}", input);\r
+ final TenantId tenantId = input.getTenantId();\r
+ if (tenantId == null) {\r
+ throw new IllegalArgumentException("Missing tenant-Id in RPC input.");\r
+ }\r
+ final FromOperData fromOperData = input.getFromOperData();\r
+ InstanceIdentifier<Tenant> tenantIid = InstanceIdentifier.builder(Tenants.class)\r
+ .child(Tenant.class, new TenantKey(tenantId))\r
+ .build();\r
+ CheckedFuture<Optional<Tenant>, ReadFailedException> futureTenant;\r
+ try (ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction()) {\r
+ if (fromOperData == null) {\r
+ futureTenant = rTx.read(LogicalDatastoreType.CONFIGURATION, tenantIid);\r
+ } else {\r
+ futureTenant = rTx.read(LogicalDatastoreType.OPERATIONAL, tenantIid);\r
+ }\r
+ }\r
+ return Futures.transform(futureTenant,\r
+ new Function<Optional<Tenant>, RpcResult<GetSubjectsBetweenEndpointGroupsOutput>>() {\r
+\r
+ @Override\r
+ public RpcResult<GetSubjectsBetweenEndpointGroupsOutput> apply(Optional<Tenant> potentialTenant) {\r
+ GetSubjectsBetweenEndpointGroupsOutputBuilder outputBuilder = new GetSubjectsBetweenEndpointGroupsOutputBuilder();\r
+ if (!potentialTenant.isPresent()) {\r
+ LOG.trace(\r
+ "No tenant with id {} in {} datastore",\r
+ tenantId.getValue(),\r
+ fromOperData == null ? LogicalDatastoreType.CONFIGURATION : LogicalDatastoreType.OPERATIONAL);\r
+ return RpcResultBuilder.success(outputBuilder.build()).build();\r
+ }\r
+\r
+ Tenant tenant = potentialTenant.get();\r
+ Table<EgKey, EgKey, Policy> resolvedPolicy = PolicyResolverUtils.resolvePolicy(ImmutableSet.of(new IndexedTenant(\r
+ tenant)));\r
+ List<EndpointGroupPairWithSubject> epgPairsWithSubjects = new ArrayList<>();\r
+ for (Cell<EgKey, EgKey, Policy> policyByConsProvEpg : resolvedPolicy.cellSet()) {\r
+ Policy policy = policyByConsProvEpg.getValue();\r
+ List<RuleGroup> subjects = getUniqueSortedSubjects(policy);\r
+ List<UiSubject> uiSubjects = new ArrayList<>();\r
+ for (RuleGroup subject : subjects) {\r
+ UiSubject uiSubject = new UiSubjectBuilder().setName(subject.getRelatedSubject())\r
+ .setOrder(subject.getOrder())\r
+ .setUiRule(getUiRules(subject.getRules()))\r
+ .build();\r
+ uiSubjects.add(uiSubject);\r
+ }\r
+ EgKey consEgKey = policyByConsProvEpg.getRowKey();\r
+ EgKey provEgKey = policyByConsProvEpg.getColumnKey();\r
+ LOG.trace(\r
+ "Resolved policies from {} datastore: \nConsumer EPG: {}\nProvider EPG: {}\nPolicy: {}",\r
+ fromOperData == null ? LogicalDatastoreType.CONFIGURATION : LogicalDatastoreType.OPERATIONAL,\r
+ consEgKey, provEgKey, policy);\r
+ EndpointGroupPairWithSubject epgPairWithSubject = new EndpointGroupPairWithSubjectBuilder().setConsumerEndpointGroupId(\r
+ consEgKey.getEgId())\r
+ .setConsumerTenantId(consEgKey.getTenantId())\r
+ .setProviderEndpointGroupId(provEgKey.getEgId())\r
+ .setProviderTenantId(provEgKey.getTenantId())\r
+ .setUiSubject(uiSubjects)\r
+ .build();\r
+ epgPairsWithSubjects.add(epgPairWithSubject);\r
+ }\r
+ GetSubjectsBetweenEndpointGroupsOutput result = outputBuilder.setEndpointGroupPairWithSubject(\r
+ epgPairsWithSubjects).build();\r
+ return RpcResultBuilder.success(result).build();\r
+ }\r
+ });\r
+ }\r
+\r
+ private List<RuleGroup> getUniqueSortedSubjects(Policy policy) {\r
+ Set<RuleGroup> uniqueSubjects = new HashSet<>();\r
+ for (List<RuleGroup> subjects : policy.getRuleMap().values()) {\r
+ for (RuleGroup subject : subjects) {\r
+ uniqueSubjects.add(subject);\r
+ }\r
+ }\r
+ ArrayList<RuleGroup> sortedSubjects = new ArrayList<>(uniqueSubjects);\r
+ Collections.sort(sortedSubjects);\r
+ return sortedSubjects;\r
+ }\r
+\r
+ private List<UiRule> getUiRules(List<Rule> rules) {\r
+ if (rules == null) {\r
+ return Collections.emptyList();\r
+ }\r
+ List<UiRule> uiRules = new ArrayList<>();\r
+ for (Rule rule : rules) {\r
+ UiRule uiRule = new UiRuleBuilder().setName(rule.getName())\r
+ .setOrder(rule.getOrder())\r
+ .setClassifierRef(rule.getClassifierRef())\r
+ .setActionRef(rule.getActionRef())\r
+ .build();\r
+ uiRules.add(uiRule);\r
+ }\r
+ return uiRules;\r
+ }\r
+\r
+ /**\r
+ * @see java.lang.AutoCloseable#close()\r
+ */\r
+ @Override\r
+ public void close() throws Exception {\r
+ rpcRegistration.close();\r
+ }\r
+\r
+}\r
--- /dev/null
+module ui-backend-impl {
+
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:ui-backend:impl";
+ prefix "ui-backend-impl";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+
+ description
+ "This module contains the base YANG definitions for
+ ui-backend implementation.";
+
+ revision "2015-05-11" {
+ description
+ "Initial revision.";
+ }
+
+ // This is the definition of the service implementation as a module identity.
+ identity ui-backend-impl {
+ base config:module-type;
+
+ // Specifies the prefix for generated java classes.
+ config:java-name-prefix UiBackend;
+ }
+
+ // Augments the 'configuration' choice node under modules/module.
+ augment "/config:modules/config:module/config:configuration" {
+ case ui-backend-impl {
+ when "/config:modules/config:module/config:type = 'ui-backend-impl'";
+
+ container data-broker {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-async-data-broker;
+ }
+ }
+ }
+
+ container rpc-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity mdsal:binding-rpc-registry;
+ }
+ }
+ }
+
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+module ui-backend {\r
+ namespace "urn:opendaylight:params:xml:ns:yang:controller:config:ui-backend";\r
+ prefix "ui-backend";\r
+\r
+ import policy {prefix gbp-policy;}\r
+ import gbp-common {prefix gbp-common;}\r
+ import endpoint {prefix endpoint;}\r
+\r
+ description\r
+ "Module contains RPC definitions for more easier interaction of the GUI with the GBP APIs.";\r
+\r
+ revision "2015-05-11" {\r
+ description "Initial revision of ui-backend model";\r
+ }\r
+\r
+ grouping endpoint-group-identifier-fields {\r
+ leaf tenant-id {\r
+ type gbp-common:tenant-id;\r
+ }\r
+ leaf endpoint-group-id {\r
+ type gbp-common:endpoint-group-id;\r
+ }\r
+ }\r
+\r
+ grouping consumer-endpoint-group-ref {\r
+ leaf consumer-tenant-id {\r
+ type leafref {\r
+ path "/gbp-policy:tenants/gbp-policy:tenant/gbp-policy:id";\r
+ }\r
+ }\r
+ leaf consumer-endpoint-group-id {\r
+ type leafref {\r
+ path "/gbp-policy:tenants/gbp-policy:tenant/gbp-policy:endpoint-group/gbp-policy:id";\r
+ }\r
+ }\r
+ }\r
+\r
+ grouping provider-endpoint-group-ref {\r
+ leaf provider-tenant-id {\r
+ type leafref {\r
+ path "/gbp-policy:tenants/gbp-policy:tenant/gbp-policy:id";\r
+ }\r
+ }\r
+ leaf provider-endpoint-group-id {\r
+ type leafref {\r
+ path "/gbp-policy:tenants/gbp-policy:tenant/gbp-policy:endpoint-group/gbp-policy:id";\r
+ }\r
+ }\r
+ }\r
+\r
+ rpc get-endpoints-from-endpoint-group {\r
+ description "Returns endpoints which are in the given endpoint group.";\r
+ input {\r
+ uses endpoint-group-identifier-fields;\r
+ }\r
+ output {\r
+ list ui-endpoint {\r
+ description\r
+ "Endpoints indexed by layer 2 addreses.";\r
+ key "l2-context mac-address";\r
+ uses endpoint:endpoint-fields;\r
+ }\r
+ }\r
+ }\r
+\r
+ rpc get-subjects-between-endpoint-groups {\r
+ description "Returns subjects between endpoint group pairs where endpoint groups are from the given tenant.";\r
+ input {\r
+ leaf tenant-id {\r
+ description "Tenant ID of the tenant.";\r
+ type gbp-common:tenant-id;\r
+ mandatory true;\r
+ }\r
+ container from-oper-data {\r
+ presence "Resolve subjects for endpoint gorup pairs based on operational data.";\r
+ }\r
+ }\r
+ output {\r
+ list endpoint-group-pair-with-subject {\r
+ key "consumer-endpoint-group-id consumer-tenant-id provider-endpoint-group-id provider-tenant-id";\r
+ uses consumer-endpoint-group-ref;\r
+ uses provider-endpoint-group-ref;\r
+ list ui-subject {\r
+ key "name";\r
+ leaf name {\r
+ description "A name for the subject";\r
+ type gbp-common:subject-name;\r
+ }\r
+ list ui-rule {\r
+ key "name";\r
+ leaf name {\r
+ description "A name for the rule";\r
+ type gbp-common:rule-name;\r
+ }\r
+ uses gbp-policy:has-classifier-refs;\r
+ uses gbp-policy:has-action-refs;\r
+ uses gbp-policy:has-order;\r
+ }\r
+ uses gbp-policy:has-order;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+}\r