diff options
author | Maros Marsalek <mmarsale@cisco.com> | 2016-04-12 10:13:37 +0200 |
---|---|---|
committer | Maros Marsalek <mmarsale@cisco.com> | 2016-04-12 10:13:37 +0200 |
commit | 28208ac2b1b9e068c51eee79cf1bfedc6a818195 (patch) | |
tree | 4bb01d13f3a070ddb7b6b4bd22393a61a527dad8 /v3po/v3po2vpp/src/main | |
parent | 1c690387dcfe8730ca9c0d4fc5ea732b172ae249 (diff) |
HONEYCOMB-9: Migrate Interface listener
Change-Id: Iffde1ee21b749a8c8efa96c243f7f8bb0811b4c7
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'v3po/v3po2vpp/src/main')
18 files changed, 1292 insertions, 141 deletions
diff --git a/v3po/v3po2vpp/src/main/config/default-config.xml b/v3po/v3po2vpp/src/main/config/default-config.xml index 1a1e6a8f5..89c3c47a2 100644 --- a/v3po/v3po2vpp/src/main/config/default-config.xml +++ b/v3po/v3po2vpp/src/main/config/default-config.xml @@ -53,6 +53,15 @@ </module> <module> + <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:v3po2vpp">prefix:interfaces-honeycomb-writer</type> + <name>interfaces-honeycomb-writer</name> + <vpp-japi-ifc> + <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:vpp:japi:cfg">prefix:vpp-japi</type> + <name>vpp-japi</name> + </vpp-japi-ifc> + </module> + + <module> <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:delegating-reader-registry</type> <name>read-registry</name> <root-readers> @@ -64,6 +73,7 @@ <name>interfaces-state-honeycomb-reader</name> </root-readers> </module> + <module> <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:utils">prefix:delegating-writer-registry</type> <name>write-registry</name> @@ -71,8 +81,13 @@ <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer</type> <name>vpp-honeycomb-writer</name> </root-writers> + <root-writers> + <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-writer</type> + <name>interfaces-honeycomb-writer</name> + </root-writers> </module> </modules> + <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config"> <service> <type xmlns:prefix="urn:honeycomb:params:xml:ns:yang:translate:api">prefix:honeycomb-reader</type> @@ -93,6 +108,11 @@ <provider>/modules/module[type='vpp-honeycomb-writer'][name='vpp-honeycomb-writer'] </provider> </instance> + <instance> + <name>interfaces-honeycomb-writer</name> + <provider>/modules/module[type='interfaces-honeycomb-writer'][name='interfaces-honeycomb-writer'] + </provider> + </instance> </service> </services> </data> diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java new file mode 100644 index 000000000..69ff63137 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/EthernetCustomizer.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import javax.annotation.Nonnull; +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.interfaces._interface.Ethernet; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class EthernetCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Ethernet> { + + private static final Logger LOG = LoggerFactory.getLogger(EthernetCustomizer.class); + + public EthernetCustomizer(final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Nonnull + @Override + public Optional<Ethernet> extract(@Nonnull final InstanceIdentifier<Ethernet> currentId, + @Nonnull final DataObject parentData) { + return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getEthernet()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ethernet> id, + @Nonnull final Ethernet dataAfter, @Nonnull final Context writeContext) { + // TODO + LOG.warn("Unsupported, ignoring configuration {}", dataAfter); + + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Ethernet> id, + @Nonnull final Ethernet dataBefore, @Nonnull final Ethernet dataAfter, + @Nonnull final Context writeContext) { + // TODO + LOG.warn("Unsupported, ignoring configuration {}", dataAfter); + + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Ethernet> id, + @Nonnull final Ethernet dataBefore, @Nonnull final Context writeContext) { + // TODO + LOG.warn("Unsupported, ignoring configuration delete {}", id); + + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java new file mode 100644 index 000000000..6b91e2e0a --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/InterfaceCustomizer.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces; + +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +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.InterfaceKey; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.openvpp.vppjapi.vppApi; + +/** + * Ietf interface write customizer that only caches interface objects for child writers + */ +public class InterfaceCustomizer extends VppApiCustomizer implements ListWriterCustomizer<Interface, InterfaceKey> { + + public static final String IFC_AFTER_CTX = InterfaceCustomizer.class.toString() + "ifcAfter"; + public static final String IFC_BEFORE_CTX = InterfaceCustomizer.class.toString() + "ifcBefore"; + + public InterfaceCustomizer(final vppApi vppApi) { + super(vppApi); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id, + @Nonnull final Interface dataAfter, + @Nonnull final Context writeContext) { + writeContext.put(IFC_AFTER_CTX, dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id, + @Nonnull final Interface dataBefore, + @Nonnull final Interface dataAfter, + @Nonnull final Context writeContext) { + writeContext.put(IFC_BEFORE_CTX, dataBefore); + writeContext.put(IFC_AFTER_CTX, dataAfter); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id, + @Nonnull final Interface dataBefore, + @Nonnull final Context writeContext) { + writeContext.put(IFC_BEFORE_CTX, dataBefore); + } + + @Nonnull + @Override + public List<Interface> extract(@Nonnull final InstanceIdentifier<Interface> currentId, + @Nonnull final DataObject parentData) { + return ((Interfaces) parentData).getInterface(); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java new file mode 100644 index 000000000..e596f8fbf --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/L2Customizer.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; +import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils; +import io.fd.honeycomb.v3po.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +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.interfaces._interface.L2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.Interconnection; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.interconnection.BridgeBased; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.l2.interconnection.XconnectBased; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class L2Customizer extends VppApiCustomizer implements ChildWriterCustomizer<L2> { + + private static final Logger LOG = LoggerFactory.getLogger(L2Customizer.class); + + public L2Customizer(final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Nonnull + @Override + public Optional<L2> extract(@Nonnull final InstanceIdentifier<L2> currentId, @Nonnull final DataObject parentData) { + return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getL2()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataAfter, + @Nonnull final Context writeContext) + throws WriteFailedException { + final Interface ifc = (Interface) writeContext.get(InterfaceCustomizer.IFC_AFTER_CTX); + + final int swIfc = getSwIfc(ifc); + try { + setL2(id, swIfc, ifc, dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Write of L2 failed", e); + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore, + @Nonnull final L2 dataAfter, @Nonnull final Context writeContext) + throws WriteFailedException { + final Interface ifcBefore = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + final Interface ifcAfter = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + + final int swIfc = getSwIfc(ifcBefore); + // TODO handle update properly (if possible) + try { + setL2(id, swIfc, ifcAfter, dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Update of L2 failed", e); + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); + } + } + + private int getSwIfc(final Interface ifcBefore) { + int swIfcIndex = getVppApi().swIfIndexFromName(ifcBefore.getName()); + checkArgument(swIfcIndex != -1, "Interface %s does not exist", ifcBefore.getName()); + return swIfcIndex; + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<L2> id, @Nonnull final L2 dataBefore, + @Nonnull final Context writeContext) { + final Interface ifcBefore = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + + final int swIfc = getSwIfc(ifcBefore); + // TODO implement delete (if possible) + } + + private void setL2(final InstanceIdentifier<L2> id, final int swIfIndex, final Interface ifc, final L2 vppL2) + throws VppApiInvocationException, WriteFailedException { + LOG.debug("Setting L2 for interface: %s", ifc.getName()); + // Nothing besides interconnection here + setInterconnection(id, swIfIndex, ifc, vppL2); + } + + private void setInterconnection(final InstanceIdentifier<L2> id, final int swIfIndex, final Interface ifc, + final L2 vppL2) + throws VppApiInvocationException, WriteFailedException { + Interconnection ic = vppL2.getInterconnection(); + if (ic instanceof XconnectBased) { + setXconnectBasedL2(swIfIndex, ifc, (XconnectBased) ic); + } else if (ic instanceof BridgeBased) { + setBridgeBasedL2(swIfIndex, ifc, (BridgeBased) ic); + } else { + // FIXME how does choice extensibility work + // FIXME it is not even possible to create a dedicated customizer for Interconnection, since it's not a DataObject + // FIXME we might need a choice customizer + // THis choice is already from augment, so its probably not possible to augment augmented choice + LOG.error("Unable to handle Interconnection of type {}", ic.getClass()); + throw new WriteFailedException(id, "Unable to handle Interconnection of type " + ic.getClass()); + } + } + + private void setBridgeBasedL2(final int swIfIndex, final Interface ifc, final BridgeBased bb) + throws VppApiInvocationException { + + LOG.debug("Setting bridge based interconnection(bridge-domain=%s) for interface: %s", + bb.getBridgeDomain(), ifc.getName()); + + String bdName = bb.getBridgeDomain(); + int bdId = getVppApi().bridgeDomainIdFromName(bdName); + checkArgument(bdId > 0, "Unable to set Interconnection for Interface: %s, bridge domain: %s does not exist", + ifc.getName(), bdName); + + byte bvi = bb.isBridgedVirtualInterface() + ? (byte) 1 + : (byte) 0; + byte shg = bb.getSplitHorizonGroup().byteValue(); + + final int ctxId = getVppApi().swInterfaceSetL2Bridge(swIfIndex, bdId, shg, bvi, (byte) 1 /* enable */); + final int rv = V3poUtils.waitForResponse(ctxId, getVppApi()); + + if (rv < 0) { + LOG.warn("Failed to update bridge based interconnection flags for: {}, interconnection: {}", ifc.getName(), + bb); + throw new VppApiInvocationException("swInterfaceSetL2Bridge", ctxId, rv); + } else { + LOG.debug("Bridge based interconnection updated successfully for: {}, interconnection: {}", ifc.getName(), + bb); + } + } + + private void setXconnectBasedL2(final int swIfIndex, final Interface ifc, final XconnectBased ic) + throws VppApiInvocationException { + + String outSwIfName = ic.getXconnectOutgoingInterface(); + LOG.debug("Setting xconnect based interconnection(outgoing ifc=%s) for interface: %s", outSwIfName, + ifc.getName()); + + int outSwIfIndex = getVppApi().swIfIndexFromName(outSwIfName); + checkArgument(outSwIfIndex > 0, + "Unable to set Interconnection for Interface: %s, outgoing interface: %s does not exist", + ifc.getName(), outSwIfIndex); + + int ctxId = getVppApi().swInterfaceSetL2Xconnect(swIfIndex, outSwIfIndex, (byte) 1 /* enable */); + final int rv = V3poUtils.waitForResponse(ctxId, getVppApi()); + + if (rv < 0) { + LOG.warn("Failed to update xconnect based interconnection flags for: {}, interconnection: {}", + ifc.getName(), ic); + throw new VppApiInvocationException("swInterfaceSetL2Xconnect", ctxId, rv); + } else { + LOG.debug("Xconnect based interconnection updated successfully for: {}, interconnection: {}", ifc.getName(), + ic); + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java new file mode 100644 index 000000000..8d930d80c --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/RoutingCustomizer.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; +import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils; +import io.fd.honeycomb.v3po.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +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.interfaces._interface.Routing; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RoutingCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Routing> { + + private static final Logger LOG = LoggerFactory.getLogger(RoutingCustomizer.class); + + public RoutingCustomizer(final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Nonnull + @Override + public Optional<Routing> extract(@Nonnull final InstanceIdentifier<Routing> currentId, + @Nonnull final DataObject parentData) { + return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getRouting()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id, + @Nonnull final Routing dataAfter, @Nonnull final Context writeContext) + throws WriteFailedException.CreateFailedException { + final Interface ifc = (Interface) writeContext.get(InterfaceCustomizer.IFC_AFTER_CTX); + + try { + setRouting(ifc.getName(), dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Update of Routing failed", e); + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id, + @Nonnull final Routing dataBefore, @Nonnull final Routing dataAfter, + @Nonnull final Context writeContext) + throws WriteFailedException.UpdateFailedException { + final Interface ifcBefore = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + final Interface ifcAfter = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + + try { + // TODO handle updates properly + setRouting(ifcAfter.getName(), dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Update of Routing failed", e); + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Routing> id, + @Nonnull final Routing dataBefore, @Nonnull final Context writeContext) { + // TODO implement delete + } + + private void setRouting(final String name, final Routing rt) throws VppApiInvocationException { + final int swIfc = getSwIfc(name); + LOG.debug("Setting routing for interface: {}, {}. Routing: {}", name, swIfc, rt); + + int vrfId = (rt != null) + ? rt.getVrfId().intValue() + : 0; + + if (vrfId != 0) { + final int ctxId = getVppApi().swInterfaceSetTable(swIfc, (byte) 0, /* isIpv6 */ vrfId); + final int rv = V3poUtils.waitForResponse(ctxId, getVppApi()); + if (rv < 0) { + LOG.debug("Failed to set routing for interface: {}, {}, vxlan: {}", name, swIfc, rt); + throw new VppApiInvocationException("swInterfaceSetTable", ctxId, rv); + } else { + LOG.debug("Routing set successfully for interface: {}, {}, routing: {}", name, swIfc, rt); + } + } + } + + private int getSwIfc(final String name) { + int swIfcIndex = getVppApi().swIfIndexFromName(name); + checkArgument(swIfcIndex != -1, "Interface %s does not exist", name); + return swIfcIndex; + } + +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VppInterfaceCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VppInterfaceCustomizer.java new file mode 100644 index 000000000..3ea3f9743 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VppInterfaceCustomizer.java @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; +import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils; +import io.fd.honeycomb.v3po.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +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.VxlanTunnel; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VppInterfaceCustomizer extends VppApiCustomizer + implements ChildWriterCustomizer<VppInterfaceAugmentation> { + + private static final Logger LOG = LoggerFactory.getLogger(VppInterfaceCustomizer.class); + + public VppInterfaceCustomizer(final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Nonnull + @Override + public Optional<VppInterfaceAugmentation> extract( + @Nonnull final InstanceIdentifier<VppInterfaceAugmentation> currentId, + @Nonnull final DataObject parentData) { + return Optional.fromNullable(((Interface) parentData).getAugmentation(VppInterfaceAugmentation.class)); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<VppInterfaceAugmentation> id, + @Nonnull final VppInterfaceAugmentation dataAfter, + @Nonnull final Context writeContext) + throws WriteFailedException { + final Interface ifc = (Interface) writeContext.get(InterfaceCustomizer.IFC_AFTER_CTX); + try { + setInterface(id, ifc, dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Update of VppInterfaceAugment failed", e); + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<VppInterfaceAugmentation> id, + @Nonnull final VppInterfaceAugmentation dataBefore, + @Nonnull final VppInterfaceAugmentation dataAfter, + @Nonnull final Context writeContext) + throws WriteFailedException.UpdateFailedException { + final Interface ifcBefore = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + final Interface ifc = (Interface) writeContext.get(InterfaceCustomizer.IFC_AFTER_CTX); + try { + updateInterface(id, ifc, dataBefore, dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Update of VppInterfaceAugment failed", e); + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<VppInterfaceAugmentation> id, + @Nonnull final VppInterfaceAugmentation dataBefore, + @Nonnull final Context writeContext) { + final Interface ifcBefore = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + + LOG.info("Deleting interface: {}, type: {}", ifcBefore.getName(), ifcBefore.getType().getSimpleName()); + + if (ifcBefore.getType().isAssignableFrom(EthernetCsmacd.class)) { + LOG.error("Interface {}, type: {} cannot be deleted", + ifcBefore.getName(), ifcBefore.getType().getSimpleName()); + + /* FIXME: Add additional interface types here. + * + * } else if (swIf.getType().isAssignableFrom(*.class)) { + */ + + } + } + + + private void updateInterface(final InstanceIdentifier<VppInterfaceAugmentation> id, final Interface swIf, + final VppInterfaceAugmentation dataBefore, + final VppInterfaceAugmentation dataAfter) throws VppApiInvocationException { + LOG.info("Updating interface {}, type: {}", swIf.getName(), swIf.getType().getSimpleName()); + LOG.debug("Updating interface {}", swIf); + + Class<? extends InterfaceType> ifType = checkNotNull(swIf.getType(), "Interface type missing for %s", swIf); + String swIfName = swIf.getName(); + int swIfIndex = getVppApi().swIfIndexFromName(swIfName); + checkArgument(swIfIndex != -1, "Updating non-existing vpp interface: %s", swIfName); + + // TODO handle updates properly + + if (VxlanTunnel.class.isAssignableFrom(ifType)) { + updateVxlanTunnelInterface(swIf); + } else if (EthernetCsmacd.class.isAssignableFrom(ifType)) { + updateEthernetCsmacdInterface(swIf, swIfName, swIfIndex); + } + } + + + private void setInterface(final InstanceIdentifier<VppInterfaceAugmentation> id, final Interface swIf, + final VppInterfaceAugmentation dataAfter) + throws VppApiInvocationException, WriteFailedException { + LOG.info("Setting interface {}, type: {}", swIf.getName(), swIf.getType().getSimpleName()); + LOG.debug("Setting interface {}", swIf); + + Class<? extends InterfaceType> ifType = checkNotNull(swIf.getType(), "Interface type missing for %s", swIf); + String swIfName = swIf.getName(); + int swIfIndex = getVppApi().swIfIndexFromName(swIfName); + checkArgument(swIfIndex == -1, "Creating already-existing vpp interface: %s", swIfName); + + if (VxlanTunnel.class.isAssignableFrom(ifType)) { + createVxlanTunnelInterface(swIf, swIfName); + } else if (EthernetCsmacd.class.isAssignableFrom(ifType)) { + createEthernetCsmacdInterface(id, swIfName, dataAfter); + } + } + + private void createVxlanTunnelInterface(final Interface swIf, final String swIfName) + throws VppApiInvocationException { + LOG.debug("Creating {} interface {}", swIf.getType().getSimpleName(), swIf.getName()); + + // FIXME, Vxlan child writer needs to be handled before this is + int newSwIfIndex = getVppApi().swIfIndexFromName(swIfName); + + setInterfaceFlags(swIfName, newSwIfIndex, swIf.isEnabled() + ? (byte) 1 + : (byte) 0); + setDescription(swIf); + } + + private void updateVxlanTunnelInterface(final Interface swIf) { + LOG.debug("Updating {} interface {}", swIf.getType().getSimpleName(), swIf.getName()); + + // TODO handle + } + + private void createEthernetCsmacdInterface(final InstanceIdentifier<VppInterfaceAugmentation> id, + final String swIfName, final VppInterfaceAugmentation dataAfter) throws WriteFailedException { + LOG.warn("Unable to create interface: {}, type: {}", swIfName, EthernetCsmacd.class); + throw new WriteFailedException.CreateFailedException(id, dataAfter); + } + + private void updateEthernetCsmacdInterface(final Interface swIf, + final String swIfName, final int swIfIndex) + throws VppApiInvocationException { + LOG.debug("Updating {} interface {}", swIf.getType().getSimpleName(), swIf.getName()); + byte enabled = swIf.isEnabled() + ? (byte) 1 + : (byte) 0; + setInterfaceFlags(swIfName, swIfIndex, enabled); + setDescription(swIf); + } + + private void setInterfaceFlags(final String swIfName, final int swIfIndex, final byte enabled) + throws VppApiInvocationException { + int ctxId = getVppApi().swInterfaceSetFlags(swIfIndex, enabled, enabled, (byte) 0 /* deleted */); + + LOG.debug("Updating interface flags for: {}, index: {}, enabled: {}, ctxId: {}", swIfName, swIfIndex, + enabled, ctxId); + + final int rv = V3poUtils.waitForResponse(ctxId, getVppApi()); + if (rv < 0) { + LOG.warn("Failed to update interface flags for: {}, index: {}, enabled: {}, ctxId: {}", swIfName, swIfIndex, + enabled, ctxId); + throw new VppApiInvocationException("swInterfaceSetFlags", ctxId, rv); + } else { + LOG.debug("Interface flags updated successfully for: {}, index: {}, enabled: {}, ctxId: {}", + swIfName, swIfIndex, enabled, ctxId); + } + } + + private void setDescription(final Interface swIf) { + if (swIf.getDescription() != null) { + getVppApi().setInterfaceDescription(swIf.getName(), swIf.getDescription()); + } else { + getVppApi().setInterfaceDescription(swIf.getName(), ""); + } + } + +} + diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java new file mode 100644 index 000000000..2b2774ece --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/VxlanCustomizer.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; +import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils; +import io.fd.honeycomb.v3po.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +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.VxlanTunnel; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class VxlanCustomizer extends VppApiCustomizer implements ChildWriterCustomizer<Vxlan> { + + private static final Logger LOG = LoggerFactory.getLogger(VxlanCustomizer.class); + + + public VxlanCustomizer(final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Nonnull + @Override + public Optional<Vxlan> extract(@Nonnull final InstanceIdentifier<Vxlan> currentId, + @Nonnull final DataObject parentData) { + return Optional.fromNullable(((VppInterfaceAugmentation) parentData).getVxlan()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataAfter, + @Nonnull final Context writeContext) + throws WriteFailedException.CreateFailedException { + final Interface ifc = (Interface) writeContext.get(InterfaceCustomizer.IFC_AFTER_CTX); + try { + createVxlanTunnel(ifc.getName(), dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Write of Vxlan failed", e); + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataBefore, + @Nonnull final Vxlan dataAfter, @Nonnull final Context writeContext) + throws WriteFailedException.UpdateFailedException { + final Interface ifcBefore = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + final Interface ifcAfter = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + + // TODO handle update in a better way + try { + createVxlanTunnel(ifcAfter.getName(), dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Update of L2 failed", e); + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Vxlan> id, @Nonnull final Vxlan dataBefore, + @Nonnull final Context writeContext) { + final Interface ifcBefore = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + + // TODO handle delete + } + + private void createVxlanTunnel(final String swIfName, final Vxlan vxlan) throws VppApiInvocationException { + Ipv4Address srcAddress = vxlan.getSrc(); + Ipv4Address dstAddress = vxlan.getDst(); + + int srcAddr = V3poUtils.parseIp(srcAddress.getValue()); + int dstAddr = V3poUtils.parseIp(dstAddress.getValue()); + int encapVrfId = vxlan.getEncapVrfId().intValue(); + int vni = vxlan.getVni().getValue().intValue(); + + LOG.debug("Setting vxlan tunnel for interface: {}. Vxlan: {}", swIfName, vxlan); + int ctxId = getVppApi().vxlanAddDelTunnel((byte) 1 /* is add */, srcAddr, dstAddr, encapVrfId, -1, vni); + final int rv = V3poUtils.waitForResponse(ctxId, getVppApi()); + if (rv < 0) { + LOG.debug("Failed to set vxlan tunnel for interface: {}, vxlan: {}", swIfName, vxlan); + throw new VppApiInvocationException("vxlanAddDelTunnel", ctxId, rv); + } else { + LOG.debug("Vxlan tunnel set successfully for: {}, vxlan: {}", swIfName, vxlan); + // FIXME avoid this dump just to fill cache in vpp-japi + // refresh interfaces to be able to get ifIndex + getVppApi().swInterfaceDump((byte) 1, V3poUtils.IFC_TYPES.inverse().get(VxlanTunnel.class).getBytes()); + } + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.java new file mode 100644 index 000000000..9f3584908 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Interface1Customizer.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import javax.annotation.Nonnull; +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.ip.rev140616.Interface1; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class Interface1Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Interface1> { + + public Interface1Customizer(final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Nonnull + @Override + public Optional<Interface1> extract(@Nonnull final InstanceIdentifier<Interface1> currentId, + @Nonnull final DataObject parentData) { + return Optional.fromNullable(((Interface) parentData).getAugmentation(Interface1.class)); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Interface1> id, + @Nonnull final Interface1 dataAfter, @Nonnull final Context writeContext) { + + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Interface1> id, + @Nonnull final Interface1 dataBefore, @Nonnull final Interface1 dataAfter, + @Nonnull final Context writeContext) { + + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Interface1> id, + @Nonnull final Interface1 dataBefore, @Nonnull final Context writeContext) { + + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java new file mode 100644 index 000000000..08974fe68 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv4Customizer.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.InterfaceCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiInvocationException; +import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils; +import io.fd.honeycomb.v3po.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +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.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.Subnet; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.Netmask; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.ipv4.address.subnet.PrefixLength; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Ipv4Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Ipv4> { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv4Customizer.class); + + public Ipv4Customizer(final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Nonnull + @Override + public Optional<Ipv4> extract(@Nonnull final InstanceIdentifier<Ipv4> currentId, + @Nonnull final DataObject parentData) { + return Optional.fromNullable(((Interface1) parentData).getIpv4()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id, + @Nonnull final Ipv4 dataAfter, @Nonnull final Context writeContext) + throws WriteFailedException { + final Interface ifc = (Interface) writeContext.get(InterfaceCustomizer.IFC_AFTER_CTX); + + try { + setIpv4(id, ifc.getName(), dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Create of Ipv4 failed", e); + throw new WriteFailedException.CreateFailedException(id, dataAfter, e); + } + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id, + @Nonnull final Ipv4 dataBefore, @Nonnull final Ipv4 dataAfter, + @Nonnull final Context writeContext) + throws WriteFailedException { + final Interface ifcBefore = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + final Interface ifcAfter = (Interface) writeContext.get(InterfaceCustomizer.IFC_BEFORE_CTX); + + // TODO handle update in a better way + try { + setIpv4(id, ifcAfter.getName(), dataAfter); + } catch (VppApiInvocationException e) { + LOG.warn("Update of Ipv4 failed", e); + throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter, e); + } + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv4> id, + @Nonnull final Ipv4 dataBefore, @Nonnull final Context writeContext) { + // TODO implement delete + } + + private void setIpv4(final InstanceIdentifier<Ipv4> id, final String name, final Ipv4 ipv4) + throws WriteFailedException, VppApiInvocationException { + final int swIfc = getSwIfc(name); + + for (Address ipv4Addr : ipv4.getAddress()) { + Subnet subnet = ipv4Addr.getSubnet(); + + if (subnet instanceof PrefixLength) { + setPrefixLengthSubnet(name, swIfc, ipv4Addr, (PrefixLength) subnet); + } else if (subnet instanceof Netmask) { + setNetmaskSubnet(); + } else { + // FIXME how does choice extensibility work + // FIXME it is not even possible to create a dedicated customizer for Interconnection, since it's not a DataObject + // FIXME we might need a choice customizer + // THis choice is already from augment, so its probably not possible to augment augmented choice + LOG.error("Unable to handle subnet of type {}", subnet.getClass()); + throw new WriteFailedException(id, "Unable to handle subnet of type " + subnet.getClass()); + } + } + } + + private void setNetmaskSubnet() { + // FIXME + throw new UnsupportedOperationException("Unimplemented"); + } + + private void setPrefixLengthSubnet(final String name, final int swIfc, final Address ipv4Addr, + final PrefixLength subnet) throws VppApiInvocationException { + Short plen = subnet.getPrefixLength(); + LOG.debug("Setting Subnet(prefix-length) for interface: {}, {}. Subnet: {}, Ipv4: {}", name, swIfc, subnet, + ipv4Addr); + + byte[] addr = V3poUtils.ipv4AddressNoZoneToArray(ipv4Addr.getIp()); + + checkArgument(plen > 0, "Invalid length"); + checkNotNull(addr, "Null address"); + + final int ctxId = getVppApi().swInterfaceAddDelAddress(swIfc, (byte) 1 /* isAdd */, (byte) 0 /* isIpv6 */, + (byte) 0 /* delAll */, plen.byteValue(), addr); + + final int rv = V3poUtils.waitForResponse(ctxId, getVppApi()); + if (rv < 0) { + LOG.warn("Failed to set Subnet(prefix-length) for interface: {}, {}, Subnet: {}, Ipv4: {}", name, swIfc, + subnet, ipv4Addr); + throw new VppApiInvocationException("swInterfaceAddDelAddress", ctxId, rv); + } else { + LOG.debug("Subnet(prefix-length) set successfully for interface: {}, {}, Subnet: {}, Ipv4: {}", name, + swIfc, subnet, ipv4Addr); + } + } + + + private int getSwIfc(final String name) { + int swIfcIndex = getVppApi().swIfIndexFromName(name); + checkArgument(swIfcIndex != -1, "Interface %s does not exist", name); + return swIfcIndex; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java new file mode 100644 index 000000000..3798f891a --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/interfaces/ip/Ipv6Customizer.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.interfaces.ip; + +import com.google.common.base.Optional; +import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.spi.write.ChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Ipv6Customizer extends VppApiCustomizer implements ChildWriterCustomizer<Ipv6> { + + private static final Logger LOG = LoggerFactory.getLogger(Ipv6Customizer.class); + + public Ipv6Customizer(final org.openvpp.vppjapi.vppApi vppApi) { + super(vppApi); + } + + @Nonnull + @Override + public Optional<Ipv6> extract(@Nonnull final InstanceIdentifier<Ipv6> currentId, + @Nonnull final DataObject parentData) { + return Optional.fromNullable(((Interface1) parentData).getIpv6()); + } + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id, + @Nonnull final Ipv6 dataAfter, @Nonnull final Context writeContext) { + // TODO + LOG.warn("Unsupported, ignoring configuration {}", dataAfter); + } + + @Override + public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id, + @Nonnull final Ipv6 dataBefore, @Nonnull final Ipv6 dataAfter, + @Nonnull final Context writeContext) { + LOG.warn("Unsupported, ignoring configuration {}", dataAfter); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Ipv6> id, + @Nonnull final Ipv6 dataBefore, @Nonnull final Context writeContext) { + LOG.warn("Unsupported, ignoring configuration delete {}", id); + // TODO + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java new file mode 100644 index 000000000..18a8103cc --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/utils/V3poUtils.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.translate.v3po.utils; + +import com.google.common.base.Splitter; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.EthernetCsmacd; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.iana._if.type.rev140508.SoftwareLoopback; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfaceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VxlanTunnel; +import org.openvpp.vppjapi.vppApi; + +public final class V3poUtils { + + // TODO move to vpp-translate-utils + + public static final int RESPONSE_NOT_READY = -77; + public static final int RELEASE = 1; + public static final Splitter DOT_SPLITTER = Splitter.on('.'); + public static final BiMap<String, Class<? extends InterfaceType>> IFC_TYPES = HashBiMap.create(); + static { + V3poUtils.IFC_TYPES.put("vxlan", VxlanTunnel.class); + V3poUtils.IFC_TYPES.put("lo", SoftwareLoopback.class); + V3poUtils.IFC_TYPES.put("Ether", EthernetCsmacd.class); + // TODO missing types below +// V3poUtils.IFC_TYPES.put("l2tpv3_tunnel", EthernetCsmacd.class); +// V3poUtils.IFC_TYPES.put("tap", EthernetCsmacd.class); + } + + private V3poUtils() {} + + public static int waitForResponse(final int ctxId, final vppApi vppApi) { + int rv; + while ((rv = vppApi.getRetval(ctxId, RELEASE)) == RESPONSE_NOT_READY) { + // TODO limit attempts + } + return rv; + } + + public static int parseIp(final String address) { + int result = 0; + + // iterate over each octet + for (String part : DOT_SPLITTER.split(address)) { + // shift the previously parsed bits over by 1 byte + result = result << 8; + // set the low order bits to the current octet + result |= Integer.parseInt(part); + } + return result; + } + + public static byte[] ipv4AddressNoZoneToArray(final Ipv4AddressNoZone ipv4Addr) { + byte[] retval = new byte[4]; + String[] dots = ipv4Addr.getValue().split("\\."); + + for (int d = 3; d >= 0; d--) { + retval[d] = (byte) (Short.parseShort(dots[3 - d]) & 0xff); + } + return retval; + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java index ffbc95beb..c69f2ef0a 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/v3po/translate/v3po/vpp/BridgeDomainCustomizer.java @@ -23,6 +23,7 @@ import static com.google.common.base.Preconditions.checkState; import io.fd.honeycomb.v3po.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.v3po.translate.v3po.util.VppApiCustomizer; import io.fd.honeycomb.v3po.translate.Context; +import io.fd.honeycomb.v3po.translate.v3po.utils.V3poUtils; import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -41,8 +42,6 @@ public class BridgeDomainCustomizer private static final Logger LOG = LoggerFactory.getLogger(BridgeDomainCustomizer.class); private static final byte ADD_OR_UPDATE_BD = (byte) 1; - private static final int RESPONSE_NOT_READY = -77; - private static final int RELEASE = 1; public BridgeDomainCustomizer(final org.openvpp.vppjapi.vppApi api) { super(api); @@ -55,14 +54,6 @@ public class BridgeDomainCustomizer return ((BridgeDomains) parentData).getBridgeDomain(); } - private int waitForResponse(final int ctxId) { - int rv; - while ((rv = getVppApi().getRetval(ctxId, RELEASE)) == RESPONSE_NOT_READY) { - // TODO limit attempts - } - return rv; - } - private int addOrUpdateBridgeDomain(final int bdId, @Nonnull final BridgeDomain bd) { byte flood = booleanToByte(bd.isFlood()); byte forward = booleanToByte(bd.isForward()); @@ -71,7 +62,7 @@ public class BridgeDomainCustomizer byte arpTerm = booleanToByte(bd.isArpTermination()); int ctxId = getVppApi().bridgeDomainAddDel(bdId, flood, forward, learn, uuf, arpTerm, ADD_OR_UPDATE_BD); - return waitForResponse(ctxId); + return V3poUtils.waitForResponse(ctxId, getVppApi()); } @Override @@ -111,7 +102,7 @@ public class BridgeDomainCustomizer (byte) 0 /* arpTerm */, (byte) 0 /* isAdd */); - int rv = waitForResponse(ctxId); + int rv = V3poUtils.waitForResponse(ctxId, getVppApi()); checkState(rv >= 0, "Bridge domain delete failed. Return code: %s", rv); LOG.debug("Bridge domain {} deleted as {} successfully", bdName, bdId); diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java new file mode 100644 index 000000000..4710d9e1a --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModule.java @@ -0,0 +1,114 @@ +package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406; + +import com.google.common.collect.Lists; +import io.fd.honeycomb.v3po.translate.impl.TraversalType; +import io.fd.honeycomb.v3po.translate.impl.write.CompositeChildWriter; +import io.fd.honeycomb.v3po.translate.impl.write.CompositeListWriter; +import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter; +import io.fd.honeycomb.v3po.translate.util.RWUtils; +import io.fd.honeycomb.v3po.translate.util.write.CloseableWriter; +import io.fd.honeycomb.v3po.translate.util.write.NoopWriterCustomizer; +import io.fd.honeycomb.v3po.translate.util.write.ReflexiveChildWriterCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.EthernetCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.InterfaceCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.L2Customizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.RoutingCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.VppInterfaceCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.VxlanCustomizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv4Customizer; +import io.fd.honeycomb.v3po.translate.v3po.interfaces.ip.Ipv6Customizer; +import io.fd.honeycomb.v3po.translate.write.ChildWriter; +import java.util.ArrayList; +import java.util.List; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; +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.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv4; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.interfaces._interface.Ipv6; +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.interfaces._interface.Ethernet; +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.interfaces._interface.Routing; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Vxlan; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.ChildOf; + +public class InterfacesHoneycombWriterModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesHoneycombWriterModule { + public InterfacesHoneycombWriterModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { + super(identifier, dependencyResolver); + } + + public InterfacesHoneycombWriterModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.InterfacesHoneycombWriterModule oldModule, java.lang.AutoCloseable oldInstance) { + super(identifier, dependencyResolver, oldModule, oldInstance); + } + + @Override + public void customValidation() { + // add custom validation form module attributes here. + } + + @Override + public java.lang.AutoCloseable createInstance() { + + final List<ChildWriter<? extends Augmentation<Interface>>> ifcAugmentations = Lists.newArrayList(); + ifcAugmentations.add(getVppIfcAugmentationWriter()); + + final ChildWriter<Interface> interfaceWriter = new CompositeListWriter<>(Interface.class, + RWUtils.<Interface>emptyChildWriterList(), + ifcAugmentations, + new InterfaceCustomizer(getVppJapiIfcDependency())); + + final List<ChildWriter<? extends ChildOf<Interfaces>>> childWriters = new ArrayList<>(); + childWriters.add(interfaceWriter); + + // FIXME if we just return the root writer and cfg subsystem takes care to set it into reader registry, + // we loose the ordering information for root writers + // Or can we rely to the order in which readers are configured ? + return new CloseableWriter<>(new CompositeRootWriter<>(Interfaces.class, + childWriters, new NoopWriterCustomizer<Interfaces>())); + } + + private ChildWriter<? extends Augmentation<Interface>> getInterface1AugmentationWriter() { + final ChildWriter<Ipv4> ipv4Writer = new CompositeChildWriter<>(Ipv4.class, + new Ipv4Customizer(getVppJapiIfcDependency())); + final ChildWriter<Ipv6> ipv6Writer = new CompositeChildWriter<>(Ipv6.class, + new Ipv6Customizer(getVppJapiIfcDependency())); + + final List<ChildWriter<? extends ChildOf<Interface1>>> interface1ChildWriters = Lists.newArrayList(); + interface1ChildWriters.add(ipv4Writer); + interface1ChildWriters.add(ipv6Writer); + + return new CompositeChildWriter<>(Interface1.class, + interface1ChildWriters, new ReflexiveChildWriterCustomizer<Interface1>()); + } + + private ChildWriter<VppInterfaceAugmentation> getVppIfcAugmentationWriter() { + + final ChildWriter<Ethernet> ethernetWriter = new CompositeChildWriter<>(Ethernet.class, + new EthernetCustomizer(getVppJapiIfcDependency())); + + final ChildWriter<Routing> routingWriter = new CompositeChildWriter<>(Routing.class, + new RoutingCustomizer(getVppJapiIfcDependency())); + + final ChildWriter<Vxlan> vxlanWriter = new CompositeChildWriter<>(Vxlan.class, + new VxlanCustomizer(getVppJapiIfcDependency())); + + final ChildWriter<L2> l2Writer = new CompositeChildWriter<>(L2.class, + new L2Customizer(getVppJapiIfcDependency())); + + final List<ChildWriter<? extends ChildOf<VppInterfaceAugmentation>>> vppIfcChildWriters = Lists.newArrayList(); + // TODO what's the order here ? + vppIfcChildWriters.add(ethernetWriter); + vppIfcChildWriters.add(vxlanWriter); + vppIfcChildWriters.add(l2Writer); + vppIfcChildWriters.add(routingWriter); + + return new CompositeChildWriter<>(VppInterfaceAugmentation.class, + vppIfcChildWriters, + RWUtils.<VppInterfaceAugmentation>emptyAugWriterList(), + new VppInterfaceCustomizer(getVppJapiIfcDependency()), + // It's important that this customizer is handled in a postorder way, because you first have to handle child nodes + // e.g. Vxlan before setting other interface or vppInterfaceAugmentation leaves + TraversalType.POSTORDER); + } +} diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModuleFactory.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModuleFactory.java new file mode 100644 index 000000000..9332d3017 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesHoneycombWriterModuleFactory.java @@ -0,0 +1,13 @@ +/* +* Generated file +* +* Generated from: yang module name: v3po2vpp yang module local name: interfaces-honeycomb-writer +* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator +* Generated at: Fri Apr 08 13:28:05 CEST 2016 +* +* Do not modify this file unless it is present under src/main directory +*/ +package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406; +public class InterfacesHoneycombWriterModuleFactory extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesHoneycombWriterModuleFactory { + +} diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java index 5b79ff0d3..aa72a29af 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/InterfacesStateHoneycombReaderModule.java @@ -1,14 +1,11 @@ package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406; -import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader; import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader; import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader; import io.fd.honeycomb.v3po.translate.read.ChildReader; -import io.fd.honeycomb.v3po.translate.read.ReadContext; -import io.fd.honeycomb.v3po.translate.read.ReadFailedException; -import io.fd.honeycomb.v3po.translate.read.Reader; import io.fd.honeycomb.v3po.translate.util.RWUtils; +import io.fd.honeycomb.v3po.translate.util.read.CloseableReader; import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer; import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.InterfaceCustomizer; import io.fd.honeycomb.v3po.translate.v3po.interfacesstate.VppInterfaceStateCustomizer; @@ -17,14 +14,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceBuilder; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey; -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.VppInterfaceStateAugmentation; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.openvpp.vppjapi.vppApi; -import javax.annotation.Nonnull; - public class InterfacesStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractInterfacesStateHoneycombReaderModule { public InterfacesStateHoneycombReaderModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { super(identifier, dependencyResolver); @@ -53,44 +45,10 @@ public class InterfacesStateHoneycombReaderModule extends org.opendaylight.yang. RWUtils.<Interface>singletonAugReaderList(vppInterfaceStateAugmentationChildReader), new InterfaceCustomizer(vppApi)); - return new CloseableReader(new CompositeRootReader<>( + return new CloseableReader<>(new CompositeRootReader<>( InterfacesState.class, RWUtils.singletonChildReaderList(interfaceReader), RWUtils.<InterfacesState>emptyAugReaderList(), new ReflexiveRootReaderCustomizer<>(InterfacesStateBuilder.class))); } - - - private static final class CloseableReader implements Reader<InterfacesState>, AutoCloseable { - - private CompositeRootReader<InterfacesState, InterfacesStateBuilder> compositeRootReader; - - public CloseableReader( - final CompositeRootReader<InterfacesState, InterfacesStateBuilder> compositeRootReader) { - this.compositeRootReader = compositeRootReader; - } - - @Nonnull - @Override - public Optional<? extends DataObject> read(@Nonnull InstanceIdentifier<? extends DataObject> id, - @Nonnull ReadContext ctx) throws ReadFailedException { - return compositeRootReader.read(id, ctx); - } - - @Nonnull - @Override - public InstanceIdentifier<InterfacesState> getManagedDataObjectType() { - return compositeRootReader.getManagedDataObjectType(); - } - - @Override - public String toString() { - return compositeRootReader.toString(); - } - - @Override - public void close() throws Exception { - //NOOP - } - } } diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java index 5694bc139..a9eff593d 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppHoneycombWriterModule.java @@ -1,27 +1,21 @@ package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406; -import io.fd.honeycomb.v3po.translate.TranslationException; import io.fd.honeycomb.v3po.translate.impl.write.CompositeChildWriter; import io.fd.honeycomb.v3po.translate.impl.write.CompositeListWriter; import io.fd.honeycomb.v3po.translate.impl.write.CompositeRootWriter; import io.fd.honeycomb.v3po.translate.util.RWUtils; +import io.fd.honeycomb.v3po.translate.util.write.CloseableWriter; import io.fd.honeycomb.v3po.translate.util.write.NoopWriterCustomizer; import io.fd.honeycomb.v3po.translate.util.write.ReflexiveChildWriterCustomizer; import io.fd.honeycomb.v3po.translate.v3po.vpp.BridgeDomainCustomizer; import io.fd.honeycomb.v3po.translate.write.ChildWriter; -import io.fd.honeycomb.v3po.translate.write.WriteContext; -import io.fd.honeycomb.v3po.translate.write.Writer; import java.util.ArrayList; import java.util.List; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.Vpp; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.BridgeDomains; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomain; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.bridge.domains.BridgeDomainKey; import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class VppHoneycombWriterModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractVppHoneycombWriterModule { public VppHoneycombWriterModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) { @@ -51,46 +45,10 @@ public class VppHoneycombWriterModule extends org.opendaylight.yang.gen.v1.urn.h final List<ChildWriter<? extends ChildOf<Vpp>>> childWriters = new ArrayList<>(); childWriters.add(bridgeDomainsReader); - return new CloseableWriter(new CompositeRootWriter<>( + return new CloseableWriter<>(new CompositeRootWriter<>( Vpp.class, childWriters, new NoopWriterCustomizer<Vpp>())); } - // TODO move to translate-utils - private static final class CloseableWriter implements Writer<Vpp>, AutoCloseable { - - private CompositeRootWriter<Vpp> vppCompositeRootWriter; - - public CloseableWriter( - final CompositeRootWriter<Vpp> vppCompositeRootWriter) { - this.vppCompositeRootWriter = vppCompositeRootWriter; - } - - @Override - public void update( - @Nonnull final InstanceIdentifier<? extends DataObject> id, - @Nullable final DataObject dataBefore, - @Nullable final DataObject dataAfter, - @Nonnull final WriteContext ctx) throws TranslationException { - vppCompositeRootWriter.update(id, dataBefore, dataAfter, ctx); - } - - @Nonnull - @Override - public InstanceIdentifier<Vpp> getManagedDataObjectType() { - return vppCompositeRootWriter.getManagedDataObjectType(); - } - - @Override - public String toString() { - return vppCompositeRootWriter.toString(); - } - - @Override - public void close() throws Exception { - - } - } - } diff --git a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java index 8da7dad1c..0e1d48035 100644 --- a/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java +++ b/v3po/v3po2vpp/src/main/java/org/opendaylight/yang/gen/v1/urn/honeycomb/params/xml/ns/yang/v3po2vpp/rev160406/VppStateHoneycombReaderModule.java @@ -1,21 +1,17 @@ package org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406; -import com.google.common.base.Optional; import io.fd.honeycomb.v3po.translate.impl.read.CompositeChildReader; import io.fd.honeycomb.v3po.translate.impl.read.CompositeListReader; import io.fd.honeycomb.v3po.translate.impl.read.CompositeRootReader; import io.fd.honeycomb.v3po.translate.read.ChildReader; -import io.fd.honeycomb.v3po.translate.read.ReadContext; -import io.fd.honeycomb.v3po.translate.read.ReadFailedException; -import io.fd.honeycomb.v3po.translate.read.Reader; import io.fd.honeycomb.v3po.translate.util.RWUtils; +import io.fd.honeycomb.v3po.translate.util.read.CloseableReader; import io.fd.honeycomb.v3po.translate.util.read.ReflexiveChildReaderCustomizer; import io.fd.honeycomb.v3po.translate.util.read.ReflexiveRootReaderCustomizer; import io.fd.honeycomb.v3po.translate.v3po.vppstate.BridgeDomainCustomizer; import io.fd.honeycomb.v3po.translate.v3po.vppstate.VersionCustomizer; import java.util.ArrayList; import java.util.List; -import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppStateBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.BridgeDomains; @@ -25,8 +21,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.vpp.state.bridge.domains.BridgeDomainKey; import org.opendaylight.yangtools.yang.binding.ChildOf; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.openvpp.vppjapi.vppApi; public class VppStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.v3po2vpp.rev160406.AbstractVppStateHoneycombReaderModule { @@ -61,44 +55,11 @@ public class VppStateHoneycombReaderModule extends org.opendaylight.yang.gen.v1. childVppReaders.add(versionReader); childVppReaders.add(bridgeDomainsReader); - return new CloseableReader(new CompositeRootReader<>( + return new CloseableReader<>(new CompositeRootReader<>( VppState.class, childVppReaders, RWUtils.<VppState>emptyAugReaderList(), new ReflexiveRootReaderCustomizer<>(VppStateBuilder.class))); } - // TODO move to utils - private static final class CloseableReader implements Reader<VppState>, AutoCloseable { - - private CompositeRootReader<VppState, VppStateBuilder> vppStateVppStateBuilderCompositeRootReader; - - public CloseableReader( - final CompositeRootReader<VppState, VppStateBuilder> vppStateVppStateBuilderCompositeRootReader) { - this.vppStateVppStateBuilderCompositeRootReader = vppStateVppStateBuilderCompositeRootReader; - } - - @Nonnull - @Override - public Optional<? extends DataObject> read(@Nonnull final InstanceIdentifier<? extends DataObject> id, - @Nonnull final ReadContext ctx) throws ReadFailedException { - return vppStateVppStateBuilderCompositeRootReader.read(id, ctx); - } - - @Nonnull - @Override - public InstanceIdentifier<VppState> getManagedDataObjectType() { - return vppStateVppStateBuilderCompositeRootReader.getManagedDataObjectType(); - } - - @Override - public String toString() { - return vppStateVppStateBuilderCompositeRootReader.toString(); - } - - @Override - public void close() throws Exception { - //NOOP - } - } } diff --git a/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang b/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang index 9d3199970..286feb987 100644 --- a/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang +++ b/v3po/v3po2vpp/src/main/yang/v3po2vpp.yang @@ -79,4 +79,25 @@ module v3po2vpp { } } + identity interfaces-honeycomb-writer { + base config:module-type; + config:provided-service tapi:honeycomb-writer; + } + + augment "/config:modules/config:module/config:configuration" { + case interfaces-honeycomb-writer { + when "/config:modules/config:module/config:type = 'interfaces-honeycomb-writer'"; + + container vpp-japi-ifc { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity vjc:vpp-japi; + } + } + } + + } + } + }
\ No newline at end of file |