<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<!-- project build -->
--- /dev/null
+/*
+ * 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
+ */
+
+package org.opendaylight.groupbasedpolicy.sf;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.ParameterType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.Int;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.Range;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.String;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueInRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported.range.value.fields.SupportedRangeValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported.string.value.fields.SupportedStringValueBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Optional;
+
+public class ClassifierInstanceValidator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ClassifierInstanceValidator.class);
+ private final Map<ParameterName, Optional<ParameterType>> parameterByName = new HashMap<>();
+
+ public ClassifierInstanceValidator(SupportedClassifierDefinition constraint) {
+ for (SupportedParameterValues supportedParams : constraint.getSupportedParameterValues()) {
+ ParameterName parameterName = checkNotNull(supportedParams.getParameterName());
+ ParameterType parameterType = supportedParams.getParameterType();
+ parameterByName.put(parameterName, Optional.fromNullable(parameterType));
+ }
+ }
+
+ public boolean validate(ClassifierInstance ci) {
+ List<ParameterValue> params = ci.getParameterValue();
+ for (ParameterValue param : params) {
+ ParameterName paramName = param.getName();
+ Optional<ParameterType> potentialParamConstraint = parameterByName.get(paramName);
+ if (potentialParamConstraint == null) {
+ LOG.info("Parameter {} with value {} is not supported.", paramName, param);
+ return false;
+ }
+ if (!potentialParamConstraint.isPresent()) {
+ LOG.info("There is no constraint for parameter {}. \nTherefore the parameter is considered as valid.",
+ param);
+ continue;
+ }
+ ParameterType paramConstraint = potentialParamConstraint.get();
+ if (paramConstraint instanceof Int) {
+ boolean paramValid = isParamValid(param, (Int) paramConstraint);
+ if (!paramValid) {
+ LOG.info("Parameter {} with value {} is not valid.", paramName, param);
+ return false;
+ }
+ } else if (paramConstraint instanceof Range) {
+ boolean paramValid = isParamValid(param, (Range) paramConstraint);
+ if (!paramValid) {
+ LOG.info("Parameter {} with value {} is not valid.", paramName, param);
+ return false;
+ }
+ } else if (paramConstraint instanceof String) {
+ boolean paramValid = isParamValid(param, (String) paramConstraint);
+ if (!paramValid) {
+ LOG.info("Parameter {} with value {} is not valid.", paramName, param);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ private boolean isParamValid(ParameterValue param, Int constraint) {
+ Long value = param.getIntValue();
+ if (value == null) {
+ return false;
+ }
+ if (constraint.getSupportedIntValue() != null
+ && constraint.getSupportedIntValue().contains(new SupportedIntValueBuilder().setValue(value).build())) {
+ return true;
+ }
+ List<SupportedIntValueInRange> intRangeValues = constraint.getSupportedIntValueInRange();
+ if (intRangeValues != null) {
+ for (SupportedIntValueInRange supportedValue : intRangeValues) {
+ if (supportedValue.getMin() <= value && supportedValue.getMax() >= value) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isParamValid(ParameterValue param, Range constraint) {
+ RangeValue value = param.getRangeValue();
+ if (value == null) {
+ return false;
+ }
+ List<SupportedRangeValue> intRangeValues = constraint.getSupportedRangeValue();
+ if (intRangeValues != null) {
+ for (SupportedRangeValue supportedValue : intRangeValues) {
+ if (supportedValue.getMin() <= value.getMin() && supportedValue.getMax() >= value.getMax()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean isParamValid(ParameterValue param, String constraint) {
+ java.lang.String value = param.getStringValue();
+ if (value == null) {
+ return false;
+ }
+ if (constraint.getSupportedStringValue() != null && constraint.getSupportedStringValue()
+ .contains(new SupportedStringValueBuilder().setValue(value).build())) {
+ return true;
+ }
+ return false;
+ }
+
+ public Set<ParameterName> getSupportedParameters() {
+ return parameterByName.keySet();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((parameterByName == null) ? 0 : parameterByName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ ClassifierInstanceValidator other = (ClassifierInstanceValidator) obj;
+ if (parameterByName == null) {
+ if (other.parameterByName != null)
+ return false;
+ } else if (!parameterByName.equals(other.parameterByName))
+ return false;
+ return true;
+ }
+
+ @Override
+ public java.lang.String toString() {
+ return "ClassifierInstanceValidator [parameterByName=" + parameterByName + "]";
+ }
+
+}
import org.opendaylight.groupbasedpolicy.sf.classifiers.EtherTypeClassifierDefinition;
import org.opendaylight.groupbasedpolicy.sf.classifiers.IpProtoClassifierDefinition;
import org.opendaylight.groupbasedpolicy.sf.classifiers.L4ClassifierDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
- * On creation, puts known Subject Feature Definitions to operational datastore; deletes them on #close()
+ * On creation, puts known Subject Feature Definitions to config datastore; deletes them on #close()
*/
public class SubjectFeatureDefinitionProvider implements AutoCloseable {
- private static final Logger LOG =
- LoggerFactory.getLogger(SubjectFeatureDefinitionProvider.class);
private final DataBroker dataProvider;
public SubjectFeatureDefinitionProvider(DataBroker dataProvider)
throws TransactionCommitFailedException {
this.dataProvider = dataProvider;
-
putSubjectFeatureDefinitions();
}
private void putSubjectFeatureDefinitions() throws TransactionCommitFailedException {
WriteTransaction wt = this.dataProvider.newWriteOnlyTransaction();
- wt.put(LogicalDatastoreType.OPERATIONAL, EtherTypeClassifierDefinition.IID,
+ wt.put(LogicalDatastoreType.CONFIGURATION, EtherTypeClassifierDefinition.IID,
EtherTypeClassifierDefinition.DEFINITION);
- wt.put(LogicalDatastoreType.OPERATIONAL, IpProtoClassifierDefinition.IID,
+ wt.put(LogicalDatastoreType.CONFIGURATION, IpProtoClassifierDefinition.IID,
IpProtoClassifierDefinition.DEFINITION);
- wt.put(LogicalDatastoreType.OPERATIONAL, L4ClassifierDefinition.IID,
+ wt.put(LogicalDatastoreType.CONFIGURATION, L4ClassifierDefinition.IID,
L4ClassifierDefinition.DEFINITION);
- wt.put(LogicalDatastoreType.OPERATIONAL, AllowActionDefinition.IID,
+ wt.put(LogicalDatastoreType.CONFIGURATION, AllowActionDefinition.IID,
AllowActionDefinition.DEFINITION);
- wt.put(LogicalDatastoreType.OPERATIONAL, ChainActionDefinition.IID,
+ wt.put(LogicalDatastoreType.CONFIGURATION, ChainActionDefinition.IID,
ChainActionDefinition.DEFINITION);
wt.submit().checkedGet();
private void deleteSubjectFeatureDefinitions() throws TransactionCommitFailedException {
WriteTransaction wt = this.dataProvider.newWriteOnlyTransaction();
- wt.delete(LogicalDatastoreType.OPERATIONAL, EtherTypeClassifierDefinition.IID);
- wt.delete(LogicalDatastoreType.OPERATIONAL, IpProtoClassifierDefinition.IID);
- wt.delete(LogicalDatastoreType.OPERATIONAL, L4ClassifierDefinition.IID);
+ wt.delete(LogicalDatastoreType.CONFIGURATION, EtherTypeClassifierDefinition.IID);
+ wt.delete(LogicalDatastoreType.CONFIGURATION, IpProtoClassifierDefinition.IID);
+ wt.delete(LogicalDatastoreType.CONFIGURATION, L4ClassifierDefinition.IID);
- wt.delete(LogicalDatastoreType.OPERATIONAL, AllowActionDefinition.IID);
- wt.delete(LogicalDatastoreType.OPERATIONAL, ChainActionDefinition.IID);
+ wt.delete(LogicalDatastoreType.CONFIGURATION, AllowActionDefinition.IID);
+ wt.delete(LogicalDatastoreType.CONFIGURATION, ChainActionDefinition.IID);
wt.submit().checkedGet();
}
--- /dev/null
+/*
+ * 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
+ */
+
+package org.opendaylight.groupbasedpolicy.sf;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.SetMultimap;
+
+public class SupportedClassifierDefinitionListener
+ implements DataTreeChangeListener<SupportedClassifierDefinition>, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(SupportedClassifierDefinitionListener.class);
+
+ private final DataBroker dataProvider;
+ private final ListenerRegistration<SupportedClassifierDefinitionListener> registration;
+ @VisibleForTesting
+ final SetMultimap<ClassifierDefinitionId, InstanceIdentifier<SupportedClassifierDefinition>> supportedCdIidByCdId =
+ HashMultimap.create();
+ @VisibleForTesting
+ final Map<InstanceIdentifier<SupportedClassifierDefinition>, ClassifierInstanceValidator> ciValidatorBySupportedCdIid =
+ new HashMap<>();
+
+ public SupportedClassifierDefinitionListener(DataBroker dataProvider) {
+ this.dataProvider = checkNotNull(dataProvider);
+ registration =
+ dataProvider.registerDataTreeChangeListener(
+ new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(Renderers.class)
+ .child(Renderer.class)
+ .child(Capabilities.class)
+ .child(SupportedClassifierDefinition.class)
+ .build()),
+ this);
+ }
+
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<SupportedClassifierDefinition>> changes) {
+ for (DataTreeModification<SupportedClassifierDefinition> change : changes) {
+ DataObjectModification<SupportedClassifierDefinition> rootNode = change.getRootNode();
+ InstanceIdentifier<SupportedClassifierDefinition> rootIdentifier = change.getRootPath().getRootIdentifier();
+ switch (rootNode.getModificationType()) {
+ case WRITE:
+ ClassifierDefinitionId classifierDefinitionId = rootNode.getDataAfter().getClassifierDefinitionId();
+ if (containsParameters(rootNode.getDataAfter())) {
+ ClassifierInstanceValidator ciValidator =
+ new ClassifierInstanceValidator(rootNode.getDataAfter());
+ ciValidatorBySupportedCdIid.put(rootIdentifier, ciValidator);
+ // TODO register validator to Policy Resolver service
+ }
+ supportedCdIidByCdId.put(classifierDefinitionId, rootIdentifier);
+ putOrRemoveClassifierDefinitionInOperDs(classifierDefinitionId);
+ break;
+ case DELETE:
+ classifierDefinitionId = rootNode.getDataBefore().getClassifierDefinitionId();
+ // TODO unregister validator from Policy Resolver service
+ supportedCdIidByCdId.remove(classifierDefinitionId, rootIdentifier);
+ ciValidatorBySupportedCdIid.remove(rootIdentifier);
+ putOrRemoveClassifierDefinitionInOperDs(classifierDefinitionId);
+ break;
+ case SUBTREE_MODIFIED:
+ classifierDefinitionId = rootNode.getDataAfter().getClassifierDefinitionId();
+ if (containsParameters(rootNode.getDataAfter())) {
+ ClassifierInstanceValidator ciValidator =
+ new ClassifierInstanceValidator(rootNode.getDataAfter());
+ ClassifierInstanceValidator oldCiValidator =
+ ciValidatorBySupportedCdIid.put(rootIdentifier, ciValidator);
+ // TODO unregister old validator from Policy Resolver service and register
+ // new one
+ }
+ putOrRemoveClassifierDefinitionInOperDs(classifierDefinitionId);
+ break;
+ }
+ }
+ }
+
+ private boolean containsParameters(SupportedClassifierDefinition supportedClassifierDefinition) {
+ return supportedClassifierDefinition.getSupportedParameterValues() != null
+ && !supportedClassifierDefinition.getSupportedParameterValues().isEmpty();
+ }
+
+ private void putOrRemoveClassifierDefinitionInOperDs(ClassifierDefinitionId classifierDefinitionId) {
+ ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+ ClassifierDefinition cd = createClassifierDefinitionWithUnionOfParams(classifierDefinitionId, rwTx);
+ if (cd != null) {
+ rwTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.classifierDefinitionIid(classifierDefinitionId), cd);
+ } else {
+ DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
+ IidFactory.classifierDefinitionIid(classifierDefinitionId), rwTx);
+ }
+ DataStoreHelper.submitToDs(rwTx);
+ }
+
+ @VisibleForTesting
+ ClassifierDefinition createClassifierDefinitionWithUnionOfParams(ClassifierDefinitionId classifierDefinitionId,
+ ReadTransaction rTx) {
+ Optional<ClassifierDefinition> potentialCdFromDs = DataStoreHelper.readFromDs(
+ LogicalDatastoreType.CONFIGURATION, IidFactory.classifierDefinitionIid(classifierDefinitionId), rTx);
+ if (!potentialCdFromDs.isPresent()) {
+ LOG.error("Classifier-definition with ID {} does not exist in CONF datastore.", classifierDefinitionId);
+ return null;
+ }
+ ClassifierDefinition cdFromDs = potentialCdFromDs.get();
+ Set<InstanceIdentifier<SupportedClassifierDefinition>> supportedCdIids =
+ supportedCdIidByCdId.get(classifierDefinitionId);
+ if (supportedCdIids.isEmpty()) {
+ LOG.debug("Classifier-definition with ID {} is not supported by any renderer.", classifierDefinitionId);
+ return null;
+ }
+ if (cdFromDs.getParameter() == null || cdFromDs.getParameter().isEmpty()) {
+ LOG.debug("Classifier-definition with ID {} does not contain any parameter", classifierDefinitionId);
+ return cdFromDs;
+ }
+ List<Parameter> params = new ArrayList<>();
+ for (InstanceIdentifier<SupportedClassifierDefinition> supportedCdIid : supportedCdIids) {
+ ClassifierInstanceValidator ciValidator = ciValidatorBySupportedCdIid.get(supportedCdIid);
+ Set<ParameterName> supportedParams = ciValidator.getSupportedParameters();
+ for (ParameterName supportedParamName : supportedParams) {
+ for (Parameter param : cdFromDs.getParameter()) {
+ if (param.getName().equals(supportedParamName)) {
+ params.add(param);
+ }
+ }
+ }
+ }
+ ClassifierDefinitionBuilder cdBuilder = new ClassifierDefinitionBuilder(cdFromDs);
+ return cdBuilder.setParameter(params).build();
+ }
+
+ @Override
+ public void close() throws Exception {
+ registration.close();
+ }
+
+}
.setDescription(new Description("Allow the specified traffic to pass"))
.build();
- public static final InstanceIdentifier IID =
+ public static final InstanceIdentifier<ActionDefinition> IID =
InstanceIdentifier.builder(SubjectFeatureDefinitions.class)
.child(ActionDefinition.class, DEFINITION.getKey())
.build();
.build())))
.build();
- public static final InstanceIdentifier IID =
+ public static final InstanceIdentifier<ActionDefinition> IID =
InstanceIdentifier.builder(SubjectFeatureDefinitions.class)
.child(ActionDefinition.class, DEFINITION.getKey())
.build();
.build()))
.build();
- public static final InstanceIdentifier IID =
+ public static final InstanceIdentifier<ClassifierDefinition> IID =
InstanceIdentifier.builder(SubjectFeatureDefinitions.class)
.child(ClassifierDefinition.class, DEFINITION.getKey())
.build();
.build()))
.build();
- public static final InstanceIdentifier IID =
+ public static final InstanceIdentifier<ClassifierDefinition> IID =
InstanceIdentifier.builder(SubjectFeatureDefinitions.class)
.child(ClassifierDefinition.class, DEFINITION.getKey())
.build();
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.IsRequired;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter.Type;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.ParameterBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
new ParameterBuilder().setName(new ParameterName(SRC_PORT_PARAM))
.setDescription(new Description("The source port number to match against"))
.setType(Type.Int)
+ .setIsRequired(IsRequired.Optional)
.build(),
new ParameterBuilder().setName(new ParameterName(SRC_PORT_RANGE_PARAM))
.setDescription(new Description("The source port range to match against"))
.setType(Type.Range)
+ .setIsRequired(IsRequired.Optional)
.build(),
new ParameterBuilder().setName(new ParameterName(DST_PORT_PARAM))
.setDescription(new Description("The destination port number to match against"))
.setType(Type.Int)
- .build(), new ParameterBuilder().setName(new ParameterName(DST_PORT_RANGE_PARAM))
+ .setIsRequired(IsRequired.Optional)
+ .build(),
+ new ParameterBuilder().setName(new ParameterName(DST_PORT_RANGE_PARAM))
.setDescription(new Description("The destination port range to match against"))
.setType(Type.Range)
+ .setIsRequired(IsRequired.Optional)
.build()))
.build();
- public static final InstanceIdentifier IID =
+ public static final InstanceIdentifier<ClassifierDefinition> IID =
InstanceIdentifier.builder(SubjectFeatureDefinitions.class)
.child(ClassifierDefinition.class, DEFINITION.getKey())
.build();
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Key;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3Prefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.EndpointL3PrefixKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionKey;
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.TenantKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Contract;
.build();
}
+ public static InstanceIdentifier<ClassifierDefinition> classifierDefinitionIid(
+ ClassifierDefinitionId classifierDefinitionId) {
+ return InstanceIdentifier.builder(SubjectFeatureDefinitions.class)
+ .child(ClassifierDefinition.class, new ClassifierDefinitionKey(classifierDefinitionId))
+ .build();
+ }
+
public static InstanceIdentifier<ClassifierRef> classifierRefIid(TenantId tenantId, ContractId contractId,
SubjectName subjectName, RuleName ruleName, ClassifierName classifierRefName) {
return InstanceIdentifier.builder(Tenants.class)
description "A globally unique identifier";
}
+ typedef unique-id-string {
+ type string {
+ length "1..256";
+ }
+ description "A globally unique identifier (based on String)";
+ }
+
// *************
// Relator names
// *************
// ****************
typedef subject-feature-id {
- type unique-id;
+ type unique-id-string;
description "A unique ID for a parameterized object";
}
// Global Configuration
// ********************
+ grouping classifier-definition-fields {
+ uses subject-feature-definition;
+
+ leaf id {
+ description "A unique ID for the classifier definition";
+ type gbp-common:classifier-definition-id;
+ mandatory true;
+ }
+
+ leaf name {
+ description
+ "A user-visible name for the classifier definition";
+ type gbp-common:classifier-name;
+ }
+ }
+
+ grouping action-definition-fields {
+ uses subject-feature-definition;
+
+ leaf id {
+ description "A unique ID for the action";
+ type gbp-common:action-definition-id;
+ mandatory true;
+ }
+
+ leaf name {
+ description "A user-visible name for the action";
+ type gbp-common:action-name;
+ }
+ }
+
container subject-feature-definitions {
description
"Contains configuration for the set of actions and
references it.";
key "id";
- uses subject-feature-definition;
-
- leaf id {
- description "A unique ID for the classifier definition";
- type gbp-common:classifier-definition-id;
- mandatory true;
- }
-
- leaf name {
- description
- "A user-visible name for the classifier definition";
- type gbp-common:classifier-name;
- }
+ uses classifier-definition-fields;
}
list action-definition {
references it.";
key "id";
- uses subject-feature-definition;
-
- leaf id {
- description "A unique ID for the action";
- type gbp-common:action-definition-id;
- mandatory true;
- }
-
- leaf name {
- description "A user-visible name for the action";
- type gbp-common:action-name;
- }
+ uses action-definition-fields;
}
}
--- /dev/null
+/*
+ * 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
+ */
+
+module renderer {
+ yang-version 1;
+
+ namespace "urn:opendaylight:groupbasedpolicy:renderer";
+ prefix "gbp-renderer";
+
+ import gbp-common {
+ prefix gbp-common;
+ revision-date 2014-04-21;
+ }
+ import policy {
+ prefix policy;
+ revision-date 2014-04-21;
+ }
+ import ietf-inet-types {
+ prefix inet;
+ revision-date 2010-09-24;
+ }
+
+ description
+ "This module defines renderer capabilities.";
+
+ revision "2015-11-03" {
+ description
+ "Initial revision.";
+ }
+
+ typedef renderer-name {
+ type gbp-common:name;
+ description "A name for a renderer";
+ }
+
+ grouping supported-string-value-fields {
+ list supported-string-value {
+ description "String value has to be identical.";
+ key value;
+ leaf value {
+ type string;
+ }
+ }
+ }
+
+ grouping supported-int-value-fields {
+ list supported-int-value {
+ description "Int value has to be identical.";
+ key value;
+ leaf value {
+ type int64;
+ }
+ }
+ list supported-int-value-in-range {
+ description "Int value has to be inside the range include boundaries.";
+ key "min max";
+ leaf min {
+ type int64;
+ }
+ leaf max {
+ type int64;
+ }
+ }
+ }
+
+ grouping supported-range-value-fields {
+ list supported-range-value {
+ description "Min and max values have to be inside the range include boundaries.";
+ key "min max";
+ leaf min {
+ type int64;
+ }
+ leaf max {
+ type int64;
+ }
+ }
+ }
+
+ grouping has-parameters-type {
+ choice parameter-type {
+ case string {
+ uses supported-string-value-fields;
+ }
+ case int {
+ uses supported-int-value-fields;
+ }
+ case range {
+ uses supported-range-value-fields;
+ }
+ }
+ }
+
+ container renderers {
+ description
+ "Leaf containing all renderers' description.";
+
+ config false;
+
+ list renderer {
+ description
+ "A renderer provides a list of capabilities.";
+
+ key name;
+
+ leaf name {
+ description
+ "A user-visible name for the renderer";
+ type renderer-name;
+ }
+
+ container capabilities {
+ description "Capabilities this renderer provides.";
+
+ list supported-classifier-definition {
+ description
+ "Classifier definitions this renderer can use.";
+
+ key classifier-definition-id;
+
+ leaf classifier-definition-id {
+ description "Reference to a classifier definition in config datastore.";
+ type leafref {
+ path "/policy:subject-feature-definitions/policy:classifier-definition/policy:id";
+ }
+ }
+
+ leaf parent-classifier-definition-id {
+ description
+ "Optional reference to a parent classifier definition,
+ to provide a hierarchical structure.";
+ type leafref {
+ path "/policy:subject-feature-definitions/policy:classifier-definition/policy:id";
+ }
+ }
+
+ list supported-parameter-values {
+ description "Represents supported paramters and its values by renderer.
+ If it contains only parameter-name without paramater-type, it means that any value is supported.";
+ key parameter-name;
+
+ leaf parameter-name {
+ description "TODO";
+ type leafref {
+ path "/policy:subject-feature-definitions/policy:classifier-definition/policy:parameter/policy:name";
+ }
+ }
+
+ uses has-parameters-type;
+ }
+ }
+
+ list supported-action-definition {
+ description
+ "Action definitions this renderer can use.";
+
+ key action-definition-id;
+
+ leaf action-definition-id {
+ description "Reference to an action definition in config datastore.";
+ type leafref {
+ path "/policy:subject-feature-definitions/policy:action-definition/policy:id";
+ }
+ }
+
+ leaf parent-action-definition-id {
+ description
+ "Optional reference to a parent action definition,
+ to provide a hierarchical structure.";
+ type leafref {
+ path "/policy:subject-feature-definitions/policy:action-definition/policy:id";
+ }
+ }
+
+ list supported-parameter-values {
+ description "Represents supported paramters and its values by renderer.
+ If it contains only parameter-name without paramater-type, it means that any value is supported.";
+ key parameter-name;
+
+ leaf parameter-name {
+ description "TODO";
+ type leafref {
+ path "/policy:subject-feature-definitions/policy:action-definition/policy:parameter/policy:name";
+ }
+ }
+
+ uses has-parameters-type;
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null
+package org.opendaylight.groupbasedpolicy.sf;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.sf.classifiers.EtherTypeClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.sf.classifiers.L4ClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.test.GbpDataBrokerTest;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinitionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValuesBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import com.google.common.collect.ImmutableList;
+
+public class SupportedClassifierDefinitionListenerTest extends GbpDataBrokerTest {
+
+ private SupportedClassifierDefinitionListener listener;
+
+ @Before
+ public void init() {
+ listener = new SupportedClassifierDefinitionListener(getDataBroker());
+ }
+
+ @Test
+ public void testCreateClassifierDefinitionWithUnionOfParams_allParamsSupportedByRenderer() throws Exception {
+ WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
+ wTx.put(LogicalDatastoreType.CONFIGURATION,
+ IidFactory.classifierDefinitionIid(EtherTypeClassifierDefinition.ID),
+ EtherTypeClassifierDefinition.DEFINITION, true);
+ wTx.submit().get();
+
+ SupportedClassifierDefinition supportedClassifierDefinition = new SupportedClassifierDefinitionBuilder()
+ .setClassifierDefinitionId(EtherTypeClassifierDefinition.ID)
+ .setSupportedParameterValues(
+ ImmutableList.<SupportedParameterValues>of(new SupportedParameterValuesBuilder()
+ .setParameterName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM)).build()))
+ .build();
+ Renderer renderer = createRenderer("renderer1");
+ registerSupportedClassifierDefByRenderer(supportedClassifierDefinition, renderer);
+
+ ClassifierDefinition newCd = listener.createClassifierDefinitionWithUnionOfParams(
+ EtherTypeClassifierDefinition.ID, getDataBroker().newReadOnlyTransaction());
+ Assert.assertEquals(EtherTypeClassifierDefinition.DEFINITION, newCd);
+ }
+
+ @Test
+ public void testCreateClassifierDefinitionWithUnionOfParams_someParamsSupportedByRenderer() throws Exception {
+ WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
+ wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierDefinitionIid(L4ClassifierDefinition.ID),
+ L4ClassifierDefinition.DEFINITION, true);
+ wTx.submit().get();
+
+ SupportedClassifierDefinition supportedClassifierDefinition = new SupportedClassifierDefinitionBuilder()
+ .setClassifierDefinitionId(L4ClassifierDefinition.ID)
+ .setSupportedParameterValues(
+ ImmutableList.<SupportedParameterValues>of(new SupportedParameterValuesBuilder()
+ .setParameterName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM)).build()))
+ .build();
+ Renderer renderer = createRenderer("renderer1");
+ registerSupportedClassifierDefByRenderer(supportedClassifierDefinition, renderer);
+
+ ClassifierDefinition newCd = listener.createClassifierDefinitionWithUnionOfParams(L4ClassifierDefinition.ID,
+ getDataBroker().newReadOnlyTransaction());
+ ClassifierDefinition expectedCd = new ClassifierDefinitionBuilder(L4ClassifierDefinition.DEFINITION)
+ .setParameter(ImmutableList.<Parameter>of(getParameterFromDefinition(L4ClassifierDefinition.DEFINITION,
+ L4ClassifierDefinition.DST_PORT_PARAM)))
+ .build();
+ Assert.assertEquals(expectedCd, newCd);
+ }
+
+ private Renderer createRenderer(String rendererName) {
+ return new RendererBuilder().setName(new RendererName(rendererName)).build();
+ }
+
+ private Parameter getParameterFromDefinition(ClassifierDefinition cd, String parameter) {
+ for (Parameter param : cd.getParameter()) {
+ if (param.getName().getValue().equals(parameter)) {
+ return param;
+ }
+ }
+ throw new IllegalArgumentException("Parameter " + parameter + " is not located in " + cd);
+ }
+
+ private void registerSupportedClassifierDefByRenderer(SupportedClassifierDefinition supportedClassifierDefinition,
+ Renderer renderer) {
+ InstanceIdentifier<SupportedClassifierDefinition> scdIid = InstanceIdentifier.builder(Renderers.class)
+ .child(Renderer.class, renderer.getKey())
+ .child(Capabilities.class)
+ .child(SupportedClassifierDefinition.class, supportedClassifierDefinition.getKey())
+ .build();
+ listener.ciValidatorBySupportedCdIid.put(scdIid,
+ new ClassifierInstanceValidator(supportedClassifierDefinition));
+ listener.supportedCdIidByCdId.put(supportedClassifierDefinition.getClassifierDefinitionId(), scdIid);
+ }
+
+}
--- /dev/null
+/*
+ * 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
+ */
+
+package org.opendaylight.groupbasedpolicy.test;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import javax.annotation.Nonnull;
+
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.yangtools.yang.binding.YangModuleInfo;
+import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ImmutableSet.Builder;
+
+/**
+ * Loads only modules of GBP and it's dependencies for data broker.
+ * <br>
+ * Therefore this implementation is faster than {@link AbstractDataBrokerTest}
+ */
+public abstract class CustomDataBrokerTest extends AbstractDataBrokerTest {
+
+ @Override
+ protected Iterable<YangModuleInfo> getModuleInfos() throws Exception {
+ Builder<YangModuleInfo> moduleInfoSet = ImmutableSet.<YangModuleInfo>builder();
+ for (Class<?> clazz : getClassesFromModules()) {
+ loadModuleInfos(clazz, moduleInfoSet);
+ }
+ return moduleInfoSet.build();
+ }
+
+ /**
+ * @return a class from every yang module which needs to be loaded. Cannot return {@code null}
+ * or empty collection.
+ */
+ public abstract @Nonnull Collection<Class<?>> getClassesFromModules();
+
+ public static void loadModuleInfos(Class<?> clazzFromModule, Builder<YangModuleInfo> moduleInfoSet)
+ throws Exception {
+ YangModuleInfo moduleInfo = BindingReflections.getModuleInfo(clazzFromModule);
+ checkState(moduleInfo != null, "Module Info for %s is not available.", clazzFromModule);
+ collectYangModuleInfo(moduleInfo, moduleInfoSet);
+ }
+
+ private static void collectYangModuleInfo(final YangModuleInfo moduleInfo,
+ final Builder<YangModuleInfo> moduleInfoSet) throws IOException {
+ moduleInfoSet.add(moduleInfo);
+ for (YangModuleInfo dependency : moduleInfo.getImportedModules()) {
+ collectYangModuleInfo(dependency, moduleInfoSet);
+ }
+ }
+}
--- /dev/null
+/*
+ * 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
+ */
+
+package org.opendaylight.groupbasedpolicy.test;
+
+import java.util.Collection;
+
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.ResolvedPolicies;
+
+import com.google.common.collect.ImmutableList;
+
+/**
+ * Loads only modules of GBP and it's dependencies for data broker.
+ * <br>
+ * Therefore this implementation is faster than {@link AbstractDataBrokerTest}
+ */
+public class GbpDataBrokerTest extends CustomDataBrokerTest {
+
+ @Override
+ public Collection<Class<?>> getClassesFromModules() {
+ return ImmutableList.<Class<?>>of(Renderers.class, Tenants.class, Endpoints.class, ResolvedPolicies.class);
+ }
+
+}
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-broker-impl</artifactId>
+ <version>${mdsal.version}</version>
+ <type>test-jar</type>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
<!-- project build -->
</plugin>
</plugins>
</build>
-</project>
\ No newline at end of file
+</project>
+ "Max. table ID would be out of range. Check config-subsystem.\n{}", e);
}
- // TODO this will be writing to capabilities in DS
-// if (dataBroker != null) {
-// WriteTransaction t = dataBroker.newWriteOnlyTransaction();
-// t.put(LogicalDatastoreType.OPERATIONAL,
-// InstanceIdentifier
-// .builder(SubjectFeatureDefinitions.class)
-// .build(),
-// SubjectFeatures.OF_OVERLAY_FEATURES);
-// t.submit();
-// }
+ // TODO write capabilities in DS
for(Entry<ActionDefinitionId, Action> entry : SubjectFeatures.getActions().entrySet()) {
policyResolver.registerActionDefinitions(entry.getKey(), entry.getValue());
/*
* Copyright (c) 2014 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
import java.util.List;
import java.util.Map;
+import com.google.common.base.Strings;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
-
-import com.google.common.base.Strings;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues;
/**
* Represent a classifier definition, and provide tools for generating flow
*
* @return the {@link ClassifierDefinition} for this classifier
*/
- public abstract ClassifierDefinition getClassDef();
+ public abstract ClassifierDefinition getClassifierDefinition();
/**
* @return parent classifier, see {@link Classifier}
} catch (IllegalArgumentException e) {
hasReqParams = false;
}
- if (hasReqParams == true) {
+ if (hasReqParams) {
matchBuilders = parent.update(matchBuilders, params);
updatedClassifiers.add(parent);
}
return new ClassificationResult(matchBuilders);
}
+ public abstract List<SupportedParameterValues> getSupportedParameterValues();
+
/**
* Checks presence of required {@code params} in order to decide if classifier can update {@code matches} properly
* in method {@link #update(List, Map)}
import java.util.List;
import java.util.Map;
+import com.google.common.collect.ImmutableList;
import org.opendaylight.groupbasedpolicy.sf.classifiers.EtherTypeClassifierDefinition;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.IntBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValuesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetType;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
}
@Override
- public ClassifierDefinition getClassDef() {
+ public ClassifierDefinition getClassifierDefinition() {
return EtherTypeClassifierDefinition.DEFINITION;
}
+ @Override
+ public List<SupportedParameterValues> getSupportedParameterValues() {
+
+ List<SupportedIntValue> values = ImmutableList.of(
+ new SupportedIntValueBuilder().setValue(EtherTypeClassifierDefinition.ARP_VALUE)
+ .build(),
+ new SupportedIntValueBuilder().setValue(EtherTypeClassifierDefinition.IPv4_VALUE)
+ .build(),
+ new SupportedIntValueBuilder().setValue(EtherTypeClassifierDefinition.IPv6_VALUE)
+ .build());
+ SupportedParameterValuesBuilder b = new SupportedParameterValuesBuilder();
+ b.setParameterName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM));
+ b.setParameterType(new IntBuilder().setSupportedIntValue(values).build());
+
+ return ImmutableList.of(b.build());
+ }
+
@Override
protected void checkPresenceOfRequiredParams(Map<String, ParameterValue> params) {
if (params.get(EtherTypeClassifierDefinition.ETHERTYPE_PARAM) == null) {
- throw new IllegalArgumentException("Parameter " + EtherTypeClassifierDefinition.ETHERTYPE_PARAM
- + " not specified.");
+ throw new IllegalArgumentException(
+ "Parameter " + EtherTypeClassifierDefinition.ETHERTYPE_PARAM + " not specified.");
}
if (params.get(EtherTypeClassifierDefinition.ETHERTYPE_PARAM).getIntValue() == null) {
- throw new IllegalArgumentException("Value of " + EtherTypeClassifierDefinition.ETHERTYPE_PARAM
- + " parameter is not present.");
+ throw new IllegalArgumentException(
+ "Value of " + EtherTypeClassifierDefinition.ETHERTYPE_PARAM + " parameter is not present.");
}
}
@Override
- protected List<MatchBuilder> update(List<MatchBuilder> matches, Map<String, ParameterValue> params) {
+ protected List<MatchBuilder> update(List<MatchBuilder> matches,
+ Map<String, ParameterValue> params) {
Long type = params.get(EtherTypeClassifierDefinition.ETHERTYPE_PARAM).getIntValue();
for (MatchBuilder match : matches) {
EthernetMatchBuilder em;
private void equalOrNotSetValidation(EthernetType ethTypeInMatch, long paramValue) {
if (ethTypeInMatch != null) {
if (paramValue != ethTypeInMatch.getType().getValue().longValue()) {
- throw new IllegalArgumentException("Classification conflict detected at "
- + EtherTypeClassifierDefinition.ETHERTYPE_PARAM + " parameter for values "
- + ethTypeInMatch.getType().getValue() + " and " + paramValue + ". It is not allowed "
- + "to assign different values to the same parameter among all the classifiers within one rule.");
+ throw new IllegalArgumentException(
+ "Classification conflict detected at " + EtherTypeClassifierDefinition.ETHERTYPE_PARAM + " parameter for values " + ethTypeInMatch
+ .getType()
+ .getValue() + " and " + paramValue + ". It is not allowed " + "to assign different values to the same parameter among all the classifiers within one rule.");
}
}
}
import java.util.List;
import java.util.Map;
+import com.google.common.collect.ImmutableList;
import org.opendaylight.groupbasedpolicy.sf.classifiers.IpProtoClassifierDefinition;
import org.opendaylight.groupbasedpolicy.sf.classifiers.EtherTypeClassifierDefinition;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.IntBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValuesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
/**
}
@Override
- public ClassifierDefinition getClassDef() {
+ public ClassifierDefinition getClassifierDefinition() {
return IpProtoClassifierDefinition.DEFINITION;
}
+ @Override
+ public List<SupportedParameterValues> getSupportedParameterValues() {
+
+ List<SupportedIntValue> values = ImmutableList.of(
+ new SupportedIntValueBuilder().setValue(IpProtoClassifierDefinition.ICMP_VALUE)
+ .build(),
+ new SupportedIntValueBuilder().setValue(IpProtoClassifierDefinition.SCTP_VALUE)
+ .build(),
+ new SupportedIntValueBuilder().setValue(IpProtoClassifierDefinition.TCP_VALUE)
+ .build(),
+ new SupportedIntValueBuilder().setValue(IpProtoClassifierDefinition.UDP_VALUE)
+ .build());
+ SupportedParameterValuesBuilder b = new SupportedParameterValuesBuilder();
+ b.setParameterName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM));
+ b.setParameterType(new IntBuilder().setSupportedIntValue(values).build());
+
+ return ImmutableList.of(b.build());
+ }
+
@Override
protected void checkPresenceOfRequiredParams(Map<String, ParameterValue> params) {
if (params.get(IpProtoClassifierDefinition.PROTO_PARAM) == null) {
import java.util.Map;
import java.util.Set;
+import com.google.common.collect.ImmutableList;
import org.opendaylight.groupbasedpolicy.sf.classifiers.IpProtoClassifierDefinition;
import org.opendaylight.groupbasedpolicy.sf.classifiers.L4ClassifierDefinition;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.parameters.type.parameter.type.IntBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValuesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueInRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported._int.value.fields.SupportedIntValueInRangeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported.range.value.fields.SupportedRangeValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.supported.range.value.fields.SupportedRangeValueBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch;
import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatchBuilder;
}
@Override
- public ClassifierDefinition getClassDef() {
+ public ClassifierDefinition getClassifierDefinition() {
return L4ClassifierDefinition.DEFINITION;
}
+ @Override
+ public List<SupportedParameterValues> getSupportedParameterValues() {
+ List<SupportedIntValueInRange> allPossiblePortsIntInRange = ImmutableList.of(
+ new SupportedIntValueInRangeBuilder().setMin(1L).setMax(65535L).build());
+ List<SupportedRangeValue> allPossiblePortsRange = ImmutableList.of(
+ new SupportedRangeValueBuilder().setMin(1L).setMax(65535L).build());
+
+ SupportedParameterValuesBuilder srcPorts = new SupportedParameterValuesBuilder();
+ srcPorts.setParameterName(new ParameterName(L4ClassifierDefinition.SRC_PORT_PARAM));
+ srcPorts.setParameterType(
+ new IntBuilder().setSupportedIntValueInRange(allPossiblePortsIntInRange).build());
+
+ SupportedParameterValuesBuilder dstPorts = new SupportedParameterValuesBuilder();
+ dstPorts.setParameterName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM));
+ dstPorts.setParameterType(
+ new IntBuilder().setSupportedIntValueInRange(allPossiblePortsIntInRange).build());
+
+ SupportedParameterValuesBuilder srcPortsRange = new SupportedParameterValuesBuilder();
+ srcPorts.setParameterName(new ParameterName(L4ClassifierDefinition.SRC_PORT_RANGE_PARAM));
+ srcPorts.setParameterType(
+ new IntBuilder().setSupportedIntValueInRange(allPossiblePortsIntInRange).build());
+
+ SupportedParameterValuesBuilder dstPortsRange = new SupportedParameterValuesBuilder();
+ dstPorts.setParameterName(new ParameterName(L4ClassifierDefinition.DST_PORT_RANGE_PARAM));
+ dstPorts.setParameterType(
+ new IntBuilder().setSupportedIntValueInRange(allPossiblePortsIntInRange).build());
+
+ return ImmutableList.of(srcPorts.build(), dstPorts.build(), srcPortsRange.build(),
+ dstPortsRange.build());
+ }
+
@Override
protected void checkPresenceOfRequiredParams(Map<String, ParameterValue> params) {
validatePortParam(params, L4ClassifierDefinition.SRC_PORT_PARAM, L4ClassifierDefinition.SRC_PORT_RANGE_PARAM);
--- /dev/null
+/*
+ * 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
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.SubjectFeatureDefinitions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinitionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinitionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.supported.classifier.definition.SupportedParameterValues;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SubjectFeatureDefinitionsListener
+ implements DataTreeChangeListener<ClassifierDefinition>, AutoCloseable {
+
+ private static final Logger LOG =
+ LoggerFactory.getLogger(SubjectFeatureDefinitionsListener.class);
+
+ private final DataBroker dataProvider;
+ private final ListenerRegistration<SubjectFeatureDefinitionsListener> registration;
+
+ private static final Map<ClassifierDefinitionId, Classifier> OF_CLASSIFIERS =
+ SubjectFeatures.getClassifiers();
+
+ public SubjectFeatureDefinitionsListener(DataBroker dataProvider) {
+ this.dataProvider = checkNotNull(dataProvider);
+ registration = dataProvider.registerDataTreeChangeListener(
+ new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.builder(SubjectFeatureDefinitions.class)
+ .child(ClassifierDefinition.class)
+ .build()), this);
+
+ }
+
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<ClassifierDefinition>> changes) {
+
+ for (DataTreeModification<ClassifierDefinition> change : changes) {
+ DataObjectModification<ClassifierDefinition> rootNode = change.getRootNode();
+
+ List<SupportedClassifierDefinition> supportedClassifierDefinitions = new ArrayList<>();
+
+ switch (rootNode.getModificationType()) {
+ case WRITE:
+ case SUBTREE_MODIFIED:
+ ClassifierDefinition classifierDefinitionAfter =
+ checkNotNull(rootNode.getDataAfter());
+ Classifier ourClassifier =
+ OF_CLASSIFIERS.get(classifierDefinitionAfter.getId());
+ if (ourClassifier != null) {
+ List<SupportedParameterValues> spValues =
+ ourClassifier.getSupportedParameterValues();
+
+ SupportedClassifierDefinitionBuilder scdBuilder =
+ new SupportedClassifierDefinitionBuilder().setClassifierDefinitionId(
+ ourClassifier.getClassifierDefinition().getId())
+ .setSupportedParameterValues(spValues);
+ if (ourClassifier.getParent() != null) {
+ scdBuilder.setParentClassifierDefinitionId(
+ ourClassifier.getParent().getId());
+ }
+ supportedClassifierDefinitions.add(scdBuilder.build());
+ }
+
+ if (!supportedClassifierDefinitions.isEmpty()) {
+ WriteTransaction wt = dataProvider.newWriteOnlyTransaction();
+ for (SupportedClassifierDefinition def : supportedClassifierDefinitions) {
+ wt.put(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(Renderers.class)
+ .child(Renderer.class)
+ .child(Capabilities.class)
+ .child(SupportedClassifierDefinition.class)
+ .build(), def, true);
+ }
+ wt.submit();
+ }
+ break;
+
+ case DELETE:
+ ClassifierDefinition classifierDefinitionBefore =
+ checkNotNull(rootNode.getDataAfter());
+ ClassifierDefinitionId id = classifierDefinitionBefore.getId();
+ WriteTransaction wt = dataProvider.newWriteOnlyTransaction();
+ wt.delete(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(Renderers.class)
+ .child(Renderer.class)
+ .child(Capabilities.class)
+ .child(SupportedClassifierDefinition.class,
+ new SupportedClassifierDefinitionKey(id))
+ .build());
+ wt.submit();
+ break;
+ }
+
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ registration.close();
+ }
+}
* Defines the subject features that are supported by the OF overlay renderer
*/
public class SubjectFeatures {
- private static final Map<ClassifierDefinitionId, Classifier> classifiers =
- ImmutableMap.<ClassifierDefinitionId, Classifier>
- of(EtherTypeClassifierDefinition.ID, Classifier.ETHER_TYPE_CL,
- IpProtoClassifierDefinition.ID, Classifier.IP_PROTO_CL,
- L4ClassifierDefinition.ID, Classifier.L4_CL);
+
+ private static final Map<ClassifierDefinitionId, Classifier> classifiers = ImmutableMap.
+ of(EtherTypeClassifierDefinition.ID, Classifier.ETHER_TYPE_CL,
+ IpProtoClassifierDefinition.ID, Classifier.IP_PROTO_CL,
+ L4ClassifierDefinition.ID, Classifier.L4_CL);
private static final List<ClassifierDefinition> classifierDefs =
ImmutableList.copyOf(Collections2.transform(classifiers.values(),
new Function<Classifier, ClassifierDefinition>() {
@Override
public ClassifierDefinition apply(Classifier input) {
- return input.getClassDef();
+ return input.getClassifierDefinition();
}
}
));
- private static final Map<ActionDefinitionId, Action> actions =
- ImmutableMap.<ActionDefinitionId, Action>
- of(AllowActionDefinition.ID, new AllowAction(),
- ChainActionDefinition.ID, new ChainAction());
+ private static final Map<ActionDefinitionId, Action> actions = ImmutableMap.
+ of(AllowActionDefinition.ID, new AllowAction(), ChainActionDefinition.ID,
+ new ChainAction());
private static final List<ActionDefinition> actionDefs =
ImmutableList.copyOf(Collections2.transform(actions.values(),
return classifiers.get(id);
}
+
+ public static Map<ClassifierDefinitionId, Classifier> getClassifiers() {
+ return classifiers;
+ }
+
public static Map<ActionDefinitionId, Action> getActions() {
return actions;
}
--- /dev/null
+/*
+ * 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
+ */
+
+package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.ImmutableList;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.groupbasedpolicy.sf.classifiers.EtherTypeClassifierDefinition;
+import org.opendaylight.groupbasedpolicy.util.IidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.Parameter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definition.ParameterBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.definitions.ClassifierDefinitionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.Renderers;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.Capabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.capabilities.SupportedClassifierDefinitionKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class SubjectFeatureDefinitionsListenerTest extends AbstractDataBrokerTest {
+
+ private static final Parameter PARAM_INT =
+ new ParameterBuilder().setName(new ParameterName("paramInt"))
+ .setType(Parameter.Type.Int)
+ .build();
+ private static final ClassifierDefinition CD_WITH_PARAM_INT =
+ new ClassifierDefinitionBuilder().setId(
+ new ClassifierDefinitionId(EtherTypeClassifierDefinition.ID.getValue()))
+ .setDescription(new Description("some description"))
+ .setName(new ClassifierName("cd_with_one_param"))
+ .setParameter(ImmutableList.of(PARAM_INT))
+ .build();
+
+ @Test
+ public void testPutEtherTypeClassifierDefinition() throws Exception {
+ Renderer renderer1 = new RendererBuilder().setName(new RendererName("renderer1")).build();
+ WriteTransaction wTx = getDataBroker().newWriteOnlyTransaction();
+ wTx.put(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(Renderers.class).child(Renderer.class, renderer1.getKey()).build(),
+ renderer1);
+
+ wTx.put(LogicalDatastoreType.CONFIGURATION,
+ IidFactory.classifierDefinitionIid(CD_WITH_PARAM_INT.getId()), CD_WITH_PARAM_INT,
+ true);
+ wTx.submit().get();
+
+ ReadOnlyTransaction rTx = getDataBroker().newReadOnlyTransaction();
+ CheckedFuture<Optional<SupportedClassifierDefinition>, ReadFailedException> f =
+ rTx.read(LogicalDatastoreType.OPERATIONAL,
+ InstanceIdentifier.builder(Renderers.class)
+ .child(Renderer.class, renderer1.getKey())
+ .child(Capabilities.class)
+ .child(SupportedClassifierDefinition.class,
+ new SupportedClassifierDefinitionKey(
+ EtherTypeClassifierDefinition.ID))
+ .build());
+ Futures.addCallback(f, new FutureCallback<Optional<SupportedClassifierDefinition>>() {
+
+ @Override
+ public void onSuccess(Optional<SupportedClassifierDefinition> result) {
+ if (result.isPresent()) {
+ SupportedClassifierDefinition def = result.get();
+ Assert.assertEquals(CD_WITH_PARAM_INT.getId(), def.getClassifierDefinitionId());
+ Assert.assertEquals(SubjectFeatures.getClassifier(CD_WITH_PARAM_INT.getId())
+ .getSupportedParameterValues(), def.getSupportedParameterValues());
+ }
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ throw new RuntimeException(t);
+ }
+ });
+ f.checkedGet();
+ }
+
+}