<version>${neutron.version}</version>
<type>xml</type>
</dependency>
- <dependency>
- <groupId>org.opendaylight.neutron</groupId>
- <artifactId>dummyprovider</artifactId>
- <version>${neutron.version}</version>
- </dependency>
<!-- Faas -->
<dependency>
<feature version="${neutron.version}">odl-neutron-service</feature>
<feature version="${project.version}">odl-groupbasedpolicy-base</feature>
<bundle>mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}</bundle>
- <bundle>mvn:org.opendaylight.neutron/dummyprovider/{{VERSION}}</bundle>
<bundle>mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}</bundle>
<configfile finalname="${config.configfile.directory}/15-l2-l3-domain-extension.xml">mvn:org.opendaylight.groupbasedpolicy/l2-l3-domain-extension/{{VERSION}}/xml/config</configfile>
<configfile finalname="${config.configfile.directory}/15-neutron-mapper.xml">mvn:org.opendaylight.groupbasedpolicy/neutron-mapper/{{VERSION}}/xml/config</configfile>
public class NeutronMapper implements DataTreeChangeListener<Neutron>, AutoCloseable {
private final static SecurityRuleBuilder EIG_INGRESS_IPV4_SEC_RULE_BUILDER = new SecurityRuleBuilder()
- .setId(new Uuid("0a629f80-2408-11e6-b67b-9e71128cae77"))
+ .setUuid(new Uuid("0a629f80-2408-11e6-b67b-9e71128cae77"))
.setDirection(DirectionIngress.class)
.setEthertype(EthertypeV4.class)
.setSecurityGroupId(MappingUtils.EIG_UUID);
private final static SecurityRuleBuilder EIG_EGRESS_IPV4_SEC_RULE_BUILDER = new SecurityRuleBuilder()
- .setId(new Uuid("0f1789be-2408-11e6-b67b-9e71128cae77"))
+ .setUuid(new Uuid("0f1789be-2408-11e6-b67b-9e71128cae77"))
.setDirection(DirectionEgress.class)
.setEthertype(EthertypeV4.class)
.setSecurityGroupId(MappingUtils.EIG_UUID);
private final static SecurityRuleBuilder EIG_INGRESS_IPV6_SEC_RULE_BUILDER = new SecurityRuleBuilder()
- .setId(new Uuid("139b7f90-2408-11e6-b67b-9e71128cae77"))
+ .setUuid(new Uuid("139b7f90-2408-11e6-b67b-9e71128cae77"))
.setDirection(DirectionIngress.class)
.setEthertype(EthertypeV6.class)
.setSecurityGroupId(MappingUtils.EIG_UUID);
private final static SecurityRuleBuilder EIG_EGRESS_IPV6_SEC_RULE_BUILDER = new SecurityRuleBuilder()
- .setId(new Uuid("17517202-2408-11e6-b67b-9e71128cae77"))
+ .setUuid(new Uuid("17517202-2408-11e6-b67b-9e71128cae77"))
.setDirection(DirectionEgress.class)
.setEthertype(EthertypeV6.class)
.setSecurityGroupId(MappingUtils.EIG_UUID);
private final static SecurityGroupBuilder EIG_SEC_GROUP_BUILDER =
- new SecurityGroupBuilder().setUuid(MappingUtils.EIG_UUID).setDescription("EXTERNAL_group");
+ new SecurityGroupBuilder().setUuid(MappingUtils.EIG_UUID);
private final NeutronNetworkAware networkAware;
private final NeutronSecurityGroupAware securityGroupAware;
private AddressEndpointRegBuilder createBasicMacAddrEpInputBuilder(Port port,
NetworkDomainId networkContainment, @Nullable List<EndpointGroupId> endpointGroupsToAdd) {
AddressEndpointRegBuilder addrEpbuilder = new AddressEndpointRegBuilder().setAddressType(MacAddressType.class)
- .setAddress(port.getMacAddress())
+ .setAddress(port.getMacAddress().getValue())
.setAddressType(MacAddressType.class)
.setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
.setContextId(new ContextId(port.getNetworkId().getValue()))
Port port) {
return new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder().setL2Context(
new L2BridgeDomainId(port.getNetworkId().getValue()))
- .setMacAddress(new MacAddress(port.getMacAddress()))
+ .setMacAddress(new MacAddress(port.getMacAddress().getValue()))
.setTenant(new TenantId(port.getTenantId().getValue()))
.setTimestamp(System.currentTimeMillis());
}
}
UniqueId portId = new UniqueId(port.getUuid().getValue());
EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()), new MacAddress(
- port.getMacAddress()));
+ port.getMacAddress().getValue()));
LOG.trace("Adding Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getUuid()
.getValue(), port.getDeviceOwner(), epKey);
EndpointByPort endpointByPort = MappingFactory.createEndpointByPort(epKey, portId);
if (isUnregisteredEndpoint) {
UniqueId portId = new UniqueId(port.getUuid().getValue());
EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()), new MacAddress(
- port.getMacAddress()));
+ port.getMacAddress().getValue()));
LOG.trace("Removing Port-Endpoint mapping for port {} (device owner {}) and endpoint {}", port.getUuid()
.getValue(), port.getDeviceOwner(), epKey);
DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
if (isUnregisteredBaseEndpoint) {
UniqueId portId = new UniqueId(port.getUuid().getValue());
EndpointKey epKey = new EndpointKey(new L2BridgeDomainId(port.getNetworkId().getValue()), new MacAddress(
- port.getMacAddress()));
+ port.getMacAddress().getValue()));
LOG.trace("Removing Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
port.getUuid().getValue(), port.getDeviceOwner(), epKey);
- PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress(),
+ PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress().getValue(),
MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
DataStoreHelper.removeIfExists(LogicalDatastoreType.OPERATIONAL,
NeutronGbpIidFactory.baseEndpointByPortIid(portId), rwTx);
UnregisterEndpointInputBuilder inputBuilder = new UnregisterEndpointInputBuilder();
List<AddressEndpointUnreg> list = new ArrayList<>();
AddressEndpointUnregBuilder addrL2EpUnregBuilder = new AddressEndpointUnregBuilder();
- addrL2EpUnregBuilder.setAddress(port.getMacAddress())
+ addrL2EpUnregBuilder.setAddress(port.getMacAddress().getValue())
.setAddressType(MacAddressType.class)
.setContextId(new ContextId(port.getNetworkId().getValue()))
.setContextType(MappingUtils.L2_BRDIGE_DOMAIN);
org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder inputBuilder =
new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInputBuilder();
L2 l2Ep = new L2Builder().setL2Context(new L2BridgeDomainId(port.getNetworkId().getValue()))
- .setMacAddress(new MacAddress(port.getMacAddress()))
+ .setMacAddress(new MacAddress(port.getMacAddress().getValue()))
.build();
inputBuilder.setL2(ImmutableList.of(l2Ep));
// we've registered EP with only first IP so remove only EP with first IP
LOG.debug("Name exception", e);
}
}
- if (!Strings.isNullOrEmpty(secGroup.getDescription())) {
- try {
- epgBuilder.setDescription(new Description(secGroup.getDescription()));
- } catch (Exception e) {
- LOG.info("Description '{}' of Neutron Security-group '{}' is ignored.",
- secGroup.getDescription(), secGroup.getUuid().getValue());
- LOG.debug("Description exception", e);
- }
- }
epgBuilder.setIntraGroupPolicy(IntraGroupPolicy.RequireContract);
rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tId, epgId),
epgBuilder.build(), true);
import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
-import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet subnet,
IpAddress virtualRouterIp) {
SubnetBuilder sb = new SubnetBuilder();
- sb.setIpPrefix(Utils.createIpPrefix(subnet.getCidr()));
+ sb.setIpPrefix(subnet.getCidr());
sb.setVirtualRouterIp(virtualRouterIp);
NetworkDomainBuilder ndb = new NetworkDomainBuilder();
if (!Strings.isNullOrEmpty(subnet.getName())) {
LOG.debug("Name exception", e);
}
}
- subnetBuilder.setIpPrefix(Utils.createIpPrefix(subnet.getCidr()));
+ subnetBuilder.setIpPrefix(subnet.getCidr());
subnetBuilder.setVirtualRouterIp(virtualRouterIp);
return subnetBuilder.build();
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmpV6;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;\r
\r
import com.google.common.collect.ImmutableList;\r
}\r
\r
public static ContractId getContractId(SecurityRule secRule) {\r
- return new ContractId(secRule.getId().getValue());\r
+ return new ContractId(secRule.getUuid().getValue());\r
}\r
\r
public static ClassifierInstance getClassifierInstance(SecurityRule secRule) {\r
* {@link ProtocolUdp}, {@link ProtocolIcmp}, {@link ProtocolIcmpV6}\r
*/\r
public static Long getProtocol(SecurityRule secRule) {\r
- Class<? extends ProtocolBase> protocol = secRule.getProtocol();\r
+ SecurityRuleAttributes.Protocol protocol = secRule.getProtocol();\r
if (protocol == null) {\r
return null;\r
}\r
- if (protocol.isAssignableFrom(ProtocolTcp.class)) {\r
- return IpProtoClassifierDefinition.TCP_VALUE;\r
+ if (protocol.getUint8() != null) {\r
+ return protocol.getUint8().longValue();\r
}\r
- if (protocol.isAssignableFrom(ProtocolUdp.class)) {\r
- return IpProtoClassifierDefinition.UDP_VALUE;\r
- }\r
- if (protocol.isAssignableFrom(ProtocolIcmp.class)) {\r
- return IpProtoClassifierDefinition.ICMP_VALUE;\r
- }\r
- if (protocol.isAssignableFrom(ProtocolIcmpV6.class)) {\r
- return IpProtoClassifierDefinition.ICMPv6_VALUE;\r
+ if (protocol.getIdentityref() != null) {\r
+ if (protocol.getIdentityref().equals(ProtocolTcp.class)) {\r
+ return IpProtoClassifierDefinition.TCP_VALUE;\r
+ }\r
+ if (protocol.getIdentityref().equals(ProtocolUdp.class)) {\r
+ return IpProtoClassifierDefinition.UDP_VALUE;\r
+ }\r
+ if (protocol.getIdentityref().equals(ProtocolIcmp.class)) {\r
+ return IpProtoClassifierDefinition.ICMP_VALUE;\r
+ }\r
+ if (protocol.getIdentityref().equals(ProtocolIcmpV6.class)) {\r
+ return IpProtoClassifierDefinition.ICMPv6_VALUE;\r
+ }\r
}\r
throw new IllegalArgumentException("Neutron Security Rule Protocol value " + protocol + " is not supported.");\r
}\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
public class SecRuleNameDecoder {
.append(portMax.longValue());
}
}
- Class<? extends ProtocolBase> protocol = secRule.getProtocol();
+ SecurityRuleAttributes.Protocol protocol = secRule.getProtocol();
if (protocol != null) {
if (keyBuilder.length() > 0) {
keyBuilder.append(MappingUtils.NAME_DOUBLE_DELIMETER);
}
+ String protocolString = "";
+ if (protocol.getUint8() != null) {
+ protocolString = protocol.getUint8().toString();
+ } else if (protocol.getIdentityref() != null) {
+ protocolString = protocol.getIdentityref().getSimpleName();
+ }
keyBuilder.append(IpProtoClassifierDefinition.DEFINITION.getName().getValue())
.append(MappingUtils.NAME_VALUE_DELIMETER)
- .append(protocol.getSimpleName());
+ .append(protocolString);
}
Class<? extends EthertypeBase> ethertype = secRule.getEthertype();
if (ethertype != null) {
return Optional.absent();
}
for (SecurityRule secRule : securityRules.getSecurityRule()) {
- if (secRule.getId().equals(uuid)) {
+ if (secRule.getUuid().equals(uuid)) {
return Optional.of(secRule);
}
}
import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperAssert;
import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
import org.opendaylight.groupbasedpolicy.neutron.mapper.util.PortUtils;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput;
.setDeviceId("deviceId")
.setFixedIps(ImmutableList.of(portIpWithSubnet))
.setNetworkId(networkUuid)
- .setMacAddress("00:00:00:00:35:02")
+ .setMacAddress(new MacAddress("00:00:00:00:35:02"))
.build();
Port neutronPort2 = new PortBuilder().setTenantId(new Uuid(tenantUuid))
.setFixedIps(ImmutableList.of(portIpWithSubnet))
.setDeviceOwner(PortUtils.DEVICE_OWNER_DHCP)
.setFixedIps(ImmutableList.of(portIpWithSubnet))
.setNetworkId(networkUuid)
- .setMacAddress("00:00:00:00:35:02")
+ .setMacAddress(new MacAddress("00:00:00:00:35:02"))
.build();
Ports neutronPorts = new PortsBuilder().setPort(ImmutableList.of(neutronPort1, neutronPort2)).build();
when(neutron.getPorts()).thenReturn(neutronPorts);
.setUuid(portUuid)
.setDeviceId("deviceId")
.setNetworkId(networkUuid)
- .setMacAddress("00:00:00:00:35:02");
+ .setMacAddress(new MacAddress("00:00:00:00:35:02"));
}
private Subnets createSubnets() {
.setUuid(subnetUuid)
.setName("subnetName")
.setNetworkId(networkUuid)
- .setCidr("10.0.0.0/24")
+ .setCidr(Utils.createIpPrefix("10.0.0.0/24"))
.build();
return new SubnetsBuilder().setSubnet(ImmutableList.of(subnet)).build();
}
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator;
import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.groupbasedpolicy.util.IidFactory;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
.setName("subnetName")
.setNetworkId(networkUuid)
.setGatewayIp(ipAddress)
- .setCidr("10.0.0.0/24")
+ .setCidr(Utils.createIpPrefix("10.0.0.0/24"))
.build();
return new SubnetsBuilder().setSubnet(ImmutableList.of(subnet)).build();
}
SecurityGroup secGroupA = new SecurityGroupBuilder().setUuid(new Uuid(uuid))
.setTenantId(new Uuid(tenantId))
.setName("correctName")
- .setDescription("correct description")
.build();
groupAware.onCreated(secGroupA, null);
SecurityGroup secGroupA = new SecurityGroupBuilder().setUuid(new Uuid(uuid))
.setTenantId(new Uuid(tenantId))
.setName("123")
- .setDescription(longDescription)
.build();
groupAware.onCreated(secGroupA, null);
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.NeutronBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.SecurityGroupsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.SecurityRulesBuilder;
"dabfd4da-af89-45dd-85f8-181768c1b4c9", tenant, EthertypeV4.class, DirectionEgress.class, goldSecGrp,
null);
String serverSecGrp = "71cf4fe5-b146-409e-8151-cd921298ce32";
- SecurityRule serverIn80Tcp10_1_1_0 = new SecurityRuleBuilder().setId(new Uuid("9dbb533d-d9b2-4dc9-bae7-ee60c8df184d"))
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ SecurityRule serverIn80Tcp10_1_1_0 = new SecurityRuleBuilder().setUuid(new Uuid("9dbb533d-d9b2-4dc9-bae7-ee60c8df184d"))
.setTenantId(new Uuid(tenant))
.setEthertype(EthertypeV4.class)
- .setProtocol(ProtocolTcp.class)
+ .setProtocol(protocolTcp)
.setPortRangeMin(80)
.setPortRangeMax(80)
.setDirection(DirectionIngress.class)
.setSecurityGroupId(new Uuid(serverSecGrp))
.setRemoteIpPrefix(new IpPrefix(new Ipv4Prefix("10.1.1.0/24")))
.build();
- SecurityRule serverInIp20_1_1_0 = new SecurityRuleBuilder().setId(new Uuid("adf7e558-de47-4f9e-a9b8-96e19db5d1ac"))
+ SecurityRule serverInIp20_1_1_0 = new SecurityRuleBuilder().setUuid(new Uuid("adf7e558-de47-4f9e-a9b8-96e19db5d1ac"))
.setTenantId(new Uuid(tenant))
.setEthertype(EthertypeV4.class)
.setDirection(DirectionIngress.class)
.get();
assertTrue(potentialTenant.isPresent());
Optional<Contract> potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
Contract contract = potentialContract.get();
PolicyAssert.assertContract(contract, goldInIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, goldOutIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, serverOutIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(serverIn80Tcp10_1_1_0.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(serverIn80Tcp10_1_1_0.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContractWithEic(contract, serverIn80Tcp10_1_1_0);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(serverInIp20_1_1_0.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(serverInIp20_1_1_0.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContractWithEic(contract, serverInIp20_1_1_0);
EndpointGroup epg = potentialEpg.get();
PolicyAssert.assertConsumerNamedSelectors(
epg,
- ImmutableSet.of(new ContractId(goldInIpv4.getId().getValue()),
- new ContractId(goldOutIpv4.getId().getValue()),
- new ContractId(serverIn80Tcp10_1_1_0.getId().getValue()),
- new ContractId(serverInIp20_1_1_0.getId().getValue()),
- new ContractId(serverOutIpv4.getId().getValue())));
+ ImmutableSet.of(new ContractId(goldInIpv4.getUuid().getValue()),
+ new ContractId(goldOutIpv4.getUuid().getValue()),
+ new ContractId(serverIn80Tcp10_1_1_0.getUuid().getValue()),
+ new ContractId(serverInIp20_1_1_0.getUuid().getValue()),
+ new ContractId(serverOutIpv4.getUuid().getValue())));
potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(serverSecGrp))).get();
assertTrue(potentialEpg.isPresent());
epg = potentialEpg.get();
PolicyAssert.assertConsumerNamedSelectors(epg, ImmutableSet.of(
- new ContractId(serverIn80Tcp10_1_1_0.getId().getValue()),
- new ContractId(serverInIp20_1_1_0.getId().getValue()),
- new ContractId(goldInIpv4.getId().getValue())));
+ new ContractId(serverIn80Tcp10_1_1_0.getUuid().getValue()),
+ new ContractId(serverInIp20_1_1_0.getUuid().getValue()),
+ new ContractId(goldInIpv4.getUuid().getValue())));
}
@Test
ruleAware.addNeutronSecurityRule(serverInIpv4, neutron, rwTx);
TenantId tenantId = new TenantId(tenant);
Optional<Contract> potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
Contract contract = potentialContract.get();
PolicyAssert.assertContract(contract, goldInIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, goldOutIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, serverOutIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(serverInIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(serverInIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, serverInIpv4);
EndpointGroup epg = potentialEpg.get();
PolicyAssert.assertConsumerNamedSelectors(
epg,
- ImmutableSet.of(new ContractId(goldInIpv4.getId().getValue()),
- new ContractId(goldOutIpv4.getId().getValue()),
- new ContractId(serverOutIpv4.getId().getValue()),
- new ContractId(serverInIpv4.getId().getValue())));
+ ImmutableSet.of(new ContractId(goldInIpv4.getUuid().getValue()),
+ new ContractId(goldOutIpv4.getUuid().getValue()),
+ new ContractId(serverOutIpv4.getUuid().getValue()),
+ new ContractId(serverInIpv4.getUuid().getValue())));
potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(serverSecGrp))).get();
assertTrue(potentialEpg.isPresent());
PolicyAssert.assertConsumerNamedSelectors(
epg,
- ImmutableSet.of(new ContractId(goldInIpv4.getId().getValue()),
- new ContractId(goldOutIpv4.getId().getValue()),
- new ContractId(serverOutIpv4.getId().getValue()),
- new ContractId(serverInIpv4.getId().getValue())));
+ ImmutableSet.of(new ContractId(goldInIpv4.getUuid().getValue()),
+ new ContractId(goldOutIpv4.getUuid().getValue()),
+ new ContractId(serverOutIpv4.getUuid().getValue()),
+ new ContractId(serverInIpv4.getUuid().getValue())));
}
@Test
SecurityRule serverOutIpv4 = NeutronEntityFactory.securityRuleWithEtherType(
"8b9c48d3-44a8-46be-be35-6f3237d98071", tenant, EthertypeV4.class, DirectionEgress.class, serverSecGrp,
null);
- SecurityRule serverIn80TcpIpv4 = new SecurityRuleBuilder().setId(new Uuid("adf7e558-de47-4f9e-a9b8-96e19db5d1ac"))
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ SecurityRule serverIn80TcpIpv4 = new SecurityRuleBuilder().setUuid(new Uuid("adf7e558-de47-4f9e-a9b8-96e19db5d1ac"))
.setTenantId(new Uuid(tenant))
.setEthertype(EthertypeV4.class)
- .setProtocol(ProtocolTcp.class)
+ .setProtocol(protocolTcp)
.setPortRangeMin(80)
.setPortRangeMax(80)
.setDirection(DirectionIngress.class)
ruleAware.addNeutronSecurityRule(serverIn80TcpIpv4, neutron, rwTx);
TenantId tenantId = new TenantId(tenant);
Optional<Contract> potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(goldInIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
Contract contract = potentialContract.get();
PolicyAssert.assertContract(contract, goldInIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(goldOutIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, goldOutIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(serverOutIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, serverOutIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(serverIn80TcpIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(serverIn80TcpIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, serverIn80TcpIpv4);
EndpointGroup epg = potentialEpg.get();
PolicyAssert.assertConsumerNamedSelectors(
epg,
- ImmutableSet.of(new ContractId(goldInIpv4.getId().getValue()),
- new ContractId(goldOutIpv4.getId().getValue()),
- new ContractId(serverOutIpv4.getId().getValue()),
- new ContractId(serverIn80TcpIpv4.getId().getValue())));
+ ImmutableSet.of(new ContractId(goldInIpv4.getUuid().getValue()),
+ new ContractId(goldOutIpv4.getUuid().getValue()),
+ new ContractId(serverOutIpv4.getUuid().getValue()),
+ new ContractId(serverIn80TcpIpv4.getUuid().getValue())));
potentialEpg = rwTx.read(LogicalDatastoreType.CONFIGURATION,
IidFactory.endpointGroupIid(tenantId, new EndpointGroupId(serverSecGrp))).get();
assertTrue(potentialEpg.isPresent());
epg = potentialEpg.get();
PolicyAssert.assertConsumerNamedSelectors(
epg,
- ImmutableSet.of(new ContractId(goldInIpv4.getId().getValue()),
- new ContractId(serverIn80TcpIpv4.getId().getValue())));
+ ImmutableSet.of(new ContractId(goldInIpv4.getUuid().getValue()),
+ new ContractId(serverIn80TcpIpv4.getUuid().getValue())));
}
@Test
ruleAware.addNeutronSecurityRule(defaultOutIpv6, neutron, rwTx);
TenantId tenantId = new TenantId(tenant);
Optional<Contract> potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(defaultInIpv4Default.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(defaultInIpv4Default.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
Contract contract = potentialContract.get();
PolicyAssert.assertContract(contract, defaultInIpv4Default);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(defaultInIpv6Default.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(defaultInIpv6Default.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, defaultInIpv6Default);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(defaultOutIpv4.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(defaultOutIpv4.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, defaultOutIpv4);
potentialContract = rwTx.read(LogicalDatastoreType.CONFIGURATION,
- IidFactory.contractIid(tenantId, new ContractId(defaultOutIpv6.getId().getValue()))).get();
+ IidFactory.contractIid(tenantId, new ContractId(defaultOutIpv6.getUuid().getValue()))).get();
assertTrue(potentialContract.isPresent());
contract = potentialContract.get();
PolicyAssert.assertContract(contract, defaultOutIpv6);
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.NeutronBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.SecurityGroupsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
// create neutron security rule
private SecurityRule buildNeutronSecurityRule() {
- return new SecurityRuleBuilder().setId(new Uuid(RULE_ID))
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ return new SecurityRuleBuilder().setUuid(new Uuid(RULE_ID))
.setTenantId(new Uuid(RULE_TENANT_ID))
.setSecurityGroupId(new Uuid(RULE_GROUP_ID))
.setRemoteIpPrefix(new IpPrefix(new Ipv4Prefix("192.0.0.1/24")))
.setPortRangeMin(1000)
.setPortRangeMax(5000)
- .setProtocol(ProtocolTcp.class)
+ .setProtocol(protocolTcp)
.setEthertype(EthertypeV4.class)
.setDirection(DirectionIngress.class)
.build();
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRuleBuilder;
@Before
public void setUp() throws Exception {
- secRuleBuilder = new SecurityRuleBuilder().setId(new Uuid("01234567-abcd-ef01-0123-0123456789ab"));
+ secRuleBuilder = new SecurityRuleBuilder().setUuid(new Uuid("01234567-abcd-ef01-0123-0123456789ab"));
}
@Test
@Test
public final void testGetClassifierInstance_EthertypeAndProtocol() {
secRuleBuilder.setEthertype(EthertypeV4.class);
- secRuleBuilder.setProtocol(ProtocolTcp.class);
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ secRuleBuilder.setProtocol(protocolTcp);
ClassifierInstance ci = SecRuleEntityDecoder.getClassifierInstance(secRuleBuilder.build());
Assert.assertEquals(IpProtoClassifierDefinition.DEFINITION.getId(), ci.getClassifierDefinitionId());
// name is ip_proto_tcp__ether_type_IPv4
@Test
public final void testGetClassifierInstance_EthertypeAndProtocolAndPort() {
secRuleBuilder.setEthertype(EthertypeV4.class);
- secRuleBuilder.setProtocol(ProtocolTcp.class);
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ secRuleBuilder.setProtocol(protocolTcp);
secRuleBuilder.setPortRangeMin(5);
secRuleBuilder.setPortRangeMax(5);
ClassifierInstance ci = SecRuleEntityDecoder.getClassifierInstance(secRuleBuilder.build());
@Test
public final void testGetClassifierInstance_EthertypeAndProtocolAndPorts() {
secRuleBuilder.setEthertype(EthertypeV4.class);
- secRuleBuilder.setProtocol(ProtocolTcp.class);
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ secRuleBuilder.setProtocol(protocolTcp);
secRuleBuilder.setPortRangeMin(5);
secRuleBuilder.setPortRangeMax(10);
ClassifierInstance ci = SecRuleEntityDecoder.getClassifierInstance(secRuleBuilder.build());
@Test
public void testIsProtocolOfOneWithinTwo_oneProtocolTcpTwoProtocolTcp() {
- SecurityRule one = secRuleBuilder.setProtocol(ProtocolTcp.class).build();
- SecurityRule two = secRuleBuilder.setProtocol(ProtocolTcp.class).build();
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ SecurityRule one = secRuleBuilder.setProtocol(protocolTcp).build();
+ SecurityRule two = secRuleBuilder.setProtocol(protocolTcp).build();
assertTrue(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
}
@Test
public void testIsProtocolOfOneWithinTwo_oneProtocolTcpTwoProtocolNull() {
- SecurityRule one = secRuleBuilder.setProtocol(ProtocolTcp.class).build();
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ SecurityRule one = secRuleBuilder.setProtocol(protocolTcp).build();
SecurityRule two = secRuleBuilder.setProtocol(null).build();
assertTrue(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
}
@Test
public void testIsProtocolOfOneWithinTwo_oneProtocolTcpTwoProtocolUdp() {
- SecurityRule one = secRuleBuilder.setProtocol(ProtocolTcp.class).build();
- SecurityRule two = secRuleBuilder.setProtocol(ProtocolUdp.class).build();
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ SecurityRule one = secRuleBuilder.setProtocol(protocolTcp).build();
+ SecurityRuleAttributes.Protocol protocolUdp = new SecurityRuleAttributes.Protocol(ProtocolUdp.class);
+ SecurityRule two = secRuleBuilder.setProtocol(protocolUdp).build();
assertFalse(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
}
@Test
public void testIsProtocolOfOneWithinTwo_oneProtocolNullTwoProtocolTcp() {
SecurityRule one = secRuleBuilder.setProtocol(null).build();
- SecurityRule two = secRuleBuilder.setProtocol(ProtocolTcp.class).build();
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ SecurityRule two = secRuleBuilder.setProtocol(protocolTcp).build();
assertFalse(SecRuleEntityDecoder.isProtocolOfOneWithinTwo(one, two));
}
@Test
public final void testGetProtocol_protoTcp() {
- secRuleBuilder.setProtocol(ProtocolTcp.class);
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ secRuleBuilder.setProtocol(protocolTcp);
Assert.assertEquals(IpProtoClassifierDefinition.TCP_VALUE, SecRuleEntityDecoder.getProtocol(secRuleBuilder.build()));
}
@Test
public final void testGetProtocol_protoUdp() {
- secRuleBuilder.setProtocol(ProtocolUdp.class);
+ SecurityRuleAttributes.Protocol protocolUdp = new SecurityRuleAttributes.Protocol(ProtocolUdp.class);
+ secRuleBuilder.setProtocol(protocolUdp);
Assert.assertEquals(IpProtoClassifierDefinition.UDP_VALUE, SecRuleEntityDecoder.getProtocol(secRuleBuilder.build()));
}
@Test
public final void testGetProtocol_protoIcmp() {
- secRuleBuilder.setProtocol(ProtocolIcmp.class);
+ SecurityRuleAttributes.Protocol protocolIcmp = new SecurityRuleAttributes.Protocol(ProtocolIcmp.class);
+ secRuleBuilder.setProtocol(protocolIcmp);
Assert.assertEquals(IpProtoClassifierDefinition.ICMP_VALUE, SecRuleEntityDecoder.getProtocol(secRuleBuilder.build()));
}
@Test
public final void testGetProtocol_protoUnknown() {
- secRuleBuilder.setProtocol(UnknownProtocol.class);
+ SecurityRuleAttributes.Protocol protocolUnknown = new SecurityRuleAttributes.Protocol(UnknownProtocol.class);
+ secRuleBuilder.setProtocol(protocolUnknown);
thrown.expect(IllegalArgumentException.class);
SecRuleEntityDecoder.getProtocol(secRuleBuilder.build());
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRuleBuilder;
public class SecRuleNameDecoderTest {
@Before
public void setUp() throws Exception {
- secRule = new SecurityRuleBuilder().setId(new Uuid("01234567-abcd-ef01-0123-0123456789ab"));
+ secRule = new SecurityRuleBuilder().setUuid(new Uuid("01234567-abcd-ef01-0123-0123456789ab"));
}
@Test
public final void testGetClassifierInstanceName() {
secRule.setDirection(DirectionIngress.class);
secRule.setEthertype(EthertypeV4.class);
- secRule.setProtocol(ProtocolTcp.class);
+ SecurityRuleAttributes.Protocol protocolTcp = new SecurityRuleAttributes.Protocol(ProtocolTcp.class);
+ secRule.setProtocol(protocolTcp);
secRule.setPortRangeMin(8010);
secRule.setPortRangeMax(8020);
StringBuilder frmtBuilder = new StringBuilder();
.append(EtherTypeClassifierDefinition.DEFINITION.getName().getValue())
.append(MappingUtils.NAME_VALUE_DELIMETER)
.append("%s");
- String frmtClsfName = String.format(frmtBuilder.toString(), 8010, 8020, secRule.getProtocol().getSimpleName(),
+ String frmtClsfName = String.format(frmtBuilder.toString(), 8010, 8020, secRule.getProtocol().getIdentityref().getSimpleName(),
secRule.getEthertype().getSimpleName());
ClassifierName expectedClsfInstanceName = new ClassifierName(frmtClsfName);
assertEquals(expectedClsfInstanceName, SecRuleNameDecoder.getClassifierInstanceName(secRule.build()));
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolBase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
public static SecurityRule securityRuleWithoutGroupIds(String id, String tenant, Class<? extends EthertypeBase> etherType,
Class<? extends DirectionBase> direction, Class<? extends ProtocolBase> protocol, int portMin, int portMax) {
+ SecurityRuleAttributes.Protocol proto = new SecurityRuleAttributes.Protocol(protocol);
SecurityRuleBuilder secRule = new SecurityRuleBuilder();
- secRule.setId(new Uuid(id));
+ secRule.setUuid(new Uuid(id));
secRule.setTenantId(new Uuid(tenant));
secRule.setEthertype(etherType);
secRule.setDirection(direction);
- secRule.setProtocol(protocol);
+ secRule.setProtocol(proto);
secRule.setPortRangeMin(portMin);
secRule.setPortRangeMax(portMax);
return secRule.build();
public static SecurityRule securityRuleWithEtherType(String id, String tenant,
Class<? extends EthertypeBase> etherType, Class<? extends DirectionBase> direction, String ownerGroupId,
String remoteGroupId) {
- SecurityRuleBuilder securityRuleBuilder = new SecurityRuleBuilder().setId(new Uuid(id))
+ SecurityRuleBuilder securityRuleBuilder = new SecurityRuleBuilder().setUuid(new Uuid(id))
.setTenantId(new Uuid(tenant))
.setEthertype(etherType)
.setDirection(direction)
}
public static void assertContractWithEic(Contract contract, SecurityRule secRule) {
- assertEquals(new ContractId(secRule.getId().getValue()), contract.getId());
+ assertEquals(new ContractId(secRule.getUuid().getValue()), contract.getId());
assertNull(contract.getQuality());
assertNull(contract.getTarget());
assertOneClauseWithEicWithOneSubject(contract, secRule);
}
public static void assertContract(Contract contract, SecurityRule secRule) {
- assertEquals(new ContractId(secRule.getId().getValue()), contract.getId());
+ assertEquals(new ContractId(secRule.getUuid().getValue()), contract.getId());
assertNull(contract.getQuality());
assertNull(contract.getTarget());
assertOneClauseWithOneSubject(contract, secRule);
<artifactId>neutron-mapper</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.opendaylight.neutron</groupId>
- <artifactId>neutron-spi</artifactId>
- <version>${neutron.version}</version>
- </dependency>
<dependency>
<groupId>org.opendaylight.groupbasedpolicy</groupId>
<artifactId>vpp-renderer</artifactId>
</plugin>
</plugins>
</build>
-</project>
\ No newline at end of file
+</project>
--- /dev/null
+/*\r
+ * Copyright (c) 2016 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.neutron.vpp.mapper.processors;\r
+\r
+import java.util.ArrayList;\r
+import java.util.List;\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.binding.api.ReadWriteTransaction;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.FlatNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.NetworkTypeBase;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.VlanNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomain;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomainBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomainKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRef;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRefBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeFlat;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVlan;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.annotations.VisibleForTesting;\r
+import com.google.common.base.Function;\r
+import com.google.common.base.Optional;\r
+import com.google.common.collect.Lists;\r
+\r
+public class NetworkAware implements MappingProvider<Network> {\r
+\r
+ private static final Logger LOG = LoggerFactory.getLogger(NetworkAware.class);\r
+\r
+ private final DataBroker dataBroker;\r
+\r
+ public NetworkAware(DataBroker dataBroker) {\r
+ this.dataBroker = dataBroker;\r
+ }\r
+\r
+ @Override\r
+ public InstanceIdentifier<Network> getNeutronDtoIid() {\r
+ return InstanceIdentifier.builder(Neutron.class).child(Networks.class).child(Network.class).build();\r
+ }\r
+\r
+ @Override\r
+ public void processCreatedNeutronDto(Network network) {\r
+ BridgeDomain bridgeDomain = createBridgeDomain(network);\r
+ if (bridgeDomain != null) {\r
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
+ rwTx.put(LogicalDatastoreType.CONFIGURATION, getBridgeDomainIid(bridgeDomain.getId()), bridgeDomain);\r
+ DataStoreHelper.submitToDs(rwTx);\r
+ }\r
+ }\r
+\r
+ @VisibleForTesting\r
+ BridgeDomain createBridgeDomain(Network network) {\r
+ BridgeDomainBuilder bridgeDomainBuilder = new BridgeDomainBuilder();\r
+ String description = (network.getName() != null) ? network.getName() : "Neutron network";\r
+ bridgeDomainBuilder.setDescription(description);\r
+ bridgeDomainBuilder.setId(network.getUuid().getValue());\r
+ NetworkProviderExtension providerAug = network.getAugmentation(NetworkProviderExtension.class);\r
+ if (providerAug == null || providerAug.getNetworkType() == null) {\r
+ LOG.error("Cannot create VPP bridge domain. Network type not specified in neutron network: {}", network);\r
+ return null;\r
+ }\r
+ bridgeDomainBuilder.setPhysicalLocationRef(resolveDomainLocations(providerAug));\r
+ bridgeDomainBuilder.setType(convertNetworkType(providerAug.getNetworkType()));\r
+ if (providerAug.getNetworkType().isAssignableFrom(NetworkTypeVlan.class)\r
+ && providerAug.getSegmentationId() != null) {\r
+ try {\r
+ bridgeDomainBuilder.setVlan(new VlanId(Integer.valueOf(providerAug.getSegmentationId())));\r
+ } catch (NumberFormatException e) {\r
+ LOG.error("Neutron network {}. Cannot create VLAN ID from segmentation-id: {}. {}",\r
+ providerAug.getSegmentationId(), network.getUuid(), e);\r
+ return null;\r
+ }\r
+ }\r
+ return bridgeDomainBuilder.build();\r
+ }\r
+\r
+ @VisibleForTesting\r
+ List<PhysicalLocationRef> resolveDomainLocations(NetworkProviderExtension providerAug) {\r
+ List<PhysicalLocationRef> locationRefs = new ArrayList<>();\r
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+ if (providerAug.getPhysicalNetwork() == null) {\r
+ return null;\r
+ }\r
+ Optional<Topology> readTopology = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ getTopologyIid(new TopologyId(providerAug.getPhysicalNetwork())), rTx);\r
+ if (readTopology.isPresent()) {\r
+ Topology topology = readTopology.get();\r
+ for (Node node : topology.getNode()) {\r
+ PhysicalLocationRefBuilder location = new PhysicalLocationRefBuilder();\r
+ location.setNodeId(node.getNodeId());\r
+ location.setInterface(Lists.transform(node.getTerminationPoint(),\r
+ new Function<TerminationPoint, String>() {\r
+\r
+ @Override\r
+ public String apply(TerminationPoint input) {\r
+ return input.getTpId().getValue();\r
+ }\r
+ }));\r
+ locationRefs.add(location.build());\r
+ }\r
+ }\r
+ return locationRefs;\r
+ }\r
+\r
+ public static Class<? extends NetworkTypeBase> convertNetworkType(\r
+ Class<? extends org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeBase> base) {\r
+ if (base.isAssignableFrom(NetworkTypeFlat.class)) {\r
+ return FlatNetwork.class;\r
+ }\r
+ if (base.isAssignableFrom(NetworkTypeVlan.class)) {\r
+ return VlanNetwork.class;\r
+ }\r
+ throw new IllegalStateException("Unsupported network type: " + base);\r
+ }\r
+\r
+ InstanceIdentifier<Topology> getTopologyIid(TopologyId topologyId) {\r
+ return InstanceIdentifier.builder(NetworkTopology.class)\r
+ .child(Topology.class, new TopologyKey(topologyId))\r
+ .build();\r
+ }\r
+\r
+ InstanceIdentifier<BridgeDomain> getBridgeDomainIid(String id) {\r
+ return InstanceIdentifier.builder(Config.class).child(BridgeDomain.class, new BridgeDomainKey(id)).build();\r
+ }\r
+\r
+ @Override\r
+ public void processUpdatedNeutronDto(Network originalNetwork, Network updatedNetwork) {\r
+ InstanceIdentifier<BridgeDomain> bdId = getBridgeDomainIid(originalNetwork.getUuid().getValue());\r
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
+ rwTx.delete(LogicalDatastoreType.CONFIGURATION, bdId);\r
+ rwTx.put(LogicalDatastoreType.CONFIGURATION, bdId, createBridgeDomain(updatedNetwork));\r
+ DataStoreHelper.submitToDs(rwTx);\r
+ }\r
+\r
+ @Override\r
+ public void processDeletedNeutronDto(Network network) {\r
+ InstanceIdentifier<BridgeDomain> bdId = getBridgeDomainIid(network.getUuid().getValue());\r
+ ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction();\r
+ rwTx.delete(LogicalDatastoreType.CONFIGURATION, bdId);\r
+ DataStoreHelper.submitToDs(rwTx);\r
+ }\r
+}\r
\r
private void registerHandlersAndListeners(DataBroker dataBroker, SocketInfo socketInfo) {\r
PortHandler portHandler = new PortHandler(dataBroker, socketInfo);\r
- dataChangeProviders.add(new BaseEndpointByPortListener(portHandler, dataBroker));\r
+ dataChangeProviders.add(new PortAware(portHandler, dataBroker));\r
+ dataChangeProviders.add(new NetworkAware(dataBroker));\r
}\r
\r
@Override\r
import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;\r
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
\r
-public class BaseEndpointByPortListener extends DataTreeChangeHandler<BaseEndpointByPort> implements\r
+public class PortAware extends DataTreeChangeHandler<BaseEndpointByPort> implements\r
MappingProvider<Port> {\r
\r
private final PortHandler portHandler;\r
\r
- protected BaseEndpointByPortListener(PortHandler portHandler, DataBroker dataProvider) {\r
+ protected PortAware(PortHandler portHandler, DataBroker dataProvider) {\r
super(dataProvider);\r
this.portHandler = portHandler;\r
registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,\r
\r
private static final Logger LOG = LoggerFactory.getLogger(MappingProvider.class);\r
\r
- private static final String COMPUTE_OWNER = "compute";\r
+ private static final String[] COMPUTE_OWNER = {"compute"};\r
private static final String VHOST_USER = "vhostuser";\r
private static final String NETCONF_TOPOLOGY_ID = "topology-netconf";\r
\r
private BindingTransactionChain transactionChain;\r
- BaseEndpointByPortListener portByBaseEpListener;\r
+ PortAware portByBaseEpListener;\r
DataBroker dataBroker;\r
SocketInfo socketInfo;\r
\r
String vifType = portBindingExt.getVifType();\r
String deviceOwner = port.getDeviceOwner();\r
if (vifType != null && deviceOwner != null) {\r
- if (vifType.contains(VHOST_USER) && deviceOwner.contains(COMPUTE_OWNER)) {\r
- return true;\r
+ if (vifType.contains(VHOST_USER)) {\r
+ for (String computeOwner : COMPUTE_OWNER) {\r
+ if (deviceOwner.contains(computeOwner)) {\r
+ return true;\r
+ }\r
+ }\r
}\r
}\r
}\r
--- /dev/null
+/*\r
+ * Copyright (c) 2016 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.neutron.vpp.mapper.processors;\r
+\r
+import static org.junit.Assert.assertEquals;\r
+import static org.junit.Assert.assertNull;\r
+import static org.junit.Assert.assertFalse;\r
+import static org.junit.Assert.assertTrue;\r
+\r
+import java.util.List;\r
+import java.util.UUID;\r
+\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.mockito.Mockito;\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.binding.api.WriteTransaction;\r
+import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;\r
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.FlatNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.VlanNetwork;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomain;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRef;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeFlat;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVlan;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtensionBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;\r
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;\r
+\r
+import com.google.common.base.Optional;\r
+import com.google.common.collect.ImmutableList;\r
+\r
+public class NetworkAwareTest extends AbstractDataBrokerTest {\r
+\r
+ private DataBroker dataBroker;\r
+ private NetworkAware networkAware;\r
+ private NetworkProviderExtensionBuilder netExtBuilder;\r
+\r
+ @Before\r
+ public void init() {\r
+ dataBroker = Mockito.spy(getDataBroker());\r
+ networkAware = new NetworkAware(dataBroker);\r
+ netExtBuilder = new NetworkProviderExtensionBuilder();\r
+ netExtBuilder.setPhysicalNetwork("physicalNet");\r
+ }\r
+\r
+ @Test\r
+ public void testProcessCreatedNeutronDto_flat() {\r
+ netExtBuilder.setNetworkType(NetworkTypeFlat.class);\r
+ Network network = createTestNetwork("net", netExtBuilder.build());\r
+ networkAware.processCreatedNeutronDto(network);\r
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+ Optional<BridgeDomain> optBrDomain = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ networkAware.getBridgeDomainIid(network.getUuid().getValue()), rTx);\r
+ assertTrue(optBrDomain.isPresent());\r
+ }\r
+\r
+ @Test\r
+ public void testProcessUpdatedNeutronDto() {\r
+ netExtBuilder.setNetworkType(NetworkTypeFlat.class);\r
+ Network network1 = createTestNetwork("net1", netExtBuilder.build());\r
+ Network network2 = new NetworkBuilder(network1).setName("net2")\r
+ .addAugmentation(NetworkProviderExtension.class, netExtBuilder.build())\r
+ .build();\r
+ networkAware.processUpdatedNeutronDto(network1, network2);\r
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+ Optional<BridgeDomain> optBrDomain = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ networkAware.getBridgeDomainIid(network2.getUuid().getValue()), rTx);\r
+ assertTrue(optBrDomain.isPresent());\r
+ assertEquals(optBrDomain.get().getDescription(), "net2");\r
+ }\r
+\r
+ @Test\r
+ public void testProcessDeletedNeutronDto() {\r
+ netExtBuilder.setNetworkType(NetworkTypeFlat.class);\r
+ Network network = createTestNetwork("net1", netExtBuilder.build());\r
+ networkAware.processDeletedNeutronDto(network);\r
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();\r
+ Optional<BridgeDomain> optBrDomain = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,\r
+ networkAware.getBridgeDomainIid(network.getUuid().getValue()), rTx);\r
+ assertFalse(optBrDomain.isPresent());\r
+ }\r
+\r
+ @Test\r
+ public void testCreateBridgeDomain_vlanNetwork() {\r
+ netExtBuilder.setNetworkType(NetworkTypeVlan.class);\r
+ netExtBuilder.setSegmentationId("2016");\r
+ Network vlanNetwork = createTestNetwork("VlanNet", netExtBuilder.build());\r
+ BridgeDomain bridgeDomain = networkAware.createBridgeDomain(vlanNetwork);\r
+ assertEquals(bridgeDomain.getId(), vlanNetwork.getUuid().getValue());\r
+ assertEquals(bridgeDomain.getDescription(), vlanNetwork.getName());\r
+ assertEquals(bridgeDomain.getType(), VlanNetwork.class);\r
+ assertEquals(bridgeDomain.getVlan(), new VlanId(Integer.valueOf(2016)));\r
+ }\r
+\r
+ @Test\r
+ public void testCreateBridgeDomain_flatNetwork() {\r
+ netExtBuilder.setNetworkType(NetworkTypeFlat.class);\r
+ Network flatNetwork = createTestNetwork("FlatNet", netExtBuilder.build());\r
+ BridgeDomain bridgeDomain = networkAware.createBridgeDomain(flatNetwork);\r
+ assertEquals(bridgeDomain.getId(), flatNetwork.getUuid().getValue());\r
+ assertEquals(bridgeDomain.getDescription(), flatNetwork.getName());\r
+ assertEquals(bridgeDomain.getType(), FlatNetwork.class);\r
+ }\r
+\r
+ @Test\r
+ public void testCreateBridgeDomain_noPhysicalNetwork() {\r
+ netExtBuilder.setNetworkType(NetworkTypeFlat.class);\r
+ netExtBuilder.setPhysicalNetwork(null);\r
+ Network flatNetwork = createTestNetwork("FlatNet", netExtBuilder.build());\r
+ BridgeDomain bridgeDomain = networkAware.createBridgeDomain(flatNetwork);\r
+ assertNull(bridgeDomain.getPhysicalLocationRef());\r
+ }\r
+\r
+ @Test\r
+ public void testCreateBridgeDomain_noNetworkType() {\r
+ Network vlanNetwork = createTestNetwork("noTypeNet", new NetworkProviderExtensionBuilder().build());\r
+ BridgeDomain bridgeDomain = networkAware.createBridgeDomain(vlanNetwork);\r
+ assertNull(bridgeDomain);\r
+ }\r
+\r
+ @Test\r
+ public void testResolveDomainLocations() {\r
+ NodeId nodeId = new NodeId("node1");\r
+ TpId tpId = new TpId("tp1");\r
+ TopologyId topologyId = new TopologyId("physicalNet");\r
+ writeBasicTopology(topologyId, nodeId, tpId);\r
+ NetworkProviderExtension netExt = new NetworkProviderExtensionBuilder().setPhysicalNetwork("physicalNet")\r
+ .build();\r
+ List<PhysicalLocationRef> resolvedLocations = networkAware.resolveDomainLocations(netExt);\r
+ PhysicalLocationRef physLocationRef = resolvedLocations.get(0);\r
+ assertEquals(nodeId, physLocationRef.getNodeId());\r
+ assertEquals(tpId.getValue(), physLocationRef.getInterface().get(0));\r
+ }\r
+\r
+ private Network createTestNetwork(String name, NetworkProviderExtension ext) {\r
+ return new NetworkBuilder().setUuid(new Uuid(UUID.randomUUID().toString()))\r
+ .setName(name)\r
+ .addAugmentation(NetworkProviderExtension.class, ext)\r
+ .build();\r
+ }\r
+\r
+ private void writeBasicTopology(TopologyId topologyId, NodeId nodeId, TpId tpId) {\r
+ TerminationPoint tp = new TerminationPointBuilder().setTpId(tpId).build();\r
+ Node node = new NodeBuilder().setNodeId(new NodeId(nodeId))\r
+ .setTerminationPoint(ImmutableList.<TerminationPoint>of(tp))\r
+ .build();\r
+ Topology topology = new TopologyBuilder().setTopologyId(topologyId)\r
+ .setNode(ImmutableList.<Node>of(node))\r
+ .build();\r
+ WriteTransaction wTx = dataBroker.newWriteOnlyTransaction();\r
+ wTx.put(LogicalDatastoreType.CONFIGURATION, networkAware.getTopologyIid(new TopologyId("physicalNet")),\r
+ topology, true);\r
+ DataStoreHelper.submitToDs(wTx);\r
+ }\r
+}\r
private Port port;\r
private BaseEndpointByPort bebp;\r
private NeutronListener neutronListener;\r
- private BaseEndpointByPortListener baseEpByPortListener;\r
+ private PortAware baseEpByPortListener;\r
\r
@Before\r
public void init() {\r
dataBroker = getDataBroker();\r
neutronListener = new NeutronListener(dataBroker, socketInfo);\r
neutronListener.clearDataChangeProviders();\r
- baseEpByPortListener = Mockito.spy(new BaseEndpointByPortListener(new PortHandler(\r
+ baseEpByPortListener = Mockito.spy(new PortAware(new PortHandler(\r
dataBroker, socketInfo), dataBroker));\r
neutronListener.addDataChangeProvider(baseEpByPortListener);\r
}\r
.child(GbpByNeutronMappings.class)\r
.child(BaseEndpointsByPorts.class)\r
.child(BaseEndpointByPort.class)\r
- .build())), any(BaseEndpointByPortListener.class));\r
+ .build())), any(PortAware.class));\r
neutronListener.close();\r
}\r
\r
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.odlparent</groupId>
+ <artifactId>odlparent-lite</artifactId>
+ <version>1.7.0-SNAPSHOT</version>
+ <relativePath/>
+ </parent>
+
<groupId>org.opendaylight.groupbasedpolicy</groupId>
<artifactId>groupbasedpolicy.project</artifactId>
<version>0.4.0-SNAPSHOT</version>
<module>sxp-mapper</module>
</modules>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-deploy-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-install-plugin</artifactId>
+ <configuration>
+ <skip>true</skip>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
<scm>
<connection>scm:git:ssh://git.opendaylight.org:29418/groupbasedpolicy.git</connection>
<developerConnection>scm:git:ssh://git.opendaylight.org:29418/groupbasedpolicy.git</developerConnection>
<groupId>org.opendaylight.netconf</groupId>
<artifactId>sal-netconf-connector</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types-2013-07-15</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-module-junit4</artifactId>
+ <version>1.6.4</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.powermock</groupId>
+ <artifactId>powermock-api-mockito</artifactId>
+ <version>1.6.4</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<name>policy-validator-registry</name>
</policy-validator-registry>
- <renderer-name>ios-xe</renderer-name>
+ <renderer-name>ios-xe-renderer</renderer-name>
</module>
</modules>
</data>
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager;
-import com.google.common.util.concurrent.ListenableFuture;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+import com.google.common.util.concurrent.ListenableFuture;
+
/**
* Purpose: general policy manager prescription
*/
* synchronize given configuration with device
* @param dataBefore
* @param dataAfter
+ * @param version version needed to by apply
*/
- ListenableFuture<Boolean> syncPolicy(Configuration dataBefore, Configuration dataAfter);
+ ListenableFuture<Boolean> syncPolicy(Configuration dataBefore, Configuration dataAfter, long version);
@Override
void close();
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl;
+import com.google.common.base.Preconditions;
import java.util.List;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.IosXeRendererProvider;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache.EpPolicyCacheImpl;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener.EpPolicyTemplateBySgtListenerImpl;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener.IosXeCapableNodeListenerImpl;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener.RendererConfigurationListenerImpl;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.NodeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
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;
-
/**
* Purpose: bootstrap provider implementation of Ios-xe renderer
*/
private final DataBroker dataBroker;
private final RendererName rendererName;
private RendererConfigurationListenerImpl rendererConfigurationListener;
- private EpPolicyTemplateBySgtListenerImpl epPolicyTemplateBySgtListener;
private IosXeCapableNodeListenerImpl iosXeCapableNodeListener;
- private EpPolicyCacheImpl epPolicyCache;
- private PolicyManager policyManager;
- private NodeManager nodeManager;
public IosXeRendererProviderImpl(final DataBroker dataBroker, final BindingAwareBroker broker,
final RendererName rendererName) {
if (rendererConfigurationListener != null) {
rendererConfigurationListener.close();
}
- if (epPolicyTemplateBySgtListener != null) {
- epPolicyTemplateBySgtListener.close();
- }
if (iosXeCapableNodeListener != null) {
iosXeCapableNodeListener.close();
}
- if (epPolicyCache != null) {
- epPolicyCache.invalidateAll();
- }
}
@Override
LOG.info("starting ios-xe renderer");
//TODO register listeners:
// node-manager
- nodeManager = new NodeManager(dataBroker, providerContext);
- // ep-policy-template-by-sgt
- epPolicyCache = new EpPolicyCacheImpl();
- epPolicyTemplateBySgtListener = new EpPolicyTemplateBySgtListenerImpl(dataBroker, epPolicyCache);
+ NodeManager nodeManager = new NodeManager(dataBroker, providerContext);
// network-topology
iosXeCapableNodeListener = new IosXeCapableNodeListenerImpl(dataBroker, nodeManager);
// policy-manager and delegates
- policyManager = new PolicyManagerImpl(dataBroker, epPolicyCache);
+ PolicyManager policyManager = new PolicyManagerImpl(dataBroker, nodeManager);
final PolicyManager policyManagerZip = new PolicyManagerZipImpl(policyManager);
// renderer-configuration endpoints
+++ /dev/null
-/*
- * Copyright (c) 2016 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.ios_xe_provider.impl.cache;
-
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.cache.DSTreeBasedCache;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.RendererPolicyUtil;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
-
-/**
- * Purpose: cache for {@link EndpointPolicyTemplateBySgt}
- */
-public class EpPolicyCacheImpl implements DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> {
-
- private final ConcurrentMap<EpPolicyTemplateCacheKey, Sgt> cache;
- private final EpPolicyTemplateCacheKeyFactory keyFactory;
-
- public EpPolicyCacheImpl() {
- cache = new ConcurrentHashMap<>();
- keyFactory = new EpPolicyTemplateCacheKeyFactory(RendererPolicyUtil.createEndpointGroupIdOrdering(),
- RendererPolicyUtil.createConditionNameOrdering());
- }
-
- @Override
- public void invalidate(final EndpointPolicyTemplateBySgt exSource) {
- cache.remove(keyFactory.createKey(exSource));
- }
-
- @Override
- public void add(final EndpointPolicyTemplateBySgt newSource) {
- final EpPolicyTemplateCacheKey key = keyFactory.createKey(newSource);
- cache.put(key, newSource.getSgt());
- }
-
- @Override
- public void update(final EndpointPolicyTemplateBySgt before, final EndpointPolicyTemplateBySgt after) {
- cache.remove(keyFactory.createKey(before));
- cache.put(keyFactory.createKey(after), after.getSgt());
- }
-
- @Override
- public Sgt lookupValue(final EpPolicyTemplateCacheKey key) {
- return cache.get(keyFactory.createKey(key));
- }
-
- @Override
- public void invalidateAll() {
- cache.clear();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2016 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.ios_xe_provider.impl.listener;
-
-import com.google.common.base.Preconditions;
-import java.util.Collection;
-import javax.annotation.Nonnull;
-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.common.api.data.LogicalDatastoreType;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.cache.DSTreeBasedCache;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache.EpPolicyTemplateCacheKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.SxpMapper;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Purpose: listen to {@link EndpointPolicyTemplateBySgt} changes for caching purposes
- */
-public class EpPolicyTemplateBySgtListenerImpl implements DataTreeChangeListener<EndpointPolicyTemplateBySgt>, AutoCloseable {
-
- private static final Logger LOG = LoggerFactory.getLogger(EpPolicyTemplateBySgtListenerImpl.class);
-
- private final ListenerRegistration<EpPolicyTemplateBySgtListenerImpl> listenerRegistration;
- private final DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> cache;
-
- public EpPolicyTemplateBySgtListenerImpl(final DataBroker dataBroker,
- final DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> cache) {
- this.cache = Preconditions.checkNotNull(cache, "missing ep-policy-template cache");
- final InstanceIdentifier<EndpointPolicyTemplateBySgt> templatePath = InstanceIdentifier.create(SxpMapper.class)
- .child(EndpointPolicyTemplateBySgt.class);
-
- final DataTreeIdentifier<EndpointPolicyTemplateBySgt> treePath = new DataTreeIdentifier<>(
- LogicalDatastoreType.CONFIGURATION, templatePath);
- listenerRegistration = dataBroker.registerDataTreeChangeListener(treePath, this);
- LOG.info("ep-policy-template listener registered");
- }
-
- @Override
- public void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<EndpointPolicyTemplateBySgt>> collection) {
- LOG.debug("ep-policy-template changed");
- for (DataTreeModification<EndpointPolicyTemplateBySgt> epPolicyTemplateModification : collection) {
- final DataObjectModification<EndpointPolicyTemplateBySgt> rootNode = epPolicyTemplateModification
- .getRootNode();
- final DataObjectModification.ModificationType modificationType = rootNode.getModificationType();
- switch (modificationType) {
- case DELETE:
- // invalidate cache
- cache.invalidate(rootNode.getDataBefore());
- break;
- case WRITE:
- // extend cache
- cache.add(rootNode.getDataAfter());
- break;
- case SUBTREE_MODIFIED:
- // update cache
- cache.update(rootNode.getDataBefore(), rootNode.getDataAfter());
- break;
- default:
- LOG.warn("modification type not supported: {}", modificationType);
- }
- }
- }
-
- @Override
- public void close() {
- listenerRegistration.close();
- }
-}
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener;
import com.google.common.base.Preconditions;
-import java.util.Collection;
-import javax.annotation.Nonnull;
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.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.Renderer;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.RendererKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.annotation.Nonnull;
+import java.util.Collection;
+import java.util.Optional;
+
/**
* Purpose: process changes of configured renderer policies
*/
final RendererPolicy dataBefore = rootNode.getDataBefore();
final RendererPolicy dataAfter = rootNode.getDataAfter();
- if (dataAfter != null && dataBefore == null) {
- policyManager.syncPolicy(dataAfter.getConfiguration(), null);
- }
- else if (dataAfter == null && dataBefore != null) {
- policyManager.syncPolicy(null, dataBefore.getConfiguration());
+ // Policy configuration
+ Configuration oldConfig = null;
+ Configuration newConfig = null;
+ long version = 0;
+ if (dataBefore != null) {
+ oldConfig = dataBefore.getConfiguration();
}
- else if (dataAfter != null) {
- policyManager.syncPolicy(dataAfter.getConfiguration(), dataBefore.getConfiguration());
+ if (dataAfter != null) {
+ newConfig = dataAfter.getConfiguration();
+ if (dataAfter.getVersion() != null) {
+ version = dataAfter.getVersion();
+ }
}
+ policyManager.syncPolicy(newConfig, oldConfig, version);
}
}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.MountPoint;
import org.opendaylight.controller.md.sal.binding.api.MountPointService;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.NodeWriter;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NodeWriter;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.RendererName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.slf4j.LoggerFactory;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
-import java.util.Map;
import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connected;
import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connecting;
public static final RendererName iosXeRenderer = new RendererName("ios-xe-renderer");
private static final TopologyId TOPOLOGY_ID = new TopologyId("topology-netconf");
private static final Logger LOG = LoggerFactory.getLogger(NodeManager.class);
- private static final Map<InstanceIdentifier, DataBroker> netconfNodeCache = new HashMap<>();
private final DataBroker dataBroker;
private final MountPointService mountService;
private final List<String> requiredCapabilities;
requiredCapabilities = new RequiredCapabilities().initializeRequiredCapabilities();
}
- static DataBroker getDataBrokerFromCache(InstanceIdentifier iid) {
- return netconfNodeCache.get(iid); // TODO read from DS
- }
-
public void syncNodes(Node dataAfter, Node dataBefore) {
// New node
if (dataBefore == null && dataAfter != null) {
InstanceIdentifier mountPointIid = getMountpointIid(node);
// Mountpoint iid == path in renderer-node
RendererNode rendererNode = remapNode(mountPointIid);
- DataBroker mountpoint = getNodeMountPoint(mountPointIid);
NodeWriter nodeWriter = new NodeWriter();
nodeWriter.cache(rendererNode);
if (isCapableNetconfDevice(node, netconfNode)) {
+ resolveDisconnectedNode(node);
+ return;
+ }
+ IpAddress managementIpAddress = netconfNode.getHost().getIpAddress();
+ if (managementIpAddress == null) {
+ LOG.warn("Node {} does not contain management ip address", node.getNodeId().getValue());
+ resolveDisconnectedNode(node);
return;
}
nodeWriter.commitToDatastore(dataBroker);
- netconfNodeCache.put(mountPointIid, mountpoint);
}
private void resolveDisconnectedNode(Node node) {
NodeWriter nodeWriter = new NodeWriter();
nodeWriter.cache(rendererNode);
nodeWriter.removeFromDatastore(dataBroker);
- netconfNodeCache.remove(mountPointIid);
}
private RendererNode remapNode(InstanceIdentifier path) {
return true;
}
- private DataBroker getNodeMountPoint(InstanceIdentifier mountPointIid) {
+ DataBroker getNodeMountPoint(InstanceIdentifier mountPointIid) {
+ if (mountPointIid == null) {
+ return null;
+ }
Optional<MountPoint> optionalObject = mountService.getMountPoint(mountPointIid);
MountPoint mountPoint;
if (optionalObject.isPresent()) {
return null;
}
+ NodeId getNodeIdByMountpointIid(InstanceIdentifier mountpointIid) {
+ NodeKey identifier = (NodeKey) mountpointIid.firstKeyOf(Node.class);
+ return identifier.getNodeId();
+ }
+
+ String getNodeManagementIpByMountPointIid(InstanceIdentifier mountpointIid) {
+ NodeId nodeId = getNodeIdByMountpointIid(mountpointIid);
+ InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId(NodeManager.TOPOLOGY_ID)))
+ .child(Node.class, new NodeKey(nodeId)).build();
+ ReadWriteTransaction rwt = dataBroker.newReadWriteTransaction();
+ try {
+ CheckedFuture<Optional<Node>, ReadFailedException> submitFuture =
+ rwt.read(LogicalDatastoreType.CONFIGURATION, nodeIid);
+ Optional<Node> optional = submitFuture.checkedGet();
+ if (optional != null && optional.isPresent()) {
+ Node node = optional.get();
+ if (node != null) {
+ NetconfNode netconfNode = getNodeAugmentation(node);
+ if (netconfNode != null && netconfNode.getHost() != null) {
+ IpAddress ipAddress = netconfNode.getHost().getIpAddress();
+ if (ipAddress != null && ipAddress.getIpv4Address() != null) {
+ return ipAddress.getIpv4Address().getValue();
+ }
+ return null;
+ }
+ }
+ } else {
+ LOG.debug("Failed to read. {}", Thread.currentThread().getStackTrace()[1]);
+ }
+ } catch (ReadFailedException e) {
+ LOG.warn("Read transaction failed to {} ", e);
+ } catch (Exception e) {
+ LOG.error("Failed to .. {}", e.getMessage());
+ }
+ return null;
+ }
+
private NetconfNode getNodeAugmentation(Node node) {
NetconfNode netconfNode = node.getAugmentation(NetconfNode.class);
if (netconfNode == null) {
* @return list of string representations of required capabilities
*/
List<String> initializeRequiredCapabilities() {
- String writableDataStore = "urn:ietf:params:netconf:capability:writable-running:1.0";
String capabilityEntries[] = {ned, tailfCommon, tailfCliExtension, tailfMetaExtension, ietfYangTypes,
- ietfInetTypes, writableDataStore};
+ ietfInetTypes};
return Arrays.asList(capabilityEntries);
}
}
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
+
+import com.google.common.base.Function;
import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.groupbasedpolicy.api.sf.AllowActionDefinition;
-import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.cache.DSTreeBasedCache;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache.EpPolicyTemplateCacheKey;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyWriter;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.RendererPolicyUtil;
-import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.LocalBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.ConfigServiceChainPathModeBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.ServiceIndexBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.Services;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.ServicesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.ServiceTypeChoice;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionForwarderBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308.config.service.chain.grouping.IpBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.AddressEndpointKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
-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.HasDirection;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
+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.RendererKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.In;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.CONSUMER;
-import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER;
-
public class PolicyManagerImpl implements PolicyManager {
- private static final Logger LOG = LoggerFactory.getLogger(PolicyMapper.class);
+ private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerImpl.class);
+ private static final String policyMapName = "service-chains";
private final DataBroker dataBroker;
- private DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> epPolicyCache;
- private final PolicyMapper mapper;
- private final String policyMapName = "service-chains";
- private Map<DataBroker, PolicyWriter> perDeviceWriterCache = new HashMap<>();
-
- public enum ActionCase { ALLOW, CHAIN }
-
+ private final NodeManager nodeManager;
public PolicyManagerImpl(final DataBroker dataBroker,
- final DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> epPolicyCache) {
+ final NodeManager nodeManager) {
this.dataBroker = Preconditions.checkNotNull(dataBroker);
- this.epPolicyCache = Preconditions.checkNotNull(epPolicyCache);
- mapper = new PolicyMapper(dataBroker);
+ this.nodeManager = Preconditions.checkNotNull(nodeManager);
}
@Override
- public ListenableFuture<Boolean> syncPolicy(final Configuration dataBefore, final Configuration dataAfter) {
- // CREATE
+ public ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, final Configuration dataBefore,
+ final long version) {
+ final ListenableFuture<Boolean> result;
+ if (dataBefore == null && dataAfter != null) {
+ result = syncPolicy(dataAfter, Create);
+ } else if (dataBefore != null && dataAfter == null) {
+ result = syncPolicy(dataBefore, Delete);
+ } else {
+ // TODO implement
+ result = Futures.immediateFuture(false);
+ }
+
+ reportVersion(version);
+
+ // chain version update (TODO: status)
+ return Futures.transform(result, new AsyncFunction<Boolean, Boolean>() {
+ @Override
+ public ListenableFuture<Boolean> apply(final Boolean input) throws Exception {
+ if (input != null && input) {
+ return Futures.transform(reportVersion(version), new Function<Void, Boolean>() {
+ @Nullable
+ @Override
+ public Boolean apply(@Nullable final Void input) {
+ return Boolean.TRUE;
+ }
+ });
+ } else {
+ return Futures.immediateFuture(input);
+ }
+ }
+ });
+ }
+
+ private ListenableFuture<Boolean> syncPolicy(final Configuration dataAfter, DsAction action) {
+ if (dataAfter.getRendererEndpoints() == null
+ || dataAfter.getRendererEndpoints().getRendererEndpoint() == null) {
+ LOG.debug("no configuration obtained - skipping");
+ return Futures.immediateFuture(true);
+ }
+ final Map<DataBroker, PolicyWriter> policyWriterPerDeviceCache = new HashMap<>();
for (RendererEndpoint rendererEndpoint : dataAfter.getRendererEndpoints().getRendererEndpoint()) {
- // Get mountpoint
- if (dataAfter.getEndpoints() == null) {
+ if (dataAfter.getEndpoints() == null || dataAfter.getEndpoints().getAddressEndpointWithLocation() == null) {
+ LOG.debug("renderer-endpoint: missing address-endpoint-with-location");
+ //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
continue;
}
- DataBroker mountpoint = getAbsoluteLocationMountpoint(rendererEndpoint, dataAfter.getEndpoints()
- .getAddressEndpointWithLocation());
+
+ final List<AddressEndpointWithLocation> endpointsWithLocation = dataAfter.getEndpoints()
+ .getAddressEndpointWithLocation();
+ final InstanceIdentifier mountpointIid = PolicyManagerUtil.getAbsoluteLocationMountpoint(rendererEndpoint, endpointsWithLocation);
+ final DataBroker mountpoint = nodeManager.getNodeMountPoint(mountpointIid);
if (mountpoint == null) {
+ LOG.debug("no data-broker for mount-point [{}] available", mountpointIid);
+ //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
continue;
}
- // Initialize appropriate writer
- PolicyWriter policyWriter;
- if (perDeviceWriterCache.containsKey(mountpoint)) {
- policyWriter = perDeviceWriterCache.get(mountpoint);
- } else {
- policyWriter = new PolicyWriter(mountpoint);
- perDeviceWriterCache.put(mountpoint, policyWriter);
+
+ // Find policy writer
+ PolicyWriter policyWriter = policyWriterPerDeviceCache.get(mountpoint);
+ if (policyWriter == null) {
+ // Initialize new policy writer
+ final String interfaceName = PolicyManagerUtil.getInterfaceNameForPolicyMap(rendererEndpoint, endpointsWithLocation);
+ final NodeId nodeId = nodeManager.getNodeIdByMountpointIid(mountpointIid);
+ final String managementIpAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
+ if (interfaceName == null || managementIpAddress == null) {
+ LOG.debug("can not create policyWriter: interface={}, managementIpAddress={}",
+ interfaceName, managementIpAddress);
+ //TODO: dump all resolvedRule-rule-peerEP-EP combinantions to status
+ continue;
+ }
+ policyWriter = new PolicyWriter(mountpoint, interfaceName, managementIpAddress, policyMapName, nodeId);
+ policyWriterPerDeviceCache.put(mountpoint, policyWriter);
}
+
+ final Sgt sourceSgt = PolicyManagerUtil.findSgtTag(rendererEndpoint, dataAfter.getEndpoints()
+ .getAddressEndpointWithLocation());
// Peer Endpoint
for (PeerEndpointWithPolicy peerEndpoint : rendererEndpoint.getPeerEndpointWithPolicy()) {
- // Sgt Tags
- final Sgt sourceSgt = findSgtTag(rendererEndpoint, dataAfter.getEndpoints()
- .getAddressEndpointWithLocation());
- final Sgt destinationSgt = findSgtTag(peerEndpoint, dataAfter.getEndpoints()
+ final Sgt destinationSgt = PolicyManagerUtil.findSgtTag(peerEndpoint, dataAfter.getEndpoints()
.getAddressEndpointWithLocation());
if (sourceSgt == null || destinationSgt == null) {
+ LOG.debug("endpoint-policy: missing sgt value(sourceSgt={}, destinationSgt={})",
+ sourceSgt, destinationSgt);
+ //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
continue;
}
- syncPolicyEntities(sourceSgt, destinationSgt, policyWriter, dataAfter, peerEndpoint);
+ PolicyManagerUtil.syncPolicyEntities(sourceSgt, destinationSgt, policyWriter, dataAfter, peerEndpoint);
}
}
- // Flush
- perDeviceWriterCache.values().forEach(PolicyWriter::commitToDatastore);
- perDeviceWriterCache.clear();
-
- return Futures.immediateFuture(true);
- }
-
- private void syncPolicyEntities(final Sgt sourceSgt, final Sgt destinationSgt, PolicyWriter policyWriter,
- final Configuration dataAfter, final PeerEndpointWithPolicy peerEndpoint) {
- // Class map
- String classMapName = generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
- Match match = mapper.createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
- ClassMap classMap = mapper.createClassMap(classMapName, match);
- policyWriter.write(classMap);
-
- Map<ActionCase, Action> actionMap = getActionInDirection(dataAfter, peerEndpoint);
- if (actionMap == null || actionMap.isEmpty()) {
- return;
- }
- // Policy map entry
- List<Class> policyMapEntries = new ArrayList<>();
- if (actionMap.containsKey(ActionCase.ALLOW)) {
- policyMapEntries = resolveAllowAction();
- }
- if (actionMap.containsKey(ActionCase.CHAIN)) {
- policyMapEntries = resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName);
- }
- policyWriter.write(policyMapEntries);
- }
- private Sgt findSgtTag(final AddressEndpointKey endpointKey,
- final List<AddressEndpointWithLocation> endpointsWithLocation) {
- if (endpointKey == null || endpointsWithLocation == null) {
- return null;
- }
- AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpointKey,
- endpointsWithLocation);
- return epPolicyCache.lookupValue(new EpPolicyTemplateCacheKey(endpointWithLocation));
- }
+ //TODO: return real (cumulated) future
+ final List<CheckedFuture<Void, TransactionCommitFailedException>> allFutureResults = new ArrayList<>();
+ if (action.equals(Create)) {
+ policyWriterPerDeviceCache.values().forEach(pw -> allFutureResults.add(pw.commitToDatastore()));
+ } else if (action.equals(Delete)) {
+ policyWriterPerDeviceCache.values().forEach(pw -> allFutureResults.add(pw.removeFromDatastore()));
+ } else {
+ LOG.info("unsupported policy manage action: {}", action);
- private List<Class> resolveChainAction(final PeerEndpointWithPolicy peerEndpoint, final Sgt sourceSgt,
- final Sgt destinationSgt, final Map<ActionCase, Action> actionMap,
- final String classMapName) {
- List<Class> entries = new ArrayList<>();
- final Action action = actionMap.get(ActionCase.CHAIN);
- ServiceFunctionPath servicePath = PolicyManagerUtil.getServicePath(action.getParameterValue());
- if (servicePath == null) {
- return null;
}
- TenantId tenantId = getTenantId(peerEndpoint);
- if (tenantId == null) {
- return null;
- }
- RenderedServicePath renderedPath = PolicyManagerUtil.createRenderedPath(servicePath, tenantId);
- entries.add(mapper.createPolicyEntry(classMapName, renderedPath, ActionCase.CHAIN));
- if (servicePath.isSymmetric()) {
- // symmetric path is in opposite direction. Roles of renderer and peer endpoint will invert
- RenderedServicePath symmetricPath = PolicyManagerUtil
- .createSymmetricRenderedPath(servicePath, renderedPath, tenantId);
- String oppositeClassMapName = generateClassMapName(destinationSgt.getValue(), sourceSgt.getValue());
- entries.add(mapper.createPolicyEntry(oppositeClassMapName, symmetricPath, ActionCase.CHAIN));
- }
- return entries;
- }
- private List<Class> resolveAllowAction() {
- List<Class> entries = new ArrayList<>();
- entries.add(mapper.createPolicyEntry(policyMapName, null, ActionCase.ALLOW));
- return entries;
- }
+ final ListenableFuture<List<Void>> cumulativeResult = Futures.allAsList(allFutureResults);
- private DataBroker getAbsoluteLocationMountpoint(final RendererEndpoint endpoint,
- final List<AddressEndpointWithLocation> endpointsWithLocation) {
- if (endpoint == null || endpointsWithLocation == null) {
- return null;
- }
- AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint,
- endpointsWithLocation);
- final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation();
- final LocationType locationType = absoluteLocation.getLocationType();
- ExternalLocationCase location = (ExternalLocationCase) locationType;
- if (location == null) {
- LOG.warn("Endpoint {} does not contain info about external location",
- endpointWithLocation.getKey().toString());
- return null;
- }
- InstanceIdentifier mountPointId = location.getExternalNodeMountPoint();
- return NodeManager.getDataBrokerFromCache(mountPointId);
- }
-
- private String generateClassMapName(Integer sourceTag, Integer destinationTag) {
- return "srcTag" + sourceTag + "_dstTag" + destinationTag;
- }
-
- private Map<ActionCase, Action> getActionInDirection(Configuration data, PeerEndpointWithPolicy peer) {
- List<ResolvedRule> rulesInDirection = new ArrayList<>();
- // Find all rules in desired direction
- for (RuleGroupWithRendererEndpointParticipation ruleGroupKey :
- peer.getRuleGroupWithRendererEndpointParticipation()) {
- EndpointPolicyParticipation participation = ruleGroupKey.getRendererEndpointParticipation();
- RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey);
- if (ruleGroup == null || ruleGroup.getResolvedRule() == null) {
- continue;
- }
-
- for (ResolvedRule resolvedRule : ruleGroup.getResolvedRule()) {
- if (resolvedRule == null) {
- continue;
- }
- if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) {
- continue;
- }
- // TODO only first Classifier used
- Classifier classifier = resolvedRule.getClassifier().get(0);
- HasDirection.Direction direction = classifier.getDirection();
- if ((participation.equals(PROVIDER) && direction.equals(Out)) ||
- (participation.equals(CONSUMER) && direction.equals(In))) {
- rulesInDirection.add(resolvedRule);
- }
- }
- }
- if (rulesInDirection.isEmpty()) {
- return null; // TODO define drop?
- }
- // TODO use only first rule with ActionDefinitionID for now
- Map<ActionCase, Action> result = new HashMap<>();
- for (ResolvedRule resolvedRule : rulesInDirection) {
- // TODO only first action used for now
- Action action = resolvedRule.getAction().get(0);
- if (action.getActionDefinitionId() != null) {
- ActionDefinitionId actionDefinitionId = action.getActionDefinitionId();
- if (actionDefinitionId.equals(AllowActionDefinition.ID)) {
- result.put(ActionCase.ALLOW, action);
- return result;
- } else if (actionDefinitionId.equals(ChainActionDefinition.ID)) {
- result.put(ActionCase.CHAIN, action);
- return result;
- }
- }
- }
- return null;
- }
-
- private RuleGroup findRuleGroup(final Configuration data,
- final RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation) {
- final TenantId tenantId = ruleGroupWithParticipation.getTenantId();
- final ContractId contractId = ruleGroupWithParticipation.getContractId();
- final SubjectName subjectName = ruleGroupWithParticipation.getSubjectName();
- for (RuleGroup ruleGroup : data.getRuleGroups().getRuleGroup()) {
- if (!ruleGroup.getTenantId().equals(tenantId))
- continue;
- if (!ruleGroup.getContractId().equals(contractId)) {
- continue;
- }
- if (ruleGroup.getSubjectName().equals(subjectName)) {
- return ruleGroup;
- }
- }
- return null;
- }
-
- private TenantId getTenantId(PeerEndpointWithPolicy peer) {
- for (RuleGroupWithRendererEndpointParticipation ruleGroup :
- peer.getRuleGroupWithRendererEndpointParticipation()) {
- if (ruleGroup.getTenantId() != null) {
- return ruleGroup.getTenantId();
+ return Futures.transform(cumulativeResult, new Function<List<Void>, Boolean>() {
+ @Nullable
+ @Override
+ public Boolean apply(@Nullable final List<Void> input) {
+ LOG.trace("considering all submits as successful - otherwise there will be exception");
+ return Boolean.TRUE;
}
- }
- return null;
- }
-
-
- private void resolveFirstSffOnClassifier(final Ipv4Address nodeIpAddress,
- final Set<RenderedServicePath> firstHops) {
- // Local forwarder
- LocalBuilder localSffBuilder = new LocalBuilder();
- localSffBuilder.setIp(new IpBuilder().setAddress(nodeIpAddress).build());
-
- // TODO add sff to writer
-
- for (RenderedServicePath renderedPath : firstHops) {
- // Remote forwarder
- RenderedServicePathHop firstRenderedPathHop = renderedPath.getRenderedServicePathHop().get(0);
- SffName sffName = firstRenderedPathHop.getServiceFunctionForwarder();
-
- // Remap sff and its management ip address
- org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder serviceFunctionForwarder =
- SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sffName);
- String sffMgmtIpAddress = serviceFunctionForwarder.getIpMgmtAddress().getIpv4Address().getValue();
-
- ServiceFfNameBuilder remoteSffBuilder = new ServiceFfNameBuilder();
- remoteSffBuilder.setName(sffName.getValue())
- .setKey(new ServiceFfNameKey(sffName.getValue()))
- .setIp(new IpBuilder().setAddress(new Ipv4Address(sffMgmtIpAddress)).build());
- // TODO add sff to writer
-
- // Service chain
- List<Services> services = new ArrayList<>();
- ServiceTypeChoice serviceTypeChoice = sffTypeChoice(sffName.getValue());
- ServicesBuilder servicesBuilder = new ServicesBuilder();
- servicesBuilder.setServiceIndexId(renderedPath.getStartingIndex())
- .setServiceTypeChoice(serviceTypeChoice);
- List<ServicePath> servicePaths = new ArrayList<>();
- ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
- servicePathBuilder.setKey(new ServicePathKey(renderedPath.getPathId()))
- .setServicePathId(renderedPath.getPathId())
- .setConfigServiceChainPathMode(new ConfigServiceChainPathModeBuilder()
- .setServiceIndex(new ServiceIndexBuilder()
- .setServices(services).build()).build());
- servicePaths.add(servicePathBuilder.build());
- ServiceChainBuilder chainBuilder = new ServiceChainBuilder();
- chainBuilder.setServicePath(servicePaths);
- ServiceChain serviceChain = chainBuilder.build();
- // TODO add service-chain to writer
- }
+ });
}
- private ServiceTypeChoice sffTypeChoice(String forwarderName) {
- ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder();
- sffBuilder.setServiceFunctionForwarder(forwarderName);
- return sffBuilder.build();
+ private CheckedFuture<Void, TransactionCommitFailedException> reportVersion(long version) {
+ WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
+ InstanceIdentifier<RendererPolicy> iid = InstanceIdentifier.create(Renderers.class)
+ .child(Renderer.class, new RendererKey(NodeManager.iosXeRenderer))
+ .child(RendererPolicy.class);
+ wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, new RendererPolicyBuilder().setVersion(version).build());
+ return wtx.submit();
}
@Override
public void close() {
//NOOP
}
+
+ enum DsAction {Create, Delete}
+
+ public enum ActionCase {ALLOW, CHAIN}
}
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.ListeningExecutorService;
-import com.google.common.util.concurrent.MoreExecutors;
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BinaryOperator;
+
import org.apache.commons.lang3.tuple.MutablePair;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
/**
* Purpose: wrap {@link PolicyManager} with state compression mechanism
*/
}
@Override
- public ListenableFuture<Boolean> syncPolicy(final Configuration dataBefore, final Configuration dataAfter) {
+ public ListenableFuture<Boolean> syncPolicy(final Configuration dataBefore, final Configuration dataAfter, final long version) {
LOG.trace("firing configuration zip");
// add config to zipping storage
final ConfigPairBox configPair = new ConfigPairBox(dataBefore, dataAfter);
public ListenableFuture<Boolean> call() throws Exception {
final ConfigPairBox configPairBox = configPairKeeper.getAndSet(null);
LOG.debug("delegating policy configuration");
- return delegate.syncPolicy(configPairBox.getLeft(), configPair.getRight());
+ return delegate.syncPolicy(configPairBox.getLeft(), configPair.getRight(), version);
}
}));
} else {
+++ /dev/null
-/*
- * Copyright (c) 2016 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.ios_xe_provider.impl.manager;
-
-import com.google.common.base.Preconditions;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308.PolicyActionType;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.SecurityGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Destination;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.DestinationBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Source;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.SourceBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.Type;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.TypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.MatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionList;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.ForwardCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.ForwardBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePath;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathBuilder;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathKey;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN;
-
-class PolicyMapper {
-
- private final DataBroker dataBroker;
- private static final Logger LOG = LoggerFactory.getLogger(PolicyMapper.class);
-
- PolicyMapper(final DataBroker dataBroker) {
- this.dataBroker = Preconditions.checkNotNull(dataBroker);
- }
-
- Match createSecurityGroupMatch(int sourceTag, int destinationTag) {
- MatchBuilder matchBuilder = new MatchBuilder();
- SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder();
- Source source = new SourceBuilder().setTag(sourceTag).build();
- Destination destination = new DestinationBuilder().setTag(destinationTag).build();
- sgBuilder.setSource(source)
- .setDestination(destination);
- return matchBuilder.setSecurityGroup(sgBuilder.build()).build();
- }
-
- ClassMap createClassMap(final String classMapName, Match match) {
- ClassMapBuilder cmBuilder = new ClassMapBuilder();
- cmBuilder.setName(classMapName)
- .setKey(new ClassMapKey(classMapName))
- .setMatch(match)
- .setPrematch(ClassMap.Prematch.MatchAll);
- return cmBuilder.build();
- }
-
- Class createPolicyEntry(String policyClassName, RenderedServicePath renderedPath,
- PolicyManagerImpl.ActionCase actionCase) {
- // Forward Case
- ForwardCaseBuilder forwardCaseBuilder = new ForwardCaseBuilder();
- if (actionCase.equals(CHAIN) && renderedPath != null) {
- // Chain Action
- ForwardBuilder forwardBuilder = new ForwardBuilder();
- List<ServicePath> servicePaths = new ArrayList<>();
- ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
- servicePathBuilder.setKey(new ServicePathKey(renderedPath.getPathId()))
- .setServicePathId(renderedPath.getPathId())
- .setServiceIndex(renderedPath.getStartingIndex());
- servicePaths.add(servicePathBuilder.build());
- forwardBuilder.setServicePath(servicePaths);
- forwardCaseBuilder.setForward(forwardBuilder.build());
- }
- // Create Action List
- List<ActionList> actionList = new ArrayList<>();
- ActionListBuilder actionListBuilder = new ActionListBuilder();
- actionListBuilder.setKey(new ActionListKey(PolicyActionType.Forward))
- .setActionType(PolicyActionType.Forward)
- .setActionParam(forwardCaseBuilder.build());
- actionList.add(actionListBuilder.build());
- // Build class entry
- ClassBuilder policyClassBuilder = new ClassBuilder();
- policyClassBuilder.setName(new ClassNameType(policyClassName))
- .setKey(new ClassKey(new ClassNameType(policyClassName)))
- .setActionList(actionList);
- return policyClassBuilder.build();
- }
-
- public Type getServicePolicyType(String name) {
- TypeBuilder typeBuilder = new TypeBuilder();
- org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChainBuilder serviceChainBuilder =
- new org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChainBuilder();
- serviceChainBuilder.setName(name)
- .setDirection(org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction.Input);
- typeBuilder.setServiceChain(serviceChainBuilder.build());
- return typeBuilder.build();
- }
-
- PolicyMap policyMap(String policyMapName) {
- PolicyMapBuilder pmBuilder = new PolicyMapBuilder();
- pmBuilder.setName(policyMapName)
- .setKey(new PolicyMapKey(policyMapName))
- .setType(null);
- return pmBuilder.build();
- }
-}
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
+import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.In;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.CONSUMER;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
-import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
-import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
-import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.PolicyActionType;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.SecurityGroup;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.SecurityGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Destination;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.DestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Source;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.SourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.TypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionList;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.AppnavPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.ForwardCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.ForwardBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePath;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.AddressEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
+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.subject.feature.instance.ParameterValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
public class PolicyManagerUtil {
private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerUtil.class);
- public static ServiceFunctionPath getServicePath(List<ParameterValue> params) {
- if (params == null || params.isEmpty()) {
- LOG.error("Cannot found service path, parameter value is null");
+ public static void syncPolicyEntities(final Sgt sourceSgt, final Sgt destinationSgt, PolicyWriter policyWriter,
+ final Configuration dataAfter, final PeerEndpointWithPolicy peerEndpoint) {
+ // Class map
+ final String classMapName = PolicyManagerUtil.generateClassMapName(sourceSgt.getValue(), destinationSgt.getValue());
+ final Match match = PolicyManagerUtil.createSecurityGroupMatch(sourceSgt.getValue(), destinationSgt.getValue());
+ final ClassMap classMap = PolicyManagerUtil.createClassMap(classMapName, match);
+ final Map<PolicyManagerImpl.ActionCase, Action> actionMap = PolicyManagerUtil.getActionInDirection(dataAfter, peerEndpoint);
+ if (actionMap == null || actionMap.isEmpty()) {
+ LOG.debug("no usable action found for EP-sgt[{}] | peerEP-sgt[{}]",
+ sourceSgt, destinationSgt);
+ return;
+ }
+ policyWriter.cache(classMap);
+
+ // Policy map entry
+ if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN)) {
+ ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+ }
+ }
+
+ public static Sgt findSgtTag(final AddressEndpointKey endpointKey,
+ final List<AddressEndpointWithLocation> endpointsWithLocation) {
+ if (endpointKey == null || endpointsWithLocation == null) {
return null;
}
- Map<String, Object> paramsMap = new HashMap<>();
- for (ParameterValue value : params) {
- if (value.getName() == null)
- continue;
- if (value.getIntValue() != null) {
- paramsMap.put(value.getName().getValue(), value.getIntValue());
- } else if (value.getStringValue() != null) {
- paramsMap.put(value.getName().getValue(), value.getStringValue());
- }
+ final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpointKey,
+ endpointsWithLocation);
+ final AddressEndpointWithLocationAug augmentation = endpointWithLocation.getAugmentation(AddressEndpointWithLocationAug.class);
+ if (augmentation == null) {
+ return null;
}
- String chainName = null;
- for (String name : paramsMap.keySet()) {
- if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) {
- chainName = (String) paramsMap.get(name);
+
+ return augmentation.getSgt();
+ }
+
+ private static Match createSecurityGroupMatch(final int sourceTag, final int destinationTag) {
+ final SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder();
+ final Source source = new SourceBuilder().setTag(sourceTag).build();
+ final Destination destination = new DestinationBuilder().setTag(destinationTag).build();
+ sgBuilder.setDestination(destination)
+ .setSource(source);
+ final SecurityGroup securityGroup = sgBuilder.build();
+ final MatchBuilder matchBuilder = new MatchBuilder();
+ matchBuilder.setSecurityGroup(securityGroup);
+ return matchBuilder.build();
+ }
+
+ static ClassMap createClassMap(final String classMapName, final Match match) {
+ final ClassMapBuilder cmBuilder = new ClassMapBuilder();
+ cmBuilder.setName(classMapName)
+ .setKey(new ClassMapKey(classMapName))
+ .setPrematch(ClassMap.Prematch.MatchAll)
+ .setMatch(match);
+ return cmBuilder.build();
+ }
+
+ static TenantId getTenantId(final PeerEndpointWithPolicy peer) {
+ for (RuleGroupWithRendererEndpointParticipation ruleGroup :
+ peer.getRuleGroupWithRendererEndpointParticipation()) {
+ if (ruleGroup.getTenantId() != null) {
+ return ruleGroup.getTenantId();
}
}
- if (chainName == null) {
- LOG.error("Cannot found service path, chain name is null");
+ return null;
+ }
+
+ static String generateClassMapName(final int sourceTag, final int destinationTag) {
+ return "srcTag" + sourceTag + "_dstTag" + destinationTag;
+ }
+
+ static Class createPolicyEntry(final String policyClassName, final RenderedServicePath renderedPath,
+ final PolicyManagerImpl.ActionCase actionCase) {
+ // Forward Case
+ final ForwardCaseBuilder forwardCaseBuilder = new ForwardCaseBuilder();
+ if (actionCase.equals(CHAIN) && renderedPath != null) {
+ // Chain Action
+ final ForwardBuilder forwardBuilder = new ForwardBuilder();
+ final List<ServicePath> servicePaths = new ArrayList<>();
+ final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
+ servicePathBuilder.setKey(new ServicePathKey(renderedPath.getPathId()))
+ .setServicePathId(renderedPath.getPathId())
+ .setServiceIndex(renderedPath.getStartingIndex());
+ servicePaths.add(servicePathBuilder.build());
+ forwardBuilder.setServicePath(servicePaths);
+ forwardCaseBuilder.setForward(forwardBuilder.build());
+ }
+ // Create Action List
+ final List<ActionList> actionList = new ArrayList<>();
+ final ActionListBuilder actionListBuilder = new ActionListBuilder();
+ actionListBuilder.setKey(new ActionListKey(PolicyActionType.Forward))
+ .setActionType(PolicyActionType.Forward)
+ .setActionParam(forwardCaseBuilder.build());
+ actionList.add(actionListBuilder.build());
+ // Build class entry
+ final ClassBuilder policyClassBuilder = new ClassBuilder();
+ policyClassBuilder.setName(new ClassNameType(policyClassName))
+ .setKey(new ClassKey(new ClassNameType(policyClassName)))
+ .setActionList(actionList);
+ return policyClassBuilder.build();
+ }
+
+ public static PolicyMap createPolicyMap(final String policyMapName, final List<Class> policyMapEntries) {
+ // Create default class entry
+ final AppnavPolicyBuilder appnavPolicyBuilder = new AppnavPolicyBuilder();
+ appnavPolicyBuilder.setPassThrough(true);
+ final ClassBuilder defaultBuilder = new ClassBuilder();
+ defaultBuilder.setName(new ClassNameType("class-default"))
+ .setKey(new ClassKey(new ClassNameType("class-default")))
+ .setAppnavPolicy(appnavPolicyBuilder.build());
+ policyMapEntries.add(defaultBuilder.build());
+ // Construct policy map
+ final PolicyMapBuilder policyMapBuilder = new PolicyMapBuilder();
+ policyMapBuilder.setName(policyMapName)
+ .setKey(new PolicyMapKey(policyMapName))
+ .setType(PolicyMap.Type.ServiceChain)
+ .setXmlClass(policyMapEntries);
+ return policyMapBuilder.build();
+ }
+
+ public static ServicePolicy createServicePolicy(final String chainName, final ServiceChain.Direction direction) {
+ // Service Chain
+ final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder();
+ serviceChainBuilder.setName(chainName) // Same as the policy map name
+ .setDirection(direction);
+ // Service policy
+ final TypeBuilder typeBuilder = new TypeBuilder();
+ typeBuilder.setServiceChain(serviceChainBuilder.build());
+ // Service Policy
+ ServicePolicyBuilder servicePolicyBuilder = new ServicePolicyBuilder();
+ servicePolicyBuilder.setType(typeBuilder.build());
+
+ return servicePolicyBuilder.build();
+ }
+
+ public static InstanceIdentifier getAbsoluteLocationMountpoint(final RendererEndpoint endpoint,
+ final List<AddressEndpointWithLocation> endpointsWithLocation) {
+ if (endpointsWithLocation.isEmpty()) {
return null;
}
- ServiceFunctionPath serviceFunctionPath = findServiceFunctionPath(new SfcName(chainName));
- if (serviceFunctionPath == null) {
- LOG.error("Service function path not found for name {}", chainName);
+ AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint,
+ endpointsWithLocation);
+ final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation();
+ final LocationType locationType = absoluteLocation.getLocationType();
+ ExternalLocationCase location = (ExternalLocationCase) locationType;
+ if (location == null) {
+ LOG.warn("Endpoint {} does not contain info about external location",
+ endpointWithLocation.getKey().toString());
return null;
}
- return serviceFunctionPath;
+ return location.getExternalNodeMountPoint();
}
- public static RenderedServicePath createRenderedPath(ServiceFunctionPath sfp, TenantId tenantId) {
- RenderedServicePath renderedServicePath;
- // Try to read existing RSP
- RspName rspName = new RspName(sfp.getName().getValue() + tenantId.getValue() + "-gbp-rsp");
- renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
- if (renderedServicePath != null) {
- return renderedServicePath;
+ public static String getInterfaceNameForPolicyMap(final RendererEndpoint endpoint,
+ final List<AddressEndpointWithLocation> endpointsWithLocation) {
+ if (endpoint == null || endpointsWithLocation == null) {
+ return null;
}
- LOG.info("Rendered service path with name {} not found, creating a new one ..", rspName.getValue());
- CreateRenderedPathInput input = new CreateRenderedPathInputBuilder()
- .setParentServiceFunctionPath(sfp.getName().getValue())
- .setName(rspName.getValue())
- .setSymmetric(sfp.isSymmetric())
- .build();
- renderedServicePath = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, input);
- LOG.info("Rendered service path {} created", rspName.getValue());
- return renderedServicePath;
+ final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint,
+ endpointsWithLocation);
+ final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation();
+ final LocationType locationType = absoluteLocation.getLocationType();
+ final ExternalLocationCase location = (ExternalLocationCase) locationType;
+ if (location == null) {
+ LOG.warn("Endpoint {} does not contain info about external location",
+ endpointWithLocation.getKey().toString());
+ return null;
+ }
+ return location.getExternalNodeConnector();
}
- private static ServiceFunctionPath findServiceFunctionPath(SfcName chainName) {
- ServiceFunctionPaths allPaths = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
- for (ServiceFunctionPath serviceFunctionPath : allPaths.getServiceFunctionPath()) {
- if (serviceFunctionPath.getServiceChainName().equals(chainName)) {
- return serviceFunctionPath;
+
+ private static Map<PolicyManagerImpl.ActionCase, Action> getActionInDirection(final Configuration data, final PeerEndpointWithPolicy peer) {
+ final List<ResolvedRule> rulesInDirection = new ArrayList<>();
+ // Find all rules in desired direction
+ for (RuleGroupWithRendererEndpointParticipation ruleGroupKey :
+ peer.getRuleGroupWithRendererEndpointParticipation()) {
+ final EndpointPolicyParticipation participation = ruleGroupKey.getRendererEndpointParticipation();
+ final RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey);
+ if (ruleGroup == null || ruleGroup.getResolvedRule() == null) {
+ continue;
+ }
+
+ for (ResolvedRule resolvedRule : ruleGroup.getResolvedRule()) {
+ if (resolvedRule == null) {
+ continue;
+ }
+ if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) {
+ continue;
+ }
+ // TODO only first Classifier used
+ final Classifier classifier = resolvedRule.getClassifier().get(0);
+ final HasDirection.Direction direction = classifier.getDirection();
+ if ((participation.equals(PROVIDER) && direction.equals(Out)) ||
+ (participation.equals(CONSUMER) && direction.equals(In))) {
+ rulesInDirection.add(resolvedRule);
+ }
+ }
+ }
+ if (rulesInDirection.isEmpty()) {
+ return null;
+ }
+ // TODO use only first rule with ActionDefinitionID for now
+ final Map<PolicyManagerImpl.ActionCase, Action> result = new HashMap<>();
+ for (ResolvedRule resolvedRule : rulesInDirection) {
+ // TODO only first action used for now
+ final Action action = resolvedRule.getAction().get(0);
+ if (action.getActionDefinitionId() != null) {
+ final ActionDefinitionId actionDefinitionId = action.getActionDefinitionId();
+ // Currently only chain action is supported
+ if (actionDefinitionId.equals(ChainActionDefinition.ID)) {
+ result.put(PolicyManagerImpl.ActionCase.CHAIN, action);
+ return result;
+ }
}
}
return null;
}
- public static RenderedServicePath createSymmetricRenderedPath(ServiceFunctionPath sfp, RenderedServicePath rsp,
- TenantId tenantId) {
- RenderedServicePath reversedRenderedPath;
- // Try to read existing RSP
- RspName rspName = new RspName(sfp.getName().getValue() + tenantId.getValue() + "-gbp-rsp-Reverse");
- reversedRenderedPath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
- if (reversedRenderedPath != null) {
- return reversedRenderedPath;
+ private static RuleGroup findRuleGroup(final Configuration data,
+ final RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation) {
+ final TenantId tenantId = ruleGroupWithParticipation.getTenantId();
+ final ContractId contractId = ruleGroupWithParticipation.getContractId();
+ final SubjectName subjectName = ruleGroupWithParticipation.getSubjectName();
+ for (RuleGroup ruleGroup : data.getRuleGroups().getRuleGroup()) {
+ if (!ruleGroup.getTenantId().equals(tenantId)) {
+ continue;
+ }
+ if (!ruleGroup.getContractId().equals(contractId)) {
+ continue;
+ }
+ if (ruleGroup.getSubjectName().equals(subjectName)) {
+ return ruleGroup;
+ }
}
- LOG.info("Reversed rendered service path with name {} not found, creating a new one ..", rspName.getValue());
- reversedRenderedPath = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
- LOG.info("Rendered service path {} created", rspName.getValue());
- return reversedRenderedPath;
+ return null;
}
}
+++ /dev/null
-/*
- * Copyright (c) 2016 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.ios_xe_provider.impl.util;
-
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.CheckedFuture;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
-import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class PolicyWriter {
-
- private static final Logger LOG = LoggerFactory.getLogger(PolicyWriter.class);
-
- private final DataBroker mountpoint;
- // Local cache
- private List<ClassMap> classMapEntries;
- private List<Class> policyMapEntries;
-
- public PolicyWriter(final DataBroker dataBroker) {
- mountpoint = Preconditions.checkNotNull(dataBroker);
- classMapEntries = new ArrayList<>();
- policyMapEntries = new ArrayList<>();
- }
-
- public void write(ClassMap classMap) {
- classMapEntries.add(classMap);
- }
-
- public void write(List<Class> policyMapEntries) {
- this.policyMapEntries.addAll(policyMapEntries);
- }
-
- public void commitToDatastore() {
- // create and write service-policy
- // create and write policy-map with policyMapEntries
- // create and write class-maps
-
- WriteTransaction wtx = mountpoint.newWriteOnlyTransaction();
- // Class maps
- for (ClassMap entry : classMapEntries) {
- InstanceIdentifier<ClassMap> iid = classMapInstanceIdentifier(entry);
- try {
- wtx.merge(LogicalDatastoreType.CONFIGURATION, iid, entry, true);
- CheckedFuture<Void, TransactionCommitFailedException> submitFuture = wtx.submit();
- submitFuture.checkedGet();
- // Clear cache
- classMapEntries.clear();
- } catch (TransactionCommitFailedException e) {
- LOG.error("Write transaction failed to {}", e.getMessage());
- } catch (Exception e) {
- LOG.error("Failed to .. {}", e.getMessage());
- }
- }
- }
-
- private InstanceIdentifier<ClassMap> classMapInstanceIdentifier(ClassMap classMap) {
- return InstanceIdentifier.builder(Native.class)
- .child(ClassMap.class, new ClassMapKey(classMap.getName())).build();
- }
-}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.ios_xe_provider.impl.util;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
+import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.config.service.chain.grouping.IpBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.Local;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.LocalBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.ConfigServiceChainPathModeBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.ServiceIndexBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.Services;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.ServicesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.ServiceTypeChoice;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionForwarderBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+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.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class ServiceChainingUtil {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ServiceChainingUtil.class);
+
+ static ServiceFunctionPath getServicePath(final List<ParameterValue> params) {
+ if (params == null || params.isEmpty()) {
+ LOG.error("Cannot found service path, parameter value is null");
+ return null;
+ }
+ final Map<String, Object> paramsMap = new HashMap<>();
+ for (ParameterValue value : params) {
+ if (value.getName() == null)
+ continue;
+ if (value.getIntValue() != null) {
+ paramsMap.put(value.getName().getValue(), value.getIntValue());
+ } else if (value.getStringValue() != null) {
+ paramsMap.put(value.getName().getValue(), value.getStringValue());
+ }
+ }
+ String chainName = null;
+ for (String name : paramsMap.keySet()) {
+ if (name.equals(ChainActionDefinition.SFC_CHAIN_NAME)) {
+ chainName = (String) paramsMap.get(name);
+ }
+ }
+ if (chainName == null) {
+ LOG.error("Cannot found service path, chain name is null");
+ return null;
+ }
+ final ServiceFunctionPath serviceFunctionPath = findServiceFunctionPath(new SfcName(chainName));
+ if (serviceFunctionPath == null) {
+ LOG.error("Service function path not found for name {}", chainName);
+ return null;
+ }
+ return serviceFunctionPath;
+ }
+
+ static void resolveChainAction(final PeerEndpointWithPolicy peerEndpoint, final Sgt sourceSgt,
+ final Sgt destinationSgt, final Map<PolicyManagerImpl.ActionCase, Action> actionMap,
+ final String classMapName, PolicyWriter policyWriter) {
+ final List<Class> entries = new ArrayList<>();
+ final Action action = actionMap.get(PolicyManagerImpl.ActionCase.CHAIN);
+ final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(action.getParameterValue());
+ if (servicePath == null) {
+ //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
+ return;
+ }
+ final TenantId tenantId = PolicyManagerUtil.getTenantId(peerEndpoint);
+ if (tenantId == null) {
+ //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
+ return;
+ }
+ final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(servicePath, tenantId);
+ // Create appropriate service path && remote forwarder
+ final boolean sfcPartSucessful = setSfcPart(renderedPath, policyWriter);
+ if (!sfcPartSucessful) {
+ //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
+ return;
+ }
+
+ // atomic creation of symmetric policy-entries
+ final Class policyEntry = PolicyManagerUtil.createPolicyEntry(classMapName, renderedPath, PolicyManagerImpl.ActionCase.CHAIN);
+ if (!servicePath.isSymmetric()) {
+ entries.add(policyEntry);
+ } else {
+ // symmetric path is in opposite direction. Roles of renderer and peer endpoint will invert
+ final RenderedServicePath symmetricPath = ServiceChainingUtil
+ .createSymmetricRenderedPath(servicePath, renderedPath, tenantId);
+ if (symmetricPath == null) {
+ //TODO: dump particular resolvedRule-rule-peerEP-EP combinantions to status
+ return;
+ } else {
+ final String oppositeClassMapName = PolicyManagerUtil.generateClassMapName(destinationSgt.getValue(),
+ sourceSgt.getValue());
+ final Class policyEntrySymmetric = PolicyManagerUtil.createPolicyEntry(oppositeClassMapName,
+ symmetricPath, PolicyManagerImpl.ActionCase.CHAIN);
+
+ entries.add(policyEntry);
+ entries.add(policyEntrySymmetric);
+ }
+ }
+ policyWriter.cache(entries);
+ }
+
+ static RenderedServicePath createRenderedPath(final ServiceFunctionPath sfp, final TenantId tenantId) {
+ RenderedServicePath renderedServicePath;
+ // Try to read existing RSP
+ final RspName rspName = new RspName(sfp.getName().getValue() + tenantId.getValue() + "-gbp-rsp");
+ renderedServicePath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
+ if (renderedServicePath != null) {
+ return renderedServicePath;
+ }
+ LOG.info("Rendered service path with name {} not found, creating a new one ..", rspName.getValue());
+ final CreateRenderedPathInput input = new CreateRenderedPathInputBuilder()
+ .setParentServiceFunctionPath(sfp.getName().getValue())
+ .setName(rspName.getValue())
+ .setSymmetric(sfp.isSymmetric())
+ .build();
+ renderedServicePath = SfcProviderRenderedPathAPI.createRenderedServicePathAndState(sfp, input);
+ LOG.info("Rendered service path {} created", rspName.getValue());
+ return renderedServicePath;
+ }
+
+ static RenderedServicePath createSymmetricRenderedPath(final ServiceFunctionPath sfp, final RenderedServicePath rsp,
+ final TenantId tenantId) {
+ RenderedServicePath reversedRenderedPath;
+ // Try to read existing RSP
+ final RspName rspName = new RspName(sfp.getName().getValue() + tenantId.getValue() + "-gbp-rsp-Reverse");
+ reversedRenderedPath = SfcProviderRenderedPathAPI.readRenderedServicePath(rspName);
+ if (reversedRenderedPath != null) {
+ return reversedRenderedPath;
+ }
+ LOG.info("Reversed rendered service path with name {} not found, creating a new one ..", rspName.getValue());
+ reversedRenderedPath = SfcProviderRenderedPathAPI.createSymmetricRenderedServicePathAndState(rsp);
+ LOG.info("Rendered service path {} created", rspName.getValue());
+ return reversedRenderedPath;
+ }
+
+ /**
+ * Method checks up, whether a {@link Local} Service Function Forwarder is present on device or not.
+ *
+ * @param mountpoint used to access specific device
+ * @return true if Local Forwarder is present, false otherwise
+ */
+ static boolean checkLocalForwarderPresence(DataBroker mountpoint) {
+ InstanceIdentifier<Local> localSffIid = InstanceIdentifier.builder(Native.class)
+ .child(ServiceChain.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder.class)
+ .child(Local.class).build();
+ ReadWriteTransaction rwt = mountpoint.newReadWriteTransaction();
+ CheckedFuture<Optional<Local>, ReadFailedException> submitFuture = rwt.read(LogicalDatastoreType.CONFIGURATION,
+ localSffIid);
+ try {
+ Optional<Local> optionalLocalSff = submitFuture.checkedGet();
+ return optionalLocalSff.isPresent();
+ } catch (ReadFailedException e) {
+ LOG.warn("Read transaction failed to {} ", e);
+ } catch (Exception e) {
+ LOG.error("Failed to .. {}", e.getMessage());
+ }
+ return false;
+ }
+
+ /**
+ * Method checks up, if some {@link ServicePath} is present on device.
+ *
+ * @param mountpoint used to access specific device
+ * @return true if service chain does not exist, is null or does not contain any service path. False otherwise
+ */
+ public static boolean checkServicePathPresence(DataBroker mountpoint) {
+ InstanceIdentifier<ServiceChain> serviceChainIid = InstanceIdentifier.builder(Native.class)
+ .child(ServiceChain.class).build();
+ ReadWriteTransaction rwt = mountpoint.newReadWriteTransaction();
+ CheckedFuture<Optional<ServiceChain>, ReadFailedException> submitFuture = rwt.read(LogicalDatastoreType.CONFIGURATION,
+ serviceChainIid);
+ try {
+ Optional<ServiceChain> optionalServiceChain = submitFuture.checkedGet();
+ if (optionalServiceChain.isPresent()) {
+ ServiceChain chain = optionalServiceChain.get();
+ return chain == null || chain.getServicePath() == null || chain.getServicePath().isEmpty();
+ } else {
+ return true;
+ }
+ } catch (ReadFailedException e) {
+ LOG.warn("Read transaction failed to {} ", e);
+ } catch (Exception e) {
+ LOG.error("Failed to .. {}", e.getMessage());
+ }
+ return false;
+ }
+
+ static ServiceFunctionPath findServiceFunctionPath(final SfcName chainName) {
+ final ServiceFunctionPaths allPaths = SfcProviderServicePathAPI.readAllServiceFunctionPaths();
+ for (ServiceFunctionPath serviceFunctionPath : allPaths.getServiceFunctionPath()) {
+ if (serviceFunctionPath.getServiceChainName().equals(chainName)) {
+ return serviceFunctionPath;
+ }
+ }
+ return null;
+ }
+
+ static boolean setSfcPart(final RenderedServicePath renderedServicePath, PolicyWriter policyWriter) {
+ // TODO: break into smaller methods with partial result
+ if (renderedServicePath != null && renderedServicePath.getRenderedServicePathHop() != null &&
+ !renderedServicePath.getRenderedServicePathHop().isEmpty()) {
+ final RenderedServicePathHop firstHop = renderedServicePath.getRenderedServicePathHop().get(0);
+ if (firstHop == null) {
+ LOG.error("Rendered service path {} does not contain any hop", renderedServicePath.getName().getValue());
+ return false;
+ }
+ final SffName sffName = firstHop.getServiceFunctionForwarder();
+ final ServiceFunctionForwarder serviceFunctionForwarder = SfcProviderServiceForwarderAPI.readServiceFunctionForwarder(sffName);
+ if (serviceFunctionForwarder == null) {
+ LOG.error("Sff with name {} does not exist", sffName.getValue());
+ return false;
+ }
+ // Forwarders
+ //
+ // If classifier node is also forwarder, first entry in service path has to point to first service function
+ // (Local case)
+ //
+ // If first hop Sff is on different node, first service path entry has to point to that specific service
+ // forwarder (Remote case)
+
+ // Local case (only when does not exist)
+
+ if (!checkLocalForwarderPresence(policyWriter.getCurrentMountpoint())) {
+ final LocalBuilder localSffBuilder = new LocalBuilder();
+ localSffBuilder.setIp(new IpBuilder().setAddress(new Ipv4Address(policyWriter.getManagementIpAddress()))
+ .build());
+ policyWriter.cache(localSffBuilder.build());
+ } else {
+ LOG.info("Local forwarder for node {} is already created", policyWriter.getCurrentNodeId());
+ }
+ // Set up choice. If remote, this choice is overwritten
+ ServiceTypeChoice serviceTypeChoice = functionTypeChoice(firstHop.getServiceFunctionName().getValue());
+ // Remote case
+ if (serviceFunctionForwarder.getIpMgmtAddress() == null
+ || serviceFunctionForwarder.getIpMgmtAddress().getIpv4Address() == null) {
+ LOG.error("Cannot create remote forwarder, SFF {} does not contain management ip address",
+ sffName.getValue());
+ return false;
+ }
+ final String sffMgmtIpAddress = serviceFunctionForwarder.getIpMgmtAddress().getIpv4Address().getValue();
+ // If local SFF has the same ip as first hop sff, it's the same SFF; no need to create a remote one
+ if (!sffMgmtIpAddress.equals(policyWriter.getManagementIpAddress())) {
+ final ServiceFfNameBuilder remoteSffBuilder = new ServiceFfNameBuilder();
+ remoteSffBuilder.setName(sffName.getValue())
+ .setKey(new ServiceFfNameKey(sffName.getValue()))
+ .setIp(new IpBuilder().setAddress(new Ipv4Address(sffMgmtIpAddress)).build());
+ policyWriter.cache(remoteSffBuilder.build());
+ serviceTypeChoice = forwarderTypeChoice(sffName.getValue());
+ }
+
+ // Service chain
+ final List<Services> services = new ArrayList<>();
+ final ServicesBuilder servicesBuilder = new ServicesBuilder();
+ servicesBuilder.setServiceIndexId(renderedServicePath.getStartingIndex())
+ .setServiceTypeChoice(serviceTypeChoice);
+ final List<ServicePath> servicePaths = new ArrayList<>();
+ final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
+ servicePathBuilder.setKey(new ServicePathKey(renderedServicePath.getPathId()))
+ .setServicePathId(renderedServicePath.getPathId())
+ .setConfigServiceChainPathMode(new ConfigServiceChainPathModeBuilder()
+ .setServiceIndex(new ServiceIndexBuilder()
+ .setServices(services).build()).build());
+ servicePaths.add(servicePathBuilder.build());
+ final ServiceChainBuilder chainBuilder = new ServiceChainBuilder();
+ chainBuilder.setServicePath(servicePaths);
+ final ServiceChain serviceChain = chainBuilder.build();
+ policyWriter.cache(serviceChain);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ static ServiceTypeChoice forwarderTypeChoice(final String forwarderName) {
+ final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder();
+ sffBuilder.setServiceFunctionForwarder(forwarderName);
+ return sffBuilder.build();
+ }
+
+ static ServiceTypeChoice functionTypeChoice(final String functionName) {
+ final ServiceFunctionBuilder sfBuilder = new ServiceFunctionBuilder();
+ sfBuilder.setServiceFunction(functionName);
+ return sfBuilder.build();
+ }
+
+}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
+package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer;
import com.google.common.util.concurrent.CheckedFuture;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
--- /dev/null
+/*
+ * Copyright (c) 2016 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.ios_xe_provider.impl.writer;
+
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308.Native;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.Interface;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernet;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._interface.GigabitEthernetKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePath;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.Local;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfNameKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PolicyWriter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(PolicyWriter.class);
+
+ private final DataBroker mountpoint;
+ // Local cache
+ private final List<ClassMap> classMapEntries;
+ private final List<Class> policyMapEntries;
+ private final List<ServiceFfName> remoteForwarders;
+ private final List<ServiceChain> serviceChains;
+ private final NodeId nodeId;
+ private final String interfaceName;
+ private final String policyMapName;
+ private final String managementIpAddress;
+ private Local localForwarder;
+
+ public PolicyWriter(final DataBroker dataBroker, final String interfaceName, final String ipAddress,
+ final String policyMapName, final NodeId nodeId) {
+ classMapEntries = new ArrayList<>();
+ policyMapEntries = new ArrayList<>();
+ remoteForwarders = new ArrayList<>();
+ serviceChains = new ArrayList<>();
+
+ this.nodeId = Preconditions.checkNotNull(nodeId);
+ mountpoint = Preconditions.checkNotNull(dataBroker);
+ managementIpAddress = Preconditions.checkNotNull(ipAddress);
+ this.interfaceName = Preconditions.checkNotNull(interfaceName);
+ this.policyMapName = Preconditions.checkNotNull(policyMapName);
+ }
+
+ public void cache(ClassMap classMap) {
+ classMapEntries.add(classMap);
+ }
+
+ public void cache(List<Class> policyMapEntries) {
+ this.policyMapEntries.addAll(policyMapEntries);
+ }
+
+ public void cache(Local localForwarder) {
+ this.localForwarder = localForwarder;
+ }
+
+ public void cache(ServiceFfName remoteForwarder) {
+ remoteForwarders.add(remoteForwarder);
+ }
+
+ public void cache(ServiceChain serviceChain) {
+ serviceChains.add(serviceChain);
+ }
+
+ public CheckedFuture<Void, TransactionCommitFailedException> commitToDatastore() {
+ WriteTransaction wtx = mountpoint.newWriteOnlyTransaction();
+ // GBP
+ // Class maps
+ for (ClassMap entry : classMapEntries) {
+ InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
+ wtx.merge(LogicalDatastoreType.CONFIGURATION, classMapIid, entry);
+ LOG.info("Created class-map {} on node {}", entry.getName(), nodeId.getValue());
+ }
+
+ // Policy map
+ PolicyMap policyMap = PolicyManagerUtil.createPolicyMap(policyMapName, policyMapEntries);
+ InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier();
+ wtx.merge(LogicalDatastoreType.CONFIGURATION, policyMapIid, policyMap);
+ LOG.info("Created policy-map {} on node {}", policyMap.getName(), nodeId.getValue());
+
+ // Interface
+ ServicePolicy servicePolicy = PolicyManagerUtil.createServicePolicy(policyMapName, Direction.Input);
+ InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
+ wtx.merge(LogicalDatastoreType.CONFIGURATION, servicePolicyIid, servicePolicy);
+ LOG.info("Service-policy interface {}, bound to policy-map {} created on node {}",
+ interfaceName, policyMap.getName(), nodeId.getValue());
+
+ //SFC
+ // Local forwarder (if some service chain exists, otherwise is useless)
+ if (!serviceChains.isEmpty()) {
+ InstanceIdentifier<Local> localIid = localSffInstanceIdentifier();
+ wtx.merge(LogicalDatastoreType.CONFIGURATION, localIid, localForwarder);
+ LOG.info("Local forwarder created on node {}", nodeId.getValue());
+ }
+
+ // Remote forwarders
+ for (ServiceFfName forwarder : remoteForwarders) {
+ InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
+ wtx.merge(LogicalDatastoreType.CONFIGURATION, forwarderIid, forwarder);
+ LOG.info("Remote forwarder {} created on node {}", forwarder.getName(), nodeId.getValue());
+ }
+
+ // Service paths
+ for (ServiceChain serviceChain : serviceChains) {
+ for (ServicePath entry : serviceChain.getServicePath()) {
+ InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
+ wtx.merge(LogicalDatastoreType.CONFIGURATION, servicePathIid, entry);
+ LOG.info("Service path with Id {} created on node {}", entry.getServicePathId(), nodeId.getValue());
+ }
+ }
+
+ return wtx.submit();
+ }
+
+ public CheckedFuture<Void, TransactionCommitFailedException> removeFromDatastore() {
+ ReadWriteTransaction wtx = mountpoint.newReadWriteTransaction();
+ //GBP
+ // Interface
+ InstanceIdentifier<ServicePolicy> servicePolicyIid = interfaceInstanceIdentifier(interfaceName);
+ wtx.delete(LogicalDatastoreType.CONFIGURATION, servicePolicyIid);
+ LOG.info("Service-policy removed from interface {} on node {}", interfaceName, nodeId.getValue());
+
+ // Policy map
+ InstanceIdentifier<PolicyMap> policyMapIid = policyMapInstanceIdentifier();
+ wtx.delete(LogicalDatastoreType.CONFIGURATION, policyMapIid);
+ LOG.info("Policy-map removed from node node {}", nodeId.getValue());
+
+ // Class map
+ for (ClassMap entry : classMapEntries) {
+ InstanceIdentifier<ClassMap> classMapIid = classMapInstanceIdentifier(entry);
+ wtx.delete(LogicalDatastoreType.CONFIGURATION, classMapIid);
+ LOG.info("Class-map {} removed from node {}", entry.getName(), nodeId.getValue());
+ }
+
+ //SFC
+ // Service paths
+ for (ServiceChain serviceChain : serviceChains) {
+ for (ServicePath entry : serviceChain.getServicePath()) {
+ InstanceIdentifier<ServicePath> servicePathIid = servicePathInstanceIdentifier(entry.getKey());
+ wtx.delete(LogicalDatastoreType.CONFIGURATION, servicePathIid);
+ LOG.info("Service path with Id {} removed from node {}", entry.getServicePathId(), nodeId.getValue());
+ }
+ }
+
+ // Remote forwarders
+ for (ServiceFfName forwarder : remoteForwarders) {
+ InstanceIdentifier<ServiceFfName> forwarderIid = remoteSffInstanceIdentifier(forwarder);
+ wtx.delete(LogicalDatastoreType.CONFIGURATION, forwarderIid);
+ LOG.info("Remote forwarder {} removed from node {}", forwarder.getName(), nodeId.getValue());
+ }
+
+ // Local forwarder - remove only if there is no more service-paths on device. If paths removed above were last
+ // ones, remove local forwarder. If there are still some paths present, they were created by sfc and local
+ // forwarder cannot be removed (because it was created by sfc as well)
+ if (ServiceChainingUtil.checkServicePathPresence(mountpoint)) {
+ InstanceIdentifier<Local> localIid = localSffInstanceIdentifier();
+ wtx.delete(LogicalDatastoreType.CONFIGURATION, localIid);
+ LOG.info("Local forwarder removed from node {}", nodeId.getValue());
+ }
+
+ return wtx.submit();
+ }
+
+ private InstanceIdentifier<ClassMap> classMapInstanceIdentifier(ClassMap classMap) {
+ return InstanceIdentifier.builder(Native.class)
+ .child(ClassMap.class, new ClassMapKey(classMap.getName())).build();
+ }
+
+ private InstanceIdentifier<PolicyMap> policyMapInstanceIdentifier() {
+ return InstanceIdentifier.builder(Native.class)
+ .child(PolicyMap.class, new PolicyMapKey(policyMapName)).build();
+ }
+
+ private InstanceIdentifier<ServicePolicy> interfaceInstanceIdentifier(String ethernetName) {
+ return InstanceIdentifier.builder(Native.class)
+ .child(Interface.class)
+ .child(GigabitEthernet.class, new GigabitEthernetKey(ethernetName))
+ .child(ServicePolicy.class)
+ .build();
+ }
+
+ private InstanceIdentifier<Local> localSffInstanceIdentifier() {
+ return InstanceIdentifier.builder(Native.class)
+ .child(ServiceChain.class)
+ .child(ServiceFunctionForwarder.class)
+ .child(Local.class).build();
+ }
+
+ private InstanceIdentifier<ServiceFfName> remoteSffInstanceIdentifier(ServiceFfName sffName) {
+ return InstanceIdentifier.builder(Native.class)
+ .child(ServiceChain.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServiceFunctionForwarder.class)
+ .child(ServiceFfName.class, new ServiceFfNameKey(sffName.getName())).build();
+ }
+
+ private InstanceIdentifier<ServicePath> servicePathInstanceIdentifier(ServicePathKey key) {
+ return InstanceIdentifier.builder(Native.class)
+ .child(ServiceChain.class)
+ .child(ServicePath.class, key).build();
+ }
+
+ public String getManagementIpAddress() {
+ return managementIpAddress;
+ }
+
+ public DataBroker getCurrentMountpoint() {
+ return mountpoint;
+ }
+
+ public NodeId getCurrentNodeId() {
+ return nodeId;
+ }
+}
+++ /dev/null
-module ietf-inet-types {
-
- namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
- prefix "inet";
-
- organization
- "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
-
- contact
- "WG Web: <http://tools.ietf.org/wg/netmod/>
- WG List: <mailto:netmod@ietf.org>
-
- WG Chair: David Kessens
- <mailto:david.kessens@nsn.com>
-
- WG Chair: Juergen Schoenwaelder
- <mailto:j.schoenwaelder@jacobs-university.de>
-
- Editor: Juergen Schoenwaelder
- <mailto:j.schoenwaelder@jacobs-university.de>";
-
- description
- "This module contains a collection of generally useful derived
- YANG data types for Internet addresses and related things.
-
- Copyright (c) 2013 IETF Trust and the persons identified as
- authors of the code. All rights reserved.
-
- Redistribution and use in source and binary forms, with or
- without modification, is permitted pursuant to, and subject
- to the license terms contained in, the Simplified BSD License
- set forth in Section 4.c of the IETF Trust's Legal Provisions
- Relating to IETF Documents
- (http://trustee.ietf.org/license-info).
-
- This version of this YANG module is part of RFC 6991; see
- the RFC itself for full legal notices.";
-
- revision 2013-07-15 {
- description
- "This revision adds the following new data types:
- - ip-address-no-zone
- - ipv4-address-no-zone
- - ipv6-address-no-zone";
- reference
- "RFC 6991: Common YANG Data Types";
- }
-
- revision 2010-09-24 {
- description
- "Initial revision.";
- reference
- "RFC 6021: Common YANG Data Types";
- }
-
- /*** collection of types related to protocol fields ***/
-
- typedef ip-version {
- type enumeration {
- enum unknown {
- value "0";
- description
- "An unknown or unspecified version of the Internet
- protocol.";
- }
- enum ipv4 {
- value "1";
- description
- "The IPv4 protocol as defined in RFC 791.";
- }
- enum ipv6 {
- value "2";
- description
- "The IPv6 protocol as defined in RFC 2460.";
- }
- }
- description
- "This value represents the version of the IP protocol.
-
- In the value set and its semantics, this type is equivalent
- to the InetVersion textual convention of the SMIv2.";
- reference
- "RFC 791: Internet Protocol
- RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
- RFC 4001: Textual Conventions for Internet Network Addresses";
- }
-
- typedef dscp {
- type uint8 {
- range "0..63";
- }
- description
- "The dscp type represents a Differentiated Services Code Point
- that may be used for marking packets in a traffic stream.
- In the value set and its semantics, this type is equivalent
- to the Dscp textual convention of the SMIv2.";
- reference
- "RFC 3289: Management Information Base for the Differentiated
- Services Architecture
- RFC 2474: Definition of the Differentiated Services Field
- (DS Field) in the IPv4 and IPv6 Headers
- RFC 2780: IANA Allocation Guidelines For Values In
- the Internet Protocol and Related Headers";
- }
-
- typedef ipv6-flow-label {
- type uint32 {
- range "0..1048575";
- }
- description
- "The ipv6-flow-label type represents the flow identifier or Flow
- Label in an IPv6 packet header that may be used to
- discriminate traffic flows.
-
- In the value set and its semantics, this type is equivalent
- to the IPv6FlowLabel textual convention of the SMIv2.";
- reference
- "RFC 3595: Textual Conventions for IPv6 Flow Label
- RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
- }
-
- typedef port-number {
- type uint16 {
- range "0..65535";
- }
- description
- "The port-number type represents a 16-bit port number of an
- Internet transport-layer protocol such as UDP, TCP, DCCP, or
- SCTP. Port numbers are assigned by IANA. A current list of
- all assignments is available from <http://www.iana.org/>.
-
- Note that the port number value zero is reserved by IANA. In
- situations where the value zero does not make sense, it can
- be excluded by subtyping the port-number type.
- In the value set and its semantics, this type is equivalent
- to the InetPortNumber textual convention of the SMIv2.";
- reference
- "RFC 768: User Datagram Protocol
- RFC 793: Transmission Control Protocol
- RFC 4960: Stream Control Transmission Protocol
- RFC 4340: Datagram Congestion Control Protocol (DCCP)
- RFC 4001: Textual Conventions for Internet Network Addresses";
- }
-
- /*** collection of types related to autonomous systems ***/
-
- typedef as-number {
- type uint32;
- description
- "The as-number type represents autonomous system numbers
- which identify an Autonomous System (AS). An AS is a set
- of routers under a single technical administration, using
- an interior gateway protocol and common metrics to route
- packets within the AS, and using an exterior gateway
- protocol to route packets to other ASes. IANA maintains
- the AS number space and has delegated large parts to the
- regional registries.
-
- Autonomous system numbers were originally limited to 16
- bits. BGP extensions have enlarged the autonomous system
- number space to 32 bits. This type therefore uses an uint32
- base type without a range restriction in order to support
- a larger autonomous system number space.
-
- In the value set and its semantics, this type is equivalent
- to the InetAutonomousSystemNumber textual convention of
- the SMIv2.";
- reference
- "RFC 1930: Guidelines for creation, selection, and registration
- of an Autonomous System (AS)
- RFC 4271: A Border Gateway Protocol 4 (BGP-4)
- RFC 4001: Textual Conventions for Internet Network Addresses
- RFC 6793: BGP Support for Four-Octet Autonomous System (AS)
- Number Space";
- }
-
- /*** collection of types related to IP addresses and hostnames ***/
-
- typedef ip-address {
- type union {
- type inet:ipv4-address;
- type inet:ipv6-address;
- }
- description
- "The ip-address type represents an IP address and is IP
- version neutral. The format of the textual representation
- implies the IP version. This type supports scoped addresses
- by allowing zone identifiers in the address format.";
- reference
- "RFC 4007: IPv6 Scoped Address Architecture";
- }
-
- typedef ipv4-address {
- type string {
- pattern
- '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
- + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
- + '(%[\p{N}\p{L}]+)?';
- }
- description
- "The ipv4-address type represents an IPv4 address in
- dotted-quad notation. The IPv4 address may include a zone
- index, separated by a % sign.
-
- The zone index is used to disambiguate identical address
- values. For link-local addresses, the zone index will
- typically be the interface index number or the name of an
- interface. If the zone index is not present, the default
- zone of the device will be used.
-
- The canonical format for the zone index is the numerical
- format";
- }
-
- typedef ipv6-address {
- type string {
- pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
- + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
- + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
- + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
- + '(%[\p{N}\p{L}]+)?';
- pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
- + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
- + '(%.+)?';
- }
- description
- "The ipv6-address type represents an IPv6 address in full,
- mixed, shortened, and shortened-mixed notation. The IPv6
- address may include a zone index, separated by a % sign.
-
- The zone index is used to disambiguate identical address
- values. For link-local addresses, the zone index will
- typically be the interface index number or the name of an
- interface. If the zone index is not present, the default
- zone of the device will be used.
-
-
-
- The canonical format of IPv6 addresses uses the textual
- representation defined in Section 4 of RFC 5952. The
- canonical format for the zone index is the numerical
- format as described in Section 11.2 of RFC 4007.";
- reference
- "RFC 4291: IP Version 6 Addressing Architecture
- RFC 4007: IPv6 Scoped Address Architecture
- RFC 5952: A Recommendation for IPv6 Address Text
- Representation";
- }
-
- typedef ip-address-no-zone {
- type union {
- type inet:ipv4-address-no-zone;
- type inet:ipv6-address-no-zone;
- }
- description
- "The ip-address-no-zone type represents an IP address and is
- IP version neutral. The format of the textual representation
- implies the IP version. This type does not support scoped
- addresses since it does not allow zone identifiers in the
- address format.";
- reference
- "RFC 4007: IPv6 Scoped Address Architecture";
- }
-
- typedef ipv4-address-no-zone {
- type inet:ipv4-address {
- pattern '[0-9\.]*';
- }
- description
- "An IPv4 address without a zone index. This type, derived from
- ipv4-address, may be used in situations where the zone is
- known from the context and hence no zone index is needed.";
- }
-
- typedef ipv6-address-no-zone {
- type inet:ipv6-address {
- pattern '[0-9a-fA-F:\.]*';
- }
- description
- "An IPv6 address without a zone index. This type, derived from
- ipv6-address, may be used in situations where the zone is
- known from the context and hence no zone index is needed.";
- reference
- "RFC 4291: IP Version 6 Addressing Architecture
- RFC 4007: IPv6 Scoped Address Architecture
- RFC 5952: A Recommendation for IPv6 Address Text
- Representation";
- }
-
- typedef ip-prefix {
- type union {
- type inet:ipv4-prefix;
- type inet:ipv6-prefix;
- }
- description
- "The ip-prefix type represents an IP prefix and is IP
- version neutral. The format of the textual representations
- implies the IP version.";
- }
-
- typedef ipv4-prefix {
- type string {
- pattern
- '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
- + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
- + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
- }
- description
- "The ipv4-prefix type represents an IPv4 address prefix.
- The prefix length is given by the number following the
- slash character and must be less than or equal to 32.
-
- A prefix length value of n corresponds to an IP address
- mask that has n contiguous 1-bits from the most
- significant bit (MSB) and all other bits set to 0.
-
- The canonical format of an IPv4 prefix has all bits of
- the IPv4 address set to zero that are not part of the
- IPv4 prefix.";
- }
-
- typedef ipv6-prefix {
- type string {
- pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
- + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
- + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
- + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
- + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
- pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
- + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
- + '(/.+)';
- }
-
-
- description
- "The ipv6-prefix type represents an IPv6 address prefix.
- The prefix length is given by the number following the
- slash character and must be less than or equal to 128.
-
- A prefix length value of n corresponds to an IP address
- mask that has n contiguous 1-bits from the most
- significant bit (MSB) and all other bits set to 0.
-
- The IPv6 address should have all bits that do not belong
- to the prefix set to zero.
-
- The canonical format of an IPv6 prefix has all bits of
- the IPv6 address set to zero that are not part of the
- IPv6 prefix. Furthermore, the IPv6 address is represented
- as defined in Section 4 of RFC 5952.";
- reference
- "RFC 5952: A Recommendation for IPv6 Address Text
- Representation";
- }
-
- /*** collection of domain name and URI types ***/
-
- typedef domain-name {
- type string {
- pattern
- '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
- + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
- + '|\.';
- length "1..253";
- }
- description
- "The domain-name type represents a DNS domain name. The
- name SHOULD be fully qualified whenever possible.
-
- Internet domain names are only loosely specified. Section
- 3.5 of RFC 1034 recommends a syntax (modified in Section
- 2.1 of RFC 1123). The pattern above is intended to allow
- for current practice in domain name use, and some possible
- future expansion. It is designed to hold various types of
- domain names, including names used for A or AAAA records
- (host names) and other records, such as SRV records. Note
- that Internet host names have a stricter syntax (described
- in RFC 952) than the DNS recommendations in RFCs 1034 and
- 1123, and that systems that want to store host names in
- schema nodes using the domain-name type are recommended to
- adhere to this stricter standard to ensure interoperability.
-
- The encoding of DNS names in the DNS protocol is limited
- to 255 characters. Since the encoding consists of labels
- prefixed by a length bytes and there is a trailing NULL
- byte, only 253 characters can appear in the textual dotted
- notation.
-
- The description clause of schema nodes using the domain-name
- type MUST describe when and how these names are resolved to
- IP addresses. Note that the resolution of a domain-name value
- may require to query multiple DNS records (e.g., A for IPv4
- and AAAA for IPv6). The order of the resolution process and
- which DNS record takes precedence can either be defined
- explicitly or may depend on the configuration of the
- resolver.
-
- Domain-name values use the US-ASCII encoding. Their canonical
- format uses lowercase US-ASCII characters. Internationalized
- domain names MUST be A-labels as per RFC 5890.";
- reference
- "RFC 952: DoD Internet Host Table Specification
- RFC 1034: Domain Names - Concepts and Facilities
- RFC 1123: Requirements for Internet Hosts -- Application
- and Support
- RFC 2782: A DNS RR for specifying the location of services
- (DNS SRV)
- RFC 5890: Internationalized Domain Names in Applications
- (IDNA): Definitions and Document Framework";
- }
-
- typedef host {
- type union {
- type inet:ip-address;
- type inet:domain-name;
- }
- description
- "The host type represents either an IP address or a DNS
- domain name.";
- }
-
- typedef uri {
- type string;
- description
- "The uri type represents a Uniform Resource Identifier
- (URI) as defined by STD 66.
-
- Objects using the uri type MUST be in US-ASCII encoding,
- and MUST be normalized as described by RFC 3986 Sections
- 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary
- percent-encoding is removed, and all case-insensitive
- characters are set to lowercase except for hexadecimal
- digits, which are normalized to uppercase as described in
- Section 6.2.2.1.
-
- The purpose of this normalization is to help provide
- unique URIs. Note that this normalization is not
- sufficient to provide uniqueness. Two URIs that are
- textually distinct after this normalization may still be
- equivalent.
-
- Objects using the uri type may restrict the schemes that
- they permit. For example, 'data:' and 'urn:' schemes
- might not be appropriate.
-
- A zero-length URI is not a valid URI. This can be used to
- express 'URI absent' where required.
-
- In the value set and its semantics, this type is equivalent
- to the Uri SMIv2 textual convention defined in RFC 5017.";
- reference
- "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
- RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
- Group: Uniform Resource Identifiers (URIs), URLs,
- and Uniform Resource Names (URNs): Clarifications
- and Recommendations
- RFC 5017: MIB Textual Conventions for Uniform Resource
- Identifiers (URIs)";
- }
-
-}
\ No newline at end of file
}
}
- grouping config-service-chain-grouping {
- leaf description {
- tailf:info "Service function forwarder description";
- description "Service function forwarder description";
- tailf:cli-multi-value;
- type string {
- tailf:info "LINE;;Up to 256 characters describing this " + "service function forwarder";
- length "1..256";
- }
- }
- container ip {
- tailf:info "IP address for Service Function Forwarder";
- description "IP address for Service Function Forwarder";
- leaf address {
- tailf:info "Set IPv4 address";
- description "Set IPv4 address";
- type inet:ipv4-address {
- tailf:info "A.B.C.D;;IP address of Service Function Forwarder";
- }
- }
- }
- }
-
grouping interface-atm-grouping {
// Removed body
}
/// service-chain
/// ========================================================================
+ grouping config-service-chain-grouping {
+ leaf description {
+ tailf:info "Service function forwarder description";
+ description "Service function forwarder description";
+ tailf:cli-multi-value;
+ type string {
+ tailf:info "LINE;;Up to 256 characters describing this " + "service function forwarder";
+ length "1..256";
+ }
+ }
+ container ip {
+ tailf:info "IP address for Service Function Forwarder";
+ description "IP address for Service Function Forwarder";
+ leaf address {
+ tailf:info "Set IPv4 address";
+ description "Set IPv4 address";
+ type inet:ipv4-address {
+ tailf:info "A.B.C.D;;IP address of Service Function Forwarder";
+ }
+ }
+ }
+ }
+
container service-chain {
tailf:info "Service Chain mode";
description "Service Chain mode";
+++ /dev/null
-/*
- * Copyright (c) 2016 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.ios_xe_provider.impl.cache;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
-
-/**
- * Test for {@link EpPolicyCacheImpl}.
- */
-public class EpPolicyCacheImplTest {
-
- private static final int SGT1 = 1;
- private static final int SGT2 = 2;
- private static final String TENANT1 = "tenant1";
- private static final String TENANT2 = "tenant2";
-
- private static final EpPolicyTemplateCacheKey KEY_1 = createKey(TENANT1, new String[]{"n1", "n2"});
- private static final EpPolicyTemplateCacheKey KEY_2 = createKey(TENANT2, new String[]{"n3"});
-
- private static final EndpointPolicyTemplateBySgt TEMPLATE_1 = createTemplate(SGT1, TENANT1, new String[]{"n1", "n2"});
- private static final EndpointPolicyTemplateBySgt TEMPLATE_2 = createTemplate(SGT2, TENANT2, new String[]{"n3"});
-
- private EpPolicyCacheImpl cache;
-
- @Before
- public void setUp() throws Exception {
- cache = new EpPolicyCacheImpl();
- }
-
- @Test
- public void testInvalidate() throws Exception {
- cache.add(TEMPLATE_1);
- cache.add(TEMPLATE_2);
-
- checkValuePresence(KEY_1, SGT1);
-
- checkValuePresence(KEY_2, SGT2);
-
- cache.invalidate(TEMPLATE_1);
- Assert.assertNull(cache.lookupValue(KEY_1));
- Assert.assertNotNull(cache.lookupValue(KEY_2));
- }
-
- @Test
- public void testAdd() throws Exception {
- cache.add(TEMPLATE_1);
- checkValuePresence(KEY_1, SGT1);
- }
-
- @Test
- public void testUpdate() throws Exception {
- cache.add(TEMPLATE_1);
- checkValuePresence(KEY_1, SGT1);
-
- cache.update(TEMPLATE_1, TEMPLATE_2);
-
- Assert.assertNull(cache.lookupValue(KEY_1));
- checkValuePresence(KEY_2, SGT2);
- }
-
- @Test
- public void testLookupValue() throws Exception {
- cache.add(TEMPLATE_1);
- checkValuePresence(KEY_1, SGT1);
- }
-
- private void checkValuePresence(final EpPolicyTemplateCacheKey key, final int expectedSgt) {
- final Sgt sgt = cache.lookupValue(key);
- Assert.assertNotNull(sgt);
- Assert.assertEquals(expectedSgt, sgt.getValue().intValue());
- }
-
- @Test
- public void testLookupValue_withChangedOrder() throws Exception {
- Assert.assertNull(cache.lookupValue(KEY_1));
- cache.add(TEMPLATE_1);
- checkValuePresence(KEY_1, SGT1);
-
- final EpPolicyTemplateCacheKey twistedKey1 = createKey(TENANT1, new String[]{"n1", "n2"}, new String[]{"n2", "n1"});
- checkValuePresence(twistedKey1, SGT1);
-
- final EpPolicyTemplateCacheKey twistedKey2 = createKey(TENANT1, new String[]{"n2", "n1"}, new String[]{"n1", "n2"});
- checkValuePresence(twistedKey2, SGT1);
- }
-
- @Test
- public void testInvalidateAll() throws Exception {
- cache.add(TEMPLATE_1);
- cache.add(TEMPLATE_2);
- checkValuePresence(KEY_1, SGT1);
-
- cache.invalidateAll();
- Assert.assertNull(cache.lookupValue(KEY_1));
- Assert.assertNull(cache.lookupValue(KEY_2));
- }
-
- private static EndpointPolicyTemplateBySgt createTemplate(final int sgt, final String tenant, final String[] names) {
- final List<ConditionName> conditions = buildConditions(names);
- final List<EndpointGroupId> endpointGroupIds = buildEndpointGroupIds(names);
-
- return new EndpointPolicyTemplateBySgtBuilder()
- .setSgt(new Sgt(sgt))
- .setTenant(new TenantId(tenant))
- .setConditions(conditions)
- .setEndpointGroups(endpointGroupIds)
- .build();
- }
-
- private static List<EndpointGroupId> buildEndpointGroupIds(final String[] names) {
- final List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
- for (String epgId : names) {
- endpointGroupIds.add(new EndpointGroupId(epgId));
- }
- return endpointGroupIds;
- }
-
- private static List<ConditionName> buildConditions(final String[] names) {
- final List<ConditionName> conditions = new ArrayList<>();
- for (String condition : names) {
- conditions.add(new ConditionName(condition));
- }
- return conditions;
- }
-
- private static EpPolicyTemplateCacheKey createKey(final String tenant, final String[] names) {
- return createKey(tenant, names, names);
- }
-
- private static EpPolicyTemplateCacheKey createKey(final String tenant, final String[] epgIds, final String[] conditionNames) {
- return new EpPolicyTemplateCacheKey(new AddressEndpointWithLocationBuilder()
- .setTenant(new TenantId(tenant))
- .setEndpointGroup(buildEndpointGroupIds(epgIds))
- .setCondition(buildConditions(conditionNames))
- .build());
- }
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2016 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.ios_xe_provider.impl.listener;
-
-import com.google.common.collect.Lists;
-import java.util.Collections;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Matchers;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.runners.MockitoJUnitRunner;
-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.DataTreeIdentifier;
-import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.cache.DSTreeBasedCache;
-import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache.EpPolicyTemplateCacheKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
-
-/**
- * Test for {@link EpPolicyTemplateBySgtListenerImpl}.
- */
-@RunWith(MockitoJUnitRunner.class)
-public class EpPolicyTemplateBySgtListenerImplTest {
-
- private static final Sgt SGT1 = new Sgt(1);
- private static final TenantId TENANT1 = new TenantId("tenant1");
- private static final TenantId TENANT2 = new TenantId("tenant2");
- @Mock
- private DataBroker dataBroker;
- @Mock
- private DSTreeBasedCache<EndpointPolicyTemplateBySgt, EpPolicyTemplateCacheKey, Sgt> cache;
- @Mock
- private ListenerRegistration<EpPolicyTemplateBySgtListenerImpl> listenerRegistration;
- @Mock
- private DataTreeModification<EndpointPolicyTemplateBySgt> dataTreeModification;
- @Mock
- private DataObjectModification<EndpointPolicyTemplateBySgt> rootNode;
-
- private final EndpointPolicyTemplateBySgt template1;
- private final EndpointPolicyTemplateBySgt template2;
-
- private EpPolicyTemplateBySgtListenerImpl listener;
-
- public EpPolicyTemplateBySgtListenerImplTest() {
- this.template1 = new EndpointPolicyTemplateBySgtBuilder()
- .setSgt(SGT1)
- .setTenant(TENANT1)
- .setEndpointGroups(Lists.newArrayList(new EndpointGroupId("epg1"), new EndpointGroupId("epg2")))
- .setConditions(Lists.newArrayList(new ConditionName("condition1"), new ConditionName("condition2")))
- .build();
-
- this.template2 = new EndpointPolicyTemplateBySgtBuilder()
- .setSgt(SGT1)
- .setTenant(TENANT2)
- .setEndpointGroups(Lists.newArrayList(new EndpointGroupId("epg3"), new EndpointGroupId("epg4")))
- .setConditions(Lists.newArrayList(new ConditionName("condition2"), new ConditionName("condition3")))
- .build();
- }
-
- @Before
- public void setUp() throws Exception {
- Mockito.when(dataBroker.registerDataTreeChangeListener(
- Matchers.<DataTreeIdentifier<EndpointPolicyTemplateBySgt>>any(),
- Matchers.<EpPolicyTemplateBySgtListenerImpl>any()))
- .thenReturn(listenerRegistration);
- listener = new EpPolicyTemplateBySgtListenerImpl(dataBroker, cache);
- }
-
- @After
- public void tearDown() throws Exception {
- Mockito.verifyNoMoreInteractions(cache);
- }
-
- @Test
- public void testOnDataTreeChanged_add() throws Exception {
- Mockito.when(rootNode.getDataAfter()).thenReturn(template1);
- Mockito.when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
- Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
-
- listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(cache).add(template1);
- }
-
- @Test
- public void testOnDataTreeChanged_remove() throws Exception {
- Mockito.when(rootNode.getDataBefore()).thenReturn(template1);
- Mockito.when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.DELETE);
- Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
-
- listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(cache).invalidate(template1);
- }
-
- @Test
- public void testOnDataTreeChanged_update() throws Exception {
- Mockito.when(rootNode.getDataBefore()).thenReturn(template1);
- Mockito.when(rootNode.getDataAfter()).thenReturn(template2);
- Mockito.when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.SUBTREE_MODIFIED);
- Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
-
- listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(cache).update(template1, template2);
- }
-
- @Test
- public void testClose() throws Exception {
- Mockito.verify(listenerRegistration, Mockito.never()).close();
- listener.close();
- Mockito.verify(listenerRegistration).close();
- listener.close();
- Mockito.verify(listenerRegistration, Mockito.times(2)).close();
- }
-}
\ No newline at end of file
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.listener;
import java.util.Collections;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
.build()))
.build())
.build())
+ .setVersion((long) order)
+ .build();
+ }
+
+ private RendererPolicy createVersion(final int order) {
+ return new RendererPolicyBuilder()
+ .setVersion((long) order)
.build();
}
Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(policyManager).syncPolicy(policy1.getConfiguration(), null);
+ Mockito.verify(policyManager).syncPolicy(policy1.getConfiguration(), null, 0);
}
@Test
Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(policyManager).syncPolicy(policy2.getConfiguration(), policy1.getConfiguration());
+ Mockito.verify(policyManager).syncPolicy(policy2.getConfiguration(), policy1.getConfiguration(), 1);
}
@Test
public void testOnDataTreeChanged_remove() throws Exception {
Mockito.when(rootNode.getDataBefore()).thenReturn(policy2);
- Mockito.when(rootNode.getDataAfter()).thenReturn(null);
+ Mockito.when(rootNode.getDataAfter()).thenReturn(createVersion(1));
Mockito.when(rootNode.getModificationType()).thenReturn(DataObjectModification.ModificationType.WRITE);
Mockito.when(dataTreeModification.getRootNode()).thenReturn(rootNode);
listener.onDataTreeChanged(Collections.singleton(dataTreeModification));
- Mockito.verify(policyManager).syncPolicy(null, policy2.getConfiguration());
+ Mockito.verify(policyManager).syncPolicy(null, policy2.getConfiguration(), 1);
}
@Test
--- /dev/null
+package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
+
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.MountPointService;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
+import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Host;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+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.RendererNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.netconf.node.connection.status.AvailableCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+import javax.annotation.Nonnull;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connected;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.Connecting;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNodeConnectionStatus.ConnectionStatus.UnableToConnect;
+
+
+public class NodeManagerTest extends CustomDataBrokerTest {
+
+ private final NodeId NODE_NAME = new NodeId("testNode");
+ private final TopologyId TOPOLOGY_ID = new TopologyId("topology-netconf");
+ private final Ipv4Address IPv4_ADDRESS = new Ipv4Address("174.25.75.11");
+ private NodeManager nodeManager;
+ private DataBroker dataBroker;
+
+ @Nonnull
+ @Override
+ public Collection<java.lang.Class<?>> getClassesFromModules() {
+ return Arrays.asList(Renderers.class, NetworkTopology.class, NetconfNode.class);
+ }
+
+ @Before
+ public void init() {
+ dataBroker = getDataBroker();
+ BindingAwareBroker.ProviderContext context = mock(BindingAwareBroker.ProviderContext.class);
+ MountPointService mountPointService = mock(MountPointService.class);
+ when(context.getSALService(any())).thenReturn(mountPointService);
+ nodeManager = new NodeManager(dataBroker, context);
+ }
+
+ @Test
+ public void testRegisterNewNode_connectingCase() throws Exception {
+ Node testNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(testNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ // Create Cases
+
+ @Test
+ public void testRegisterNewNode_connectedCaseNoIpAddress() throws Exception {
+ Node testNode = createNode(Connected, null, NODE_NAME, Capabilities.None);
+ nodeManager.syncNodes(testNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ public void testRegisterNewNode_connectedCaseNullCapabilities() throws Exception {
+ Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.None);
+ nodeManager.syncNodes(testNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ public void testRegisterNewNode_connectedCasePartialCapabilities() throws Exception {
+ Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
+ nodeManager.syncNodes(testNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ public void testRegisterNewNode_connectedCaseFullCapabilities() throws Exception {
+ Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(testNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertNotNull(result);
+ assertTrue(result.size() == 1);
+ }
+
+ @Test
+ public void testRegisterNewNode_unableToConnectCase() throws Exception {
+ Node testNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(testNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ public void testUpdateNode_fromConnectingToConnected() throws Exception {
+ Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(oldNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ assertNotNull(result);
+ assertTrue(result.size() == 1);
+ }
+
+ // Update Cases
+
+ @Test
+ public void testUpdateNode_fromConnectingToUnableToConnect() throws Exception {
+ Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ Node newNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(oldNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ public void testUpdateNode_fromConnectedToConnecting() throws Exception {
+ Node oldNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ Node newNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(oldNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertNotNull(result);
+ assertTrue(result.size() == 1);
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ public void testUpdateNode_fromConnectedToUnableToConnect() throws Exception {
+ Node oldNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ Node newNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(oldNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertNotNull(result);
+ assertTrue(result.size() == 1);
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ public void testUpdateNode_fromUnableToConnectToConnecting() throws Exception {
+ Node oldNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ Node newNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(oldNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ @Test
+ public void testUpdateNode_fromUnableToConnectToConnected() throws Exception {
+ Node oldNode = createNode(UnableToConnect, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(oldNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ assertNotNull(result);
+ assertTrue(result.size() == 1);
+ }
+
+ @Test
+ public void testUpdateNode_advancedCase() throws Exception {
+ Node oldNode = createNode(Connecting, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
+ nodeManager.syncNodes(oldNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ // One node is connecting, partial capabilities = empty list
+ assertTrue(result.isEmpty());
+ Node newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Partial);
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ // Update 1.: node is connected, still partial capabilities = empty list
+ assertTrue(result.isEmpty());
+ oldNode = newNode;
+ newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ // Update 2.: node is connected, full capabilities = 1 entry in list
+ assertNotNull(result);
+ assertTrue(result.size() == 1);
+ oldNode = newNode;
+ newNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.None);
+ nodeManager.syncNodes(newNode, oldNode);
+ result = rendererNodesReader();
+ // Update 3.: node remains connected, but without capabilities = empty list
+ assertTrue(result.isEmpty());
+ }
+
+ // Advanced update Case
+
+ @Test
+ public void testRemoveNode() throws Exception {
+ Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ nodeManager.syncNodes(testNode, null);
+ List<RendererNode> result = rendererNodesReader();
+ assertNotNull(result);
+ assertTrue(result.size() == 1);
+ nodeManager.syncNodes(null, testNode);
+ result = rendererNodesReader();
+ assertTrue(result.isEmpty());
+ }
+
+ // Remove Case
+
+ @Test
+ public void getNodeManagementIpByMountPointIid_absentNode() {
+ NodeId testNodeId = new NodeId(NODE_NAME);
+ InstanceIdentifier mountpointIid = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
+ .child(Node.class, new NodeKey(testNodeId)).build();
+ String ipAddress = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
+ assertNull(ipAddress);
+ }
+
+ @Test
+ public void getNodeManagementIpByMountPointIid_ipV4Case() throws Exception {
+ // Put node
+ Node testNode = createNode(Connected, IPv4_ADDRESS, NODE_NAME, Capabilities.Full);
+ InstanceIdentifier<Node> testNodeIid = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
+ .child(Node.class, new NodeKey(testNode.getNodeId())).build();
+ ReadWriteTransaction rwt = dataBroker.newReadWriteTransaction();
+ rwt.put(LogicalDatastoreType.CONFIGURATION, testNodeIid, testNode, true);
+ rwt.submit().checkedGet();
+ InstanceIdentifier mountpointIid = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId(TOPOLOGY_ID)))
+ .child(Node.class, new NodeKey(NODE_NAME)).build();
+ String result = nodeManager.getNodeManagementIpByMountPointIid(mountpointIid);
+ assertEquals(IPv4_ADDRESS.getValue(), result);
+ }
+
+ private Node createNode(final NetconfNodeConnectionStatus.ConnectionStatus connectionStatus,
+ final Ipv4Address ipAddress,
+ final NodeId nodeName,
+ final Capabilities choice) {
+ AvailableCapabilities capabilities = null;
+ switch (choice) {
+ case None: {
+ capabilities = emptyCapabilities();
+ break;
+ }
+ case Partial: {
+ capabilities = partialCapabilities();
+ break;
+ }
+ case Full: {
+ capabilities = fullCapabilities();
+ }
+ }
+ // Netconf node
+ NetconfNodeBuilder netconfNodeBuilder = new NetconfNodeBuilder();
+ netconfNodeBuilder.setConnectionStatus(connectionStatus)
+ .setAvailableCapabilities(capabilities)
+ .setHost(new Host(new IpAddress(ipAddress)));
+ // Node
+ NodeBuilder nodeBuilder = new NodeBuilder();
+ nodeBuilder.setNodeId(new NodeId(nodeName))
+ .setKey(new NodeKey(new NodeId(nodeName)))
+ .addAugmentation(NetconfNode.class, netconfNodeBuilder.build());
+ return nodeBuilder.build();
+ }
+
+ // Utility methods
+
+ private List<RendererNode> rendererNodesReader() throws Exception {
+ InstanceIdentifier<Renderers> renderersIid =
+ InstanceIdentifier.builder(Renderers.class).build();
+ ReadWriteTransaction rwt = dataBroker.newReadWriteTransaction();
+ CheckedFuture<Optional<Renderers>, ReadFailedException> submitFuture =
+ rwt.read(LogicalDatastoreType.OPERATIONAL, renderersIid);
+ Optional<Renderers> optionalRenderers = submitFuture.checkedGet();
+ if (optionalRenderers.isPresent()) {
+ Renderers renderers = optionalRenderers.get();
+ if (renderers != null && renderers.getRenderer() != null && !renderers.getRenderer().isEmpty()) {
+ RendererNodes writtenNodes = renderers.getRenderer().get(0).getRendererNodes();
+ if (writtenNodes != null) {
+ return writtenNodes.getRendererNode();
+ }
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ private AvailableCapabilities emptyCapabilities() {
+ AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
+ return availableCapabilitiesBuilder.build();
+ }
+
+ private AvailableCapabilities partialCapabilities() {
+ final String c1 = "(urn:ios?revision=2016-03-08)ned";
+ final String c2 = "(http://tail-f.com/yang/common?revision=2015-05-22)tailf-common";
+ final String c3 = "(http://tail-f.com/yang/common?revision=2015-03-19)tailf-cli-extensions";
+ String[] capabilityList = {c1, c2, c3};
+ AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
+ availableCapabilitiesBuilder.setAvailableCapability(Arrays.asList(capabilityList));
+ return availableCapabilitiesBuilder.build();
+ }
+
+ private AvailableCapabilities fullCapabilities() {
+ final String c1 = "(urn:ios?revision=2016-03-08)ned";
+ final String c2 = "(http://tail-f.com/yang/common?revision=2015-05-22)tailf-common";
+ final String c3 = "(http://tail-f.com/yang/common?revision=2015-03-19)tailf-cli-extensions";
+ final String c4 = "(http://tail-f.com/yang/common?revision=2013-11-07)tailf-meta-extensions";
+ final String c5 = "(urn:ietf:params:xml:ns:yang:ietf-yang-types?revision=2013-07-15)ietf-yang-types";
+ final String c6 = "(urn:ietf:params:xml:ns:yang:ietf-inet-types?revision=2013-07-15)ietf-inet-types";
+ String[] capabilityList = {c1, c2, c3, c4, c5, c6};
+ AvailableCapabilitiesBuilder availableCapabilitiesBuilder = new AvailableCapabilitiesBuilder();
+ availableCapabilitiesBuilder.setAvailableCapability(Arrays.asList(capabilityList));
+ return availableCapabilitiesBuilder.build();
+ }
+
+ private enum Capabilities {None, Partial, Full}
+}
\ No newline at end of file
--- /dev/null
+package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction.Out;
+import static org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation.PROVIDER;
+import static org.powermock.api.support.membermodification.MemberMatcher.method;
+import static org.powermock.api.support.membermodification.MemberModifier.stub;
+
+import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.PolicyManagerUtil;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.RendererPolicyUtil;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util.ServiceChainingUtil;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePathBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePathKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHopBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderKey;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
+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.forwarding.l2_l3.rev160427.IpPrefixType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.ConfigurationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.EndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererEndpointsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RendererForwarding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.RuleGroupsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.ClassifierBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRuleBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAugBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import com.google.common.util.concurrent.ListenableFuture;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({RendererPolicyUtil.class, PolicyManagerUtil.class, SfcProviderServiceForwarderAPI.class})
+public class PolicyManagerImplTest {
+
+ private final String address = "address";
+ private final String connector = "connector";
+ private final SfpName servicePath = new SfpName("service-path");
+ private final RspName renderedPath = new RspName("rendered-path");
+ private final SffName forwarderName = new SffName("service-forwarder");
+ private final ContextId contextId_1 = new ContextId("context-id-1");
+ private final ContextId contextId_2 = new ContextId("context-id-2");
+ private final ContextId contextId_3 = new ContextId("context-id-3");
+ private final ContextId contextId_4 = new ContextId("context-id-4");
+ private final ContractId contractId = new ContractId("contract-id");
+ private final String ipAddress = "192.168.50.1";
+ private final NodeId nodeId = new NodeId("node-id");
+ private final SubjectName subjectName = new SubjectName("subject-name");
+ private final TenantId tenantId = new TenantId("tenant-id");
+ private final TopologyId topologyId = new TopologyId("topology-id");
+ private final ActionDefinitionId chainActionDefinitionId = new ActionDefinitionId("Action-Chain");
+ private final ActionDefinitionId otherActionDefinitionId = new ActionDefinitionId("Action-Other");
+ private final SfName functionName = new SfName("service-function");
+ private PolicyManagerImpl policyManager;
+ private DataBroker mountpoint;
+ private NodeManager nodeManager;
+ private WriteTransaction writeTransaction;
+
+ @Before
+ public void init() {
+ mountpoint = mock(DataBroker.class);
+ writeTransaction = mock(WriteTransaction.class);
+ nodeManager = mock(NodeManager.class);
+ policyManager = new PolicyManagerImpl(mountpoint, nodeManager);
+ when(mountpoint.newWriteOnlyTransaction()).thenReturn(writeTransaction);
+ when(writeTransaction.submit()).thenReturn(Futures.immediateCheckedFuture((Void) null));
+ }
+
+ @Test
+ public void testSyncPolicy_emptyConfiguration() throws Exception {
+ Configuration policyConfiguration = createTestConfiguration(null, null, null, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
+ assertTrue((boolean) result.get());
+ }
+
+ @Test
+ public void testSyncPolicy_noEndpointsInConfiguration() throws Exception {
+ RendererEndpoint rendererEndpoint = createRendererEndpoint(contextId_1, contextId_2, null);
+ Configuration policyConfiguration = createTestConfiguration(null, Collections.singletonList(rendererEndpoint),
+ null, null);
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
+ assertTrue((boolean) result.get());
+ }
+
+ @Test
+ public void testSyncPolicy_noMountPoint() throws Exception {
+ AddressEndpointWithLocation endpointWithLocation = createAddressEndpointWithLocation(contextId_1, null, false);
+ RendererEndpoint rendererEndpoint = createRendererEndpoint(contextId_2, contextId_3, null);
+ Configuration policyConfiguration = createTestConfiguration(Collections.singletonList(endpointWithLocation),
+ Collections.singletonList(rendererEndpoint), null, null);
+
+ AbsoluteLocation location = createAbsoluteLocationExternal(connector, createMountpointIid());
+ AddressEndpointWithLocation lookupEndpoint = createAddressEndpointWithLocation(contextId_4, location, false);
+ stub(method(RendererPolicyUtil.class, "lookupEndpoint")).toReturn(lookupEndpoint);
+ when(nodeManager.getNodeMountPoint(eq(createMountpointIid()))).thenReturn(null);
+
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
+ assertTrue((boolean) result.get());
+ }
+
+ @Test
+ public void testSyncPolicy_nullSgtTags() throws Exception {
+ AddressEndpointWithLocation endpointWithLocation = createAddressEndpointWithLocation(contextId_1, null, false);
+ RendererEndpoint rendererEndpoint = createRendererEndpoint(contextId_2, contextId_3, null);
+ Configuration policyConfiguration = createTestConfiguration(Collections.singletonList(endpointWithLocation),
+ Collections.singletonList(rendererEndpoint), null, null);
+
+ AbsoluteLocation location = createAbsoluteLocationExternal(connector, createMountpointIid());
+ AddressEndpointWithLocation lookupEndpoint = createAddressEndpointWithLocation(contextId_4, location, false);
+ stub(method(RendererPolicyUtil.class, "lookupEndpoint")).toReturn(lookupEndpoint);
+ when(nodeManager.getNodeMountPoint(eq(createMountpointIid()))).thenReturn(mountpoint);
+ when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
+ when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
+
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
+ assertTrue((boolean) result.get());
+ }
+
+ @Test
+ public void testSyncPolicy_emptyRuleGroup() throws Exception {
+ AddressEndpointWithLocation endpointWithLocation = createAddressEndpointWithLocation(contextId_1, null, false);
+ RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation =
+ createRuleGroupWithRendererEpParticipation(PROVIDER);
+ RendererEndpoint rendererEndpoint = createRendererEndpoint(contextId_2, contextId_3,
+ ruleGroupWithParticipation);
+ RuleGroup ruleGroup = createRuleGroup(null);
+ Configuration policyConfiguration = createTestConfiguration(Collections.singletonList(endpointWithLocation),
+ Collections.singletonList(rendererEndpoint), null, ruleGroup);
+
+ AbsoluteLocation location = createAbsoluteLocationExternal(connector, createMountpointIid());
+ AddressEndpointWithLocation lookupEndpoint = createAddressEndpointWithLocation(contextId_4, location, true);
+ stub(method(RendererPolicyUtil.class, "lookupEndpoint")).toReturn(lookupEndpoint);
+ when(nodeManager.getNodeMountPoint(eq(createMountpointIid()))).thenReturn(mountpoint);
+ when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
+ when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
+
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
+ assertTrue((boolean) result.get());
+ }
+
+ @Test
+ public void testSyncPolicy_noActionDefinition() throws Exception {
+ AddressEndpointWithLocation endpointWithLocation = createAddressEndpointWithLocation(contextId_1, null, false);
+ RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation =
+ createRuleGroupWithRendererEpParticipation(PROVIDER);
+ RendererEndpoint rendererEndpoint = createRendererEndpoint(contextId_2, contextId_3,
+ ruleGroupWithParticipation);
+
+ RuleGroup ruleGroup = createRuleGroup(createRule(Out, null));
+ Configuration policyConfiguration = createTestConfiguration(Collections.singletonList(endpointWithLocation),
+ Collections.singletonList(rendererEndpoint), null, ruleGroup);
+
+ AbsoluteLocation location = createAbsoluteLocationExternal(connector, createMountpointIid());
+ AddressEndpointWithLocation lookupEndpoint = createAddressEndpointWithLocation(contextId_4, location, true);
+ stub(method(RendererPolicyUtil.class, "lookupEndpoint")).toReturn(lookupEndpoint);
+ when(nodeManager.getNodeMountPoint(eq(createMountpointIid()))).thenReturn(mountpoint);
+ when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
+ when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
+
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
+ assertTrue((boolean) result.get());
+ }
+
+ @Test
+ public void testSyncPolicy_otherAction() throws Exception {
+ AddressEndpointWithLocation endpointWithLocation = createAddressEndpointWithLocation(contextId_1, null, false);
+ RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation =
+ createRuleGroupWithRendererEpParticipation(PROVIDER);
+ RendererEndpoint rendererEndpoint = createRendererEndpoint(contextId_2, contextId_3,
+ ruleGroupWithParticipation);
+
+ RuleGroup ruleGroup = createRuleGroup(createRule(Out, otherActionDefinitionId));
+ Configuration policyConfiguration = createTestConfiguration(Collections.singletonList(endpointWithLocation),
+ Collections.singletonList(rendererEndpoint), null, ruleGroup);
+
+ AbsoluteLocation location = createAbsoluteLocationExternal(connector, createMountpointIid());
+ AddressEndpointWithLocation lookupEndpoint = createAddressEndpointWithLocation(contextId_4, location, true);
+ stub(method(RendererPolicyUtil.class, "lookupEndpoint")).toReturn(lookupEndpoint);
+ when(nodeManager.getNodeMountPoint(eq(createMountpointIid()))).thenReturn(mountpoint);
+ when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
+ when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
+
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
+ assertTrue((boolean) result.get());
+ }
+
+ @Test
+ public void testSyncPolicy_asymmetricChain() throws Exception {
+ AddressEndpointWithLocation endpointWithLocation = createAddressEndpointWithLocation(contextId_1, null, false);
+ RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation =
+ createRuleGroupWithRendererEpParticipation(PROVIDER);
+ RendererEndpoint rendererEndpoint = createRendererEndpoint(contextId_2, contextId_3,
+ ruleGroupWithParticipation);
+
+ RuleGroup ruleGroup = createRuleGroup(createRule(Out, chainActionDefinitionId));
+ Configuration policyConfiguration = createTestConfiguration(Collections.singletonList(endpointWithLocation),
+ Collections.singletonList(rendererEndpoint), null, ruleGroup);
+
+ AbsoluteLocation location = createAbsoluteLocationExternal(connector, createMountpointIid());
+ AddressEndpointWithLocation lookupEndpoint = createAddressEndpointWithLocation(contextId_4, location, true);
+ stub(method(RendererPolicyUtil.class, "lookupEndpoint")).toReturn(lookupEndpoint);
+ when(nodeManager.getNodeMountPoint(eq(createMountpointIid()))).thenReturn(mountpoint);
+ when(nodeManager.getNodeIdByMountpointIid(eq(createMountpointIid()))).thenReturn(nodeId);
+ when(nodeManager.getNodeManagementIpByMountPointIid(eq(createMountpointIid()))).thenReturn(ipAddress);
+ ServiceFunctionPath sfp = createServiceFunctionPath();
+ stub(method(ServiceChainingUtil.class, "getServicePath")).toReturn(sfp);
+ RenderedServicePath rsp = createRenderedServicePath();
+ stub(method(ServiceChainingUtil.class, "createRenderedPath")).toReturn(rsp);
+ ServiceFunctionForwarder serviceFunctionForwarder = createServiceForwarder();
+ stub(method(SfcProviderServiceForwarderAPI.class, "readServiceFunctionForwarder"))
+ .toReturn(serviceFunctionForwarder);
+
+ ListenableFuture result = policyManager.syncPolicy(policyConfiguration, null, 0);
+ assertTrue((boolean) result.get());
+ }
+
+ private ServiceFunctionForwarder createServiceForwarder() {
+ ServiceFunctionForwarderBuilder serviceFunctionForwarderBuilder = new ServiceFunctionForwarderBuilder();
+ serviceFunctionForwarderBuilder.setName(new SffName(forwarderName))
+ .setKey(new ServiceFunctionForwarderKey(new SffName(forwarderName)))
+ .setIpMgmtAddress(new IpAddress(new Ipv4Address(ipAddress)));
+ return serviceFunctionForwarderBuilder.build();
+ }
+
+ // Utility methods
+
+ private InstanceIdentifier createMountpointIid() {
+ return InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(topologyId))
+ .child(Node.class, new NodeKey(nodeId)).build();
+ }
+
+ private ResolvedRule createRule(HasDirection.Direction direction, ActionDefinitionId actionDefinitionId) {
+ ResolvedRuleBuilder resolvedRuleBuilder = new ResolvedRuleBuilder();
+ ClassifierBuilder classifierBuilder = new ClassifierBuilder();
+ classifierBuilder.setDirection(direction);
+ ActionBuilder actionBuilder = new ActionBuilder();
+ actionBuilder.setActionDefinitionId(actionDefinitionId);
+ resolvedRuleBuilder.setClassifier(Collections.singletonList(classifierBuilder.build()))
+ .setAction(Collections.singletonList(actionBuilder.build()));
+ return resolvedRuleBuilder.build();
+ }
+
+ private RuleGroupWithRendererEndpointParticipation createRuleGroupWithRendererEpParticipation(final EndpointPolicyParticipation participation) {
+ RuleGroupWithRendererEndpointParticipationBuilder ruleGroupBuilder = new RuleGroupWithRendererEndpointParticipationBuilder();
+ ruleGroupBuilder.setKey(new RuleGroupWithRendererEndpointParticipationKey(contractId, participation, subjectName,
+ tenantId));
+ return ruleGroupBuilder.build();
+ }
+
+ private AbsoluteLocation createAbsoluteLocationExternal(String connector, InstanceIdentifier mountpoint) {
+ ExternalLocationCaseBuilder externalLocationCaseBuilder = new ExternalLocationCaseBuilder();
+ externalLocationCaseBuilder.setExternalNodeConnector(connector)
+ .setExternalNodeMountPoint(mountpoint);
+ AbsoluteLocationBuilder absoluteLocationBuilder = new AbsoluteLocationBuilder();
+ absoluteLocationBuilder.setLocationType(externalLocationCaseBuilder.build());
+ return absoluteLocationBuilder.build();
+ }
+
+ private ServiceFunctionPath createServiceFunctionPath() {
+ ServiceFunctionPathBuilder serviceFunctionPathBuilder = new ServiceFunctionPathBuilder();
+ serviceFunctionPathBuilder.setKey(new ServiceFunctionPathKey(servicePath))
+ .setSymmetric(false);
+ return serviceFunctionPathBuilder.build();
+ }
+
+ private RenderedServicePath createRenderedServicePath() {
+ RenderedServicePathHopBuilder renderedServicePathHopBuilder = new RenderedServicePathHopBuilder();
+ renderedServicePathHopBuilder.setServiceFunctionForwarder(forwarderName);
+ renderedServicePathHopBuilder.setServiceFunctionName(functionName);
+ renderedServicePathHopBuilder.build();
+
+ RenderedServicePathBuilder renderedServicePathBuilder = new RenderedServicePathBuilder();
+ renderedServicePathBuilder.setKey(new RenderedServicePathKey(renderedPath))
+ .setRenderedServicePathHop(Collections.singletonList(renderedServicePathHopBuilder.build()));
+ return renderedServicePathBuilder.build();
+ }
+
+
+ private AddressEndpointWithLocation createAddressEndpointWithLocation(final ContextId contextId,
+ final AbsoluteLocation location,
+ boolean augmentation) {
+ AddressEndpointWithLocationAugBuilder augmentationBuilder = new AddressEndpointWithLocationAugBuilder();
+ augmentationBuilder.setSgt(new Sgt(1));
+ AddressEndpointWithLocationBuilder addressEndpointBuilder = new AddressEndpointWithLocationBuilder();
+ addressEndpointBuilder.setKey(new AddressEndpointWithLocationKey(address, IpPrefixType.class,
+ contextId, L2BridgeDomain.class))
+ .setAbsoluteLocation(location);
+ if (augmentation) {
+ addressEndpointBuilder.addAugmentation(AddressEndpointWithLocationAug.class, augmentationBuilder.build());
+ }
+ return addressEndpointBuilder.build();
+ }
+
+ private RendererEndpoint createRendererEndpoint(ContextId contextId_1, ContextId contextId_2,
+ RuleGroupWithRendererEndpointParticipation ruleGroup) {
+ PeerEndpointWithPolicyBuilder peerEndpointWithPolicyBuilder = new PeerEndpointWithPolicyBuilder();
+ peerEndpointWithPolicyBuilder.setKey(new PeerEndpointWithPolicyKey(address, IpPrefixType.class, contextId_1,
+ L2BridgeDomain.class))
+ .setRuleGroupWithRendererEndpointParticipation(Collections.singletonList(ruleGroup));
+ RendererEndpointBuilder rendererEndpointBuilder = new RendererEndpointBuilder();
+ rendererEndpointBuilder.setKey(new RendererEndpointKey(address, IpPrefixType.class, contextId_2,
+ L2BridgeDomain.class))
+ .setPeerEndpointWithPolicy(Collections.singletonList(peerEndpointWithPolicyBuilder.build()));
+ return rendererEndpointBuilder.build();
+ }
+
+ private RuleGroup createRuleGroup(ResolvedRule rule) {
+ RuleGroupBuilder ruleGroupBuilder = new RuleGroupBuilder();
+ ruleGroupBuilder.setKey(new RuleGroupKey(contractId, subjectName, tenantId))
+ .setResolvedRule(Collections.singletonList(rule));
+ return ruleGroupBuilder.build();
+ }
+
+ private Configuration createTestConfiguration(final List<AddressEndpointWithLocation> endpointsWithLocation,
+ final List<RendererEndpoint> rendererEndpoints,
+ final RendererForwarding rendererForwarding,
+ final RuleGroup ruleGroup) {
+ // Set endpoints
+ EndpointsBuilder endpointsBuilder = new EndpointsBuilder();
+ endpointsBuilder.setAddressEndpointWithLocation(endpointsWithLocation);
+ // Set renderer endpoints
+ RendererEndpointsBuilder rendererEndpointsBuilder = new RendererEndpointsBuilder();
+ rendererEndpointsBuilder.setRendererEndpoint(rendererEndpoints);
+ // Set rule group
+ RuleGroupsBuilder ruleGroupsBuilder = new RuleGroupsBuilder();
+ ruleGroupsBuilder.setRuleGroup(Collections.singletonList(ruleGroup));
+ // Build configuration
+ ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
+ configurationBuilder.setEndpoints(endpointsBuilder.build())
+ .setRendererEndpoints(rendererEndpointsBuilder.build())
+ .setRendererForwarding(rendererForwarding)
+ .setRuleGroups(ruleGroupsBuilder.build());
+ return configurationBuilder.build();
+ }
+
+
+}
\ No newline at end of file
package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.api.manager.PolicyManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Matcher;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.ConfigurationBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
/**
* Test for {@link PolicyManagerZipImpl}.
*/
@Test
public void testSyncPolicy_add() throws Exception {
- policyManager.syncPolicy(null, configAfter);
+ policyManager.syncPolicy(null, configAfter, 0);
policyManager.close();
- Mockito.verify(delegate).syncPolicy(null, configAfter);
+ Mockito.verify(delegate).syncPolicy(null, configAfter, 0);
}
@Test
public void testSyncPolicy_update() throws Exception {
- policyManager.syncPolicy(configBefore, configAfter);
+ policyManager.syncPolicy(configBefore, configAfter, 0);
policyManager.close();
- Mockito.verify(delegate).syncPolicy(configBefore, configAfter);
+ Mockito.verify(delegate).syncPolicy(configBefore, configAfter, 0);
}
@Test
public void testSyncPolicy_remove() throws Exception {
- policyManager.syncPolicy(configBefore, null);
+ policyManager.syncPolicy(configBefore, null, 0);
policyManager.close();
- Mockito.verify(delegate).syncPolicy(configBefore, null);
+ Mockito.verify(delegate).syncPolicy(configBefore, null, 0);
}
@Test
final CountDownLatch latchForFirst = new CountDownLatch(1);
final CountDownLatch latchForOthers = new CountDownLatch(1);
- Mockito.when(delegate.syncPolicy(Matchers.<Configuration>any(), Matchers.<Configuration>any()))
+ Mockito.when(delegate.syncPolicy(Matchers.<Configuration>any(), Matchers.<Configuration>any(), Matchers.anyLong()))
.thenAnswer(new Answer<ListenableFuture<Boolean>>() {
@Override
public ListenableFuture<Boolean> answer(final InvocationOnMock invocationOnMock) throws Throwable {
.thenReturn(Futures.immediateFuture(true));
final List<ListenableFuture<Boolean>> allResults = new ArrayList<>();
- allResults.add(policyManager.syncPolicy(null, configBefore));
+ allResults.add(policyManager.syncPolicy(null, configBefore, 0));
latchForOthers.await(1, TimeUnit.SECONDS);
- allResults.add(policyManager.syncPolicy(configBefore, configAfter));
- allResults.add(policyManager.syncPolicy(configAfter, null));
- allResults.add(policyManager.syncPolicy(null, configAfter2));
+ allResults.add(policyManager.syncPolicy(configBefore, configAfter, 0));
+ allResults.add(policyManager.syncPolicy(configAfter, null, 0));
+ allResults.add(policyManager.syncPolicy(null, configAfter2, 0));
latchForFirst.countDown();
Futures.allAsList(allResults).get(1, TimeUnit.SECONDS);
LOG.info("all configs finished");
policyManager.close();
final InOrder inOrder = Mockito.inOrder(delegate);
- inOrder.verify(delegate).syncPolicy(null, configBefore);
- inOrder.verify(delegate).syncPolicy(configBefore, configAfter2);
+ inOrder.verify(delegate).syncPolicy(null, configBefore, 0);
+ inOrder.verify(delegate).syncPolicy(configBefore, configAfter2, 0);
}
}
\ No newline at end of file
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.NodeWriter;
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.RendererNodes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
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.ParameterValueBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import static org.junit.Assert.assertNotNull;
+
/**
* Test for {@link PolicyManagerUtil}.
*/
new OpendaylightSfc().setDataProvider(dataBroker);
}
+ @Test
+ public void testCreateClassMap() {
+ ClassMap cm = PolicyManagerUtil.createClassMap("testName", null);
+ assertNotNull(cm);
+ }
+
@Test
public void testGetServicePath() throws Exception {
final ParameterValue paramValueSfc = new ParameterValueBuilder()
Mockito.when(roTx.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(ServiceFunctionPaths.class)))
.thenReturn(Futures.immediateCheckedFuture(Optional.of(sfPaths)));
- final ServiceFunctionPath servicePath = PolicyManagerUtil.getServicePath(Collections.singletonList(paramValueSfc));
+ final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(Collections.singletonList(paramValueSfc));
Assert.assertEquals(serviceFunctionPath, servicePath);
}
Mockito.when(roTx.read(Matchers.eq(LogicalDatastoreType.OPERATIONAL), rendererServicePathIICaptor.capture()))
.thenReturn(Futures.immediateCheckedFuture(Optional.of(renderedSP)));
- final RenderedServicePath renderedPath = PolicyManagerUtil.createRenderedPath(serviceFunctionPath, tenantId);
+ final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(serviceFunctionPath, tenantId);
Assert.assertEquals(renderedSP, renderedPath);
final InstanceIdentifier<RenderedServicePath> ii = rendererServicePathIICaptor.getValue();
Assert.assertEquals("sfp-name-01tenant-id-01-gbp-rsp", ii.firstKeyOf(RenderedServicePath.class).getName().getValue());
.thenReturn(Futures.immediateCheckedFuture(Optional.of(renderedServicePath)));
- final RenderedServicePath symmetricRenderedPath = PolicyManagerUtil.createSymmetricRenderedPath(
+ final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(
serviceFunctionPath, renderedServicePath, tenantId);
Assert.assertEquals(renderedServicePath, symmetricRenderedPath);
final InstanceIdentifier<RenderedServicePath> ii = rendererServicePathIICaptor.getValue();
--- /dev/null
+/*
+ * Copyright (c) 2016 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.ios_xe_provider.impl.util;
+
+import static org.powermock.api.support.membermodification.MemberMatcher.method;
+import static org.powermock.api.support.membermodification.MemberModifier.stub;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
+import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriter;
+import org.opendaylight.sfc.provider.api.SfcProviderRenderedPathAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServiceForwarderAPI;
+import org.opendaylight.sfc.provider.api.SfcProviderServicePathAPI;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.RspName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfcName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SffName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.common.rev151017.SfpName;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.CreateRenderedPathInput;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePathBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHop;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.rendered.service.path.RenderedServicePathHopBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarderBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPaths;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.ServiceFunctionPathsBuilder;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPath;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sfp.rev140701.service.function.paths.ServiceFunctionPathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChain;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ServiceChainBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.ServicePathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.Local;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.LocalBuilder;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.function.forwarder.ServiceFfName;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.ServiceTypeChoice;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunction;
+import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.service.chain.service.path.config.service.chain.path.mode.service.index.services.service.type.choice.ServiceFunctionForwarder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+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.ParameterValueBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+/**
+ * Test for {@link ServiceChainingUtil}.
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({
+ ServiceChainingUtil.class,
+ SfcProviderServicePathAPI.class,
+ SfcProviderRenderedPathAPI.class,
+ SfcProviderServiceForwarderAPI.class
+})
+public class ServiceChainingUtilTest {
+
+ @Captor
+ private ArgumentCaptor<RspName> rspNameCaptor;
+ @Captor
+ private ArgumentCaptor<SffName> sffNameCaptor;
+ @Captor
+ private ArgumentCaptor<ServiceFunctionPath> sfpCaptor;
+ @Captor
+ private ArgumentCaptor<CreateRenderedPathInput> createRspCaptor;
+ @Captor
+ private ArgumentCaptor<RenderedServicePath> rspCaptor;
+ @Captor
+ private ArgumentCaptor<List<Class>> listClassCaptor;
+ @Mock
+ private PolicyWriter policyWriter;
+ @Mock
+ private DataBroker dataBroker;
+ @Mock
+ private ReadWriteTransaction rwTx;
+
+ @Before
+ public void setUp() throws Exception {
+ final NodeId currentNodeId = new NodeId("unit-node-01");
+ Mockito.when(policyWriter.getCurrentNodeId()).thenReturn(currentNodeId);
+
+ final String managementIpAddress = "1.2.3.5";
+ Mockito.when(policyWriter.getManagementIpAddress()).thenReturn(managementIpAddress);
+
+ Mockito.when(dataBroker.newReadWriteTransaction()).thenReturn(rwTx);
+ }
+
+ @Test
+ public void testGetServicePath() throws Exception {
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfcPath = createSfp(sfcNameValue, false);
+ final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
+ .setServiceFunctionPath(Collections.singletonList(sfcPath))
+ .build();
+
+ stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
+
+ final ServiceFunctionPath servicePath = ServiceChainingUtil.getServicePath(Lists.newArrayList(
+ createParameterValue("sfc-chain-name", sfcNameValue)
+ ));
+ Assert.assertEquals(sfcPath, servicePath);
+ }
+
+ private ParameterValue createParameterValue(final String name, final String value) {
+ return new ParameterValueBuilder().setName(new ParameterName(name)).setStringValue(value).build();
+ }
+
+ @Test
+ public void testResolveChainAction_full() throws Exception {
+ final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy();
+ final Sgt sourceSgt = new Sgt(1);
+ final Sgt destinationSgt = new Sgt(2);
+ final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+ final String classMapName = "unit-class-map-name-01";
+
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfcPath = createSfp(sfcNameValue, false);
+ final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
+ .setServiceFunctionPath(Collections.singletonList(sfcPath))
+ .build();
+
+ stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
+
+ final RenderedServicePath rsp = createRsp("unit-rsp-02");
+ stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
+ stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
+
+ ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+
+ Mockito.verify(policyWriter).cache(listClassCaptor.capture());
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ Assert.assertEquals(1, listClassCaptor.getValue().size());
+ }
+
+ @Test
+ public void testResolveChainAction_fullSymmetric() throws Exception {
+ final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy();
+ final Sgt sourceSgt = new Sgt(1);
+ final Sgt destinationSgt = new Sgt(2);
+ final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+ final String classMapName = "unit-class-map-name-01";
+
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfcPath = createSfp(sfcNameValue, true);
+ final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
+ .setServiceFunctionPath(Collections.singletonList(sfcPath))
+ .build();
+
+ stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
+
+ final RenderedServicePath rsp = createRsp("unit-rsp-02");
+ stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
+ stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
+
+ ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+
+ Mockito.verify(policyWriter).cache(listClassCaptor.capture());
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ Assert.assertEquals(2, listClassCaptor.getValue().size());
+ }
+
+ @Test
+ public void testResolveChainAction_partial01() throws Exception {
+ final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy();
+ final Sgt sourceSgt = new Sgt(1);
+ final Sgt destinationSgt = new Sgt(2);
+ final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+ final String classMapName = "unit-class-map-name-01";
+
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfcPath = createSfp(sfcNameValue, true);
+ final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
+ .setServiceFunctionPath(Collections.singletonList(sfcPath))
+ .build();
+
+ stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
+
+ final RenderedServicePath rsp = createRsp("unit-rsp-02");
+ stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
+ stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(true);
+ stub(method(ServiceChainingUtil.class, "createSymmetricRenderedPath")).toReturn(null);
+
+ ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ @Test
+ public void testResolveChainAction_partial02() throws Exception {
+ final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy();
+ final Sgt sourceSgt = new Sgt(1);
+ final Sgt destinationSgt = new Sgt(2);
+ final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+ final String classMapName = "unit-class-map-name-01";
+
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfcPath = createSfp(sfcNameValue, false);
+ final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
+ .setServiceFunctionPath(Collections.singletonList(sfcPath))
+ .build();
+
+ stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
+
+ final RenderedServicePath rsp = createRsp("unit-rsp-02");
+ stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
+ stub(method(ServiceChainingUtil.class, "setSfcPart")).toReturn(false);
+
+ ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ @Test
+ public void testResolveChainAction_partial03() throws Exception {
+ final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy(null);
+ final Sgt sourceSgt = new Sgt(1);
+ final Sgt destinationSgt = new Sgt(2);
+ final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap();
+ final String classMapName = "unit-class-map-name-01";
+
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfcPath = createSfp(sfcNameValue, false);
+ final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
+ .setServiceFunctionPath(Collections.singletonList(sfcPath))
+ .build();
+
+ stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
+
+ final RenderedServicePath rsp = createRsp("unit-rsp-02");
+ stub(method(SfcProviderRenderedPathAPI.class, "readRenderedServicePath")).toReturn(rsp);
+
+ ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ @Test
+ public void testResolveChainAction_partial04() throws Exception {
+ final PeerEndpointWithPolicy peerEndpoint = createPeerEndpointWithPolicy(null);
+ final Sgt sourceSgt = new Sgt(1);
+ final Sgt destinationSgt = new Sgt(2);
+ final Map<PolicyManagerImpl.ActionCase, Action> actionMap = createActionMap(false);
+ final String classMapName = "unit-class-map-name-01";
+
+ ServiceChainingUtil.resolveChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, classMapName, policyWriter);
+
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ private Map<PolicyManagerImpl.ActionCase, Action> createActionMap() {
+ return createActionMap(true);
+ }
+
+ private Map<PolicyManagerImpl.ActionCase, Action> createActionMap(final boolean fillParamValue) {
+ final Map<PolicyManagerImpl.ActionCase,Action> actionMap = new HashMap<>();
+ final ActionBuilder actionValue = new ActionBuilder();
+ if (fillParamValue) {
+ actionValue.setParameterValue(Collections.singletonList(new ParameterValueBuilder()
+ .setName(new ParameterName(ChainActionDefinition.SFC_CHAIN_NAME))
+ .setStringValue("123")
+ .build()));
+ }
+ actionMap.put(PolicyManagerImpl.ActionCase.CHAIN, actionValue.build());
+ return actionMap;
+ }
+
+ private PeerEndpointWithPolicy createPeerEndpointWithPolicy() {
+ return createPeerEndpointWithPolicy(new TenantId("unit-tenant-06"));
+ }
+
+ private PeerEndpointWithPolicy createPeerEndpointWithPolicy(final TenantId tenantId) {
+ return new PeerEndpointWithPolicyBuilder()
+ .setRuleGroupWithRendererEndpointParticipation(Collections.singletonList(
+ new RuleGroupWithRendererEndpointParticipationBuilder()
+ .setTenantId(tenantId)
+ .build()
+ ))
+ .build();
+ }
+
+ @Test
+ public void testCreateRenderedPath() throws Exception {
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfp = createSfp(sfcNameValue, false);
+ final TenantId tenantId = new TenantId("unit-tennant-01");
+
+ final RenderedServicePath rsp = createRsp("unit-rsp-01");
+
+ PowerMockito.mockStatic(SfcProviderRenderedPathAPI.class);
+ final SfcProviderRenderedPathAPI api = PowerMockito.mock(SfcProviderRenderedPathAPI.class);
+ PowerMockito.when(api.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(rsp);
+
+ final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId);
+
+ Assert.assertEquals("123_plainunit-tennant-01-gbp-rsp", rspNameCaptor.getValue().getValue());
+ Assert.assertEquals(rsp, renderedPath);
+ }
+
+ @Test
+ public void testCreateRenderedPath_notExisting() throws Exception {
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfp = createSfp(sfcNameValue, false);
+ final TenantId tenantId = new TenantId("unit-tennant-01");
+
+ final RenderedServicePath rsp = createRsp("unit-rsp-01");
+
+ PowerMockito.mockStatic(SfcProviderRenderedPathAPI.class);
+ final SfcProviderRenderedPathAPI api = PowerMockito.mock(SfcProviderRenderedPathAPI.class);
+ PowerMockito.when(api.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(null);
+ PowerMockito.when(api.createRenderedServicePathAndState(
+ sfpCaptor.capture(), createRspCaptor.capture()
+ )).thenReturn(rsp);
+
+ final RenderedServicePath renderedPath = ServiceChainingUtil.createRenderedPath(sfp, tenantId);
+
+ Assert.assertEquals("123_plainunit-tennant-01-gbp-rsp", rspNameCaptor.getValue().getValue());
+
+ final ServiceFunctionPath serviceFunctionPath = sfpCaptor.getValue();
+ Assert.assertEquals("123_plain", serviceFunctionPath.getName().getValue());
+ Assert.assertFalse(serviceFunctionPath.isSymmetric());
+
+ final CreateRenderedPathInput createRPInput = createRspCaptor.getValue();
+ Assert.assertFalse(createRPInput.isSymmetric());
+ Assert.assertEquals("123_plain", createRPInput.getParentServiceFunctionPath());
+ Assert.assertEquals("123_plainunit-tennant-01-gbp-rsp", createRPInput.getName());
+
+ Assert.assertEquals(rsp, renderedPath);
+ }
+
+ private RenderedServicePath createRsp(final String rspNameValue) {
+ return new RenderedServicePathBuilder()
+ .setName(new RspName(rspNameValue))
+ .setRenderedServicePathHop(Lists.newArrayList(createRspHop("rsp-hop-01-sf")))
+ .build();
+ }
+
+ private RenderedServicePathHop createRspHop(final String sfNameValue) {
+ return new RenderedServicePathHopBuilder()
+ .setServiceFunctionName(new SfName(sfNameValue))
+ .setServiceFunctionForwarder(new SffName(sfNameValue + "+sff"))
+ .build();
+ }
+
+ private ServiceFunctionPath createSfp(final String sfcNameValue, final boolean symmetric) {
+ return new ServiceFunctionPathBuilder()
+ .setServiceChainName(new SfcName(sfcNameValue))
+ .setName(new SfpName(sfcNameValue + "_plain"))
+ .setSymmetric(symmetric)
+ .build();
+ }
+
+ @Test
+ public void testCreateSymmetricRenderedPath() throws Exception {
+ final ServiceFunctionPath sfp = createSfp("unit-sfp-02", false);
+ final RenderedServicePath rsp = createRsp("unit-rsp-02");
+ final TenantId tennantId = new TenantId("tenant-02");
+
+ PowerMockito.mockStatic(SfcProviderRenderedPathAPI.class);
+ final SfcProviderRenderedPathAPI api = PowerMockito.mock(SfcProviderRenderedPathAPI.class);
+ PowerMockito.when(api.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(rsp);
+
+ final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(sfp, rsp, tennantId);
+
+ Assert.assertEquals("unit-sfp-02_plaintenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue());
+ Assert.assertEquals(rsp, symmetricRenderedPath);
+ }
+
+ @Test
+ public void testCreateSymmetricRenderedPath_notExisting() throws Exception {
+ final ServiceFunctionPath sfp = createSfp("unit-sfp-02", false);
+ final RenderedServicePath rsp = createRsp("unit-rsp-02");
+ final TenantId tennantId = new TenantId("tenant-02");
+
+ PowerMockito.mockStatic(SfcProviderRenderedPathAPI.class);
+ final SfcProviderRenderedPathAPI api = PowerMockito.mock(SfcProviderRenderedPathAPI.class);
+ PowerMockito.when(api.readRenderedServicePath(rspNameCaptor.capture())).thenReturn(null);
+ PowerMockito.when(api.createSymmetricRenderedServicePathAndState(rspCaptor.capture())).thenReturn(rsp);
+
+ final RenderedServicePath symmetricRenderedPath = ServiceChainingUtil.createSymmetricRenderedPath(sfp, rsp, tennantId);
+
+ Assert.assertEquals("unit-sfp-02_plaintenant-02-gbp-rsp-Reverse", rspNameCaptor.getValue().getValue());
+ Assert.assertEquals(rsp, rspCaptor.getValue());
+ Assert.assertEquals(rsp, symmetricRenderedPath);
+ }
+
+ @Test
+ public void testCheckLocalForwarderPresence() throws Exception {
+ final Local local = new LocalBuilder().build();
+
+ Mockito.when(rwTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION), Matchers.<InstanceIdentifier<Local>>any()))
+ .thenReturn(Futures.<Optional<Local>, ReadFailedException>immediateCheckedFuture(Optional.of(local)))
+ .thenReturn(Futures.<Optional<Local>, ReadFailedException>immediateCheckedFuture(Optional.absent()))
+ .thenReturn(Futures.<Optional<Local>, ReadFailedException>immediateFailedCheckedFuture(new ReadFailedException("n/a")));
+
+ Assert.assertTrue(ServiceChainingUtil.checkLocalForwarderPresence(dataBroker));
+ Assert.assertFalse(ServiceChainingUtil.checkLocalForwarderPresence(dataBroker));
+ Assert.assertFalse(ServiceChainingUtil.checkLocalForwarderPresence(dataBroker));
+ Assert.assertFalse(ServiceChainingUtil.checkLocalForwarderPresence(dataBroker));
+ }
+
+ @Test
+ public void testCheckServicePathPresence() throws Exception {
+ final ServiceChain serviceChainOk = new ServiceChainBuilder()
+ .setServicePath(Collections.singletonList(new ServicePathBuilder().build()))
+ .build();
+ final ServiceChain serviceChainBad1 = new ServiceChainBuilder()
+ .setServicePath(Collections.emptyList())
+ .build();
+ final ServiceChain serviceChainBad2 = new ServiceChainBuilder().build();
+
+ Mockito.when(rwTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION), Matchers.<InstanceIdentifier<ServiceChain>>any()))
+ .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateCheckedFuture(Optional.of(serviceChainOk)))
+ .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateCheckedFuture(Optional.of(serviceChainBad1)))
+ .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateCheckedFuture(Optional.of(serviceChainBad2)))
+ .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateCheckedFuture(Optional.absent()))
+ .thenReturn(Futures.<Optional<ServiceChain>, ReadFailedException>immediateFailedCheckedFuture(new ReadFailedException("n/a")));
+
+ Assert.assertFalse(ServiceChainingUtil.checkServicePathPresence(dataBroker));
+ Assert.assertTrue(ServiceChainingUtil.checkServicePathPresence(dataBroker));
+ Assert.assertTrue(ServiceChainingUtil.checkServicePathPresence(dataBroker));
+ Assert.assertTrue(ServiceChainingUtil.checkServicePathPresence(dataBroker));
+ Assert.assertFalse(ServiceChainingUtil.checkServicePathPresence(dataBroker));
+ }
+
+ @Test
+ public void testFindServiceFunctionPath() throws Exception {
+ final String sfcNameValue = "123";
+ final ServiceFunctionPath sfcPath = createSfp(sfcNameValue, false);
+ final ServiceFunctionPaths sfcPaths = new ServiceFunctionPathsBuilder()
+ .setServiceFunctionPath(Collections.singletonList(sfcPath))
+ .build();
+
+ stub(method(SfcProviderServicePathAPI.class, "readAllServiceFunctionPaths")).toReturn(sfcPaths);
+
+ final ServiceFunctionPath servicePath = ServiceChainingUtil.findServiceFunctionPath(new SfcName(sfcNameValue));
+ Assert.assertEquals(sfcPath, servicePath);
+ }
+
+ @Test
+ public void testSetSfcPart_success() throws Exception {
+ final RenderedServicePath rsp = createRsp("unit-rsp-03");
+ final org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder
+ sff = new ServiceFunctionForwarderBuilder()
+ .setName(new SffName("unit-sff-03"))
+ .setIpMgmtAddress(new IpAddress(new Ipv4Address("1.2.3.4")))
+ .build();
+
+ stub(method(ServiceChainingUtil.class, "checkLocalForwarderPresence")).toReturn(true);
+
+ PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
+ final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
+ PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(sff);
+
+
+ final boolean outcome = ServiceChainingUtil.setSfcPart(rsp, policyWriter);
+
+ Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
+ Assert.assertTrue(outcome);
+
+ Mockito.verify(policyWriter).cache(Matchers.<ServiceFfName>any());
+ Mockito.verify(policyWriter).cache(Matchers.<ServiceChain>any());
+ Mockito.verify(policyWriter).getCurrentNodeId();
+ Mockito.verify(policyWriter).getCurrentMountpoint();
+ Mockito.verify(policyWriter).getManagementIpAddress();
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ @Test
+ public void testSetSfcPart_success_newRsp() throws Exception {
+ final RenderedServicePath rsp = createRsp("unit-rsp-03");
+ final org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.sff.rev140701.service.function.forwarders.ServiceFunctionForwarder
+ sff = new ServiceFunctionForwarderBuilder()
+ .setName(new SffName("unit-sff-03"))
+ .setIpMgmtAddress(new IpAddress(new Ipv4Address("1.2.3.4")))
+ .build();
+
+ stub(method(ServiceChainingUtil.class, "checkLocalForwarderPresence")).toReturn(false);
+
+ PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
+ final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
+ PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(sff);
+
+
+ final boolean outcome = ServiceChainingUtil.setSfcPart(rsp, policyWriter);
+
+ Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
+ Assert.assertTrue(outcome);
+
+ Mockito.verify(policyWriter).cache(Matchers.<Local>any());
+ Mockito.verify(policyWriter).cache(Matchers.<ServiceFfName>any());
+ Mockito.verify(policyWriter).cache(Matchers.<ServiceChain>any());
+ Mockito.verify(policyWriter).getCurrentMountpoint();
+ Mockito.verify(policyWriter, Mockito.times(2)).getManagementIpAddress();
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ @Test
+ public void testSetSfcPart_fail01() throws Exception {
+ Assert.assertFalse(ServiceChainingUtil.setSfcPart(null, policyWriter));
+
+ final RenderedServicePathBuilder rspBuilder = new RenderedServicePathBuilder().setName(new RspName("unit-rsp-05"));
+ Assert.assertFalse(ServiceChainingUtil.setSfcPart(rspBuilder.build(), policyWriter));
+
+ rspBuilder.setRenderedServicePathHop(Collections.emptyList());
+ Assert.assertFalse(ServiceChainingUtil.setSfcPart(rspBuilder.build(), policyWriter));
+
+ rspBuilder.setRenderedServicePathHop(Collections.singletonList(null));
+ Assert.assertFalse(ServiceChainingUtil.setSfcPart(rspBuilder.build(), policyWriter));
+
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ @Test
+ public void testSetSfcPart_fail02() throws Exception {
+ final RenderedServicePath rsp = createRsp("unit-rsp-03");
+
+ PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
+ final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
+ PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(null);
+
+ final boolean outcome = ServiceChainingUtil.setSfcPart(rsp, policyWriter);
+
+ Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
+ Assert.assertFalse(outcome);
+
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ @Test
+ public void testSetSfcPart_fail03() throws Exception {
+ final RenderedServicePath rsp = createRsp("unit-rsp-03");
+ final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder()
+ .setName(new SffName("unit-sff-03"))
+ .setIpMgmtAddress(null);
+
+ stub(method(ServiceChainingUtil.class, "checkLocalForwarderPresence")).toReturn(true);
+
+ PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
+ final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
+ PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(
+ sffBuilder.build());
+
+ Assert.assertFalse(ServiceChainingUtil.setSfcPart(rsp, policyWriter));
+
+ Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
+
+ Mockito.verify(policyWriter).getCurrentMountpoint();
+ Mockito.verify(policyWriter).getCurrentNodeId();
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+ @Test
+ public void testSetSfcPart_fail04() throws Exception {
+ final RenderedServicePath rsp = createRsp("unit-rsp-03");
+ final ServiceFunctionForwarderBuilder sffBuilder = new ServiceFunctionForwarderBuilder()
+ .setName(new SffName("unit-sff-03"))
+ .setIpMgmtAddress(new IpAddress((Ipv4Address) null));
+
+ stub(method(ServiceChainingUtil.class, "checkLocalForwarderPresence")).toReturn(true);
+
+ PowerMockito.mockStatic(SfcProviderServiceForwarderAPI.class);
+ final SfcProviderServiceForwarderAPI api = PowerMockito.mock(SfcProviderServiceForwarderAPI.class);
+ PowerMockito.when(api.readServiceFunctionForwarder(sffNameCaptor.capture())).thenReturn(
+ sffBuilder.build());
+
+ Assert.assertFalse(ServiceChainingUtil.setSfcPart(rsp, policyWriter));
+
+ Assert.assertEquals("rsp-hop-01-sf+sff", sffNameCaptor.getValue().getValue());
+
+ Mockito.verify(policyWriter).getCurrentMountpoint();
+ Mockito.verify(policyWriter).getCurrentNodeId();
+ Mockito.verifyNoMoreInteractions(policyWriter);
+ }
+
+
+ @Test
+ public void testForwarderTypeChoice() throws Exception {
+ final String sffValue = "unit-xx";
+ final ServiceTypeChoice fwChoice = ServiceChainingUtil.forwarderTypeChoice(sffValue);
+
+ Assert.assertTrue(fwChoice instanceof ServiceFunctionForwarder);
+ final ServiceFunctionForwarder sff = (ServiceFunctionForwarder) fwChoice;
+ Assert.assertEquals(sffValue, sff.getServiceFunctionForwarder());
+ }
+
+ @Test
+ public void testFunctionTypeChoice() throws Exception {
+ final String stcValue = "unit-xx";
+ final ServiceTypeChoice srvTypeChoice = ServiceChainingUtil.functionTypeChoice(stcValue);
+
+ Assert.assertTrue(srvTypeChoice instanceof ServiceFunction);
+ final ServiceFunction stc = (ServiceFunction) srvTypeChoice;
+ Assert.assertEquals(stcValue, stc.getServiceFunction());
+ }
+}
\ No newline at end of file
<artifactId>vbd-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>opendaylight-l2-types</artifactId>
+ </dependency>
<!-- testing dependencies -->
<dependency>
import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.RendererPolicyListener;
import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener;
import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppNodeListener;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.manager.BridgeDomainManagerImpl;
import org.opendaylight.groupbasedpolicy.renderer.vpp.manager.VppNodeManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.BridgeDomainManagerImpl;
import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.ForwardingManager;
import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.VppRendererPolicyManager;
import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.AllowAction;
EventBus dtoEventBus = new EventBus("DTO events");
interfaceManager = new InterfaceManager(mountDataProvider, dataBroker, NETCONF_WORKER);
dtoEventBus.register(interfaceManager);
- ForwardingManager fwManager = new ForwardingManager(interfaceManager, new BridgeDomainManagerImpl(dataBroker));
+ ForwardingManager fwManager = new ForwardingManager(interfaceManager, new BridgeDomainManagerImpl(dataBroker), dataBroker);
vppRendererPolicyManager = new VppRendererPolicyManager(fwManager, dataBroker);
dtoEventBus.register(vppRendererPolicyManager);
import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
/**
* Creates a bridge domain on VPP node and it also adds tunnels of the bridge domain to VXLAN
* full mesh topology
- *
+ *
* @param bridgeDomainName name of bridge domain
* @param vni VXLAN VNI used in full mesh topology for the given bridge domain
- * @param vppNode VPP node where the bridge domain should be created
+ * @param vppNodeId VPP node where the bridge domain should be created
* @return {@link ListenableFuture}
*/
- ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName, @Nonnull VxlanVni vni,
- NodeId vppNode);
+ ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName, @Nonnull VxlanVni vni, @Nonnull NodeId vppNodeId);
+
+ /**
+ * Creates a bridge domain on VPP node and it also adds tunnels of the bridge domain to VLAN
+ * full mesh topology
+ *
+ * @param bridgeDomainName name of bridge domain
+ * @param vlanId VLAN ID used in full mesh topology for the given bridge domain
+ * @param vppNodeId VPP node where the bridge domain should be created
+ * @return {@link ListenableFuture}
+ */
+
+ ListenableFuture<Void> createVlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName, @Nonnull VlanId vlanId, @Nonnull NodeId vppNodeId);
/**
* Removes a bridge domain from VPP node and it also removes tunnels of the bridge domain from
* VXLAN full mesh topology
- *
+ *
* @param bridgeDomainName name of bridge domain
* @param vppNode VPP node where the bridge domain should be removed from
* @return {@link ListenableFuture}
*/
ListenableFuture<Void> removeBridgeDomainFromVppNode(@Nonnull String bridgeDomainName, NodeId vppNode);
+
}
String existingBridgeDomain = resolveBridgeDomain(optIface.get());
if (bridgeDomainName.equals(existingBridgeDomain)) {
+ LOG.debug("Bridge domain {} already exists on interface {}", bridgeDomainName, interfacePath);
String nodePath = VppPathMapper.bridgeDomainToRestPath(bridgeDomainName);
if (!nodePath.equals(epLoc.getExternalNode())) {
vppEndpointLocationProvider.updateExternalNodeLocationForEndpoint(nodePath,
L2 l2 = new L2Builder()
.setInterconnection(new BridgeBasedBuilder().setBridgeDomain(bridgeDomainName).build()).build();
rwTx.merge(LogicalDatastoreType.CONFIGURATION, l2Iid, l2);
+ LOG.debug("Adding bridge domain {} to interface {}", bridgeDomainName, interfacePath);
return Futures.transform(rwTx.submit(), new Function<Void, Void>() {
@Override
String existingBridgeDomain = resolveBridgeDomain(optIface.get());
if (Strings.isNullOrEmpty(existingBridgeDomain)) {
+ LOG.debug("Bridge domain does not exist therefore it is cosidered as"
+ + "deleted for interface {}", interfacePath);
// bridge domain does not exist on interface so we consider job done
vppEndpointLocationProvider.updateExternalNodeLocationForEndpoint(null,
epLoc.getExternalNodeMountPoint(), addrEpWithLoc.getKey());
InstanceIdentifier<L2> l2Iid =
interfaceIid.builder().augmentation(VppInterfaceAugmentation.class).child(L2.class).build();
rwTx.delete(LogicalDatastoreType.CONFIGURATION, l2Iid);
+ LOG.debug("Deleting bridge domain from interface {}", interfacePath);
return Futures.transform(rwTx.submit(), new Function<Void, Void>() {
@Override
IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER,
providerAddressEndpointLocation.getKey()),
providerAddressEndpointLocation);
-
+ LOG.debug("Creating location for {}", providerAddressEndpointLocation.getKey());
Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
@Override
public void onSuccess(Void result) {
- LOG.debug("{} provides location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
+ LOG.debug("{} provided location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
providerAddressEndpointLocation);
}
WriteTransaction wTx = dataProvider.newWriteOnlyTransaction();
wTx.delete(LogicalDatastoreType.CONFIGURATION,
IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, provAddrEpLocKey));
+ LOG.debug("Deleting location for {}", provAddrEpLocKey);
Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
@Override
public void onSuccess(Void result) {
- LOG.debug("{} removes location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), provAddrEpLocKey);
+ LOG.debug("{} removed location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), provAddrEpLocKey);
}
@Override
IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER,
providerAddressEndpointLocation.getKey()),
providerAddressEndpointLocation);
-
+ LOG.debug("Updating location for {}", provAddrEpLocKey);
Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
@Override
public void onSuccess(Void result) {
- LOG.debug("{} merges location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
+ LOG.debug("{} merged location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(),
providerAddressEndpointLocation);
}
import org.opendaylight.groupbasedpolicy.renderer.vpp.event.NodeOperEvent;
import org.opendaylight.groupbasedpolicy.renderer.vpp.manager.VppNodeManager;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public class VppNodeListener implements DataTreeChangeListener<Node>, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(VppNodeListener.class);
+ private static final TopologyId TOPOLOGY_NETCONF = new TopologyId("topology-netconf");
private final ListenerRegistration<VppNodeListener> listenerRegistration;
private final VppNodeManager nodeManager;
this.eventBus = Preconditions.checkNotNull(eventBus);
// Register listener
final DataTreeIdentifier<Node> networkTopologyPath = new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
- InstanceIdentifier.builder(NetworkTopology.class).child(Topology.class).child(Node.class).build());
+ InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(TOPOLOGY_NETCONF))
+ .child(Node.class)
+ .build());
listenerRegistration =
Preconditions.checkNotNull(dataBroker.registerDataTreeChangeListener(networkTopologyPath, this));
LOG.info("Network-Topology VppNodelistener registered");
+++ /dev/null
-/*
- * Copyright (c) 2016 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.vpp.manager;
-
-import java.util.Arrays;
-
-import javax.annotation.Nonnull;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugment;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugmentBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugmentBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.topology.types.VbridgeTopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.TunnelTypeVxlan;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.network.topology.topology.tunnel.parameters.VxlanTunnelParametersBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
-import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeBuilder;
-
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
-public class BridgeDomainManagerImpl implements BridgeDomainManager {
-
- private static final TopologyId SUPPORTING_TOPOLOGY_NETCONF = new TopologyId("topology-netconf");
- private static final TopologyTypes VBRIDGE_TOPOLOGY_TYPE = new TopologyTypesBuilder().addAugmentation(
- TopologyTypesVbridgeAugment.class,
- new TopologyTypesVbridgeAugmentBuilder().setVbridgeTopology(new VbridgeTopologyBuilder().build()).build())
- .build();
- private final DataBroker dataProvder;
-
- public BridgeDomainManagerImpl(DataBroker dataProvder) {
- this.dataProvder = Preconditions.checkNotNull(dataProvder);
- }
-
- @Override
- public ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName,
- @Nonnull VxlanVni vni, NodeId vppNode) {
- TopologyKey topologyKey = new TopologyKey(new TopologyId(bridgeDomainName));
- ReadOnlyTransaction rTx = dataProvder.newReadOnlyTransaction();
- CheckedFuture<Optional<Topology>, ReadFailedException> futureTopology =
- rTx.read(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getTopologyIid(topologyKey));
- rTx.close();
- return Futures.transform(futureTopology, new AsyncFunction<Optional<Topology>, Void>() {
-
- @Override
- public ListenableFuture<Void> apply(Optional<Topology> optTopology) throws Exception {
- WriteTransaction wTx = dataProvder.newWriteOnlyTransaction();
- if (!optTopology.isPresent()) {
- TopologyVbridgeAugment vbridgeAugment =
- new TopologyVbridgeAugmentBuilder().setTunnelType(TunnelTypeVxlan.class)
- .setArpTermination(false)
- .setFlood(true)
- .setForward(true)
- .setLearn(true)
- .setUnknownUnicastFlood(true)
- .setTunnelParameters(new VxlanTunnelParametersBuilder().setVni(vni).build())
- .build();
- Topology topology = new TopologyBuilder().setKey(topologyKey)
- .setTopologyTypes(VBRIDGE_TOPOLOGY_TYPE)
- .addAugmentation(TopologyVbridgeAugment.class, vbridgeAugment)
- .build();
-
- wTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getTopologyIid(topology.getKey()),
- topology, true);
- }
- Node node = new NodeBuilder().setNodeId(vppNode)
- .setSupportingNode(Arrays.asList(new SupportingNodeBuilder()
- .setTopologyRef(SUPPORTING_TOPOLOGY_NETCONF).setNodeRef(vppNode).build()))
- .build();
- wTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getNodeIid(topologyKey, node.getKey()),
- node);
- return wTx.submit();
- }
- });
- }
-
- @Override
- public ListenableFuture<Void> removeBridgeDomainFromVppNode(@Nonnull String bridgeDomainName, NodeId vppNode) {
- WriteTransaction wTx = dataProvder.newWriteOnlyTransaction();
- wTx.delete(LogicalDatastoreType.CONFIGURATION,
- VppIidFactory.getNodeIid(new TopologyKey(new TopologyId(bridgeDomainName)), new NodeKey(vppNode)));
- return wTx.submit();
- }
-
-}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.vpp.policy;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.concurrent.TimeUnit;
+
+import javax.annotation.Nonnull;
+
+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.DataObjectModification.ModificationType;
+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.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
+import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.NodeVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyTypesVbridgeAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.TopologyVbridgeAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.node.BridgeMember;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.topology.rev160129.network.topology.topology.topology.types.VbridgeTopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.NodeVbridgeVlanAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.NodeVbridgeVlanAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.TunnelTypeVlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vlan.rev160429.network.topology.topology.tunnel.parameters.VlanNetworkParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vbridge.tunnel.vxlan.rev160429.network.topology.topology.tunnel.parameters.VxlanTunnelParametersBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypes;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeBuilder;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+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.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+public class BridgeDomainManagerImpl implements BridgeDomainManager {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainManagerImpl.class);
+ private static final TopologyId SUPPORTING_TOPOLOGY_NETCONF = new TopologyId("topology-netconf");
+ private static final TopologyTypes VBRIDGE_TOPOLOGY_TYPE = new TopologyTypesBuilder().addAugmentation(
+ TopologyTypesVbridgeAugment.class,
+ new TopologyTypesVbridgeAugmentBuilder().setVbridgeTopology(new VbridgeTopologyBuilder().build()).build())
+ .build();
+ private final DataBroker dataProvder;
+
+ private static final class ListenableFutureSetter<T extends DataObject>
+ implements DataTreeChangeListener<T> {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ListenableFutureSetter.class);
+ private final SettableFuture<Void> future;
+ private final ModificationType modificationForFutureSet;
+ private final DataTreeIdentifier<T> iid;
+ private final ListenerRegistration<ListenableFutureSetter<T>> registeredListener;
+
+ private ListenableFutureSetter(DataBroker dataProvider, SettableFuture<Void> future,
+ DataTreeIdentifier<T> iid, ModificationType modificationForFutureSet) {
+ this.future = Preconditions.checkNotNull(future);
+ Preconditions.checkArgument(!future.isDone());
+ this.modificationForFutureSet = Preconditions.checkNotNull(modificationForFutureSet);
+ this.iid = Preconditions.checkNotNull(iid);
+ registeredListener = dataProvider.registerDataTreeChangeListener(iid, this);
+ LOG.trace("Registered listener for path {}", iid.getRootIdentifier());
+ }
+
+ @Override
+ public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
+ changes.forEach(modif -> {
+ DataObjectModification<T> rootNode = modif.getRootNode();
+ ModificationType modificationType = rootNode.getModificationType();
+ if (modificationType == modificationForFutureSet) {
+ LOG.debug("{} in OPER DS: {}", modificationType.name(), iid.getRootIdentifier());
+ unregisterOnTrue(future.set(null));
+ }
+ });
+ }
+
+ private void unregisterOnTrue(boolean _true) {
+ if (_true) {
+ LOG.trace("Unregistering listener for path {}", iid.getRootIdentifier());
+ if (registeredListener != null) {
+ registeredListener.close();
+ }
+ }
+ }
+ }
+
+ public BridgeDomainManagerImpl(DataBroker dataProvder) {
+ this.dataProvder = Preconditions.checkNotNull(dataProvder);
+ }
+
+ @Override
+ public ListenableFuture<Void> createVxlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName,
+ @Nonnull VxlanVni vni, @Nonnull NodeId vppNodeId) {
+ TopologyVbridgeAugment topoAug = new TopologyVbridgeAugmentBuilder().setTunnelType(TunnelTypeVxlan.class)
+ .setArpTermination(false)
+ .setFlood(true)
+ .setForward(true)
+ .setLearn(true)
+ .setUnknownUnicastFlood(true)
+ .setTunnelParameters(new VxlanTunnelParametersBuilder().setVni(vni).build())
+ .build();
+ return createBridgeDomainOnVppNode(bridgeDomainName, topoAug, createBasicVppNodeBuilder(vppNodeId).build());
+ }
+
+ @Override
+ public ListenableFuture<Void> createVlanBridgeDomainOnVppNode(@Nonnull String bridgeDomainName,
+ @Nonnull VlanId vlanId, @Nonnull NodeId vppNodeId) {
+ TopologyVbridgeAugment topoAug = new TopologyVbridgeAugmentBuilder().setTunnelType(TunnelTypeVlan.class)
+ .setArpTermination(false)
+ .setFlood(true)
+ .setForward(true)
+ .setLearn(true)
+ .setUnknownUnicastFlood(true)
+ .setTunnelParameters(new VlanNetworkParametersBuilder().setVlanId(vlanId).build())
+ .build();
+ InstanceIdentifier<BridgeDomain> bridgeDomainConfigIid = InstanceIdentifier.builder(Config.class)
+ .child(BridgeDomain.class, new BridgeDomainKey(bridgeDomainName))
+ .build();
+ ReadOnlyTransaction rTx = dataProvder.newReadOnlyTransaction();
+ CheckedFuture<Optional<BridgeDomain>, ReadFailedException> futureTopology =
+ rTx.read(LogicalDatastoreType.CONFIGURATION, bridgeDomainConfigIid);
+ rTx.close();
+ return Futures.transform(futureTopology, new AsyncFunction<Optional<BridgeDomain>, Void>() {
+
+ @Override
+ public ListenableFuture<Void> apply(Optional<BridgeDomain> optBridgeDomainConf) throws Exception {
+ if (optBridgeDomainConf.isPresent() && optBridgeDomainConf.get().getPhysicalLocationRef() != null) {
+ for (PhysicalLocationRef ref : optBridgeDomainConf.get().getPhysicalLocationRef()) {
+ if (ref.getInterface() != null && ref.getInterface().size() > 0) {
+ NodeVbridgeVlanAugment vppNodeVlanAug = new NodeVbridgeVlanAugmentBuilder()
+ .setSuperInterface(ref.getInterface().get(0)).build();
+ Node vppNode = createBasicVppNodeBuilder(vppNodeId)
+ .addAugmentation(vppNodeVlanAug.getClass(), vppNodeVlanAug).build();
+ return createBridgeDomainOnVppNode(bridgeDomainName, topoAug, vppNode);
+ }
+ }
+ }
+ return Futures.immediateFailedFuture(
+ new Throwable("Failed to apply config for VLAN bridge domain " + bridgeDomainName));
+ }
+ });
+ }
+
+ private static NodeBuilder createBasicVppNodeBuilder(NodeId nodeId) {
+ return new NodeBuilder().setNodeId(nodeId).setSupportingNode(Arrays.asList(
+ new SupportingNodeBuilder().setTopologyRef(SUPPORTING_TOPOLOGY_NETCONF).setNodeRef(nodeId).build()));
+ }
+
+ private ListenableFuture<Void> createBridgeDomainOnVppNode(@Nonnull String bridgeDomainName,
+ final TopologyVbridgeAugment vBridgeAug, Node vppNode) {
+ TopologyKey topologyKey = new TopologyKey(new TopologyId(bridgeDomainName));
+ ReadOnlyTransaction rTx = dataProvder.newReadOnlyTransaction();
+ InstanceIdentifier<Topology> topologyIid = VppIidFactory.getTopologyIid(topologyKey);
+ CheckedFuture<Optional<Topology>, ReadFailedException> futureTopology =
+ rTx.read(LogicalDatastoreType.CONFIGURATION, topologyIid);
+ rTx.close();
+ return Futures.transform(futureTopology, new AsyncFunction<Optional<Topology>, Void>() {
+
+ @Override
+ public ListenableFuture<Void> apply(Optional<Topology> optTopology) throws Exception {
+ WriteTransaction wTx = dataProvder.newWriteOnlyTransaction();
+ if (!optTopology.isPresent()) {
+ Topology topology = new TopologyBuilder().setKey(topologyKey)
+ .setTopologyTypes(VBRIDGE_TOPOLOGY_TYPE)
+ .addAugmentation(TopologyVbridgeAugment.class, vBridgeAug)
+ .build();
+ wTx.put(LogicalDatastoreType.CONFIGURATION, topologyIid,
+ topology, true);
+ }
+ InstanceIdentifier<Node> nodeIid = VppIidFactory.getNodeIid(topologyKey, vppNode.getKey());
+ wTx.put(LogicalDatastoreType.CONFIGURATION, nodeIid, vppNode);
+ SettableFuture<Void> future = SettableFuture.create();
+ Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
+
+ @Override
+ public void onSuccess(Void result) {
+ DataTreeIdentifier<BridgeMember> bridgeMemberIid =
+ new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+ nodeIid.augmentation(NodeVbridgeAugment.class).child(BridgeMember.class));
+ LOG.debug("Request create node in topology for VBD was stored to CONF DS. {}", nodeIid);
+ new ListenableFutureSetter<>(dataProvder, future, bridgeMemberIid,
+ ModificationType.WRITE);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ LOG.warn("Request create node in topology for VBD was not stored to CONF DS. {}", nodeIid, t);
+ future.setException(new Exception("Cannot send request to VBD."));
+ }
+ });
+ return future;
+ }
+ });
+ }
+
+ @Override
+ public ListenableFuture<Void> removeBridgeDomainFromVppNode(@Nonnull String bridgeDomainName, NodeId vppNode) {
+ WriteTransaction wTx = dataProvder.newWriteOnlyTransaction();
+ InstanceIdentifier<Node> nodeIid =
+ VppIidFactory.getNodeIid(new TopologyKey(new TopologyId(bridgeDomainName)), new NodeKey(vppNode));
+ wTx.delete(LogicalDatastoreType.CONFIGURATION, nodeIid);
+ SettableFuture<Void> future = SettableFuture.create();
+ Futures.addCallback(wTx.submit(), new FutureCallback<Void>() {
+
+ @Override
+ public void onSuccess(Void result) {
+ DataTreeIdentifier<BridgeMember> bridgeMemberIid =
+ new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
+ nodeIid.augmentation(NodeVbridgeAugment.class).child(BridgeMember.class));
+ LOG.debug("Request delete node in topology for VBD was stored to CONF DS. {}", nodeIid);
+ new ListenableFutureSetter<>(dataProvder, future, bridgeMemberIid, ModificationType.DELETE);
+ }
+
+ @Override
+ public void onFailure(Throwable t) {
+ LOG.warn("Request delete node in topology for VBD was not stored to CONF DS. {}", nodeIid, t);
+ future.setException(new Exception("Cannot send request to VBD."));
+ }
+ });
+ return future;
+ }
+
+}
package org.opendaylight.groupbasedpolicy.renderer.vpp.policy;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager;
import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
+import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.Containment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.ForwardingContextContainment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2FloodDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.Config;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.VlanNetwork;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.BridgeDomainKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+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.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.SetMultimap;
-public class ForwardingManager {
+public final class ForwardingManager {
private static final Logger LOG = LoggerFactory.getLogger(ForwardingManager.class);
-
+ @VisibleForTesting
+ static long WAIT_FOR_BD_CREATION = 10; // seconds
+ private long lastVxlanVni = 1L;
+ private final Map<String, VxlanVni> vxlanVniByBridgeDomain = new HashMap<>();
private final InterfaceManager ifaceManager;
private final BridgeDomainManager bdManager;
-
- public ForwardingManager(@Nonnull InterfaceManager ifaceManager, @Nonnull BridgeDomainManager bdManager) {
+ private final DataBroker dataBroker;
+ public ForwardingManager(@Nonnull InterfaceManager ifaceManager, @Nonnull BridgeDomainManager bdManager, @Nonnull DataBroker dataBroker) {
this.ifaceManager = Preconditions.checkNotNull(ifaceManager);
this.bdManager = Preconditions.checkNotNull(bdManager);
+ this.dataBroker = Preconditions.checkNotNull(dataBroker);
}
- public void createVxlanBridgeDomainsOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
+ public Optional<BridgeDomain> readBridgeDomainConfig(String name) {
+ InstanceIdentifier<BridgeDomain> bdIid = InstanceIdentifier.builder(Config.class)
+ .child(BridgeDomain.class, new BridgeDomainKey(name))
+ .build();
+ ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
+ return DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, bdIid, rTx);
+ }
+
+ public void createBridgeDomainOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
for (String bd : vppNodesByBridgeDomain.keySet()) {
+ Optional<BridgeDomain> bdConfig = readBridgeDomainConfig(bd);
Set<NodeId> vppNodes = vppNodesByBridgeDomain.get(bd);
- for (NodeId vppNode : vppNodes) {
- try {
- bdManager.createVxlanBridgeDomainOnVppNode(bd, null, vppNode).get();
- } catch (InterruptedException | ExecutionException e) {
- LOG.warn("Bridge domain {} was not created on node {}", bd, vppNode.getValue(), e);
+ if (bdConfig.isPresent()) {
+ if (bdConfig.get().getType().equals(VlanNetwork.class)) {
+ createVlanBridgeDomains(bd, bdConfig.get().getVlan(), vppNodes);
+ }
+ } else {
+ VxlanVni vxlanVni = vxlanVniByBridgeDomain.get(bd);
+ if (vxlanVni == null) {
+ vxlanVni = new VxlanVni(lastVxlanVni++);
+ vxlanVniByBridgeDomain.put(bd, vxlanVni);
}
+ createVxlanBridgeDomains(bd, vxlanVni, vppNodes);
+ }
+ }
+ }
+
+ private void createVxlanBridgeDomains(String bd, VxlanVni vni, Set<NodeId> vppNodes) {
+ for (NodeId vppNode : vppNodes) {
+ try {
+ LOG.trace("Creating VXLAN bridge-domain {} on node {} with VNI {}", bd, vppNode.getValue(),
+ vni);
+ // TODO think about propagating ListenableFuture - timeout set as workaround
+ bdManager.createVxlanBridgeDomainOnVppNode(bd, vni, vppNode).get(WAIT_FOR_BD_CREATION,
+ TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("VXLAN Bridge domain {} was not created on node {}", bd, vppNode.getValue(), e);
+ } catch (TimeoutException e) {
+ LOG.warn("Probably, VXLAN Bridge domain {} was not created on node {} because BridgeDomainManager "
+ + "did not respond by {} seconds.", bd, vppNode.getValue(), WAIT_FOR_BD_CREATION, e);
+ }
+ }
+ }
+
+ private void createVlanBridgeDomains(String bd, VlanId vlanId, Set<NodeId> vppNodes) {
+ for (NodeId vppNode : vppNodes) {
+ try {
+ LOG.trace("Creating VLAN bridge-domain {} on node {} with VLAN ID {}", bd, vppNode.getValue(),
+ vlanId.getValue());
+ // TODO think about propagating ListenableFuture - timeout set as workaround
+ bdManager.createVlanBridgeDomainOnVppNode(bd, vlanId, vppNode).get(WAIT_FOR_BD_CREATION,
+ TimeUnit.SECONDS);
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.warn("VLAN Bridge domain {} was not created on node {}", bd, vppNode.getValue(), e);
+ } catch (TimeoutException e) {
+ LOG.warn("Probably, VLAN Bridge domain {} was not created on node {} because BridgeDomainManager "
+ + "did not respond by {} seconds.", bd, vppNode.getValue(), WAIT_FOR_BD_CREATION, e);
}
}
}
- public void removeVxlanBridgeDomainsOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
+ public void removeBridgeDomainOnNodes(SetMultimap<String, NodeId> vppNodesByBridgeDomain) {
for (String bd : vppNodesByBridgeDomain.keySet()) {
Set<NodeId> vppNodes = vppNodesByBridgeDomain.get(bd);
for (NodeId vppNode : vppNodes) {
try {
- bdManager.removeBridgeDomainFromVppNode(bd, vppNode).get();
+ bdManager.removeBridgeDomainFromVppNode(bd, vppNode).get(WAIT_FOR_BD_CREATION,
+ TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException e) {
LOG.warn("Bridge domain {} was not removed from node {}", bd, vppNode.getValue(), e);
+ } catch (TimeoutException e) {
+ LOG.warn("Probably, bridge domain {} was not removed from node {} because BridgeDomainManager "
+ + "did not respond by {} seconds.", bd, vppNode.getValue(), WAIT_FOR_BD_CREATION, e);
}
}
}
// TODO add it to the status for renderer manager
LOG.warn("Interface was not added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp, e);
}
+ } else {
+ LOG.debug("Forwarding is not created - Location of renderer endpoint contains "
+ + "external-node therefore VPP renderer assumes that interface for endpoint is "
+ + "already assigned in bridge-domain representing external-node. {}", rEp);
}
}
// TODO add it to the status for renderer manager
LOG.warn("bridge-domain was not deleted from interface for endpoint {}", rEp, e);
}
+ } else {
+ LOG.debug("Forwarding is not removed - Location of renderer endpoint does not contain "
+ + "external-node therefore VPP renderer assumes that interface for endpoint is not "
+ + "assigned to bridge-domain representing external-node. {}", rEp);
}
}
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
RendererPolicyBuilder responseBuilder = new RendererPolicyBuilder();
switch (event.getDtoModificationType()) {
case CREATED:
- LOG.trace("CREATED : {}", event);
+ LOG.trace("CREATED : {}", event.getIid());
responseBuilder.setVersion(event.getAfter().get().getVersion());
rendererPolicyCreated(event.getAfter().get());
break;
case UPDATED:
- LOG.trace("UPDATED: {}", event);
+ LOG.trace("UPDATED: {}", event.getIid());
RendererPolicy rPolicyBefore = event.getBefore().get();
RendererPolicy rPolicyAfter = event.getAfter().get();
responseBuilder.setVersion(rPolicyAfter.getVersion());
- if (!isConfigurationChanged(rPolicyBefore, rPolicyAfter)) {
+ if (rPolicyBefore.getConfiguration() == null && rPolicyAfter.getConfiguration() == null) {
LOG.debug("Configuration is not changed only updating config version from {} to {}",
rPolicyBefore.getVersion(), rPolicyAfter.getVersion());
} else {
}
break;
case DELETED:
- LOG.trace("DELETED: {}", event);
+ LOG.trace("DELETED: {}", event.getIid());
responseBuilder.setVersion(event.getBefore().get().getVersion());
rendererPolicyDeleted(event.getBefore().get());
break;
});
}
- private boolean isConfigurationChanged(RendererPolicy before, RendererPolicy after) {
- if (before.getConfiguration() == null && after.getConfiguration() == null) {
- return false;
- }
- return true;
- }
-
private void rendererPolicyUpdated(RendererPolicy rPolicyBefore, RendererPolicy rPolicyAfter) {
PolicyContext policyCtxBefore = new PolicyContext(rPolicyBefore);
PolicyContext policyCtxAfter = new PolicyContext(rPolicyAfter);
ImmutableSet<RendererEndpointKey> rendEpsAfter = policyCtxAfter.getPolicyTable().rowKeySet();
SetView<RendererEndpointKey> removedRendEps = Sets.difference(rendEpsBefore, rendEpsAfter);
+ LOG.trace("Removed renderer endpoints {}", removedRendEps);
removedRendEps.forEach(rEpKey -> fwManager.removeForwardingForEndpoint(rEpKey, policyCtxBefore));
- fwManager.removeVxlanBridgeDomainsOnNodes(removedVppNodesByL2Fd);
- fwManager.createVxlanBridgeDomainsOnNodes(createdVppNodesByL2Fd);
+ LOG.trace("Removed bridge domains on nodes {}", removedVppNodesByL2Fd);
+ LOG.trace("Created bridge domains on nodes {}", createdVppNodesByL2Fd);
+ fwManager.removeBridgeDomainOnNodes(removedVppNodesByL2Fd);
+ fwManager.createBridgeDomainOnNodes(createdVppNodesByL2Fd);
SetView<RendererEndpointKey> createdRendEps = Sets.difference(rendEpsAfter, rendEpsBefore);
+ LOG.trace("Created renderer endpoints {}", createdRendEps);
createdRendEps.forEach(rEpKey -> fwManager.createForwardingForEndpoint(rEpKey, policyCtxAfter));
SetView<RendererEndpointKey> updatedRendEps = Sets.intersection(rendEpsBefore, rendEpsAfter);
- // TODO think about all cases, but keep it simple for now
- updatedRendEps.forEach(rEpKey -> fwManager.removeForwardingForEndpoint(rEpKey, policyCtxBefore));
- updatedRendEps.forEach(rEpKey -> fwManager.createForwardingForEndpoint(rEpKey, policyCtxAfter));
+ LOG.trace("Updated renderer endpoints {}", updatedRendEps);
+ // update forwarding for endpoint
+ updatedRendEps.forEach(rEpKey -> {
+ AddressEndpointWithLocation addrEpWithLocBefore =
+ policyCtxBefore.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
+ AddressEndpointWithLocation addrEpWithLocAfter =
+ policyCtxAfter.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey));
+ if (isLocationChanged(addrEpWithLocBefore, addrEpWithLocAfter)) {
+ LOG.debug("Location is changed in endpoint {}", rEpKey);
+ LOG.trace("\nLocation before: {}\nLocation after: {}", addrEpWithLocBefore.getAbsoluteLocation(),
+ addrEpWithLocAfter.getAbsoluteLocation());
+ fwManager.removeForwardingForEndpoint(rEpKey, policyCtxBefore);
+ fwManager.createForwardingForEndpoint(rEpKey, policyCtxAfter);
+ }
+ });
+ }
+
+ private static boolean isLocationChanged(AddressEndpointWithLocation before, AddressEndpointWithLocation after) {
+ ExternalLocationCase locationBefore = ForwardingManager.resolveAndValidateLocation(before);
+ ExternalLocationCase locationAfter = ForwardingManager.resolveAndValidateLocation(after);
+ return !locationBefore.equals(locationAfter);
}
private static MapDifference<String, Collection<NodeId>> createDiffForVppNodesByL2Fd(PolicyContext policyCtxBefore,
ImmutableSet<RendererEndpointKey> rendEpsBefore = policyCtxBefore.getPolicyTable().rowKeySet();
ImmutableSet<RendererEndpointKey> rendEpsAfter = policyCtxAfter.getPolicyTable().rowKeySet();
SetMultimap<String, NodeId> vppNodesByL2FdBefore = resolveVppNodesByL2Fd(rendEpsBefore, policyCtxBefore);
- SetMultimap<String, NodeId> vppNodesByL2FdAfter = resolveVppNodesByL2Fd(rendEpsAfter, policyCtxBefore);
+ SetMultimap<String, NodeId> vppNodesByL2FdAfter = resolveVppNodesByL2Fd(rendEpsAfter, policyCtxAfter);
return Maps.difference(vppNodesByL2FdBefore.asMap(), vppNodesByL2FdAfter.asMap());
}
ImmutableSet<RendererEndpointKey> rEpKeys = policyCtx.getPolicyTable().rowKeySet();
SetMultimap<String, NodeId> vppNodesByL2Fd = resolveVppNodesByL2Fd(rEpKeys, policyCtx);
- fwManager.createVxlanBridgeDomainsOnNodes(vppNodesByL2Fd);
+ fwManager.createBridgeDomainOnNodes(vppNodesByL2Fd);
rEpKeys.forEach(rEpKey -> fwManager.createForwardingForEndpoint(rEpKey, policyCtx));
}
rEpKeys.forEach(rEpKey -> fwManager.removeForwardingForEndpoint(rEpKey, policyCtx));
SetMultimap<String, NodeId> vppNodesByL2Fd = resolveVppNodesByL2Fd(rEpKeys, policyCtx);
- fwManager.removeVxlanBridgeDomainsOnNodes(vppNodesByL2Fd);
+ fwManager.removeBridgeDomainOnNodes(vppNodesByL2Fd);
}
private static SetMultimap<String, NodeId> resolveVppNodesByL2Fd(Set<RendererEndpointKey> rEpKeys,
prefix "vpp-renderer";
import base-endpoint { prefix base-ep; revision-date 2016-04-27; }
+ import network-topology { prefix nt; revision-date 2013-10-21; }
+ import opendaylight-l2-types { prefix l2-types; revision-date "2013-08-27"; }
description
"This module is a baseline for the group-based policy vpp renderer model.";
"Initial revision.";
}
+ identity network-type-base {
+ description "Base for Network Types.";
+ }
+
+ identity flat-network {
+ description "Flat Provider Network Type";
+ base network-type-base;
+ }
+
+ identity vlan-network {
+ description "VLAN Provider Network Type";
+ base network-type-base;
+ }
+
+ typedef network-type {
+ description "Type of Network.";
+ type identityref {
+ base network-type-base;
+ }
+ }
+
container config {
list vpp-endpoint {
description "Renderer creates/removes interface on VPP node based on given parameters.";
}
}
}
+
+ list bridge-domain {
+ key "id";
+ leaf id {
+ description "Same as in VBD.";
+ type string;
+ }
+ leaf description {
+ type string;
+ }
+ leaf type {
+ mandatory true;
+ type network-type;
+ }
+ leaf vlan {
+ when "type = 'vlan-network'";
+ type l2-types:vlan-id;
+ }
+ list physical-location-ref {
+ description
+ "Refers to physical interfaces on vpp nodes through which external
+ nodes belonging to the same bridge-domain can be reached.";
+ key "node-id";
+ leaf node-id {
+ description "Refers to a VPP node.";
+ type nt:node-id;
+ }
+ leaf-list interface {
+ description "Physical interface on the VPP node.";
+ type string;
+ }
+ }
+ }
}
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.groupbasedpolicy.renderer.vpp.manager;
+package org.opendaylight.groupbasedpolicy.renderer.vpp.policy;
import java.util.Arrays;
import java.util.Collection;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.node.attributes.SupportingNodeBuilder;
import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
public class BridgeDomainManagerImplTest extends CustomDataBrokerTest {
}
@Test
- public void testCreateVxlanBridgeDomainOnVppNode() {
- ListenableFuture<Void> registered =
- bridgeDomainManager.createVxlanBridgeDomainOnVppNode(BRIDGE_DOMAIN_ID, BRIDGE_DOMAIN_VNI, VPP_NODE_ID);
- Assert.assertTrue(registered.isDone());
+ public void testCreateVxlanBridgeDomainOnVppNode() throws Exception {
+ bridgeDomainManager.createVxlanBridgeDomainOnVppNode(BRIDGE_DOMAIN_ID, BRIDGE_DOMAIN_VNI, VPP_NODE_ID);
Optional<Topology> topologyOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
VppIidFactory.getTopologyIid(BASE_TOPOLOGY.getKey()), dataBroker.newReadOnlyTransaction());
dataBroker.newReadOnlyTransaction());
Assert.assertTrue(topologyOptional.isPresent());
- ListenableFuture<Void> deleted =
- bridgeDomainManager.removeBridgeDomainFromVppNode(BRIDGE_DOMAIN_ID, VPP_NODE_ID);
- Assert.assertTrue(deleted.isDone());
+ bridgeDomainManager.removeBridgeDomainFromVppNode(BRIDGE_DOMAIN_ID, VPP_NODE_ID);
topologyOptional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
VppIidFactory.getNodeIid(new TopologyKey(BASE_TOPOLOGY_ID), new NodeKey(VPP_NODE_ID)),
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import org.junit.Assert;
import org.junit.Before;
import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager;
import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppEndpointLocationProvider;
import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppPathMapper;
-import org.opendaylight.groupbasedpolicy.renderer.vpp.manager.BridgeDomainManagerImpl;
import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory;
import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider;
import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicy;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointWithPolicyBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroupBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.bridge.domain.PhysicalLocationRef;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanVni;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.Interconnection;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBased;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import com.google.common.base.Optional;
+import com.google.common.base.Strings;
import com.google.common.util.concurrent.MoreExecutors;
@RunWith(MockitoJUnitRunner.class)
private static final InstanceIdentifier<RendererPolicy> RENDERER_POLICY_IID =
IidFactory.rendererIid(VppRenderer.NAME).child(RendererPolicy.class);
private static final ContextId CTX_ID = new ContextId("ctx");
- private static final AddressEndpointWithLocationKey CLIENT_EP_KEY =
- new AddressEndpointWithLocationKey("1.1.1.1", AddressType.class, CTX_ID, ContextType.class);
- private static final AddressEndpointWithLocationKey WEB_EP_KEY =
- new AddressEndpointWithLocationKey("2.2.2.2", AddressType.class, CTX_ID, ContextType.class);
private static final ContextId L2FD_CTX = new ContextId("l2fd");
- private static final NetworkContainment L2FD_NET_CONT =
- new NetworkContainmentBuilder().setContainment(new ForwardingContextContainmentBuilder()
- .setContextType(L2FloodDomain.class).setContextId(L2FD_CTX).build()).build();
- private final static TopologyKey TOPO_KEY = new TopologyKey(new TopologyId("topo1"));
- private final static NodeKey NODE_KEY = new NodeKey(new NodeId("node1"));
- private final static InstanceIdentifier<Node> VPP_NODE_IID = InstanceIdentifier.builder(NetworkTopology.class)
+ private final static TopologyKey TOPO_KEY = new TopologyKey(new TopologyId("topology-netconf"));
+ private final static InstanceIdentifier<Node> VPP_NODE_1_IID = InstanceIdentifier.builder(NetworkTopology.class)
.child(Topology.class, TOPO_KEY)
- .child(Node.class, NODE_KEY)
+ .child(Node.class, new NodeKey(new NodeId("node1")))
+ .build();
+ private final static InstanceIdentifier<Node> VPP_NODE_2_IID = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, TOPO_KEY)
+ .child(Node.class, new NodeKey(new NodeId("node2")))
.build();
- private static final String IFACE_NAME_CLIENT_EP = "interfaceClient";
- private static final String NODE_CONNECTOR_CLIENT_EP = VppPathMapper.interfaceToRestPath(IFACE_NAME_CLIENT_EP);
- private static final String IFACE_NAME_WEB_EP = "interfaceWeb";
- private static final String NODE_CONNECTOR_WEB_EP = VppPathMapper.interfaceToRestPath(IFACE_NAME_WEB_EP);
private static final ContractId CONTRACT_ID = new ContractId("contract");
private static final TenantId TENANT_ID = new TenantId("tenant");
private static final SubjectName SUBJECT_NAME = new SubjectName("subject");
private static final RuleName RULE_NAME = new RuleName("rule");
- private static final RuleGroupWithRendererEndpointParticipation RULE_GROUP_WITH_REND_EP_PART =
+ private static final RuleGroupWithRendererEndpointParticipation RULE_GROUP_WITH_CONSUMER =
new RuleGroupWithRendererEndpointParticipationBuilder().setContractId(CONTRACT_ID)
.setTenantId(TENANT_ID)
.setSubjectName(SUBJECT_NAME)
.setRendererEndpointParticipation(EndpointPolicyParticipation.CONSUMER)
.build();
+ private static final RuleGroupWithRendererEndpointParticipation RULE_GROUP_WITH_PROVIDER =
+ new RuleGroupWithRendererEndpointParticipationBuilder().setContractId(CONTRACT_ID)
+ .setTenantId(TENANT_ID)
+ .setSubjectName(SUBJECT_NAME)
+ .setRendererEndpointParticipation(EndpointPolicyParticipation.PROVIDER)
+ .build();
private static final RuleGroup RULE_GROUP = new RuleGroupBuilder().setContractId(CONTRACT_ID)
.setTenantId(TENANT_ID)
.setSubjectName(SUBJECT_NAME)
.setResolvedRule(Arrays.asList(new ResolvedRuleBuilder().setName(RULE_NAME).build()))
.build();
- // data for InterfaceManager
- private final static InstanceIdentifier<VppEndpoint> BASIC_VPP_CLIENT_EP_IID =
- InstanceIdentifier.builder(Config.class)
- .child(VppEndpoint.class, new VppEndpointKey(CLIENT_EP_KEY.getAddress(), CLIENT_EP_KEY.getAddressType(),
- CLIENT_EP_KEY.getContextId(), CLIENT_EP_KEY.getContextType()))
- .build();
- private final static InstanceIdentifier<VppEndpoint> BASIC_VPP_WEB_EP_IID = InstanceIdentifier.builder(Config.class)
- .child(VppEndpoint.class, new VppEndpointKey(WEB_EP_KEY.getAddress(), WEB_EP_KEY.getAddressType(),
- WEB_EP_KEY.getContextId(), WEB_EP_KEY.getContextType()))
- .build();
private final static String SOCKET = "socket";
private MountedDataBrokerProvider mountedDataProviderMock;
public Collection<Class<?>> getClassesFromModules() {
return Arrays.asList(Node.class, VppEndpoint.class, Interfaces.class, BridgeDomains.class,
LocationProviders.class, L2FloodDomain.class, VxlanVni.class, TopologyVbridgeAugment.class,
- TunnelTypeVxlan.class);
+ TunnelTypeVxlan.class, PhysicalLocationRef.class);
}
@Before
public void init() throws Exception {
+ ForwardingManager.WAIT_FOR_BD_CREATION = 2;
mountedDataProviderMock = Mockito.mock(MountedDataBrokerProvider.class);
mountPointDataBroker = getDataBroker();
setup(); // initialize new data broker for ODL data store
dataBroker = getDataBroker();
Mockito.when(mountedDataProviderMock.getDataBrokerForMountPoint(Mockito.any(InstanceIdentifier.class)))
.thenReturn(Optional.of(mountPointDataBroker));
- ifaceManager = new InterfaceManager(mountedDataProviderMock, dataBroker, MoreExecutors.newDirectExecutorService());
+ ifaceManager =
+ new InterfaceManager(mountedDataProviderMock, dataBroker, MoreExecutors.newDirectExecutorService());
bdManager = new BridgeDomainManagerImpl(mountPointDataBroker);
- fwManager = new ForwardingManager(ifaceManager, bdManager);
+ fwManager = new ForwardingManager(ifaceManager, bdManager, dataBroker);
vppRendererPolicyManager = new VppRendererPolicyManager(fwManager, dataBroker);
}
@Test
- public void testRendererPolicyChanged_createdClient() throws Exception {
- storeInterfaceFor(CLIENT_EP_KEY, IFACE_NAME_CLIENT_EP, BASIC_VPP_CLIENT_EP_IID);
+ public void testRendererPolicyChanged_created_oneEpPerEpg() throws Exception {
+ String clientIp = "1.1.1.1";
+ String clientIfaceName = "client1";
+ AbsoluteLocation clientLocation = absoluteLocation(VPP_NODE_1_IID, null, clientIfaceName);
+ AddressEndpointWithLocation clientEp = createEndpoint(clientIp, L2FD_CTX.getValue(), clientLocation);
+ String webIp = "2.2.2.2";
+ String webIfaceName = "web1";
+ AbsoluteLocation webLocation = absoluteLocation(VPP_NODE_1_IID, null, webIfaceName);
+ AddressEndpointWithLocation webEp = createEndpoint(webIp, L2FD_CTX.getValue(), webLocation);
- AddressEndpointWithLocation clientEp = new AddressEndpointWithLocationBuilder().setKey(CLIENT_EP_KEY)
- .setNetworkContainment(L2FD_NET_CONT)
- .setAbsoluteLocation(absoluteLocation(VPP_NODE_IID, null, NODE_CONNECTOR_CLIENT_EP))
- .build();
- AddressEndpointWithLocation webEp = new AddressEndpointWithLocationBuilder().setKey(WEB_EP_KEY)
- .setNetworkContainment(L2FD_NET_CONT)
- .setAbsoluteLocation(absoluteLocation(VPP_NODE_IID, null, NODE_CONNECTOR_WEB_EP))
- .build();
- Endpoints endpoints =
- new EndpointsBuilder().setAddressEndpointWithLocation(Arrays.asList(clientEp, webEp)).build();
- RendererEndpoint rendererEndpoint = new RendererEndpointBuilder()
- .setKey(KeyFactory.rendererEndpointKey(CLIENT_EP_KEY))
- .setPeerEndpointWithPolicy(Arrays.asList(new PeerEndpointWithPolicyBuilder()
- .setKey(KeyFactory.peerEndpointWithPolicyKey(WEB_EP_KEY))
- .setRuleGroupWithRendererEndpointParticipation(Arrays.asList(RULE_GROUP_WITH_REND_EP_PART))
- .build()))
- .build();
- Configuration configuration = new ConfigurationBuilder().setEndpoints(endpoints)
- .setRendererEndpoints(
- new RendererEndpointsBuilder().setRendererEndpoint(Arrays.asList(rendererEndpoint)).build())
- .setRuleGroups(new RuleGroupsBuilder().setRuleGroup(Arrays.asList(RULE_GROUP)).build())
- .build();
+ storeVppEndpoint(clientEp.getKey(), clientIfaceName, createVppEndpointIid(clientEp.getKey()));
+ storeVppEndpoint(webEp.getKey(), webIfaceName, createVppEndpointIid(webEp.getKey()));
+
+ Configuration configuration = createConfiguration(Arrays.asList(clientEp), Arrays.asList(webEp));
RendererPolicy rendererPolicy =
new RendererPolicyBuilder().setVersion(1L).setConfiguration(configuration).build();
RendererPolicyConfEvent event = new RendererPolicyConfEvent(RENDERER_POLICY_IID, null, rendererPolicy);
vppRendererPolicyManager.rendererPolicyChanged(event);
// assert state on data store behind mount point
- ReadOnlyTransaction rTxMount = mountPointDataBroker.newReadOnlyTransaction();
- Optional<Interface> potentialIface = rTxMount.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
- .builder(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME_CLIENT_EP)).build()).get();
- Assert.assertTrue(potentialIface.isPresent());
- Interface iface = potentialIface.get();
- VppInterfaceAugmentation vppIfaceAug = iface.getAugmentation(VppInterfaceAugmentation.class);
- Assert.assertNotNull(vppIfaceAug);
- Interconnection interconnection = vppIfaceAug.getL2().getInterconnection();
- Assert.assertNotNull(interconnection);
- Assert.assertTrue(interconnection instanceof BridgeBased);
- Assert.assertEquals(L2FD_CTX.getValue(), ((BridgeBased) interconnection).getBridgeDomain());
+ Interface clientIface = readAndAssertInterface(clientIfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), clientIface);
+ Interface webIface = readAndAssertInterface(webIfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), webIface);
// assert state on ODL data store
ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
Optional<LocationProvider> optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
Assert.assertTrue(optLocationProvider.isPresent());
List<ProviderAddressEndpointLocation> epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
Assert.assertNotNull(epLocs);
- Assert.assertEquals(1, epLocs.size());
- Assert.assertEquals(absoluteLocation(VPP_NODE_IID, VppPathMapper.bridgeDomainToRestPath(L2FD_CTX.getValue()),
- NODE_CONNECTOR_CLIENT_EP), epLocs.get(0).getAbsoluteLocation());
+ Assert.assertEquals(2, epLocs.size());
+ assertProviderAddressEndpointLocation(clientEp.getKey(),
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), clientIfaceName), epLocs);
+ assertProviderAddressEndpointLocation(webEp.getKey(),
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), webIfaceName), epLocs);
}
@Test
- public void testRendererPolicyChanged_createdClientAndThenWeb() throws Exception {
- testRendererPolicyChanged_createdClient();
+ public void testRendererPolicyChanged_update() throws Exception {
+ String client1IfaceName = "client1";
+ AbsoluteLocation client1LocationNodeNull = absoluteLocation(VPP_NODE_1_IID, null, client1IfaceName);
+ AddressEndpointWithLocation client1Ep =
+ createEndpoint("10.0.0.1", L2FD_CTX.getValue(), client1LocationNodeNull);
+ String web1IfaceName = "web1";
+ AbsoluteLocation web1LocationNodeNull = absoluteLocation(VPP_NODE_2_IID, null, web1IfaceName);
+ AddressEndpointWithLocation web1Ep = createEndpoint("20.0.0.1", L2FD_CTX.getValue(), web1LocationNodeNull);
+ String client2IfaceName = "client2";
+ AbsoluteLocation client2LocationNodeNull = absoluteLocation(VPP_NODE_1_IID, null, client2IfaceName);
+ AddressEndpointWithLocation client2Ep =
+ createEndpoint("10.0.0.2", L2FD_CTX.getValue(), client2LocationNodeNull);
+ String web2IfaceName = "web2";
+ AbsoluteLocation web2LocationNodeNull = absoluteLocation(VPP_NODE_2_IID, null, web2IfaceName);
+ AddressEndpointWithLocation web2Ep = createEndpoint("20.0.0.2", L2FD_CTX.getValue(), web2LocationNodeNull);
- storeInterfaceFor(WEB_EP_KEY, IFACE_NAME_WEB_EP, BASIC_VPP_WEB_EP_IID);
+ storeVppEndpoint(client1Ep.getKey(), client1IfaceName, createVppEndpointIid(client1Ep.getKey()));
+ storeVppEndpoint(web1Ep.getKey(), web1IfaceName, createVppEndpointIid(web1Ep.getKey()));
+ storeVppEndpoint(client2Ep.getKey(), client2IfaceName, createVppEndpointIid(client2Ep.getKey()));
+ storeVppEndpoint(web2Ep.getKey(), web2IfaceName, createVppEndpointIid(web2Ep.getKey()));
- AddressEndpointWithLocation webEp = new AddressEndpointWithLocationBuilder().setKey(WEB_EP_KEY)
- .setNetworkContainment(L2FD_NET_CONT)
- .setAbsoluteLocation(absoluteLocation(VPP_NODE_IID, null, NODE_CONNECTOR_WEB_EP))
- .build();
- AddressEndpointWithLocation clientEp = new AddressEndpointWithLocationBuilder().setKey(CLIENT_EP_KEY)
- .setNetworkContainment(L2FD_NET_CONT)
- .setAbsoluteLocation(absoluteLocation(VPP_NODE_IID, null, NODE_CONNECTOR_CLIENT_EP))
- .build();
- Endpoints endpoints =
- new EndpointsBuilder().setAddressEndpointWithLocation(Arrays.asList(webEp, clientEp)).build();
- RendererEndpoint rendererEndpoint = new RendererEndpointBuilder()
- .setKey(KeyFactory.rendererEndpointKey(WEB_EP_KEY))
- .setPeerEndpointWithPolicy(Arrays.asList(new PeerEndpointWithPolicyBuilder()
- .setKey(KeyFactory.peerEndpointWithPolicyKey(CLIENT_EP_KEY))
- .setRuleGroupWithRendererEndpointParticipation(Arrays.asList(RULE_GROUP_WITH_REND_EP_PART))
- .build()))
- .build();
- Configuration configuration = new ConfigurationBuilder().setEndpoints(endpoints)
- .setRendererEndpoints(
- new RendererEndpointsBuilder().setRendererEndpoint(Arrays.asList(rendererEndpoint)).build())
- .setRuleGroups(new RuleGroupsBuilder().setRuleGroup(Arrays.asList(RULE_GROUP)).build())
- .build();
+ Configuration configuration =
+ createConfiguration(Arrays.asList(client1Ep, client2Ep), Arrays.asList(web1Ep, web2Ep));
RendererPolicy rendererPolicy =
new RendererPolicyBuilder().setVersion(1L).setConfiguration(configuration).build();
RendererPolicyConfEvent event = new RendererPolicyConfEvent(RENDERER_POLICY_IID, null, rendererPolicy);
vppRendererPolicyManager.rendererPolicyChanged(event);
- // assert state on data store behind mount point
- ReadOnlyTransaction rTxMount = mountPointDataBroker.newReadOnlyTransaction();
- Optional<Interface> potentialIface = rTxMount.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
- .builder(Interfaces.class).child(Interface.class, new InterfaceKey(IFACE_NAME_WEB_EP)).build()).get();
- Assert.assertTrue(potentialIface.isPresent());
- Interface iface = potentialIface.get();
- VppInterfaceAugmentation vppIfaceAug = iface.getAugmentation(VppInterfaceAugmentation.class);
- Assert.assertNotNull(vppIfaceAug);
- Interconnection interconnection = vppIfaceAug.getL2().getInterconnection();
- Assert.assertNotNull(interconnection);
- Assert.assertTrue(interconnection instanceof BridgeBased);
- Assert.assertEquals(L2FD_CTX.getValue(), ((BridgeBased) interconnection).getBridgeDomain());
+ // assert state on data store behind mount point ######################################
+ Interface client1Iface = readAndAssertInterface(client1IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client1Iface);
+ Interface web1Iface = readAndAssertInterface(web1IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web1Iface);
+ Interface client2Iface = readAndAssertInterface(client2IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client2Iface);
+ Interface web2Iface = readAndAssertInterface(web2IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web2Iface);
// assert state on ODL data store
ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction();
Optional<LocationProvider> optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
Assert.assertTrue(optLocationProvider.isPresent());
List<ProviderAddressEndpointLocation> epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
Assert.assertNotNull(epLocs);
- Assert.assertEquals(2, epLocs.size());
- if (epLocs.get(0).getAddress().equals(CLIENT_EP_KEY.getAddress())) {
- Assert.assertEquals(absoluteLocation(VPP_NODE_IID,
- VppPathMapper.bridgeDomainToRestPath(L2FD_CTX.getValue()), NODE_CONNECTOR_CLIENT_EP),
- epLocs.get(0).getAbsoluteLocation());
- Assert.assertEquals(absoluteLocation(VPP_NODE_IID,
- VppPathMapper.bridgeDomainToRestPath(L2FD_CTX.getValue()), NODE_CONNECTOR_WEB_EP),
- epLocs.get(1).getAbsoluteLocation());
+ Assert.assertEquals(4, epLocs.size());
+ assertProviderAddressEndpointLocation(client1Ep.getKey(),
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client1IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(web1Ep.getKey(),
+ absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web1IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(client2Ep.getKey(),
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client2IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(web2Ep.getKey(),
+ absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web2IfaceName), epLocs);
+ // #####################################################################################
+
+ AbsoluteLocation client1Location =
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client1IfaceName);
+ AbsoluteLocation web1Location =
+ absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web1IfaceName);
+ AbsoluteLocation web2Location =
+ absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web2IfaceName);
+ configuration = createConfiguration(
+ Arrays.asList(
+ new AddressEndpointWithLocationBuilder(client1Ep).setAbsoluteLocation(client1Location).build(),
+ new AddressEndpointWithLocationBuilder(client2Ep).setAbsoluteLocation(client2LocationNodeNull)
+ .build()),
+ Arrays.asList(new AddressEndpointWithLocationBuilder(web1Ep).setAbsoluteLocation(web1Location).build(),
+ new AddressEndpointWithLocationBuilder(web2Ep).setAbsoluteLocation(web2Location).build()));
+ RendererPolicy rendererPolicy2 =
+ new RendererPolicyBuilder().setVersion(2L).setConfiguration(configuration).build();
+ RendererPolicyConfEvent event2 =
+ new RendererPolicyConfEvent(RENDERER_POLICY_IID, rendererPolicy, rendererPolicy2);
+
+ vppRendererPolicyManager.rendererPolicyChanged(event2);
+
+ // assert state on data store behind mount point ######################################
+ client1Iface = readAndAssertInterface(client1IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client1Iface);
+ web1Iface = readAndAssertInterface(web1IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web1Iface);
+ client2Iface = readAndAssertInterface(client2IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client2Iface);
+ web2Iface = readAndAssertInterface(web2IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web2Iface);
+ // assert state on ODL data store
+ rTx = dataBroker.newReadOnlyTransaction();
+ optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
+ IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
+ .get();
+ Assert.assertTrue(optLocationProvider.isPresent());
+ epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
+ Assert.assertNotNull(epLocs);
+ Assert.assertEquals(4, epLocs.size());
+ assertProviderAddressEndpointLocation(client1Ep.getKey(),
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client1IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(web1Ep.getKey(),
+ absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web1IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(client2Ep.getKey(),
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client2IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(web2Ep.getKey(),
+ absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web2IfaceName), epLocs);
+ // #####################################################################################
+
+ AbsoluteLocation client2Location =
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client2IfaceName);
+ configuration = createConfiguration(
+ Arrays.asList(new AddressEndpointWithLocationBuilder(client1Ep).setAbsoluteLocation(client1Location)
+ .build(),
+ new AddressEndpointWithLocationBuilder(client2Ep).setAbsoluteLocation(client2Location).build()),
+ Arrays.asList(new AddressEndpointWithLocationBuilder(web1Ep).setAbsoluteLocation(web1Location).build(),
+ new AddressEndpointWithLocationBuilder(web2Ep).setAbsoluteLocation(web2Location).build()));
+ RendererPolicy rendererPolicy3 =
+ new RendererPolicyBuilder().setVersion(3L).setConfiguration(configuration).build();
+ RendererPolicyConfEvent event3 =
+ new RendererPolicyConfEvent(RENDERER_POLICY_IID, rendererPolicy2, rendererPolicy3);
+
+ vppRendererPolicyManager.rendererPolicyChanged(event3);
+
+ // assert state on data store behind mount point ######################################
+ client1Iface = readAndAssertInterface(client1IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client1Iface);
+ web1Iface = readAndAssertInterface(web1IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web1Iface);
+ client2Iface = readAndAssertInterface(client2IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), client2Iface);
+ web2Iface = readAndAssertInterface(web2IfaceName);
+ assertBridgeDomainOnInterface(L2FD_CTX.getValue(), web2Iface);
+ // assert state on ODL data store
+ rTx = dataBroker.newReadOnlyTransaction();
+ optLocationProvider = rTx.read(LogicalDatastoreType.CONFIGURATION,
+ IidFactory.locationProviderIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER))
+ .get();
+ Assert.assertTrue(optLocationProvider.isPresent());
+ epLocs = optLocationProvider.get().getProviderAddressEndpointLocation();
+ Assert.assertNotNull(epLocs);
+ Assert.assertEquals(4, epLocs.size());
+ assertProviderAddressEndpointLocation(client1Ep.getKey(),
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client1IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(web1Ep.getKey(),
+ absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web1IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(client2Ep.getKey(),
+ absoluteLocation(VPP_NODE_1_IID, L2FD_CTX.getValue(), client2IfaceName), epLocs);
+ assertProviderAddressEndpointLocation(web2Ep.getKey(),
+ absoluteLocation(VPP_NODE_2_IID, L2FD_CTX.getValue(), web2IfaceName), epLocs);
+ // #####################################################################################
+ }
+
+ private static AbsoluteLocation absoluteLocation(InstanceIdentifier<?> mountPoint, String nodeName,
+ String nodeConnectorName) {
+ ExternalLocationCaseBuilder extLocBuilder =
+ new ExternalLocationCaseBuilder().setExternalNodeMountPoint(mountPoint);
+ if (!Strings.isNullOrEmpty(nodeName)) {
+ extLocBuilder.setExternalNode(VppPathMapper.bridgeDomainToRestPath(nodeName));
+ }
+ if (!Strings.isNullOrEmpty(nodeConnectorName)) {
+ extLocBuilder.setExternalNodeConnector(VppPathMapper.interfaceToRestPath(nodeConnectorName));
+ }
+ return new AbsoluteLocationBuilder().setLocationType(extLocBuilder.build()).build();
+ }
+
+ private AddressEndpointWithLocation createEndpoint(String ip, String l2FdIdAsNetCont,
+ AbsoluteLocation absoluteLocation) {
+ AddressEndpointWithLocationKey key =
+ new AddressEndpointWithLocationKey(ip, AddressType.class, CTX_ID, ContextType.class);
+ NetworkContainment networkContainment =
+ new NetworkContainmentBuilder().setContainment(new ForwardingContextContainmentBuilder()
+ .setContextType(L2FloodDomain.class).setContextId(new ContextId(l2FdIdAsNetCont)).build()).build();
+ return new AddressEndpointWithLocationBuilder().setKey(key)
+ .setNetworkContainment(networkContainment)
+ .setAbsoluteLocation(absoluteLocation)
+ .build();
+ }
+
+ private InstanceIdentifier<VppEndpoint> createVppEndpointIid(AddressEndpointWithLocationKey key) {
+ return InstanceIdentifier.builder(Config.class)
+ .child(VppEndpoint.class, new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(),
+ key.getContextType()))
+ .build();
+ }
+
+ private Configuration createConfiguration(List<AddressEndpointWithLocation> consumers,
+ List<AddressEndpointWithLocation> providers) {
+ List<AddressEndpointWithLocation> eps =
+ Stream.concat(consumers.stream(), providers.stream()).collect(Collectors.toList());
+ Endpoints endpoints = new EndpointsBuilder().setAddressEndpointWithLocation(eps).build();
+ List<RendererEndpoint> consumersAsRendererEps = consumers.stream().map(cons -> {
+ List<PeerEndpointWithPolicy> peers = providers.stream()
+ .map(web -> new PeerEndpointWithPolicyBuilder()
+ .setKey(KeyFactory.peerEndpointWithPolicyKey(web.getKey()))
+ .setRuleGroupWithRendererEndpointParticipation(Arrays.asList(RULE_GROUP_WITH_CONSUMER))
+ .build())
+ .collect(Collectors.toList());
+ return new RendererEndpointBuilder().setKey(KeyFactory.rendererEndpointKey(cons.getKey()))
+ .setPeerEndpointWithPolicy(peers)
+ .build();
+ }).collect(Collectors.toList());
+ List<RendererEndpoint> providersAsRendererEps = providers.stream().map(prov -> {
+ List<PeerEndpointWithPolicy> peers = consumers.stream()
+ .map(client -> new PeerEndpointWithPolicyBuilder()
+ .setKey(KeyFactory.peerEndpointWithPolicyKey(client.getKey()))
+ .setRuleGroupWithRendererEndpointParticipation(Arrays.asList(RULE_GROUP_WITH_PROVIDER))
+ .build())
+ .collect(Collectors.toList());
+ return new RendererEndpointBuilder().setKey(KeyFactory.rendererEndpointKey(prov.getKey()))
+ .setPeerEndpointWithPolicy(peers)
+ .build();
+ }).collect(Collectors.toList());
+ List<RendererEndpoint> rendererEps = Stream
+ .concat(consumersAsRendererEps.stream(), providersAsRendererEps.stream()).collect(Collectors.toList());
+ return new ConfigurationBuilder().setEndpoints(endpoints)
+ .setRendererEndpoints(new RendererEndpointsBuilder().setRendererEndpoint(rendererEps).build())
+ .setRuleGroups(new RuleGroupsBuilder().setRuleGroup(Arrays.asList(RULE_GROUP)).build())
+ .build();
+ }
+
+ private void assertProviderAddressEndpointLocation(AddressEndpointWithLocationKey expectedEpKey,
+ AbsoluteLocation expectedEpLoc, List<ProviderAddressEndpointLocation> providerEpLocs) {
+ List<ProviderAddressEndpointLocation> expectedProvEpLoc =
+ providerEpLocs.stream()
+ .filter(provEpLoc -> provEpLoc.getKey()
+ .equals(KeyFactory.providerAddressEndpointLocationKey(expectedEpKey)))
+ .collect(Collectors.toList());
+ Assert.assertFalse(expectedProvEpLoc.isEmpty());
+ Assert.assertEquals(1, expectedProvEpLoc.size());
+ Assert.assertEquals(expectedEpLoc, expectedProvEpLoc.get(0).getAbsoluteLocation());
+ }
+
+ private Interface readAndAssertInterface(String expectedInterface) throws Exception {
+ ReadOnlyTransaction rTxMount = mountPointDataBroker.newReadOnlyTransaction();
+ Optional<Interface> potentialIface = rTxMount.read(LogicalDatastoreType.CONFIGURATION, InstanceIdentifier
+ .builder(Interfaces.class).child(Interface.class, new InterfaceKey(expectedInterface)).build()).get();
+ Assert.assertTrue(potentialIface.isPresent());
+ return potentialIface.get();
+ }
+
+ private static void assertBridgeDomainOnInterface(String expectedBridgeDomain, Interface actualIface) {
+ VppInterfaceAugmentation vppIfaceAug = actualIface.getAugmentation(VppInterfaceAugmentation.class);
+ Assert.assertNotNull(vppIfaceAug);
+ if (!Strings.isNullOrEmpty(expectedBridgeDomain)) {
+ Interconnection interconnection = vppIfaceAug.getL2().getInterconnection();
+ Assert.assertNotNull(interconnection);
+ Assert.assertTrue(interconnection instanceof BridgeBased);
+ Assert.assertEquals(expectedBridgeDomain, ((BridgeBased) interconnection).getBridgeDomain());
} else {
- Assert.assertEquals(absoluteLocation(VPP_NODE_IID,
- VppPathMapper.bridgeDomainToRestPath(L2FD_CTX.getValue()), NODE_CONNECTOR_CLIENT_EP),
- epLocs.get(1).getAbsoluteLocation());
- Assert.assertEquals(absoluteLocation(VPP_NODE_IID,
- VppPathMapper.bridgeDomainToRestPath(L2FD_CTX.getValue()), NODE_CONNECTOR_WEB_EP),
- epLocs.get(0).getAbsoluteLocation());
+ if (vppIfaceAug != null) {
+ L2 l2 = vppIfaceAug.getL2();
+ if (l2 != null) {
+ Assert.assertNull(l2.getInterconnection());
+ }
+ }
}
}
- private void storeInterfaceFor(AddressEndpointWithLocationKey epKey, String ifaceName,
+ private void storeVppEndpoint(AddressEndpointWithLocationKey epKey, String ifaceName,
InstanceIdentifier<VppEndpoint> vppEpIid) {
VppEndpoint vhostEp = new VppEndpointBuilder().setAddress(epKey.getAddress())
.setAddressType(epKey.getAddressType())
.setContextId(epKey.getContextId())
.setContextType(epKey.getContextType())
.setVppInterfaceName(ifaceName)
- .setVppNodePath(VPP_NODE_IID)
+ .setVppNodePath(VPP_NODE_1_IID)
.setInterfaceTypeChoice(new VhostUserCaseBuilder().setSocket(SOCKET).build())
.build();
VppEndpointConfEvent vppEpEvent = new VppEndpointConfEvent(vppEpIid, null, vhostEp);
ifaceManager.vppEndpointChanged(vppEpEvent);
}
- private static AbsoluteLocation absoluteLocation(InstanceIdentifier<?> mountPoint, String node,
- String nodeConnector) {
- return new AbsoluteLocationBuilder()
- .setLocationType(new ExternalLocationCaseBuilder().setExternalNodeMountPoint(mountPoint)
- .setExternalNode(node)
- .setExternalNodeConnector(nodeConnector)
- .build())
- .build();
- }
-
}
<type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-rpc-registry</type>
<name>binding-rpc-broker</name>
</rpc-registry>
+ <domain-specific-registry>
+ <type xmlns:gbp="urn:opendaylight:params:xml:ns:yang:controller:config:groupbasedpolicy">
+ gbp:domain-specific-registry
+ </type>
+ <name>domain-specific-registry</name>
+ </domain-specific-registry>
</module>
</modules>
</data>
@Override
public java.lang.AutoCloseable createInstance() {
- return new SxpMapperProviderImpl(getDataBrokerDependency(), getRpcRegistryDependency());
+ return new SxpMapperProviderImpl(getDataBrokerDependency(), getRpcRegistryDependency(),
+ getDomainSpecificRegistryDependency());
}
}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.sxp.mapper.api;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+
+/**
+ * Purpose: simple asynchronous search interface allowing for custom key and returning list of values
+ *
+ * @param <X> special key type
+ * @param <V> value type
+ */
+public interface ReadableAsyncByKey<X, V> {
+
+ /**
+ * @param specialKey custom key to search by
+ * @return list of found values
+ */
+ ListenableFuture<Collection<V>> readBy(@Nonnull X specialKey);
+}
* 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.sxp.mapper.api;
-import com.google.common.util.concurrent.ListenableFuture;
import java.util.Collection;
import javax.annotation.Nonnull;
/**
- * Purpose: simple asynchronous search interface allowing for custom key and returning list of values
+ * Purpose: simple search interface allowing for custom key and returning list of values
*
* @param <X> special key type
* @param <V> value type
* @param specialKey custom key to search by
* @return list of found values
*/
- ListenableFuture<Collection<V>> readBy(@Nonnull X specialKey);
+ Collection<V> readBy(@Nonnull X specialKey);
}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.sxp.mapper.impl;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
+import java.util.AbstractMap;
+import java.util.Collection;
+import java.util.Map.Entry;
+import org.opendaylight.groupbasedpolicy.api.EndpointAugmentor;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EpPolicyTemplateValueKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EpPolicyTemplateValueKeyFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.ContainmentEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAugBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+
+public class SxpEndpointAugmentorImpl implements EndpointAugmentor {
+
+ private final ReadableByKey<EpPolicyTemplateValueKey, EndpointPolicyTemplateBySgt> epPolicyTemplateDao;
+ private final EpPolicyTemplateValueKeyFactory epPolicyTemplateKeyFactory;
+
+ public SxpEndpointAugmentorImpl(final ReadableByKey<EpPolicyTemplateValueKey, EndpointPolicyTemplateBySgt> epPolicyTemplateDao,
+ final EpPolicyTemplateValueKeyFactory epPolicyTemplateKeyFactory) {
+ this.epPolicyTemplateKeyFactory = Preconditions.checkNotNull(epPolicyTemplateKeyFactory, "epPolicyTemplateKeyFactory can not be null");
+ this.epPolicyTemplateDao = Preconditions.checkNotNull(epPolicyTemplateDao, "epPolicyTemplateDao can not be null");
+ }
+
+ @Override
+ public Entry<Class<? extends Augmentation<AddressEndpoint>>, Augmentation<AddressEndpoint>> buildAddressEndpointAugmentation(
+ AddressEndpointReg input) {
+ return null;
+ }
+
+ @Override
+ public Entry<Class<? extends Augmentation<ContainmentEndpoint>>, Augmentation<ContainmentEndpoint>> buildContainmentEndpointAugmentation(
+ ContainmentEndpointReg input) {
+ return null;
+ }
+
+ @Override
+ public Entry<Class<? extends Augmentation<AddressEndpointWithLocation>>, Augmentation<AddressEndpointWithLocation>> buildAddressEndpointWithLocationAugmentation(
+ AddressEndpoint input) {
+ final EpPolicyTemplateValueKey templateValueKey = epPolicyTemplateKeyFactory.createKey(
+ input.getTenant(), input.getEndpointGroup(), input.getCondition());
+
+ final Collection<EndpointPolicyTemplateBySgt> epPolicyTemplates = epPolicyTemplateDao.readBy(templateValueKey);
+ final Entry<Class<? extends Augmentation<AddressEndpointWithLocation>>, Augmentation<AddressEndpointWithLocation>> entry;
+
+ if (epPolicyTemplates.isEmpty()) {
+ entry = null;
+ } else {
+ //TODO: cover case when multiple templates found
+ final Augmentation<AddressEndpointWithLocation> addressEndpointWithLocationAug =
+ new AddressEndpointWithLocationAugBuilder()
+ .setSgt(Iterables.getFirst(epPolicyTemplates, null).getSgt())
+ .build();
+ entry = new AbstractMap.SimpleEntry<>(AddressEndpointWithLocationAug.class, addressEndpointWithLocationAug);
+ }
+
+ return entry;
+ }
+
+ @Override
+ public Entry<Class<? extends Augmentation<ContainmentEndpointWithLocation>>, Augmentation<ContainmentEndpointWithLocation>> buildContainmentEndpointWithLocationAugmentation(
+ ContainmentEndpoint input) {
+ return null;
+ }
+
+}
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
+import org.opendaylight.groupbasedpolicy.api.DomainSpecificRegistry;
+import org.opendaylight.groupbasedpolicy.api.EndpointAugmentor;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EPForwardingTemplateDaoImpl;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EPPolicyTemplateDaoImpl;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EpPolicyTemplateValueKeyFactory;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.MasterDatabaseBindingDaoImpl;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.SimpleCachedDaoEPForwardingTemplateImpl;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.SimpleCachedDaoImpl;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen.EPForwardingTemplateListenerImpl;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen.EPPolicyTemplateListenerImpl;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.listen.MasterDatabaseBindingListenerImpl;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.EPTemplateUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
private static final Logger LOG = LoggerFactory.getLogger(SxpMapperProviderImpl.class);
- private final DataBroker dataBrokerDependency;
- private final RpcProviderRegistry rpcRegistryDependency;
private final MasterDatabaseBindingListenerImpl sxpDatabaseListener;
private final SxpMapperReactor sxpMapperReactor;
private final EPTemplateListener epPolicyTemplateListener;
private final EPTemplateListener epForwardingTemplateListener;
+ private final DomainSpecificRegistry domainSpecificRegistry;
+ private final EndpointAugmentor sxpEndpointAugmentor;
- public SxpMapperProviderImpl(final DataBroker dataBroker, final RpcProviderRegistry rpcRegistryDependency) {
+ public SxpMapperProviderImpl(final DataBroker dataBroker, final RpcProviderRegistry rpcRegistryDependency,
+ final DomainSpecificRegistry domainSpecificRegistry) {
LOG.info("starting SxmMapper ..");
- this.dataBrokerDependency = dataBroker;
- this.rpcRegistryDependency = rpcRegistryDependency;
+ this.domainSpecificRegistry = domainSpecificRegistry;
final BaseEndpointService endpointService = rpcRegistryDependency.getRpcService(BaseEndpointService.class);
sxpMapperReactor = new SxpMapperReactorImpl(endpointService, dataBroker);
new SimpleCachedDaoEPForwardingTemplateImpl();
final SimpleCachedDao<IpPrefix, MasterDatabaseBinding> masterDBBindingCachedDao = new SimpleCachedDaoImpl<>();
- final DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> epPolicyTemplateDao = new EPPolicyTemplateDaoImpl(dataBroker, epPolicyTemplateCachedDao);
+ final EpPolicyTemplateValueKeyFactory epPolicyTemplateKeyFactory = new EpPolicyTemplateValueKeyFactory(
+ EPTemplateUtil.createEndpointGroupIdOrdering(), EPTemplateUtil.createConditionNameOrdering());
+ final EPPolicyTemplateDaoImpl epPolicyTemplateDao = new EPPolicyTemplateDaoImpl(dataBroker, epPolicyTemplateCachedDao, epPolicyTemplateKeyFactory);
final EPForwardingTemplateDaoImpl epForwardingTemplateDao = new EPForwardingTemplateDaoImpl(dataBroker,
epForwardingTemplateCachedDao);
final MasterDatabaseBindingDaoImpl masterDBBindingDao = new MasterDatabaseBindingDaoImpl(dataBroker, masterDBBindingCachedDao);
masterDBBindingDao, epForwardingTemplateDao);
epForwardingTemplateListener = new EPForwardingTemplateListenerImpl(dataBroker, sxpMapperReactor, epForwardingTemplateCachedDao,
masterDBBindingDao, epPolicyTemplateDao);
+ sxpEndpointAugmentor = new SxpEndpointAugmentorImpl(epPolicyTemplateDao, epPolicyTemplateKeyFactory);
+ domainSpecificRegistry.getEndpointAugmentorRegistry().register(sxpEndpointAugmentor);
LOG.info("started SxmMapper");
}
sxpDatabaseListener.close();
epPolicyTemplateListener.close();
epForwardingTemplateListener.close();
+ domainSpecificRegistry.getEndpointAugmentorRegistry().unregister(sxpEndpointAugmentor);
}
}
package org.opendaylight.groupbasedpolicy.sxp.mapper.impl;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.util.concurrent.AsyncFunction;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.JdkFutureAdapters;
+import com.google.common.util.concurrent.ListenableFuture;
import java.util.Collections;
-
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.util.concurrent.AsyncFunction;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.JdkFutureAdapters;
-import com.google.common.util.concurrent.ListenableFuture;
-
/**
* Purpose: exclusively processes sxp master database changes and EGP templates changes
*/
.setNetworkDomainType(epForwardingTemplate.getNetworkContainment().getNetworkDomainType())
.setNetworkDomainId(epForwardingTemplate.getNetworkContainment().getNetworkDomainId())
.build())
- .build();
- final RegisterEndpointInput epInput = new RegisterEndpointInputBuilder()
- .setAddressEndpointReg(Collections.singletonList(new AddressEndpointRegBuilder()
- .setAddressType(IpPrefixType.class)
- .setAddress(address.getValue())
- .setContextType(L3Context.class)
- .setContextId(epForwardingTemplate.getL3Context())
- .setNetworkContainment(networkContainment)
- .setCondition(epPolicyTemplate.getConditions())
- .setTenant(epPolicyTemplate.getTenant())
- .setEndpointGroup(epPolicyTemplate.getEndpointGroups())
- .build()))
+ .build();
+ final RegisterEndpointInput epInput = new RegisterEndpointInputBuilder().setAddressEndpointReg(
+ Collections.singletonList(new AddressEndpointRegBuilder().setAddressType(IpPrefixType.class)
+ .setAddress(address.getValue())
+ .setContextType(L3Context.class)
+ .setContextId(epForwardingTemplate.getL3Context())
+ .setNetworkContainment(networkContainment)
+ .setCondition(epPolicyTemplate.getConditions())
+ .setTenant(epPolicyTemplate.getTenant())
+ .setEndpointGroup(epPolicyTemplate.getEndpointGroups())
+ .build()))
.build();
epForwardingTemplate.getL3Context();
import com.google.common.base.Function;
import com.google.common.base.Optional;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.util.concurrent.CheckedFuture;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.Collection;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SxpListenerUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
/**
* Purpose: general dao for EndPoint templates
*/
-public class EPPolicyTemplateDaoImpl implements DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt> {
+public class EPPolicyTemplateDaoImpl implements DSAsyncDao<Sgt, EndpointPolicyTemplateBySgt>,
+ ReadableByKey<EpPolicyTemplateValueKey, EndpointPolicyTemplateBySgt> {
private static final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> READ_FUTURE_ABSENT = Futures.immediateFuture(Optional.absent());
private final DataBroker dataBroker;
private final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao;
+ private final EpPolicyTemplateValueKeyFactory keyFactory;
public EPPolicyTemplateDaoImpl(final DataBroker dataBroker,
- final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao) {
+ final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao,
+ final EpPolicyTemplateValueKeyFactory keyFactory) {
this.dataBroker = dataBroker;
this.cachedDao = cachedDao;
+ this.keyFactory = keyFactory;
}
@Override
@Override
public Optional<EndpointPolicyTemplateBySgt> apply(@Nullable final Optional<EndpointPolicyTemplateBySgt> input) {
if (input.isPresent()) {
- cachedDao.update(key, input.get());
+ cachedDao.update(key, keyFactory.sortValueKeyLists(input.get()));
}
return input;
}
return cachedDao.find(key);
}
+ @Override
+ public Collection<EndpointPolicyTemplateBySgt> readBy(@Nonnull final EpPolicyTemplateValueKey specialKey) {
+ final Predicate<EpPolicyTemplateValueKey> templateValuePredicate = Predicates.equalTo(specialKey);
+ final Collection<EndpointPolicyTemplateBySgt> foundTemplates = new ArrayList<>();
+
+ for (EndpointPolicyTemplateBySgt epPolicyTemplate : cachedDao.values()) {
+ final EpPolicyTemplateValueKey templateValueKey = keyFactory.createKeyWithDefaultOrdering(epPolicyTemplate);
+ if (templateValuePredicate.apply(templateValueKey)) {
+ foundTemplates.add(epPolicyTemplate);
+ }
+ }
+
+ return foundTemplates;
+ }
}
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache;
+package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao;
import java.util.List;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
/**
* Purpose: composite key holcer for {@link EndpointPolicyTemplateBySgt}
*/
-public class EpPolicyTemplateCacheKey {
+public class EpPolicyTemplateValueKey {
private final TenantId tenantId;
private final List<EndpointGroupId> epgId;
private final List<ConditionName> conditionName;
- public EpPolicyTemplateCacheKey(final TenantId tenantId, final List<EndpointGroupId> epgId, final List<ConditionName> conditionName) {
+ public EpPolicyTemplateValueKey(final TenantId tenantId, final List<EndpointGroupId> epgId, final List<ConditionName> conditionName) {
this.tenantId = tenantId;
this.epgId = epgId;
this.conditionName = conditionName;
}
- public EpPolicyTemplateCacheKey(AddressEndpointWithLocation endpoint) {
+ public EpPolicyTemplateValueKey(AddressEndpointWithLocation endpoint) {
this(endpoint.getTenant(), endpoint.getEndpointGroup(), endpoint.getCondition());
}
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
- final EpPolicyTemplateCacheKey that = (EpPolicyTemplateCacheKey) o;
+ final EpPolicyTemplateValueKey that = (EpPolicyTemplateValueKey) o;
if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false;
if (epgId != null ? !epgId.equals(that.epgId) : that.epgId != null) return false;
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.cache;
+package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao;
import com.google.common.collect.Ordering;
import java.util.Collections;
+import java.util.List;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
/**
* Purpose: create cache keys with ordered lists inside
*/
-public class EpPolicyTemplateCacheKeyFactory {
+public class EpPolicyTemplateValueKeyFactory {
private final Ordering<EndpointGroupId> epgIdOrdering;
private final Ordering<ConditionName> conditionOrdering;
- public EpPolicyTemplateCacheKeyFactory(final Ordering<EndpointGroupId> epgIdOrdering,
+ public EpPolicyTemplateValueKeyFactory(final Ordering<EndpointGroupId> epgIdOrdering,
final Ordering<ConditionName> conditionOrdering) {
this.epgIdOrdering = epgIdOrdering;
this.conditionOrdering = conditionOrdering;
}
- public EpPolicyTemplateCacheKey createKey(final EndpointPolicyTemplateBySgt newSource) {
- Collections.sort(newSource.getEndpointGroups(), epgIdOrdering);
- Collections.sort(newSource.getConditions(), conditionOrdering);
+ public EndpointPolicyTemplateBySgt sortValueKeyLists(final EndpointPolicyTemplateBySgt template) {
+ if (template.getEndpointGroups() != null) {
+ Collections.sort(template.getEndpointGroups(), epgIdOrdering);
+ }
+ if (template.getConditions() != null) {
+ Collections.sort(template.getConditions(), conditionOrdering);
+ }
+ return template;
+ }
- return new EpPolicyTemplateCacheKey(
+ public EpPolicyTemplateValueKey createKeyWithDefaultOrdering(final EndpointPolicyTemplateBySgt newSource) {
+ return new EpPolicyTemplateValueKey(
newSource.getTenant(), newSource.getEndpointGroups(), newSource.getConditions());
}
- public EpPolicyTemplateCacheKey createKey(final EpPolicyTemplateCacheKey existingKey) {
+ public EpPolicyTemplateValueKey sortValueKeyLists(final EpPolicyTemplateValueKey existingKey) {
Collections.sort(existingKey.getEpgId(), epgIdOrdering);
Collections.sort(existingKey.getConditionName(), conditionOrdering);
return existingKey;
}
+
+ public EpPolicyTemplateValueKey createKey(final TenantId tenant, final List<EndpointGroupId> endpointGroup,
+ final List<ConditionName> condition) {
+ return sortValueKeyLists(new EpPolicyTemplateValueKey(tenant, endpointGroup, condition));
+ }
}
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.MasterDatabaseBindingListener;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableAsyncByKey;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.SxpListenerUtil;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.MasterDatabaseFields;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpDatabasesFields;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomains;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
* Purpose: general dao for EndPoint templates
*/
public class MasterDatabaseBindingDaoImpl implements DSAsyncDao<IpPrefix, MasterDatabaseBinding>,
- ReadableByKey<Sgt, MasterDatabaseBinding> {
+ ReadableAsyncByKey<Sgt, MasterDatabaseBinding> {
private static final Logger LOG = LoggerFactory.getLogger(MasterDatabaseBindingDaoImpl.class);
private static final ListenableFuture<Optional<MasterDatabaseBinding>> READ_FUTURE_ABSENT = Futures.immediateFuture(Optional.absent());
cachedDao.invalidateCache();
for (Node node : input.get().getNode()) {
- final SxpNodeIdentity sxpNodeIdentity = node.getAugmentation(SxpNodeIdentity.class);
- if (sxpNodeIdentity != null) {
- final List<MasterDatabaseBinding> masterDBBindings = sxpNodeIdentity.getMasterDatabase().getMasterDatabaseBinding();
- if (masterDBBindings != null) {
- for (MasterDatabaseBinding masterDBItem : masterDBBindings) {
- // update all
- final MasterDatabaseBinding previousValue = cachedDao.update(
- masterDBItem.getIpPrefix(), masterDBItem);
- if (previousValue != null) {
- LOG.warn("updated key already obtained: [node:{}, sgt:{}]",
- node.getNodeId().getValue(),
- masterDBItem.getSecurityGroupTag());
+ java.util.Optional.ofNullable(node.getAugmentation(SxpNodeIdentity.class))
+ .map(SxpNodeIdentity::getSxpDomains)
+ .map(SxpDomains::getSxpDomain)
+ .ifPresent((sxpDomain) -> {
+ final List<MasterDatabaseBinding> masterDBBindings = sxpDomain.stream()
+ .map(SxpDatabasesFields::getMasterDatabase)
+ .filter(masterDb -> masterDb != null)
+ .map(MasterDatabaseFields::getMasterDatabaseBinding)
+ .filter(binding -> binding != null)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+
+ for (MasterDatabaseBinding masterDBItem : masterDBBindings) {
+ // update all
+ final MasterDatabaseBinding
+ previousValue =
+ cachedDao.update(masterDBItem.getIpPrefix(), masterDBItem);
+ if (previousValue != null) {
+ LOG.warn("updated key already obtained: [node:{}, sgt:{}]",
+ node.getNodeId().getValue(), masterDBItem.getSecurityGroupTag());
+ }
}
- }
- }
- }
+ });
}
} else {
LOG.warn("failed to update cache of SxpMasterDB - no data");
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableAsyncByKey;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.EPTemplateUtil;
private final InstanceIdentifier<EndpointPolicyTemplateBySgt> templatePath;
private final SxpMapperReactor sxpMapperReactor;
private final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> templateCachedDao;
- private final ReadableByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao;
+ private final ReadableAsyncByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao;
private final DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao;
public EPPolicyTemplateListenerImpl(final DataBroker dataBroker,
final SxpMapperReactor sxpMapperReactor,
final SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> templateCachedDao,
- final ReadableByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao,
+ final ReadableAsyncByKey<Sgt, MasterDatabaseBinding> masterDBBindingDao,
final DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao) {
this.sxpMapperReactor = Preconditions.checkNotNull(sxpMapperReactor);
this.templateCachedDao = Preconditions.checkNotNull(templateCachedDao);
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBinding;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomains;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomain;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.databases.fields.MasterDatabase;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
sxpDbPath = MasterDatabaseBindingListener.SXP_TOPOLOGY_PATH
.child(Node.class)
.augmentation(SxpNodeIdentity.class)
+ .child(SxpDomains.class)
+ .child(SxpDomain.class)
.child(MasterDatabase.class)
.child(MasterDatabaseBinding.class);
package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util;
import com.google.common.base.Function;
+import com.google.common.base.MoreObjects;
import com.google.common.base.Optional;
+import com.google.common.collect.Ordering;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.ArrayList;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.commons.net.util.SubnetUtils;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointForwardingTemplateBySubnet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
public final class EPTemplateUtil {
public static final String FULL_IPV4_MASK_SUFFIX = "/32";
+ private static final Comparable EMPTY_COMPARABLE = "";
private EPTemplateUtil() {
throw new IllegalAccessError("constructing util class");
});
}
+ public static Ordering<EndpointGroupId> createEndpointGroupIdOrdering() {
+ return Ordering.natural().onResultOf(new Function<EndpointGroupId, Comparable>() {
+ @Nullable
+ @Override
+ public Comparable apply(@Nullable final EndpointGroupId input) {
+ if (input == null) {
+ return EMPTY_COMPARABLE;
+ }
+ return MoreObjects.firstNonNull(input.getValue(), EMPTY_COMPARABLE);
+ }
+ });
+ }
+
+ public static Ordering<ConditionName> createConditionNameOrdering() {
+ return Ordering.natural().onResultOf(new Function<ConditionName, Comparable>() {
+ @Nullable
+ @Override
+ public Comparable apply(@Nullable final ConditionName input) {
+ if (input == null) {
+ return EMPTY_COMPARABLE;
+ }
+ return MoreObjects.firstNonNull(input.getValue(), EMPTY_COMPARABLE);
+ }
+ });
+ }
+
public static class OptionalMutablePair<L, R> extends MutablePair<Optional<L>, Optional<R>> {
public OptionalMutablePair() {
super(Optional.absent(), Optional.absent());
import config { prefix config; revision-date 2013-04-05; }
import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+ import groupbasedpolicy-cfg {prefix gbpcfg; revision-date 2015-11-06; }
description
"This module contains the base YANG definitions for
}
}
}
+ //Domain specific registry
+ container domain-specific-registry {
+ uses config:service-ref {
+ refine type {
+ mandatory true;
+ config:required-identity gbpcfg:domain-specific-registry;
+ }
+ }
+ }
}
}
}
import gbp-common { prefix gbp-common; revision-date 2014-04-21; }
import ietf-inet-types { prefix inet; revision-date 2010-09-24; }
import forwarding { prefix forwarding; revision-date 2016-04-27; }
+ import base-endpoint { prefix base-edpoint; revision-date 2016-04-27; }
+ import yang-ext { prefix ext; revision-date 2013-07-09; }
+ import renderer { prefix renderer; revision-date 2015-11-03; }
description
"This module contains the YANG definitions for
}
}
}
+
+ grouping sxp-sgt {
+ description "SGT leaf dedicated for endpoint-rpc, endpoint container and renderer configuration
+ (attach by augmentation)";
+ leaf sgt {
+ type sxp-database:sgt;
+ }
+ }
+
+ augment "renderer:renderers/renderer:renderer/renderer:renderer-policy/renderer:configuration/renderer:endpoints/renderer:address-endpoint-with-location" {
+ ext:augment-identifier "address-endpoint-with-location-aug";
+ uses sxp-sgt;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2016 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.sxp.mapper.impl;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.Spy;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EpPolicyTemplateValueKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao.EpPolicyTemplateValueKeyFactory;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.EPTemplateUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpoint;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.containment.endpoints.ContainmentEndpointBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointReg;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.ContainmentEndpointRegBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
+import org.opendaylight.yangtools.yang.binding.Augmentation;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+
+/**
+ * Test for {@link SxpEndpointAugmentorImpl}.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class SxpEndpointAugmentorImplTest {
+
+ @Mock
+ private ReadableByKey<EpPolicyTemplateValueKey, EndpointPolicyTemplateBySgt> epPolicyDao;
+ @Spy
+ private EpPolicyTemplateValueKeyFactory keyFactory = new EpPolicyTemplateValueKeyFactory(
+ EPTemplateUtil.createEndpointGroupIdOrdering(), EPTemplateUtil.createConditionNameOrdering());
+ @Captor
+ private ArgumentCaptor<EpPolicyTemplateValueKey> keyCapt;
+
+ private SxpEndpointAugmentorImpl augmetor;
+
+ @Before
+ public void setUp() throws Exception {
+ augmetor = new SxpEndpointAugmentorImpl(epPolicyDao, keyFactory);
+ }
+
+ @Test
+ public void testBuildAddressEndpointWithLocationAugmentation() throws Exception {
+ final TenantId tenantId = new TenantId("tn1");
+ final AddressEndpoint endpoint = new AddressEndpointBuilder()
+ .setTenant(tenantId)
+ .setCondition(buildConditions(new String[]{"cn2", "cn1"}))
+ .setEndpointGroup(buildEndpointGroupIds(new String[]{"epg2", "epg1"}))
+ .build();
+
+ Mockito.doCallRealMethod().when(keyFactory).sortValueKeyLists(Matchers.<EndpointPolicyTemplateBySgt>any());
+ final List<ConditionName> conditions = buildConditions(new String[]{"cn1", "cn2"});
+ final List<EndpointGroupId> endpointGroupIds = buildEndpointGroupIds(new String[]{"epg1", "epg2"});
+ final EndpointPolicyTemplateBySgt epPolicyTemplate = new EndpointPolicyTemplateBySgtBuilder()
+ .setTenant(tenantId)
+ .setEndpointGroups(endpointGroupIds)
+ .setConditions(conditions)
+ .setSgt(new Sgt(42))
+ .build();
+
+ Mockito.when(epPolicyDao.readBy(keyCapt.capture())).thenReturn(Collections.singletonList(epPolicyTemplate));
+
+ final Map.Entry<Class<? extends Augmentation<AddressEndpointWithLocation>>, Augmentation<AddressEndpointWithLocation>>
+ augmentationEntry = augmetor.buildAddressEndpointWithLocationAugmentation(endpoint);
+
+ Assert.assertEquals(AddressEndpointWithLocationAug.class, augmentationEntry.getKey());
+ Assert.assertTrue(DataObject.class.isAssignableFrom(augmentationEntry.getValue().getClass()));
+ Assert.assertEquals(AddressEndpointWithLocationAug.class, ((DataObject) augmentationEntry.getValue()).getImplementedInterface());
+ Assert.assertEquals(42, ((AddressEndpointWithLocationAug) augmentationEntry.getValue()).getSgt().getValue().intValue());
+
+ final EpPolicyTemplateValueKey keyValue = keyCapt.getValue();
+ Assert.assertEquals(tenantId, keyValue.getTenantId());
+ Assert.assertEquals(endpointGroupIds, keyValue.getEpgId());
+ Assert.assertEquals(conditions, keyValue.getConditionName());
+ }
+
+ private static List<EndpointGroupId> buildEndpointGroupIds(final String[] names) {
+ final List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
+ for (String epgId : names) {
+ endpointGroupIds.add(new EndpointGroupId(epgId));
+ }
+ return endpointGroupIds;
+ }
+
+ private static List<ConditionName> buildConditions(final String[] names) {
+ final List<ConditionName> conditions = new ArrayList<>();
+ for (String condition : names) {
+ conditions.add(new ConditionName(condition));
+ }
+ return conditions;
+ }
+
+ @Test
+ public void testBuildAddressEndpointAugmentation() throws Exception {
+ final AddressEndpointReg endpoint = new AddressEndpointRegBuilder().build();
+ Assert.assertNull(augmetor.buildAddressEndpointAugmentation(endpoint));
+ }
+
+ @Test
+ public void testBuildContainmentEndpointAugmentation() throws Exception {
+ final ContainmentEndpointReg endpoint = new ContainmentEndpointRegBuilder().build();
+ Assert.assertNull(augmetor.buildContainmentEndpointAugmentation(endpoint));
+ }
+
+ @Test
+ public void testBuildContainmentEndpointWithLocationAugmentation() throws Exception {
+ final ContainmentEndpoint endpoint = new ContainmentEndpointBuilder().build();
+ Assert.assertNull(augmetor.buildContainmentEndpointWithLocationAugmentation(endpoint));
+ }
+}
\ No newline at end of file
package org.opendaylight.groupbasedpolicy.sxp.mapper.impl.dao;
import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
import org.mockito.InOrder;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.impl.util.EPTemplateUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.SxpMapper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgt;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.sxp.mapper.EndpointPolicyTemplateBySgtBuilder;
private SimpleCachedDao<Sgt, EndpointPolicyTemplateBySgt> cachedDao;
@Mock
private ReadOnlyTransaction rTx;
+ @Spy
+ private EpPolicyTemplateValueKeyFactory keyFactory = new EpPolicyTemplateValueKeyFactory(
+ EPTemplateUtil.createEndpointGroupIdOrdering(), EPTemplateUtil.createConditionNameOrdering());
+ @Captor
+ ArgumentCaptor<Sgt> sgtCapt;
+ @Captor
+ ArgumentCaptor<EndpointPolicyTemplateBySgt> epPolicyTemplateCapt;
private EPPolicyTemplateDaoImpl dao;
@Before
public void setUp() throws Exception {
- dao = new EPPolicyTemplateDaoImpl(dataBroker, cachedDao);
+ dao = new EPPolicyTemplateDaoImpl(dataBroker, cachedDao, keyFactory);
}
@Test
Matchers.<InstanceIdentifier<EndpointPolicyTemplateBySgt>>any())).thenReturn(
Futures.<Optional<EndpointPolicyTemplateBySgt>, ReadFailedException>immediateCheckedFuture(
Optional.of(EP_POLICY_TEMPLATE_VALUE)));
+ Mockito.doCallRealMethod().when(keyFactory).sortValueKeyLists(Matchers.<EndpointPolicyTemplateBySgt>any());
final ListenableFuture<Optional<EndpointPolicyTemplateBySgt>> read = dao.read(KEY_1);
Assert.assertTrue(read.isDone());
final InstanceIdentifier<EndpointPolicyTemplateBySgt> readPath = dao.buildReadPath(KEY_1);
Assert.assertEquals(expectedPath, readPath);
}
+
+ @Test
+ public void testReadBy_single() throws Exception {
+ final EpPolicyTemplateValueKey key = new EpPolicyTemplateValueKey(new TenantId("tn1"),
+ buildEndpointGroupIds(new String[]{"epg1", "epg2"}),
+ buildConditions(new String[]{"cn1", "cn2"}));
+
+ Mockito.doCallRealMethod().when(keyFactory).createKeyWithDefaultOrdering(Matchers.<EndpointPolicyTemplateBySgt>any());
+
+ Mockito.when(cachedDao.values()).thenReturn(Lists.newArrayList(
+ createEpPolicytemplate(new Sgt(1), new String[]{"cn2", "cn1"}, new String[]{"epg1", "epg2"}, "tn1"),
+ createEpPolicytemplate(new Sgt(2), new String[]{"cn1", "cn2"}, new String[]{"epg2", "epg1"}, "tn1"),
+ createEpPolicytemplate(new Sgt(3), new String[]{"cn2", "cn1"}, new String[]{"epg2", "epg1"}, "tn1"),
+ createEpPolicytemplate(new Sgt(4), new String[]{"cn1", "cn2"}, new String[]{"epg1", "epg2"}, "tn1")
+ ));
+
+ final Collection<EndpointPolicyTemplateBySgt> policyTemplates = dao.readBy(key);
+ Assert.assertEquals(1, policyTemplates.size());
+ Assert.assertEquals(4, Iterables.getFirst(policyTemplates, null).getSgt().getValue().intValue());
+ }
+
+ @Test
+ public void testRead_unsortedLists() throws Exception {
+ final EndpointPolicyTemplateBySgt epPolicytemplateUnsorted = createEpPolicytemplate(new Sgt(1),
+ new String[]{"cn2", "cn1"}, new String[]{"epg2", "epg1"}, "tn1");
+
+ Mockito.doCallRealMethod().when(keyFactory).createKeyWithDefaultOrdering(Matchers.<EndpointPolicyTemplateBySgt>any());
+
+ Mockito.when(cachedDao.find(Matchers.<Sgt>any())).thenReturn(
+ Optional.<EndpointPolicyTemplateBySgt>absent());
+ Mockito.when(cachedDao.isEmpty()).thenReturn(true);
+ Mockito.when(dataBroker.newReadOnlyTransaction()).thenReturn(rTx);
+
+ Mockito.when(rTx.read(Matchers.eq(LogicalDatastoreType.CONFIGURATION),
+ Matchers.<InstanceIdentifier<EndpointPolicyTemplateBySgt>>any())).thenReturn(
+ Futures.<Optional<EndpointPolicyTemplateBySgt>, ReadFailedException>immediateCheckedFuture(
+ Optional.of(epPolicytemplateUnsorted)));
+
+ dao.read(new Sgt(1));
+
+ Mockito.verify(cachedDao).update(sgtCapt.capture(), epPolicyTemplateCapt.capture());
+ Mockito.verify(cachedDao).find(sgtCapt.capture());
+
+ Assert.assertEquals(1, sgtCapt.getValue().getValue().intValue());
+ final EndpointPolicyTemplateBySgt template = epPolicyTemplateCapt.getValue();
+ Assert.assertEquals(1, template.getSgt().getValue().intValue());
+ Assert.assertEquals("tn1", template.getTenant().getValue());
+ Assert.assertEquals(buildEndpointGroupIds(new String[]{"epg1", "epg2"}), template.getEndpointGroups());
+ Assert.assertEquals(buildConditions(new String[]{"cn1", "cn2"}), template.getConditions());
+ }
+
+
+ private EndpointPolicyTemplateBySgt createEpPolicytemplate(final Sgt sgt, final String[] conditionNames,
+ final String[] epgIds, final String tenant) {
+ return new EndpointPolicyTemplateBySgtBuilder()
+ .setSgt(sgt)
+ .setEndpointGroups(buildEndpointGroupIds(epgIds))
+ .setConditions(buildConditions(conditionNames))
+ .setTenant(new TenantId(tenant))
+ .build();
+ }
+
+ private static List<EndpointGroupId> buildEndpointGroupIds(final String[] names) {
+ final List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
+ for (String epgId : names) {
+ endpointGroupIds.add(new EndpointGroupId(epgId));
+ }
+ return endpointGroupIds;
+ }
+
+ private static List<ConditionName> buildConditions(final String[] names) {
+ final List<ConditionName> conditions = new ArrayList<>();
+ for (String condition : names) {
+ conditions.add(new ConditionName(condition));
+ }
+ return conditions;
+ }
}
\ No newline at end of file
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentityBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomainsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.databases.fields.MasterDatabaseBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
.setNode(Lists.newArrayList(new NodeBuilder()
.setNodeId(new NodeId("utNodeId"))
.addAugmentation(SxpNodeIdentity.class, new SxpNodeIdentityBuilder()
- .setMasterDatabase(new MasterDatabaseBuilder()
- .setMasterDatabaseBinding(Lists.newArrayList(MASTER_DB_BINDING_VALUE))
+ .setSxpDomains(new SxpDomainsBuilder()
+ .setSxpDomain(Collections.singletonList(new SxpDomainBuilder()
+ .setDomainName("global")
+ .setMasterDatabase(new MasterDatabaseBuilder()
+ .setMasterDatabaseBinding(Lists.newArrayList(MASTER_DB_BINDING_VALUE))
+ .build())
+ .build()))
.build())
.build())
.build()))
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.DSAsyncDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.EPTemplateListener;
-import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableByKey;
+import org.opendaylight.groupbasedpolicy.sxp.mapper.api.ReadableAsyncByKey;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SimpleCachedDao;
import org.opendaylight.groupbasedpolicy.sxp.mapper.api.SxpMapperReactor;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
@Mock
private DSAsyncDao<IpPrefix, EndpointForwardingTemplateBySubnet> epForwardingTemplateDao;
@Mock
- private ReadableByKey<Sgt, MasterDatabaseBinding> masterDBDao;
+ private ReadableAsyncByKey<Sgt, MasterDatabaseBinding> masterDBDao;
@Mock
private ListenerRegistration<? extends EPTemplateListener> listenerRegistration;
@Mock
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.master.database.fields.MasterDatabaseBindingKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.SxpNodeIdentity;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.SxpDomains;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.network.topology.topology.node.sxp.domains.SxpDomainKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.node.rev160308.sxp.databases.fields.MasterDatabase;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
MasterDatabaseBindingListener.SXP_TOPOLOGY_PATH
.child(Node.class, new NodeKey(new NodeId("utNodeId")))
.augmentation(SxpNodeIdentity.class)
+ .child(SxpDomains.class)
+ .child(SxpDomain.class, new SxpDomainKey("global"))
.child(MasterDatabase.class)
.child(MasterDatabaseBinding.class, new MasterDatabaseBindingKey(IP_PREFIX));
private static final DataTreeIdentifier<MasterDatabaseBinding> MASTER_DB_BINDING_TREE_PATH =