From: Michal Cmarada Date: Fri, 15 Jul 2016 06:47:11 +0000 (+0200) Subject: Tap Port implementation in VPP renderer X-Git-Tag: release/boron~53^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=ec6f67745b9665e3e3e14a0985b5514dfbe9d69b;p=groupbasedpolicy.git Tap Port implementation in VPP renderer Change-Id: I210368f121722d13703a6d0810f44ccab1e5ea02 Signed-off-by: Michal Cmarada --- diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/AbstractInterfaceCommand.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/AbstractInterfaceCommand.java index 049363119..9bf717d5c 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/AbstractInterfaceCommand.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/AbstractInterfaceCommand.java @@ -1,50 +1,102 @@ -/* - * Copyright (c) 2016 Cisco Systems. 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.commands; - -import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General; - -public abstract class AbstractInterfaceCommand> implements ConfigCommand { - - protected General.Operations operation; - protected String name; - protected String description; - protected Boolean enabled; - - protected enum linkUpDownTrap { - ENABLED, DISABLED - } - - public General.Operations getOperation() { - return operation; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public AbstractInterfaceCommand setDescription(String description) { - this.description = description; - return this; - } - - public Boolean getEnabled() { - return enabled; - } - - public AbstractInterfaceCommand setEnabled(Boolean enabled) { - this.enabled = enabled; - return this; - } - -} +/* + * Copyright (c) 2016 Cisco Systems. 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.commands; + +import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractInterfaceCommand> implements ConfigCommand { + + private static final Logger LOG = LoggerFactory.getLogger(AbstractInterfaceCommand.class); + + protected General.Operations operation; + protected String name; + protected String description; + protected Boolean enabled; + + protected enum linkUpDownTrap { + ENABLED, DISABLED + } + + public General.Operations getOperation() { + return operation; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public AbstractInterfaceCommand setDescription(String description) { + this.description = description; + return this; + } + + public Boolean getEnabled() { + return enabled; + } + + public AbstractInterfaceCommand setEnabled(Boolean enabled) { + this.enabled = enabled; + return this; + } + + public void execute(ReadWriteTransaction rwTx) { + switch (getOperation()) { + case PUT: + LOG.debug("Executing Add operations for command: {}", this); + put(rwTx); + break; + case DELETE: + LOG.debug("Executing Delete operations for command: {}", this); + delete(rwTx); + break; + case MERGE: + LOG.debug("Executing Update operations for command: {}", this); + merge(rwTx); + break; + default: + LOG.error("Execution failed for command: {}", this); + break; + } + } + + private void put(ReadWriteTransaction rwTx) { + InterfaceBuilder interfaceBuilder = getInterfaceBuilder(); + + rwTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getInterfaceIID(interfaceBuilder.getKey()), + interfaceBuilder.build(), true); + } + + private void merge(ReadWriteTransaction rwTx) { + InterfaceBuilder interfaceBuilder = getInterfaceBuilder(); + + rwTx.merge(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getInterfaceIID(interfaceBuilder.getKey()), + interfaceBuilder.build()); + } + + private void delete(ReadWriteTransaction readWriteTransaction) { + try { + readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getInterfaceIID(new InterfaceKey(name))); + } catch (IllegalStateException ex) { + LOG.debug("Interface is not present in DS {}", this, ex); + } + + } +} diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/ConfigCommand.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/ConfigCommand.java index cd8b690fd..e76c2cef2 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/ConfigCommand.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/ConfigCommand.java @@ -1,22 +1,29 @@ -/* - * Copyright (c) 2016 Cisco Systems. 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.commands; - -import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; - -public interface ConfigCommand { - - /** - * Execute command using a given data modification transaction - * - * @param readWriteTransaction Transaction for command execution - */ - void execute(ReadWriteTransaction readWriteTransaction); - -} +/* + * Copyright (c) 2016 Cisco Systems. 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.commands; + +import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; + +public interface ConfigCommand { + + /** + * Execute command using a given data modification transaction. + * + * @param readWriteTransaction Transaction for command execution + */ + void execute(ReadWriteTransaction readWriteTransaction); + + /** + * Creates Interface Builder with proper augmentations. + * + * @return InterfaceBuilder for this command with proper augmentations + */ + InterfaceBuilder getInterfaceBuilder(); +} diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/TapPortCommand.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/TapPortCommand.java new file mode 100644 index 000000000..c1e177bff --- /dev/null +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/TapPortCommand.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2016 Cisco Systems. 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.commands; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General.Operations; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap; +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.VppInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.TapBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder; + +public class TapPortCommand extends AbstractInterfaceCommand { + + private String tapName; + private PhysAddress physAddress; + private String bridgeDomain; + private Long deviceInstance; + + private TapPortCommand(TapPortCommandBuilder builder) { + this.name = builder.getInterfaceName(); + this.tapName = builder.getTapName(); + this.operation = builder.getOperation(); + this.physAddress = builder.getPhysAddress(); + this.enabled = builder.isEnabled(); + this.description = builder.getDescription(); + this.bridgeDomain = builder.getBridgeDomain(); + this.deviceInstance = builder.getDeviceInstance(); + } + + public static TapPortCommandBuilder builder() { + return new TapPortCommandBuilder(); + } + + public PhysAddress getPhysAddress() { + return physAddress; + } + + public String getBridgeDomain() { + return bridgeDomain; + } + + public Long getDeviceInstance() { + return deviceInstance; + } + + public String getTapName() { + return tapName; + } + + @Override + public InterfaceBuilder getInterfaceBuilder() { + InterfaceBuilder interfaceBuilder = new InterfaceBuilder().setKey(new InterfaceKey(name)) + .setEnabled(enabled) + .setDescription(description) + .setType(Tap.class) + .setName(name) + .setLinkUpDownTrapEnable(Interface.LinkUpDownTrapEnable.Enabled); + + // Create the Tap augmentation + VppInterfaceAugmentationBuilder vppAugmentationBuilder = + new VppInterfaceAugmentationBuilder().setTap(new TapBuilder().setMac(this.physAddress) + .setTapName(this.tapName) + .setMac(this.physAddress) + .setDeviceInstance(this.deviceInstance) + .build()); + + if (!Strings.isNullOrEmpty(bridgeDomain)) { + vppAugmentationBuilder.setL2(new L2Builder() + .setInterconnection(new BridgeBasedBuilder().setBridgeDomain(bridgeDomain).build()).build()); + } + + interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppAugmentationBuilder.build()); + return interfaceBuilder; + } + + @Override + public String toString() { + return "TapPortUserCommand [physAddress=" + physAddress + ", bridgeDomain=" + bridgeDomain + ", operations=" + + operation + ", name=" + name + ", tapName=" + tapName + ", description=" + description + ", enabled=" + + enabled + "]"; + } + + public static class TapPortCommandBuilder { + + private String interfaceName; + private String tapName; + private Operations operation; + private PhysAddress physAddress; + private String bridgeDomain; + private String description; + private Long deviceInstance = null; + private boolean enabled = true; + + public String getInterfaceName() { + return interfaceName; + } + + public TapPortCommandBuilder setInterfaceName(String interfaceName) { + this.interfaceName = interfaceName; + return this; + } + + public String getTapName() { + return tapName; + } + + public TapPortCommandBuilder setTapName(String tapName) { + this.tapName = tapName; + return this; + } + + public General.Operations getOperation() { + return operation; + } + + public TapPortCommandBuilder setOperation(Operations operation) { + this.operation = operation; + return this; + } + + public PhysAddress getPhysAddress() { + return physAddress; + } + + public TapPortCommandBuilder setPhysAddress(PhysAddress physAddress) { + this.physAddress = physAddress; + return this; + } + + public String getBridgeDomain() { + return bridgeDomain; + } + + public TapPortCommandBuilder setBridgeDomain(String bridgeDomain) { + this.bridgeDomain = bridgeDomain; + return this; + } + + public String getDescription() { + return description; + } + + public TapPortCommandBuilder setDescription(String description) { + this.description = description; + return this; + } + + public Long getDeviceInstance() { + return deviceInstance; + } + + public TapPortCommandBuilder setDeviceInstance(Long deviceInstance) { + this.deviceInstance = deviceInstance; + return this; + } + + public boolean isEnabled() { + return enabled; + } + + public TapPortCommandBuilder setEnabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + /** + * TapPortCommand build method. + * + * @return TapPortCommand + * @throws IllegalArgumentException if interfaceName, tapName or operation is null. + */ + public TapPortCommand build() { + Preconditions.checkArgument(this.interfaceName != null); + Preconditions.checkArgument(this.tapName != null); + Preconditions.checkArgument(this.operation != null); + + return new TapPortCommand(this); + } + } +} diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/VhostUserCommand.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/VhostUserCommand.java index b5c827763..f72452490 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/VhostUserCommand.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/VhostUserCommand.java @@ -1,231 +1,178 @@ -/* - * Copyright (c) 2016 Cisco Systems. 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.commands; - -import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General; -import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General.Operations; -import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUserRole; -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.VppInterfaceAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Preconditions; -import com.google.common.base.Strings; - -public class VhostUserCommand extends AbstractInterfaceCommand { - - private static final Logger LOG = LoggerFactory.getLogger(VhostUserCommand.class); - private String socket; - private VhostUserRole role; - private String bridgeDomain; - - private VhostUserCommand(VhostUserCommandBuilder builder) { - this.name = builder.getName(); - this.operation = builder.getOperation(); - this.socket = builder.getSocket(); - this.role = builder.getRole(); - this.enabled = builder.isEnabled(); - this.description = builder.getDescription(); - this.bridgeDomain = builder.getBridgeDomain(); - - } - - public static VhostUserCommandBuilder builder() { - return new VhostUserCommandBuilder(); - } - - public String getSocket() { - return socket; - } - - public VhostUserRole getRole() { - return role; - } - - public String getBridgeDomain() { - return bridgeDomain; - } - - @Override - public void execute(ReadWriteTransaction readWriteTransaction) { - switch (getOperation()) { - - case PUT: - LOG.debug("Executing Add operation for command: {}", this); - put(readWriteTransaction); - break; - case DELETE: - LOG.debug("Executing Delete operation for command: {}", this); - delete(readWriteTransaction); - break; - case MERGE: - LOG.debug("Executing Update operation for command: {}", this); - merge(readWriteTransaction); - break; - default: - LOG.error("Execution failed for command: {}", this); - break; - } - } - - private void put(ReadWriteTransaction readWriteTransaction) { - InterfaceBuilder interfaceBuilder = getVhostUserInterfaceBuilder(); - - readWriteTransaction.put(LogicalDatastoreType.CONFIGURATION, - VppIidFactory.getInterfaceIID(interfaceBuilder.getKey()), interfaceBuilder.build(), true); - } - - private void merge(ReadWriteTransaction readWriteTransaction) { - InterfaceBuilder interfaceBuilder = getVhostUserInterfaceBuilder(); - - readWriteTransaction.merge(LogicalDatastoreType.CONFIGURATION, - VppIidFactory.getInterfaceIID(interfaceBuilder.getKey()), interfaceBuilder.build()); - } - - private InterfaceBuilder getVhostUserInterfaceBuilder() { - InterfaceBuilder interfaceBuilder = - new InterfaceBuilder().setKey(new InterfaceKey(name)) - .setEnabled(enabled) - .setDescription(description) - .setType( - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class) - .setName(name) - .setLinkUpDownTrapEnable(Interface.LinkUpDownTrapEnable.Enabled); - - // Create the vhost augmentation - VppInterfaceAugmentationBuilder vppAugmentationBuilder = new VppInterfaceAugmentationBuilder() - .setVhostUser(new VhostUserBuilder().setRole(role).setSocket(socket).build()); - if (!Strings.isNullOrEmpty(bridgeDomain)) { - vppAugmentationBuilder.setL2(new L2Builder() - .setInterconnection(new BridgeBasedBuilder().setBridgeDomain(bridgeDomain).build()).build()); - } - - interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppAugmentationBuilder.build()); - return interfaceBuilder; - } - - private void delete(ReadWriteTransaction readWriteTransaction) { - try { - readWriteTransaction.delete(LogicalDatastoreType.CONFIGURATION, - VppIidFactory.getInterfaceIID(new InterfaceKey(name))); - } catch (IllegalStateException ex) { - LOG.debug("Vhost Interface is not present in DS", ex); - } - - } - - @Override - public String toString() { - return "VhostUserCommand [socket=" + socket + ", role=" + role + ", bridgeDomain=" + bridgeDomain - + ", operation=" + operation + ", name=" + name + ", description=" + description + ", enabled=" - + enabled + "]"; - } - - - - public static class VhostUserCommandBuilder { - - private String name; - private General.Operations operation; - private String socket; - private VhostUserRole role = VhostUserRole.Server; - private boolean enabled = true; - private String description; - private String bridgeDomain; - - public String getName() { - return name; - } - - public VhostUserCommandBuilder setName(String name) { - this.name = name; - return this; - } - - public General.Operations getOperation() { - return operation; - } - - public VhostUserCommandBuilder setOperation(General.Operations operation) { - this.operation = operation; - return this; - } - - public String getSocket() { - return socket; - } - - public VhostUserCommandBuilder setSocket(String socket) { - this.socket = socket; - return this; - } - - public VhostUserRole getRole() { - return role; - } - - public VhostUserCommandBuilder setRole(VhostUserRole role) { - this.role = role; - return this; - } - - public boolean isEnabled() { - return enabled; - } - - public VhostUserCommandBuilder setEnabled(boolean enabled) { - this.enabled = enabled; - return this; - } - - public String getDescription() { - return description; - } - - public VhostUserCommandBuilder setDescription(String description) { - this.description = description; - return this; - } - - public String getBridgeDomain() { - return bridgeDomain; - } - - public VhostUserCommandBuilder setBridgeDomain(String bridgeDomain) { - this.bridgeDomain = bridgeDomain; - return this; - } - - /** - * VhostUserCommand build method. - * - * @return VhostUserCommand - * @throws IllegalArgumentException if name, operation or socket is null. - */ - public VhostUserCommand build() { - Preconditions.checkArgument(this.name != null); - Preconditions.checkArgument(this.operation != null); - if (operation == Operations.PUT) { - Preconditions.checkArgument(this.socket != null); - } - - return new VhostUserCommand(this); - } - } -} +/* + * Copyright (c) 2016 Cisco Systems. 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.commands; + +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General.Operations; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUserRole; +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.VppInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.VhostUserBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder; + +import com.google.common.base.Preconditions; +import com.google.common.base.Strings; + +public class VhostUserCommand extends AbstractInterfaceCommand { + + private String socket; + private VhostUserRole role; + private String bridgeDomain; + + private VhostUserCommand(VhostUserCommandBuilder builder) { + this.name = builder.getName(); + this.operation = builder.getOperation(); + this.socket = builder.getSocket(); + this.role = builder.getRole(); + this.enabled = builder.isEnabled(); + this.description = builder.getDescription(); + this.bridgeDomain = builder.getBridgeDomain(); + + } + + public static VhostUserCommandBuilder builder() { + return new VhostUserCommandBuilder(); + } + + public String getSocket() { + return socket; + } + + public VhostUserRole getRole() { + return role; + } + + public String getBridgeDomain() { + return bridgeDomain; + } + + @Override + public InterfaceBuilder getInterfaceBuilder() { + InterfaceBuilder interfaceBuilder = + new InterfaceBuilder().setKey(new InterfaceKey(name)) + .setEnabled(enabled) + .setDescription(description) + .setType( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUser.class) + .setName(name) + .setLinkUpDownTrapEnable(Interface.LinkUpDownTrapEnable.Enabled); + + // Create the vhost augmentation + VppInterfaceAugmentationBuilder vppAugmentationBuilder = new VppInterfaceAugmentationBuilder() + .setVhostUser(new VhostUserBuilder().setRole(role).setSocket(socket).build()); + if (!Strings.isNullOrEmpty(bridgeDomain)) { + vppAugmentationBuilder.setL2(new L2Builder() + .setInterconnection(new BridgeBasedBuilder().setBridgeDomain(bridgeDomain).build()).build()); + } + + interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppAugmentationBuilder.build()); + return interfaceBuilder; + } + + @Override + public String toString() { + return "VhostUserCommand [socket=" + socket + ", role=" + role + ", bridgeDomain=" + bridgeDomain + + ", operation=" + operation + ", name=" + name + ", description=" + description + ", enabled=" + + enabled + "]"; + } + + public static class VhostUserCommandBuilder { + + private String name; + private General.Operations operation; + private String socket; + private VhostUserRole role = VhostUserRole.Server; + private boolean enabled = true; + private String description; + private String bridgeDomain; + + public String getName() { + return name; + } + + public VhostUserCommandBuilder setName(String name) { + this.name = name; + return this; + } + + public General.Operations getOperation() { + return operation; + } + + public VhostUserCommandBuilder setOperation(General.Operations operation) { + this.operation = operation; + return this; + } + + public String getSocket() { + return socket; + } + + public VhostUserCommandBuilder setSocket(String socket) { + this.socket = socket; + return this; + } + + public VhostUserRole getRole() { + return role; + } + + public VhostUserCommandBuilder setRole(VhostUserRole role) { + this.role = role; + return this; + } + + public boolean isEnabled() { + return enabled; + } + + public VhostUserCommandBuilder setEnabled(boolean enabled) { + this.enabled = enabled; + return this; + } + + public String getDescription() { + return description; + } + + public VhostUserCommandBuilder setDescription(String description) { + this.description = description; + return this; + } + + public String getBridgeDomain() { + return bridgeDomain; + } + + public VhostUserCommandBuilder setBridgeDomain(String bridgeDomain) { + this.bridgeDomain = bridgeDomain; + return this; + } + + /** + * VhostUserCommand build method. + * + * @return VhostUserCommand + * @throws IllegalArgumentException if name, operation or socket is null. + */ + public VhostUserCommand build() { + Preconditions.checkArgument(this.name != null); + Preconditions.checkArgument(this.operation != null); + if (operation == Operations.PUT) { + Preconditions.checkArgument(this.socket != null); + } + + return new VhostUserCommand(this); + } + } +} diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java index 5340f9298..12feb3776 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java @@ -19,6 +19,7 @@ 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.renderer.vpp.commands.ConfigCommand; +import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.TapPortCommand; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.VhostUserCommand; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.VhostUserCommand.VhostUserCommandBuilder; import org.opendaylight.groupbasedpolicy.renderer.vpp.event.NodeOperEvent; @@ -33,6 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo 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.vpp_renderer.rev160425.config.VppEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint.InterfaceTypeChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.TapCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.vpp.endpoint._interface.type.choice.VhostUserCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VhostUserRole; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppInterfaceAugmentation; @@ -61,7 +63,8 @@ public class InterfaceManager implements AutoCloseable { private final VppEndpointLocationProvider vppEndpointLocationProvider; private final ExecutorService netconfWorker; - public InterfaceManager(@Nonnull MountedDataBrokerProvider mountDataProvider, @Nonnull DataBroker dataProvider, @Nonnull ExecutorService netconfWorker) { + public InterfaceManager(@Nonnull MountedDataBrokerProvider mountDataProvider, @Nonnull DataBroker dataProvider, + @Nonnull ExecutorService netconfWorker) { this.mountDataProvider = Preconditions.checkNotNull(mountDataProvider); this.netconfWorker = Preconditions.checkNotNull(netconfWorker); this.vppEndpointLocationProvider = new VppEndpointLocationProvider(dataProvider); @@ -83,14 +86,21 @@ public class InterfaceManager implements AutoCloseable { break; } } catch (InterruptedException | ExecutionException e) { - LOG.error("Failed to update Vpp Endpoint. {}", e); - e.printStackTrace(); + LOG.error("Failed to update Vpp Endpoint. {}", event, e); } } private ListenableFuture vppEndpointCreated(VppEndpoint vppEndpoint) { - Optional potentialIfaceCommand = createInterfaceWithoutBdCommand(vppEndpoint, Operations.PUT); + InterfaceTypeChoice interfaceTypeChoice = vppEndpoint.getInterfaceTypeChoice(); + Optional potentialIfaceCommand = Optional.absent(); + if (interfaceTypeChoice instanceof VhostUserCase) { + potentialIfaceCommand = createInterfaceWithoutBdCommand(vppEndpoint, Operations.PUT); + } else if (interfaceTypeChoice instanceof TapCase) { + potentialIfaceCommand = createTapInterfaceWithoutBdCommand(vppEndpoint, Operations.PUT); + } + if (!potentialIfaceCommand.isPresent()) { + LOG.debug("Interface/PUT command was not created for VppEndpoint point {}", vppEndpoint); return Futures.immediateFuture(null); } ConfigCommand ifaceWithoutBdCommand = potentialIfaceCommand.get(); @@ -98,7 +108,7 @@ public class InterfaceManager implements AutoCloseable { Optional potentialVppDataProvider = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid); if (!potentialVppDataProvider.isPresent()) { LOG.debug("Cannot get data broker for mount point {}", vppNodeIid); - Futures.immediateFuture(null); + return Futures.immediateFuture(null); } DataBroker vppDataBroker = potentialVppDataProvider.get(); return createIfaceOnVpp(ifaceWithoutBdCommand, vppDataBroker, vppEndpoint, vppNodeIid); @@ -119,9 +129,17 @@ public class InterfaceManager implements AutoCloseable { }, netconfWorker); } - private ListenableFuture vppEndpointDeleted(VppEndpoint vppEndpoint) { - Optional potentialIfaceCommand = createInterfaceWithoutBdCommand(vppEndpoint, Operations.DELETE); + private ListenableFuture vppEndpointDeleted(@Nonnull VppEndpoint vppEndpoint) { + InterfaceTypeChoice interfaceTypeChoice = vppEndpoint.getInterfaceTypeChoice(); + Optional potentialIfaceCommand = Optional.absent(); + if (interfaceTypeChoice instanceof VhostUserCase) { + potentialIfaceCommand = createInterfaceWithoutBdCommand(vppEndpoint, Operations.DELETE); + } else if (interfaceTypeChoice instanceof TapCase) { + potentialIfaceCommand = createTapInterfaceWithoutBdCommand(vppEndpoint, Operations.DELETE); + } + if (!potentialIfaceCommand.isPresent()) { + LOG.debug("Interface/DELETE command was not created for VppEndpoint point {}", vppEndpoint); return Futures.immediateFuture(null); } ConfigCommand ifaceWithoutBdCommand = potentialIfaceCommand.get(); @@ -166,7 +184,7 @@ public class InterfaceManager implements AutoCloseable { break; case DELETED: if (event.isBeforeConnected()) { - // TODO we could do snapshot of VppEndpoints + // TODO we could do snapshot of VppEndpoints // which can be used for reconciliation } break; @@ -197,6 +215,32 @@ public class InterfaceManager implements AutoCloseable { return Optional.of(vhostUserCommand); } + private static Optional createTapInterfaceWithoutBdCommand(@Nonnull VppEndpoint vppEp, + @Nonnull Operations operation) { + if (!hasNodeAndInterface(vppEp)) { + LOG.debug("Interface command is not created for {}", vppEp); + return Optional.absent(); + } + TapPortCommand.TapPortCommandBuilder builder = TapPortCommand.builder(); + InterfaceTypeChoice interfaceTypeChoice = vppEp.getInterfaceTypeChoice(); + if (interfaceTypeChoice instanceof TapCase) { + TapCase tapIface = (TapCase) interfaceTypeChoice; + String name = tapIface.getName(); + if (Strings.isNullOrEmpty(name)) { + LOG.debug("Tap interface command is not created because name is missing. {}", vppEp); + return Optional.absent(); + } + builder.setTapName(name); + builder.setPhysAddress(tapIface.getPhysicalAddress()); + } + TapPortCommand tapPortCommand = builder + .setOperation(operation) + .setDescription(vppEp.getDescription()) + .setInterfaceName(vppEp.getVppInterfaceName()) + .build(); + return Optional.of(tapPortCommand); + } + /** * Adds bridge domain to an interface if the interface exist.
* It rewrites bridge domain in case it already exist.
@@ -205,7 +249,7 @@ public class InterfaceManager implements AutoCloseable { * If the interface does not exist or other problems occur {@link ListenableFuture} will fail * as {@link Futures#immediateFailedFuture(Throwable)} with {@link Exception} * containing message in {@link Exception#getMessage()} - * + * * @param bridgeDomainName bridge domain * @param addrEpWithLoc {@link AddressEndpointWithLocation} containing * {@link ExternalLocationCase} where @@ -282,7 +326,6 @@ public class InterfaceManager implements AutoCloseable { } /** - *

* Removes bridge domain (if exist) from an interface (if exist).
* {@link VppEndpointLocationProvider#VPP_ENDPOINT_LOCATION_PROVIDER} will update endpoint * location. @@ -290,7 +333,7 @@ public class InterfaceManager implements AutoCloseable { * If the interface does not exist or other problems occur {@link ListenableFuture} will fail * as {@link Futures#immediateFailedFuture(Throwable)} with {@link Exception} * containing message in {@link Exception#getMessage()} - * + * * @param addrEpWithLoc {@link AddressEndpointWithLocation} containing * {@link ExternalLocationCase} where * {@link ExternalLocationCase#getExternalNodeMountPoint()} MUST NOT be {@code null} diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/TapPortCommandTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/TapPortCommandTest.java new file mode 100644 index 000000000..1e4bdcd20 --- /dev/null +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/commands/TapPortCommandTest.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2016 Cisco Systems. 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.commands; + +import com.google.common.base.Optional; +import org.junit.Assert; +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.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.groupbasedpolicy.renderer.vpp.VppRendererDataBrokerTest; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; +import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Tap; +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.VppInterfaceAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.L2Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.TapBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.l2.base.attributes.interconnection.BridgeBasedBuilder; + +import java.util.concurrent.ExecutionException; + +public class TapPortCommandTest extends VppRendererDataBrokerTest { + + private final static String DESCRIPTION = "used for testing"; + private final static String INTERFACE_NAME = "testInterface"; + private final static String TAP_NAME = "testTap00:11:22:33:44:55"; + private final static String BRIDGE_DOMAIN = "testBD"; + private final static Long DEVICE_ID = 0L; + private final static PhysAddress MAC_ADDRESS = new PhysAddress("00:11:22:33:44:55"); + + private final static String UPD_DESCRIPTION = "updated description"; + private final static PhysAddress UPD_MAC_ADDRESS = new PhysAddress("55:44:33:22:11:00"); + private final static String UPD_TAP_NAME = "testTapUpd"; + private final static Long UPD_DEVICE_ID = 1L; + + private final static VppInterfaceAugmentationBuilder vppAugmentationBuilder = new VppInterfaceAugmentationBuilder() + .setTap(new TapBuilder().setMac(MAC_ADDRESS).setTapName(TAP_NAME).setDeviceInstance(DEVICE_ID).build()); + + private final static VppInterfaceAugmentationBuilder vppAugmentationBuilderWithBD = + new VppInterfaceAugmentationBuilder(vppAugmentationBuilder.build()) + .setL2(new L2Builder().setInterconnection(new BridgeBasedBuilder().setBridgeDomain(BRIDGE_DOMAIN) + .setBridgedVirtualInterface(false) + .build()).build()); + + private final static InterfaceBuilder interfaceBuilder = + new InterfaceBuilder().setKey(new InterfaceKey(INTERFACE_NAME)) + .setEnabled(true) + .setDescription(DESCRIPTION) + .setType(Tap.class) + .setName(INTERFACE_NAME) + .setLinkUpDownTrapEnable(Interface.LinkUpDownTrapEnable.Enabled); + + private final static Interface BASIC_INTERFACE = + interfaceBuilder.addAugmentation(VppInterfaceAugmentation.class, vppAugmentationBuilder.build()).build(); + private final static Interface BASIC_INTERFACE_WITH_BD = interfaceBuilder + .addAugmentation(VppInterfaceAugmentation.class, vppAugmentationBuilderWithBD.build()).build(); + + private DataBroker dataBroker; + + @Before + public void init() { + dataBroker = getDataBroker(); + } + + @Test + public void testAddTapPort() throws ExecutionException, InterruptedException { + ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); + TapPortCommand addCommand = TapPortCommand.builder() + .setOperation(General.Operations.PUT) + .setInterfaceName(INTERFACE_NAME) + .setTapName(TAP_NAME) + .setDescription(DESCRIPTION) + .setDeviceInstance(DEVICE_ID) + .setPhysAddress(MAC_ADDRESS) + .setEnabled(true) + .build(); + + Optional optional = executeCommand(rwTx, addCommand); + + Assert.assertTrue(optional.isPresent()); + Assert.assertEquals(BASIC_INTERFACE, optional.get()); + + } + + @Test + public void testAddTapPort_WithBridgeDomain() throws ExecutionException, InterruptedException { + ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); + TapPortCommand addCommand = TapPortCommand.builder() + .setOperation(General.Operations.PUT) + .setInterfaceName(INTERFACE_NAME) + .setTapName(TAP_NAME) + .setDescription(DESCRIPTION) + .setDeviceInstance(DEVICE_ID) + .setPhysAddress(MAC_ADDRESS) + .setBridgeDomain(BRIDGE_DOMAIN) + .setEnabled(true) + .build(); + + Optional optional = executeCommand(rwTx, addCommand); + + Assert.assertTrue(optional.isPresent()); + Assert.assertEquals(BASIC_INTERFACE_WITH_BD, optional.get()); + + } + + private Optional executeCommand(ReadWriteTransaction rwTx, TapPortCommand addCommand) + throws ExecutionException, InterruptedException { + addCommand.execute(rwTx); + + rwTx.submit().get(); + + ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction(); + + return DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getInterfaceIID(new InterfaceKey(INTERFACE_NAME)), rTx); + } + + @Test + public void testDeleteTapPort() throws ExecutionException, InterruptedException { + ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); + + rwTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getInterfaceIID(BASIC_INTERFACE.getKey()), + BASIC_INTERFACE, true); + rwTx.submit().get(); + + Optional optional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getInterfaceIID(BASIC_INTERFACE.getKey()), dataBroker.newReadOnlyTransaction()); + + Assert.assertTrue(optional.isPresent()); + + TapPortCommand deleteCommand = TapPortCommand.builder() + .setOperation(General.Operations.DELETE) + .setInterfaceName(INTERFACE_NAME) + .setTapName(TAP_NAME) + .build(); + + ReadWriteTransaction rwTxDel = dataBroker.newReadWriteTransaction(); + deleteCommand.execute(rwTxDel); + rwTxDel.submit(); + + Optional optionalDeleted = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getInterfaceIID(new InterfaceKey(deleteCommand.getName())), + dataBroker.newReadOnlyTransaction()); + + Assert.assertFalse(optionalDeleted.isPresent()); + } + + @Test + public void testUpdateTapPort() throws ExecutionException, InterruptedException { + ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); + + rwTx.put(LogicalDatastoreType.CONFIGURATION, VppIidFactory.getInterfaceIID(BASIC_INTERFACE.getKey()), + BASIC_INTERFACE, true); + rwTx.submit().get(); + + Optional optional = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getInterfaceIID(BASIC_INTERFACE.getKey()), dataBroker.newReadOnlyTransaction()); + + Assert.assertTrue(optional.isPresent()); + + TapPortCommand updateCommand = TapPortCommand.builder() + .setOperation(General.Operations.MERGE) + .setInterfaceName(INTERFACE_NAME) + .setTapName(UPD_TAP_NAME) + .setDescription(UPD_DESCRIPTION) + .setPhysAddress(UPD_MAC_ADDRESS) + .setDeviceInstance(UPD_DEVICE_ID) + .setEnabled(false) + .build(); + + ReadWriteTransaction rwTxUpd = dataBroker.newReadWriteTransaction(); + updateCommand.execute(rwTxUpd); + rwTxUpd.submit().get(); + + Optional optionalUpdated = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION, + VppIidFactory.getInterfaceIID(new InterfaceKey(updateCommand.getName())), + dataBroker.newReadOnlyTransaction()); + + Assert.assertTrue(optionalUpdated.isPresent()); + Interface updatedInterface = optionalUpdated.get(); + + Assert.assertEquals(UPD_DESCRIPTION, updatedInterface.getDescription()); + Assert.assertFalse(updatedInterface.isEnabled()); + VppInterfaceAugmentation augmentation = updatedInterface.getAugmentation(VppInterfaceAugmentation.class); + Assert.assertEquals(INTERFACE_NAME, updatedInterface.getName()); + Assert.assertEquals(UPD_DEVICE_ID, augmentation.getTap().getDeviceInstance()); + Assert.assertEquals(UPD_MAC_ADDRESS, augmentation.getTap().getMac()); + Assert.assertEquals(UPD_TAP_NAME, augmentation.getTap().getTapName()); + + } +}