diff options
7 files changed, 350 insertions, 32 deletions
diff --git a/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/VppIoamModule.java b/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/VppIoamModule.java index bf5df6389..a378a0669 100755 --- a/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/VppIoamModule.java +++ b/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/VppIoamModule.java @@ -17,12 +17,14 @@ package io.fd.hc2vpp.vppioam.impl; import com.google.common.annotations.VisibleForTesting; import com.google.inject.AbstractModule; +import com.google.inject.Provider; import com.google.inject.Singleton; import com.google.inject.multibindings.Multibinder; -import com.google.inject.Provider; import io.fd.hc2vpp.vppioam.impl.config.VppIoamWriterFactory; -import io.fd.honeycomb.translate.write.WriterFactory; +import io.fd.hc2vpp.vppioam.impl.oper.VppIoamReaderFactory; import io.fd.hc2vpp.vppioam.impl.util.JVppIoamProvider; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.write.WriterFactory; import io.fd.vpp.jvpp.ioamtrace.future.FutureJVppIoamtrace; import io.fd.vpp.jvpp.ioamtrace.future.FutureJVppIoamtraceFacade; import org.slf4j.Logger; @@ -54,6 +56,7 @@ public final class VppIoamModule extends AbstractModule { // Below are classes picked up by HC framework Multibinder.newSetBinder(binder(), WriterFactory.class).addBinding().to(VppIoamWriterFactory.class); + Multibinder.newSetBinder(binder(), ReaderFactory.class).addBinding().to(VppIoamReaderFactory.class); LOG.debug("Module iOAM successfully configured"); } diff --git a/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/oper/TraceProfileReaderCustomizer.java b/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/oper/TraceProfileReaderCustomizer.java new file mode 100644 index 000000000..d378385ef --- /dev/null +++ b/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/oper/TraceProfileReaderCustomizer.java @@ -0,0 +1,140 @@ +/* + * 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.hc2vpp.vppioam.impl.oper; + +import com.google.common.collect.Lists; +import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; +import io.fd.hc2vpp.vppioam.impl.util.FutureJVppIoamCustomizer; +import io.fd.honeycomb.translate.read.ReadContext; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.Initialized; +import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; +import io.fd.vpp.jvpp.ioamtrace.dto.TraceProfileShowConfig; +import io.fd.vpp.jvpp.ioamtrace.dto.TraceProfileShowConfigReply; +import io.fd.vpp.jvpp.ioamtrace.future.FutureJVppIoamtrace; +import java.util.List; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.IoamTraceConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.ioam.trace.config.TraceConfig; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.ioam.trace.config.TraceConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.ioam.trace.config.TraceConfigKey; +import org.opendaylight.yangtools.concepts.Builder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TraceProfileReaderCustomizer extends FutureJVppIoamCustomizer + implements InitializingListReaderCustomizer<TraceConfig, TraceConfigKey, TraceConfigBuilder>, JvppReplyConsumer{ + + private static final Logger LOG = LoggerFactory.getLogger(TraceProfileReaderCustomizer.class); + + public TraceProfileReaderCustomizer(@Nonnull FutureJVppIoamtrace futureJVppIoam) { + super(futureJVppIoam); + } + + /** + * Creates new builder that will be used to build read value. + * + * @param id + */ + @Nonnull + @Override + public TraceConfigBuilder getBuilder(@Nonnull InstanceIdentifier<TraceConfig> id) { + return new TraceConfigBuilder(); + } + + /** + * Transform Operational data into Config data. + * + * @param id InstanceIdentifier of operational data being initialized + * @param readValue Operational data being initialized(converted into config) + * @param ctx Standard read context to assist during initialization e.g. caching data between customizers + * @return Initialized, config data and its identifier + */ + @Nonnull + @Override + public Initialized<? extends DataObject> init(@Nonnull InstanceIdentifier<TraceConfig> id, @Nonnull TraceConfig readValue, @Nonnull ReadContext ctx) { + return Initialized.create(id,new TraceConfigBuilder(readValue).build()); + } + + /** + * Adds current data (identified by id) to the provided builder. + * + * @param id id of current data object + * @param builder builder for creating read value + * @param ctx context for current read + * @throws ReadFailedException if read was unsuccessful + */ + @Override + public void readCurrentAttributes(@Nonnull InstanceIdentifier<TraceConfig> id, @Nonnull TraceConfigBuilder builder, + @Nonnull ReadContext ctx) throws ReadFailedException { + + // Only one trace config is configured on the VPP side as of now. + // name of trace config, which is key for the list, is not used in the VPP implementation. + + LOG.debug("reading attribute for trace config {}",id); + final TraceProfileShowConfig request = new TraceProfileShowConfig(); + TraceProfileShowConfigReply reply = getReplyForRead(getFutureJVppIoam().traceProfileShowConfig(request) + .toCompletableFuture(),id); + if(reply == null) { + LOG.debug("{} returned null as reply from vpp",id); + return; + } + + if(reply.traceType == 0){ + LOG.debug("{} no configured trace config found",id); + return; + } + builder.setNodeId((long) reply.nodeId); + builder.setTraceAppData((long) reply.appData); + builder.setTraceNumElt((short) reply.numElts); + builder.setTraceTsp(TraceConfig.TraceTsp.forValue(reply.traceTsp)); + builder.setTraceType((short) reply.traceType); + + LOG.debug("Item {} successfully read: {}",id,builder.build()); + } + + /** + * Merge read data into provided parent builder. + * + * @param parentBuilder + * @param readValue + */ + @Override + public void merge(@Nonnull Builder<? extends DataObject> parentBuilder, @Nonnull TraceConfig readValue) { + IoamTraceConfigBuilder builder = (IoamTraceConfigBuilder) parentBuilder; + List<TraceConfig> traceConfigs = builder.getTraceConfig(); + traceConfigs.add(readValue); + builder.setTraceConfig(traceConfigs); + } + + @Nonnull + @Override + public List<TraceConfigKey> getAllIds(@Nonnull final InstanceIdentifier<TraceConfig> instanceIdentifier, + @Nonnull final ReadContext readContext) throws ReadFailedException { + + // Only one trace config is configured on the VPP side as of now. + // name of trace config, which is key for the list, is not used in the VPP implementation. + + return Lists.newArrayList(new TraceConfigKey("trace config")); + } + + @Override + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<TraceConfig> list) { + ((IoamTraceConfigBuilder) builder).setTraceConfig(list); + } +} diff --git a/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/oper/VppIoamReaderFactory.java b/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/oper/VppIoamReaderFactory.java new file mode 100644 index 000000000..8c34f54e5 --- /dev/null +++ b/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/oper/VppIoamReaderFactory.java @@ -0,0 +1,54 @@ +/* + * 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.hc2vpp.vppioam.impl.oper; + +import io.fd.honeycomb.translate.impl.read.GenericInitListReader; +import io.fd.honeycomb.translate.read.ReaderFactory; +import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; +import io.fd.vpp.jvpp.ioamtrace.future.FutureJVppIoamtrace; +import javax.annotation.Nonnull; +import javax.inject.Inject; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.IoamTraceConfig; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.IoamTraceConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.ioam.trace.config.TraceConfig; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class VppIoamReaderFactory implements ReaderFactory { + + FutureJVppIoamtrace jVppIoamtrace; + + @Inject + VppIoamReaderFactory(FutureJVppIoamtrace jVppIoamtrace){ + this.jVppIoamtrace = jVppIoamtrace; + } + + /** + * Initialize 1 or more readers and add them to provided registry. + * + * @param registry + */ + @Override + public void init(@Nonnull ModifiableReaderRegistryBuilder registry) { + + //IoamTraceConfig (Structural) + final InstanceIdentifier<IoamTraceConfig> ioamTraceConfigId = InstanceIdentifier.create(IoamTraceConfig.class); + registry.addStructuralReader(ioamTraceConfigId, IoamTraceConfigBuilder.class); + + //TraceConfig + final InstanceIdentifier<TraceConfig> traceConfigId = ioamTraceConfigId.child(TraceConfig.class); + registry.add(new GenericInitListReader<>(traceConfigId,new TraceProfileReaderCustomizer(jVppIoamtrace))); + } +} diff --git a/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/util/JVppIoamProvider.java b/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/util/JVppIoamProvider.java index a34715ca6..0b5e3e79e 100755 --- a/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/util/JVppIoamProvider.java +++ b/ioam/impl/src/main/java/io/fd/hc2vpp/vppioam/impl/util/JVppIoamProvider.java @@ -50,7 +50,7 @@ public final class JVppIoamProvider extends ProviderTrait<FutureJVppIoamtraceFac } }); - LOG.debug("Successfully loaded jvpp-ioam plugin"); + LOG.info("Successfully loaded jvpp-ioam plugin"); return new FutureJVppIoamtraceFacade(registry, jVppIoamTr); } catch (IOException e) { throw new IllegalStateException("Unable to open VPP management connection", e); diff --git a/ioam/impl/src/test/java/io/fd/hc2vpp/vppioam/impl/VppIoamModuleTest.java b/ioam/impl/src/test/java/io/fd/hc2vpp/vppioam/impl/VppIoamModuleTest.java index b1af9d5b2..68b8a87c7 100644 --- a/ioam/impl/src/test/java/io/fd/hc2vpp/vppioam/impl/VppIoamModuleTest.java +++ b/ioam/impl/src/test/java/io/fd/hc2vpp/vppioam/impl/VppIoamModuleTest.java @@ -30,7 +30,9 @@ import com.google.inject.Provider; import com.google.inject.name.Named; import com.google.inject.testing.fieldbinder.Bind; import com.google.inject.testing.fieldbinder.BoundFieldModule; +import io.fd.honeycomb.translate.impl.read.registry.CompositeReaderRegistryBuilder; import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; +import io.fd.honeycomb.translate.read.ReaderFactory; import io.fd.honeycomb.translate.write.WriterFactory; import java.util.HashSet; import java.util.Set; @@ -62,6 +64,9 @@ public class VppIoamModuleTest { @Inject private Set<WriterFactory> writerFactories = new HashSet<>(); + @Inject + private Set<ReaderFactory> readerFactories = new HashSet<>(); + @Before public void setUp() throws Exception { @@ -79,6 +84,17 @@ public class VppIoamModuleTest { assertNotNull(registryBuilder.build()); } + @Test + public void testReaderFactories() throws Exception { + assertThat(readerFactories, is(not(empty()))); + + // Test registration process (all dependencies present, topological order of readers does exist, etc.) + final CompositeReaderRegistryBuilder registryBuilder = new CompositeReaderRegistryBuilder(); + readerFactories.forEach(factory -> factory.init(registryBuilder)); + assertNotNull(registryBuilder.build()); + } + + private static final class MockJVppIoamProvider implements Provider<FutureJVppIoamtraceFacade> { @Override diff --git a/ioam/impl/src/test/java/io/fd/hc2vpp/vppioam/impl/oper/TraceProfileReaderCustomizerTest.java b/ioam/impl/src/test/java/io/fd/hc2vpp/vppioam/impl/oper/TraceProfileReaderCustomizerTest.java new file mode 100644 index 000000000..555f90b57 --- /dev/null +++ b/ioam/impl/src/test/java/io/fd/hc2vpp/vppioam/impl/oper/TraceProfileReaderCustomizerTest.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.hc2vpp.vppioam.impl.oper; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; +import io.fd.honeycomb.translate.read.ReadFailedException; +import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; +import io.fd.vpp.jvpp.ioamtrace.dto.TraceProfileShowConfig; +import io.fd.vpp.jvpp.ioamtrace.dto.TraceProfileShowConfigReply; +import io.fd.vpp.jvpp.ioamtrace.future.FutureJVppIoamtrace; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.IoamTraceConfig; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.IoamTraceConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.ioam.trace.config.TraceConfig; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.ioam.trace.config.TraceConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.ioam.sb.trace.rev160512.ioam.trace.config.TraceConfigKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public class TraceProfileReaderCustomizerTest extends ListReaderCustomizerTest<TraceConfig, TraceConfigKey, TraceConfigBuilder> { + + @Mock + protected FutureJVppIoamtrace jVppIoamtrace; + + public TraceProfileReaderCustomizerTest(){ + super(TraceConfig.class, IoamTraceConfigBuilder.class); + } + + @Override + protected ReaderCustomizer<TraceConfig, TraceConfigBuilder> initCustomizer() { + return new TraceProfileReaderCustomizer(jVppIoamtrace); + } + + @Override + public void setUp(){ + final TraceProfileShowConfigReply reply = new TraceProfileShowConfigReply(); + reply.appData = 1234; + reply.traceTsp = ((byte) TraceConfig.TraceTsp.Milliseconds.getIntValue()); + reply.nodeId = 1; + reply.numElts = 4; + reply.traceType = 0x1f; + doReturn(future(reply)).when(jVppIoamtrace).traceProfileShowConfig(any(TraceProfileShowConfig.class)); + } + + @Test + public void testReadCurrentAttributes() throws ReadFailedException { + TraceConfigBuilder builder = new TraceConfigBuilder(); + getCustomizer().readCurrentAttributes(InstanceIdentifier.create(IoamTraceConfig.class) + .child(TraceConfig.class, new TraceConfigKey("Trace config")), builder, ctx); + assertEquals(1234,builder.getTraceAppData().longValue()); + assertEquals(TraceConfig.TraceTsp.Milliseconds.getIntValue(),builder.getTraceTsp().getIntValue()); + assertEquals(1,builder.getNodeId().longValue()); + assertEquals(4,builder.getTraceNumElt().shortValue()); + assertEquals(0x1f,builder.getTraceType().shortValue()); + + verify(jVppIoamtrace).traceProfileShowConfig(any(TraceProfileShowConfig.class)); + } + +} diff --git a/ioam/ioam_trace_postman_collection.json b/ioam/ioam_trace_postman_collection.json index d5248139a..61505ac89 100644 --- a/ioam/ioam_trace_postman_collection.json +++ b/ioam/ioam_trace_postman_collection.json @@ -1,34 +1,61 @@ { - "id": "7d81e8b0-274e-1f22-de94-d40cb78a389d", - "name": "Honeycomb RESTCONF calls for iOAM Trace", - "description": "To enable iOAM trace on VPP management nodes.", - "order": [ - "f5a5aaea-2d61-a57f-191a-7cc81286f605" - ], - "folders": [], - "timestamp": 1478073563257, - "owner": 0, - "public": false, - "requests": [ + "variables": [], + "info": { + "name": "Honeycomb RESTCONF calls for iOAM Trace", + "_postman_id": "4117bd46-e112-6cfc-9d18-e566b66ba610", + "description": "To enable iOAM trace on VPP management nodes.", + "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json" + }, + "item": [ { - "id": "f5a5aaea-2d61-a57f-191a-7cc81286f605", - "headers": "Authorization: Basic YWRtaW46YWRtaW4=\nContent-Type: application/json\n", - "url": "http://localhost:8181/restconf/config/ioam-sb-trace:ioam-trace-config/", - "preRequestScript": "", - "pathVariables": {}, - "method": "PUT", - "data": [], - "dataMode": "raw", - "version": 2, - "tests": "", - "currentHelper": "normal", - "helperAttributes": {}, - "time": 1478077673476, - "name": "iaom trace", - "description": "", - "collectionId": "7d81e8b0-274e-1f22-de94-d40cb78a389d", - "responses": [], - "rawModeData": "{\n\"trace-config\":{\n \"trace-config-name\":\"trace\",\n \"acl-name\":\"testAcl\",\n \"trace-type\":31,\n \"trace-num-elt\":3,\n \"trace-tsp\":\"milliseconds\",\n \"trace-op\":\"add\",\n \"trace-app-data\":1234,\n \"data-export-profile-name\":\"dataProfileName\",\n \"transport-encap-profile-name\":\"transProfileName\",\n \"node-id\":1,\n \"node-interfaces\":[\n {\n \"index\":5,\n \"intf-name\":\"GigabitEthernetb/0/0\"\n }\n ]\n }\n}\n" + "name": "iaom trace - config", + "request": { + "url": "http://localhost:8183/restconf/config/ioam-sb-trace:ioam-trace-config/", + "method": "PUT", + "header": [ + { + "key": "Authorization", + "value": "Basic YWRtaW46YWRtaW4=", + "description": "" + }, + { + "key": "Content-Type", + "value": "application/json", + "description": "" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\"trace-config\":{\n \"trace-config-name\":\"trace\",\n \"acl-name\":\"testAcl\",\n \"trace-type\":31,\n \"trace-num-elt\":3,\n \"trace-tsp\":\"milliseconds\",\n \"trace-op\":\"add\",\n \"trace-app-data\":1234,\n \"data-export-profile-name\":\"dataProfileName\",\n \"transport-encap-profile-name\":\"transProfileName\",\n \"node-id\":1,\n \"node-interfaces\":[\n {\n \"index\":5,\n \"intf-name\":\"GigabitEthernetb/0/0\"\n }\n ]\n }\n}\n" + }, + "description": "Configure ioam trace config on VPP" + }, + "response": [] + }, + { + "name": "iaom trace - oper", + "request": { + "url": "http://localhost:8183/restconf/operational/ioam-sb-trace:ioam-trace-config/trace-config/*", + "method": "GET", + "header": [ + { + "key": "Authorization", + "value": "Basic YWRtaW46YWRtaW4=", + "description": "" + }, + { + "key": "Content-Type", + "value": "application/json", + "description": "" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\"trace-config\":{\n \"trace-config-name\":\"trace\",\n \"acl-name\":\"testAcl\",\n \"trace-type\":31,\n \"trace-num-elt\":3,\n \"trace-tsp\":\"milliseconds\",\n \"trace-op\":\"add\",\n \"trace-app-data\":1234,\n \"data-export-profile-name\":\"dataProfileName\",\n \"transport-encap-profile-name\":\"transProfileName\",\n \"node-id\":1,\n \"node-interfaces\":[\n {\n \"index\":5,\n \"intf-name\":\"GigabitEthernetb/0/0\"\n }\n ]\n }\n}\n" + }, + "description": "Read ioam trace config from VPP" + }, + "response": [] } ] }
\ No newline at end of file |