diff --git a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java index 1b69f30e1d..0acdb88d1e 100644 --- a/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java +++ b/apps/openstacknode/app/src/main/java/org/onosproject/openstacknode/web/OpenstackNodeWebResource.java @@ -101,7 +101,7 @@ public class OpenstackNodeWebResource extends AbstractWebResource { } /** - * Creates a set of openstack nodes' config from the JSON input stream. + * Updates a set of openstack nodes' config from the JSON input stream. * * @param input openstack nodes JSON input stream * @return 200 OK with the updated openstack node's config, 400 BAD_REQUEST diff --git a/apps/openstacktelemetry/BUILD b/apps/openstacktelemetry/BUILD index 8cbb47dd6f..5bd1683fd6 100644 --- a/apps/openstacktelemetry/BUILD +++ b/apps/openstacktelemetry/BUILD @@ -31,6 +31,7 @@ BUNDLES = [ "@com_google_code_gson_gson//jar", "//apps/openstacktelemetry/api:onos-apps-openstacktelemetry-api", "//apps/openstacktelemetry/app:onos-apps-openstacktelemetry-app", + "//apps/openstacktelemetry/web:onos-apps-openstacktelemetry-web", ] onos_app( diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultFlowInfo.java similarity index 92% rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java rename to apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultFlowInfo.java index b0d3aad023..c0655e9cb1 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java +++ b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultFlowInfo.java @@ -13,21 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.impl; +package org.onosproject.openstacktelemetry.api; +import org.onlab.packet.IPv4; import org.onlab.packet.IpPrefix; import org.onlab.packet.MacAddress; import org.onlab.packet.TpPort; import org.onlab.packet.VlanId; import org.onosproject.net.DeviceId; -import org.onosproject.openstacktelemetry.api.FlowInfo; -import org.onosproject.openstacktelemetry.api.StatsInfo; import java.util.Objects; import static com.google.common.base.MoreObjects.toStringHelper; import static com.google.common.base.Preconditions.checkNotNull; -import static org.onosproject.openstacktelemetry.util.OpenstackTelemetryUtil.getProtocolNameFromType; /** * Implementation class of FlowInfo. @@ -36,6 +34,11 @@ public final class DefaultFlowInfo implements FlowInfo { private static final String INGRESS_STATS = "Ingress Port :"; private static final String EGRESS_STATS = "Egress Port :"; + private static final String PROTOCOL_NAME_TCP = "tcp"; + private static final String PROTOCOL_NAME_UDP = "udp"; + private static final String PROTOCOL_NAME_ANY = "any"; + private static final int ARBITRARY_PROTOCOL = 0x0; + private final byte flowType; private final DeviceId deviceId; private final int inputInterfaceId; @@ -351,4 +354,24 @@ public final class DefaultFlowInfo implements FlowInfo { protocol, srcMac, dstMac, statsInfo); } } + + + /** + * Obtains protocol name from the protocol type. + * + * @param type transport protocol type + * @return transport protocol name + */ + private String getProtocolNameFromType(byte type) { + switch (type) { + case IPv4.PROTOCOL_TCP: + return PROTOCOL_NAME_TCP; + case IPv4.PROTOCOL_UDP: + return PROTOCOL_NAME_UDP; + case ARBITRARY_PROTOCOL: + return PROTOCOL_NAME_ANY; + default: + return PROTOCOL_NAME_ANY; + } + } } diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRule.java b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultStatsFlowRule.java similarity index 98% rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRule.java rename to apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultStatsFlowRule.java index 9ee84f8d3d..065ea63b27 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRule.java +++ b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultStatsFlowRule.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.impl; +package org.onosproject.openstacktelemetry.api; import com.google.common.base.MoreObjects; import org.onlab.packet.IpPrefix; import org.onlab.packet.TpPort; -import org.onosproject.openstacktelemetry.api.StatsFlowRule; import java.util.Objects; diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultStatsInfo.java similarity index 98% rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java rename to apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultStatsInfo.java index 6e085a2dd7..80ab0b92b8 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java +++ b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultStatsInfo.java @@ -13,9 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.impl; - -import org.onosproject.openstacktelemetry.api.StatsInfo; +package org.onosproject.openstacktelemetry.api; import java.util.Objects; diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfig.java b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultTelemetryConfig.java similarity index 99% rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfig.java rename to apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultTelemetryConfig.java index d1304463cb..02c1e84171 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfig.java +++ b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/DefaultTelemetryConfig.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.impl; +package org.onosproject.openstacktelemetry.api; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; diff --git a/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/TelemetryConfigAdminService.java b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/TelemetryConfigAdminService.java index 18ee89bf3e..c752f862dd 100644 --- a/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/TelemetryConfigAdminService.java +++ b/apps/openstacktelemetry/api/src/main/java/org/onosproject/openstacktelemetry/api/TelemetryConfigAdminService.java @@ -51,4 +51,11 @@ public interface TelemetryConfigAdminService extends TelemetryConfigService { * @param config telemetry configuration */ void updateTelemetryConfig(TelemetryConfig config); + + /** + * Removes an existing telemetry configuration with the given config name. + * + * @param name configuration name + */ + void removeTelemetryConfig(String name); } diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfoTest.java b/apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultFlowInfoTest.java similarity index 97% rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfoTest.java rename to apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultFlowInfoTest.java index 1d034151e2..0d49490ae8 100644 --- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfoTest.java +++ b/apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultFlowInfoTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.impl; +package org.onosproject.openstacktelemetry.api; import com.google.common.testing.EqualsTester; import org.junit.Before; @@ -24,8 +24,6 @@ import org.onlab.packet.MacAddress; import org.onlab.packet.TpPort; import org.onlab.packet.VlanId; import org.onosproject.net.DeviceId; -import org.onosproject.openstacktelemetry.api.FlowInfo; -import org.onosproject.openstacktelemetry.api.StatsInfo; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRuleTest.java b/apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultStatsFlowRuleTest.java similarity index 97% rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRuleTest.java rename to apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultStatsFlowRuleTest.java index 54140dcd71..cadcd87f00 100644 --- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRuleTest.java +++ b/apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultStatsFlowRuleTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.impl; +package org.onosproject.openstacktelemetry.api; import com.google.common.testing.EqualsTester; import org.junit.Before; @@ -21,7 +21,6 @@ import org.junit.Test; import org.onlab.packet.IpAddress; import org.onlab.packet.IpPrefix; import org.onlab.packet.TpPort; -import org.onosproject.openstacktelemetry.api.StatsFlowRule; import static org.junit.Assert.assertEquals; import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable; diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfoTest.java b/apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultStatsInfoTest.java similarity index 97% rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfoTest.java rename to apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultStatsInfoTest.java index bfe37454ac..9224374dd9 100644 --- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfoTest.java +++ b/apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultStatsInfoTest.java @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.impl; +package org.onosproject.openstacktelemetry.api; import com.google.common.testing.EqualsTester; import org.junit.Before; import org.junit.Test; -import org.onosproject.openstacktelemetry.api.StatsInfo; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfigTest.java b/apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultTelemetryConfigTest.java similarity index 98% rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfigTest.java rename to apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultTelemetryConfigTest.java index 637f9fc167..6734cfa785 100644 --- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfigTest.java +++ b/apps/openstacktelemetry/api/src/test/java/org/onosproject/openstacktelemetry/api/DefaultTelemetryConfigTest.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.impl; +package org.onosproject.openstacktelemetry.api; import com.google.common.collect.Maps; import com.google.common.testing.EqualsTester; diff --git a/apps/openstacktelemetry/app/BUILD b/apps/openstacktelemetry/app/BUILD index a0a9778212..91fd5aa0fb 100644 --- a/apps/openstacktelemetry/app/BUILD +++ b/apps/openstacktelemetry/app/BUILD @@ -1,4 +1,4 @@ -COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + REST + CLI + [ +COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + CLI + REST + [ "@kafka_clients//jar", "@jersey_client//jar", "@influxdb_java//jar", @@ -20,19 +20,13 @@ COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + REST + CLI + [ "//apps/openstacktelemetry/api:onos-apps-openstacktelemetry-api", ] -TEST_DEPS = TEST_ADAPTERS + TEST_REST + [ +TEST_DEPS = TEST_ADAPTERS + [ "//core/api:onos-api-tests", "//core/common:onos-core-common-tests", - "//web/api:onos-rest-tests", ] osgi_jar_with_tests( - api_description = "OpenStack Network Telemetry REST API", - api_package = "org.onosproject.openstacktelemetry.web", - api_title = "OpenStack Network Telemetry REST API", - api_version = "1.0", karaf_command_packages = ["org.onosproject.openstacktelemetry.cli"], test_deps = TEST_DEPS, - web_context = "/onos/openstacktelemetry", deps = COMPILE_DEPS, ) diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaFlowInfoByteBufferCodec.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaFlowInfoByteBufferCodec.java similarity index 97% rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaFlowInfoByteBufferCodec.java rename to apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaFlowInfoByteBufferCodec.java index 2ee625fbb5..759dd5abfe 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaFlowInfoByteBufferCodec.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaFlowInfoByteBufferCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.codec; +package org.onosproject.openstacktelemetry.codec.bytebuffer; import org.onlab.packet.IpAddress; import org.onlab.packet.IpAddress.Version; @@ -25,7 +25,7 @@ import org.onosproject.net.DeviceId; import org.onosproject.openstacktelemetry.api.ByteBufferCodec; import org.onosproject.openstacktelemetry.api.FlowInfo; import org.onosproject.openstacktelemetry.api.StatsInfo; -import org.onosproject.openstacktelemetry.impl.DefaultFlowInfo; +import org.onosproject.openstacktelemetry.api.DefaultFlowInfo; import java.nio.ByteBuffer; diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaMessageByteBufferCodec.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaMessageByteBufferCodec.java similarity index 97% rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaMessageByteBufferCodec.java rename to apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaMessageByteBufferCodec.java index 2be5f3e051..514bc2352d 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaMessageByteBufferCodec.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaMessageByteBufferCodec.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.codec; +package org.onosproject.openstacktelemetry.codec.bytebuffer; import org.onosproject.openstacktelemetry.api.FlowInfo; import org.onosproject.openstacktelemetry.api.TelemetryCodec; diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaStatsInfoByteBufferCodec.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaStatsInfoByteBufferCodec.java similarity index 95% rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaStatsInfoByteBufferCodec.java rename to apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaStatsInfoByteBufferCodec.java index ce3faa8c8b..456dc72cda 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/TinaStatsInfoByteBufferCodec.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaStatsInfoByteBufferCodec.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.onosproject.openstacktelemetry.codec; +package org.onosproject.openstacktelemetry.codec.bytebuffer; import org.onosproject.openstacktelemetry.api.ByteBufferCodec; import org.onosproject.openstacktelemetry.api.StatsInfo; -import org.onosproject.openstacktelemetry.impl.DefaultStatsInfo; +import org.onosproject.openstacktelemetry.api.DefaultStatsInfo; import java.nio.ByteBuffer; diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/package-info.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/package-info.java new file mode 100644 index 0000000000..b8ef80a460 --- /dev/null +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/bytebuffer/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2018-present Open Networking Foundation + * + * 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. + */ + +/** + * Implementations of the codec broker and openstack telemetry entity codecs. + */ +package org.onosproject.openstacktelemetry.codec.bytebuffer; \ No newline at end of file diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/gui/OpensteckTelemetryViewMessageHandler.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/gui/OpensteckTelemetryViewMessageHandler.java index dcb7082ae7..f6d9bdd454 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/gui/OpensteckTelemetryViewMessageHandler.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/gui/OpensteckTelemetryViewMessageHandler.java @@ -30,7 +30,7 @@ import org.onosproject.net.host.HostService; import org.onosproject.openstacktelemetry.api.FlowInfo; import org.onosproject.openstacktelemetry.api.StatsFlowRule; import org.onosproject.openstacktelemetry.api.StatsFlowRuleAdminService; -import org.onosproject.openstacktelemetry.impl.DefaultStatsFlowRule; +import org.onosproject.openstacktelemetry.api.DefaultStatsFlowRule; import org.onosproject.ui.RequestHandler; import org.onosproject.ui.UiConnection; import org.onosproject.ui.UiMessageHandler; diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DistributedTelemetryConfigStore.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DistributedTelemetryConfigStore.java index 8fc31a6c61..d066d859d0 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DistributedTelemetryConfigStore.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DistributedTelemetryConfigStore.java @@ -19,6 +19,7 @@ import com.google.common.collect.ImmutableSet; import org.onlab.util.KryoNamespace; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; +import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig; import org.onosproject.openstacktelemetry.api.TelemetryConfigEvent; import org.onosproject.openstacktelemetry.api.TelemetryConfigProvider; import org.onosproject.openstacktelemetry.api.TelemetryConfigStore; diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/InfluxDbTelemetryManager.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/InfluxDbTelemetryManager.java index 962779a4b7..38dd2b8af9 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/InfluxDbTelemetryManager.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/InfluxDbTelemetryManager.java @@ -201,7 +201,7 @@ public class InfluxDbTelemetryManager implements InfluxDbTelemetryAdminService { InfluxDB producer = InfluxDBFactory.connect(influxDbServerBuilder.toString(), influxDbConfig.username(), influxDbConfig.password()); - producers.put(config.name(), producer); + producers.put(name, producer); createDB(producer, influxDbConfig.database()); } diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/KafkaTelemetryManager.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/KafkaTelemetryManager.java index 152bfde2a1..06936cadac 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/KafkaTelemetryManager.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/KafkaTelemetryManager.java @@ -54,8 +54,6 @@ public class KafkaTelemetryManager implements KafkaTelemetryAdminService { private final Logger log = LoggerFactory.getLogger(getClass()); - private static final String CODEC_PREFIX = "org.onosproject.openstacktelemetry.codec."; - private static final String BOOTSTRAP_SERVERS = "bootstrap.servers"; private static final String RETRIES = "retries"; private static final String ACKS = "acks"; @@ -102,11 +100,10 @@ public class KafkaTelemetryManager implements KafkaTelemetryAdminService { Set> futureSet = Sets.newHashSet(); producers.forEach((k, v) -> { TelemetryConfig config = telemetryConfigService.getConfig(k); - KafkaTelemetryConfig kafkaConfig = - fromTelemetryConfig(config); + KafkaTelemetryConfig kafkaConfig = fromTelemetryConfig(config); try { - Class codecClazz = Class.forName(CODEC_PREFIX + kafkaConfig.codec()); + Class codecClazz = Class.forName(kafkaConfig.codec()); TelemetryCodec codec = (TelemetryCodec) codecClazz.newInstance(); ByteBuffer buffer = codec.encode(flowInfos); @@ -148,7 +145,7 @@ public class KafkaTelemetryManager implements KafkaTelemetryAdminService { prop.put(KEY_SERIALIZER, kafkaConfig.keySerializer()); prop.put(VALUE_SERIALIZER, kafkaConfig.valueSerializer()); - producers.put(config.name(), new KafkaProducer<>(prop)); + producers.put(name, new KafkaProducer<>(prop)); } } diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/StatsFlowRuleManager.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/StatsFlowRuleManager.java index 3d9f577e84..30faac7665 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/StatsFlowRuleManager.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/StatsFlowRuleManager.java @@ -57,6 +57,9 @@ import org.onosproject.openstacknetworking.api.InstancePortService; import org.onosproject.openstacknetworking.api.OpenstackNetworkService; import org.onosproject.openstacknode.api.OpenstackNode; import org.onosproject.openstacknode.api.OpenstackNodeService; +import org.onosproject.openstacktelemetry.api.DefaultFlowInfo; +import org.onosproject.openstacktelemetry.api.DefaultStatsFlowRule; +import org.onosproject.openstacktelemetry.api.DefaultStatsInfo; import org.onosproject.openstacktelemetry.api.FlowInfo; import org.onosproject.openstacktelemetry.api.OpenstackTelemetryService; import org.onosproject.openstacktelemetry.api.StatsFlowRule; diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/TelemetryConfigManager.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/TelemetryConfigManager.java index 3ae2504b1b..9832ad3801 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/TelemetryConfigManager.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/TelemetryConfigManager.java @@ -23,6 +23,7 @@ import org.onosproject.cluster.NodeId; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.event.ListenerRegistry; +import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig; import org.onosproject.openstacktelemetry.api.TelemetryConfigAdminService; import org.onosproject.openstacktelemetry.api.TelemetryConfigEvent; import org.onosproject.openstacktelemetry.api.TelemetryConfigListener; @@ -74,6 +75,7 @@ public class TelemetryConfigManager private static final String ERR_NULL_CONFIG = "Telemetry config cannot be null"; private static final String NO_CONFIG = "Telemetry config not found"; + private static final String ERR_NULL_CONFIG_NAME = "Telemetry config name cannot be null"; private static final KryoNamespace SERIALIZER_TELEMETRY_CONFIG = KryoNamespace.newBuilder() @@ -174,6 +176,14 @@ public class TelemetryConfigManager log.info(String.format(MSG_TELEMETRY_CONFIG, config.name(), MSG_UPDATED)); } + @Override + public void removeTelemetryConfig(String name) { + checkNotNull(name, ERR_NULL_CONFIG_NAME); + + telemetryConfigStore.removeTelemetryConfig(name); + log.info(String.format(MSG_TELEMETRY_CONFIG, name, MSG_REMOVED)); + } + @Override public TelemetryConfig getConfig(String name) { return nullIsNotFound(telemetryConfigStore.telemetryConfig(name), NO_CONFIG); diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/XmlTelemetryConfigLoader.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/XmlTelemetryConfigLoader.java index 39a5df09ea..c9c6e9f90d 100644 --- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/XmlTelemetryConfigLoader.java +++ b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/XmlTelemetryConfigLoader.java @@ -21,6 +21,7 @@ import com.google.common.collect.Maps; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.HierarchicalConfiguration; import org.apache.commons.configuration.XMLConfiguration; +import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig; import org.onosproject.openstacktelemetry.api.config.TelemetryConfig; import java.io.IOException; @@ -45,8 +46,8 @@ import static org.onosproject.openstacktelemetry.api.config.TelemetryConfig.Conf *

*
  *     <configs>
- *         <config name=“...” [manufacturer="..." swVersion="..."]>
- *            [<property name=“key”>value</key>]
+ *         <config name="..." [manufacturer="..." swVersion="..."]>
+ *            [<property name="key">value</key>]
  *            ...
  *        </config>
  *        ...
@@ -203,10 +204,16 @@ public class XmlTelemetryConfigLoader {
         ImmutableMap.Builder properties = ImmutableMap.builder();
 
         // note that, we only allow the inheritance from single source
-        Map parentConfigs = Maps.newHashMap();
+        final Map parentConfigs = Maps.newHashMap();
         if (!parents.isEmpty()) {
             TelemetryConfig parent = parents.get(0);
-            parentConfigs = parent.properties();
+            parent.properties().forEach(parentConfigs::put);
+        }
+
+        for (HierarchicalConfiguration b : config.configurationsAt(PROPERTY)) {
+            if (parentConfigs.keySet().contains(b.getString(NAME))) {
+                parentConfigs.remove(b.getString(NAME));
+            }
         }
 
         properties.putAll(parentConfigs);
@@ -214,6 +221,7 @@ public class XmlTelemetryConfigLoader {
         for (HierarchicalConfiguration b : config.configurationsAt(PROPERTY)) {
             properties.put(b.getString(NAME), (String) b.getRootNode().getValue());
         }
+
         return properties.build();
     }
 }
diff --git a/apps/openstacktelemetry/app/src/main/resources/definitions/dummy.json b/apps/openstacktelemetry/app/src/main/resources/definitions/dummy.json
deleted file mode 100644
index 7a73a41bfd..0000000000
--- a/apps/openstacktelemetry/app/src/main/resources/definitions/dummy.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{
-}
\ No newline at end of file
diff --git a/apps/openstacktelemetry/app/src/main/resources/org/onosproject/openstacktelemetry/impl/kafka-configs.xml b/apps/openstacktelemetry/app/src/main/resources/org/onosproject/openstacktelemetry/impl/kafka-configs.xml
index 7429ac2845..48623b6621 100644
--- a/apps/openstacktelemetry/app/src/main/resources/org/onosproject/openstacktelemetry/impl/kafka-configs.xml
+++ b/apps/openstacktelemetry/app/src/main/resources/org/onosproject/openstacktelemetry/impl/kafka-configs.xml
@@ -34,6 +34,8 @@
         
         sona.flow
         flowdata
-        TinaMessageByteBufferCodec
+        
+            org.onosproject.openstacktelemetry.codec.bytebuffer.TinaMessageByteBufferCodec
+        
     
 
\ No newline at end of file
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/TinaFlowInfoByteBufferCodecTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaFlowInfoByteBufferCodecTest.java
similarity index 92%
rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/TinaFlowInfoByteBufferCodecTest.java
rename to apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaFlowInfoByteBufferCodecTest.java
index 8f4af77b97..b1f48e4b49 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/TinaFlowInfoByteBufferCodecTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaFlowInfoByteBufferCodecTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacktelemetry.codec;
+package org.onosproject.openstacktelemetry.codec.bytebuffer;
 
 import com.google.common.testing.EqualsTester;
 import org.junit.Before;
@@ -24,10 +24,10 @@ import org.onlab.packet.MacAddress;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
 import org.onosproject.net.DeviceId;
+import org.onosproject.openstacktelemetry.api.DefaultFlowInfo;
+import org.onosproject.openstacktelemetry.api.DefaultStatsInfo;
 import org.onosproject.openstacktelemetry.api.FlowInfo;
 import org.onosproject.openstacktelemetry.api.StatsInfo;
-import org.onosproject.openstacktelemetry.impl.DefaultFlowInfo;
-import org.onosproject.openstacktelemetry.impl.DefaultStatsInfo;
 
 import java.nio.ByteBuffer;
 
@@ -52,8 +52,7 @@ public final class TinaFlowInfoByteBufferCodecTest {
     private static final MacAddress DST_MAC_ADDRESS = MacAddress.valueOf("FF:EE:DD:CC:BB:AA");
 
     private FlowInfo info;
-    private final TinaFlowInfoByteBufferCodec codec =
-            new TinaFlowInfoByteBufferCodec();
+    private final TinaFlowInfoByteBufferCodec codec = new TinaFlowInfoByteBufferCodec();
 
     /**
      * Initial setup for this unit test.
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/TinaStatsInfoByteBufferCodecTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaStatsInfoByteBufferCodecTest.java
similarity index 90%
rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/TinaStatsInfoByteBufferCodecTest.java
rename to apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaStatsInfoByteBufferCodecTest.java
index f32e5bbcdb..d217aea34a 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/TinaStatsInfoByteBufferCodecTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/bytebuffer/TinaStatsInfoByteBufferCodecTest.java
@@ -13,13 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacktelemetry.codec;
+package org.onosproject.openstacktelemetry.codec.bytebuffer;
 
 import com.google.common.testing.EqualsTester;
 import org.junit.Before;
 import org.junit.Test;
+import org.onosproject.openstacktelemetry.api.DefaultStatsInfo;
 import org.onosproject.openstacktelemetry.api.StatsInfo;
-import org.onosproject.openstacktelemetry.impl.DefaultStatsInfo;
 
 import java.nio.ByteBuffer;
 
@@ -39,8 +39,7 @@ public class TinaStatsInfoByteBufferCodecTest {
     private static final short DROP_PACKETS = 30000;
 
     private StatsInfo info;
-    private final TinaStatsInfoByteBufferCodec codec =
-                                            new TinaStatsInfoByteBufferCodec();
+    private final TinaStatsInfoByteBufferCodec codec = new TinaStatsInfoByteBufferCodec();
 
     /**
      * Initial setup for this unit test.
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultGrpcTelemetryConfigTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultGrpcTelemetryConfigTest.java
index c56247f8e0..89fc1d0533 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultGrpcTelemetryConfigTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultGrpcTelemetryConfigTest.java
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.openstacktelemetry.api.config.GrpcTelemetryConfig;
 import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
-import org.onosproject.openstacktelemetry.impl.DefaultTelemetryConfig;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
 
 import java.util.Map;
 
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultInfluxDbTelemetryConfigTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultInfluxDbTelemetryConfigTest.java
index cd4a9737f3..9f8401536c 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultInfluxDbTelemetryConfigTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultInfluxDbTelemetryConfigTest.java
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.openstacktelemetry.api.config.InfluxDbTelemetryConfig;
 import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
-import org.onosproject.openstacktelemetry.impl.DefaultTelemetryConfig;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
 
 import java.util.Map;
 
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultKafkaTelemetryConfigTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultKafkaTelemetryConfigTest.java
index ba9b34ba60..999bcf16db 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultKafkaTelemetryConfigTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultKafkaTelemetryConfigTest.java
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.openstacktelemetry.api.config.KafkaTelemetryConfig;
 import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
-import org.onosproject.openstacktelemetry.impl.DefaultTelemetryConfig;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
 
 import java.util.Map;
 
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultPrometheusTelemetryConfigTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultPrometheusTelemetryConfigTest.java
index de94f8306e..4a89b74a74 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultPrometheusTelemetryConfigTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultPrometheusTelemetryConfigTest.java
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.openstacktelemetry.api.config.PrometheusTelemetryConfig;
 import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
-import org.onosproject.openstacktelemetry.impl.DefaultTelemetryConfig;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
 
 import java.util.Map;
 
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultRestTelemetryConfigTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultRestTelemetryConfigTest.java
index c78bb63383..28b84650ec 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultRestTelemetryConfigTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/config/DefaultRestTelemetryConfigTest.java
@@ -23,7 +23,7 @@ import org.junit.Before;
 import org.junit.Test;
 import org.onosproject.openstacktelemetry.api.config.RestTelemetryConfig;
 import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
-import org.onosproject.openstacktelemetry.impl.DefaultTelemetryConfig;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
 
 import java.util.Map;
 
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultInfluxRecordTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultInfluxRecordTest.java
index 866e34d76c..da693803f4 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultInfluxRecordTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DefaultInfluxRecordTest.java
@@ -25,6 +25,8 @@ import org.onlab.packet.MacAddress;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
 import org.onosproject.net.DeviceId;
+import org.onosproject.openstacktelemetry.api.DefaultFlowInfo;
+import org.onosproject.openstacktelemetry.api.DefaultStatsInfo;
 import org.onosproject.openstacktelemetry.api.FlowInfo;
 import org.onosproject.openstacktelemetry.api.InfluxRecord;
 import org.onosproject.openstacktelemetry.api.StatsInfo;
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DistributedTelemetryConfigStoreTest.java b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DistributedTelemetryConfigStoreTest.java
index 511fa6ddb5..85f6b413f9 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DistributedTelemetryConfigStoreTest.java
+++ b/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/impl/DistributedTelemetryConfigStoreTest.java
@@ -22,6 +22,7 @@ import org.junit.Test;
 import org.onosproject.TestApplicationId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
 import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
 import org.onosproject.openstacktelemetry.api.config.TelemetryConfig.ConfigType;
 import org.onosproject.store.service.TestStorageService;
diff --git a/apps/openstacktelemetry/web/BUILD b/apps/openstacktelemetry/web/BUILD
new file mode 100644
index 0000000000..a677d58fbb
--- /dev/null
+++ b/apps/openstacktelemetry/web/BUILD
@@ -0,0 +1,19 @@
+COMPILE_DEPS = CORE_DEPS + JACKSON + KRYO + REST + [
+    "//apps/openstacktelemetry/api:onos-apps-openstacktelemetry-api",
+]
+
+TEST_DEPS = TEST_ADAPTERS + TEST_REST + [
+    "//core/api:onos-api-tests",
+    "//core/common:onos-core-common-tests",
+    "//web/api:onos-rest-tests",
+]
+
+osgi_jar_with_tests(
+    api_description = "OpenStack Network Telemetry REST API",
+    api_package = "org.onosproject.openstacktelemetry.web",
+    api_title = "OpenStack Network Telemetry REST API",
+    api_version = "1.0",
+    test_deps = TEST_DEPS,
+    web_context = "/onos/openstacktelemetry",
+    deps = COMPILE_DEPS,
+)
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonCodec.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonCodec.java
similarity index 98%
rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonCodec.java
rename to apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonCodec.java
index be51b15453..a6d75ec1e6 100644
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonCodec.java
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonCodec.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacktelemetry.codec;
+package org.onosproject.openstacktelemetry.codec.rest;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -27,7 +27,7 @@ import org.onosproject.codec.JsonCodec;
 import org.onosproject.net.DeviceId;
 import org.onosproject.openstacktelemetry.api.FlowInfo;
 import org.onosproject.openstacktelemetry.api.StatsInfo;
-import org.onosproject.openstacktelemetry.impl.DefaultFlowInfo;
+import org.onosproject.openstacktelemetry.api.DefaultFlowInfo;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onlab.packet.VlanId.NO_VID;
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/StatsFlowRuleJsonCodec.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/StatsFlowRuleJsonCodec.java
similarity index 80%
rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/StatsFlowRuleJsonCodec.java
rename to apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/StatsFlowRuleJsonCodec.java
index 384987b6a9..3d2b13fc50 100644
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/StatsFlowRuleJsonCodec.java
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/StatsFlowRuleJsonCodec.java
@@ -13,21 +13,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacktelemetry.codec;
+package org.onosproject.openstacktelemetry.codec.rest;
 
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IpPrefix;
 import org.onlab.packet.TpPort;
 import org.onosproject.codec.CodecContext;
 import org.onosproject.codec.JsonCodec;
+import org.onosproject.openstacktelemetry.api.DefaultStatsFlowRule;
 import org.onosproject.openstacktelemetry.api.StatsFlowRule;
-import org.onosproject.openstacktelemetry.impl.DefaultStatsFlowRule;
 import org.slf4j.Logger;
 
-import org.onlab.packet.IpPrefix;
-
 import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.openstacktelemetry.util.OpenstackTelemetryUtil.getProtocolTypeFromString;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -37,6 +36,11 @@ public class StatsFlowRuleJsonCodec extends JsonCodec {
 
     private final Logger log = getLogger(getClass());
 
+    private static final String PROTOCOL_NAME_TCP = "tcp";
+    private static final String PROTOCOL_NAME_UDP = "udp";
+    private static final String PROTOCOL_NAME_ANY = "any";
+    private static final int ARBITRARY_PROTOCOL = 0x0;
+
     public static final String SRC_IP_PREFIX = "srcIpPrefix";
     public static final String DST_IP_PREFIX = "dstIpPrefix";
     public static final String IP_PROTOCOL   = "ipProtocol";
@@ -88,4 +92,21 @@ public class StatsFlowRuleJsonCodec extends JsonCodec {
         }
         return null;
     }
+
+    /**
+     * Obtains transport protocol type from the given string.
+     *
+     * @param str transport protocol name
+     * @return transport protocol type
+     */
+    private byte getProtocolTypeFromString(String str) {
+        switch (str.toLowerCase()) {
+            case PROTOCOL_NAME_TCP:
+                return IPv4.PROTOCOL_TCP;
+            case PROTOCOL_NAME_UDP:
+                return IPv4.PROTOCOL_UDP;
+            default:
+                return ARBITRARY_PROTOCOL;
+        }
+    }
 }
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/StatsInfoJsonCodec.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/StatsInfoJsonCodec.java
similarity index 96%
rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/StatsInfoJsonCodec.java
rename to apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/StatsInfoJsonCodec.java
index 905b2ff77f..de8a7ef5ad 100644
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/StatsInfoJsonCodec.java
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/StatsInfoJsonCodec.java
@@ -13,13 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacktelemetry.codec;
+package org.onosproject.openstacktelemetry.codec.rest;
 
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import org.onosproject.codec.CodecContext;
 import org.onosproject.codec.JsonCodec;
 import org.onosproject.openstacktelemetry.api.StatsInfo;
-import org.onosproject.openstacktelemetry.impl.DefaultStatsInfo;
+import org.onosproject.openstacktelemetry.api.DefaultStatsInfo;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
diff --git a/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigJsonCodec.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigJsonCodec.java
new file mode 100644
index 0000000000..8c0a6e3e9e
--- /dev/null
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigJsonCodec.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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 org.onosproject.openstacktelemetry.codec.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
+import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
+
+import java.util.Map;
+import java.util.stream.IntStream;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.nullIsIllegal;
+
+/**
+ * Openstack telemetry config codec used for serializing and de-serializing JSON string.
+ */
+public final class TelemetryConfigJsonCodec extends JsonCodec {
+
+    private static final String NAME = "name";
+    private static final String TYPE = "type";
+    private static final String MANUFACTURER = "manufacturer";
+    private static final String SW_VERSION = "swVersion";
+    private static final String ENABLED = "enabled";
+    private static final String PROPS = "props";
+    private static final String KEY = "key";
+    private static final String VALUE = "value";
+
+    private static final String MISSING_MESSAGE = " is required in TelemetryConfig";
+
+    @Override
+    public ObjectNode encode(TelemetryConfig config, CodecContext context) {
+        checkNotNull(config, "TelemetryConfig cannot be null");
+
+        ObjectNode node = context.mapper().createObjectNode()
+                .put(NAME, config.name())
+                .put(TYPE, config.type().name())
+                .put(MANUFACTURER, config.manufacturer())
+                .put(SW_VERSION, config.swVersion())
+                .put(ENABLED, config.enabled());
+
+        Map props = config.properties();
+        ArrayNode propsJson = context.mapper().createArrayNode();
+        props.forEach((k, v) -> {
+            ObjectNode propNode = context.mapper().createObjectNode();
+            propNode.put(KEY, k);
+            propNode.put(VALUE, v);
+            propsJson.add(propNode);
+        });
+        node.set(PROPS, propsJson);
+        return node;
+    }
+
+    @Override
+    public TelemetryConfig decode(ObjectNode json, CodecContext context) {
+        if (json == null || !json.isObject()) {
+            return null;
+        }
+
+        // parse name
+        String name = nullIsIllegal(json.get(NAME),
+                NAME + MISSING_MESSAGE).asText();
+
+        // parse type
+        String type = nullIsIllegal(json.get(TYPE),
+                TYPE + MISSING_MESSAGE).asText();
+
+        TelemetryConfig.ConfigType configType = configType(type);
+
+        // parse manufacturer
+        String manufacturer = nullIsIllegal(json.get(MANUFACTURER).asText(),
+                MANUFACTURER + MISSING_MESSAGE);
+
+        // parse software version
+        String swVersion = nullIsIllegal(json.get(SW_VERSION),
+                SW_VERSION + MISSING_MESSAGE).asText();
+
+        // parse enabled flag
+        boolean enabled = nullIsIllegal(json.get(ENABLED),
+                ENABLED + MISSING_MESSAGE).asBoolean();
+
+        JsonNode propertiesJson = json.get(PROPS);
+        Map properties = Maps.newConcurrentMap();
+        if (propertiesJson != null) {
+            IntStream.range(0, propertiesJson.size()).forEach(i -> {
+                ObjectNode propertyJson = get(propertiesJson, i);
+                properties.put(propertyJson.get(KEY).asText(),
+                        propertyJson.get(VALUE).asText());
+            });
+        }
+
+        return new DefaultTelemetryConfig(name, configType,
+                ImmutableList.of(), manufacturer, swVersion, enabled, properties);
+    }
+
+    private TelemetryConfig.ConfigType configType(String type) {
+        switch (type.toUpperCase()) {
+            case "KAFKA" :
+                return TelemetryConfig.ConfigType.KAFKA;
+            case "GRPC" :
+                return TelemetryConfig.ConfigType.GRPC;
+            case "INFLUXDB" :
+                return TelemetryConfig.ConfigType.INFLUXDB;
+            case "PROMETHEUS" :
+                return TelemetryConfig.ConfigType.PROMETHEUS;
+            case "REST" :
+                return TelemetryConfig.ConfigType.REST;
+            default:
+                return TelemetryConfig.ConfigType.UNKNOWN;
+        }
+    }
+}
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/package-info.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/package-info.java
similarity index 92%
rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/package-info.java
rename to apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/package-info.java
index f7f6401ff7..3a699c1dd0 100644
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/codec/package-info.java
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/codec/rest/package-info.java
@@ -17,4 +17,4 @@
 /**
  * Implementations of the codec broker and openstack telemetry entity codecs.
  */
-package org.onosproject.openstacktelemetry.codec;
\ No newline at end of file
+package org.onosproject.openstacktelemetry.codec.rest;
\ No newline at end of file
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegister.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegister.java
similarity index 80%
rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegister.java
rename to apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegister.java
index c8bfeb5d3e..6bd8636f93 100644
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegister.java
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegister.java
@@ -15,18 +15,20 @@
  */
 package org.onosproject.openstacktelemetry.web;
 
+import org.onosproject.codec.CodecService;
+import org.onosproject.openstacktelemetry.api.FlowInfo;
+import org.onosproject.openstacktelemetry.api.StatsFlowRule;
+import org.onosproject.openstacktelemetry.api.StatsInfo;
+import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
+import org.onosproject.openstacktelemetry.codec.rest.FlowInfoJsonCodec;
+import org.onosproject.openstacktelemetry.codec.rest.StatsFlowRuleJsonCodec;
+import org.onosproject.openstacktelemetry.codec.rest.StatsInfoJsonCodec;
+import org.onosproject.openstacktelemetry.codec.rest.TelemetryConfigJsonCodec;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.onosproject.codec.CodecService;
-import org.onosproject.openstacktelemetry.api.FlowInfo;
-import org.onosproject.openstacktelemetry.api.StatsFlowRule;
-import org.onosproject.openstacktelemetry.api.StatsInfo;
-import org.onosproject.openstacktelemetry.codec.FlowInfoJsonCodec;
-import org.onosproject.openstacktelemetry.codec.StatsFlowRuleJsonCodec;
-import org.onosproject.openstacktelemetry.codec.StatsInfoJsonCodec;
 
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -46,6 +48,7 @@ public class OpenstackTelemetryCodecRegister {
         codecService.registerCodec(StatsInfo.class, new StatsInfoJsonCodec());
         codecService.registerCodec(FlowInfo.class, new FlowInfoJsonCodec());
         codecService.registerCodec(StatsFlowRule.class, new StatsFlowRuleJsonCodec());
+        codecService.registerCodec(TelemetryConfig.class, new TelemetryConfigJsonCodec());
 
         log.info("Started");
     }
@@ -55,6 +58,7 @@ public class OpenstackTelemetryCodecRegister {
         codecService.unregisterCodec(StatsInfo.class);
         codecService.unregisterCodec(FlowInfo.class);
         codecService.unregisterCodec(StatsFlowRule.class);
+        codecService.unregisterCodec(TelemetryConfig.class);
 
         log.info("Stopped");
     }
diff --git a/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryConfigWebResource.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryConfigWebResource.java
new file mode 100644
index 0000000000..7484d04f6c
--- /dev/null
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryConfigWebResource.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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 org.onosproject.openstacktelemetry.web;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Maps;
+import org.onosproject.openstacktelemetry.api.TelemetryConfigAdminService;
+import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
+import org.onosproject.rest.AbstractWebResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.Map;
+
+import static org.onlab.util.Tools.nullIsIllegal;
+import static org.onlab.util.Tools.nullIsNotFound;
+
+/**
+ * Handles REST API call of openstack telemetry configuration.
+ */
+@Path("config")
+public class OpenstackTelemetryConfigWebResource extends AbstractWebResource {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final String MESSAGE_CONFIG = "Received config %s request";
+    private static final String CONFIG = "config";
+    private static final String ADDRESS = "address";
+    private static final String QUERY = "QUERY";
+    private static final String UPDATE = "UPDATE";
+    private static final String DELETE = "DELETE";
+    private static final String CONFIG_NAME = "config name";
+    private static final String NOT_NULL_MESSAGE = " cannot be null";
+    private static final String CONFIG_NOT_FOUND = "Config is not found";
+
+    private final TelemetryConfigAdminService configService =
+                                        get(TelemetryConfigAdminService.class);
+
+    @Context
+    private UriInfo uriInfo;
+
+    /**
+     * Updates the telemetry configuration address from the JSON input stream.
+     *
+     * @param configName telemetry config name
+     * @param address telemetry config address
+     * @return 200 OK with the updated telemetry config, 400 BAD_REQUEST
+     * if the JSON is malformed, and 304 NOT_MODIFIED without the updated config
+     * due to incorrect configuration name so that we cannot find the existing config
+     */
+    @PUT
+    @Path("address/{name}/{address}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response updateConfigAddress(@PathParam("name") String configName,
+                                        @PathParam("address") String address) {
+        log.trace(String.format(MESSAGE_CONFIG, UPDATE));
+
+        try {
+            TelemetryConfig config = configService.getConfig(
+                    nullIsIllegal(configName, CONFIG_NAME + NOT_NULL_MESSAGE));
+
+            if (config == null) {
+                log.warn("There is no config found to modify for {}", configName);
+                return Response.notModified().build();
+            } else {
+                Map updatedProperties =
+                        Maps.newHashMap(config.properties());
+                updatedProperties.put(ADDRESS,
+                        nullIsIllegal(address, ADDRESS + NOT_NULL_MESSAGE));
+                TelemetryConfig updatedConfig =
+                        config.updateProperties(updatedProperties);
+
+                configService.updateTelemetryConfig(updatedConfig);
+                return Response.ok().build();
+            }
+
+        } catch (Exception e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Deletes the telemetry configuration by referring to configuration name.
+     *
+     * @param configName telemetry configuration name
+     * @return 204 NO_CONTENT, 400 BAD_REQUEST if the JSON is malformed,
+     * and 304 NOT_MODIFIED without removing config, due to incorrect
+     * configuration name so that we cannot find the existing config
+     */
+    @DELETE
+    @Path("{name}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response deleteTelemetryConfig(@PathParam("name") String configName) {
+        log.trace(String.format(MESSAGE_CONFIG, DELETE));
+
+        TelemetryConfig config = configService.getConfig(
+                nullIsIllegal(configName, CONFIG_NAME + NOT_NULL_MESSAGE));
+
+        if (config == null) {
+            log.warn("There is no config found to delete for {}", configName);
+            return Response.notModified().build();
+        } else {
+            configService.removeTelemetryConfig(configName);
+            return Response.noContent().build();
+        }
+    }
+
+    /**
+     * Get details of telemetry config.
+     * Returns detailed properties of the specified telemetry config.
+     *
+     * @param configName telemetry configName
+     * @return 200 OK with detailed properties of the specific telemetry config
+     * @onos.rsModel TelemetryConfig
+     */
+    @GET
+    @Path("{name}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getConfig(@PathParam("name") String configName) {
+        log.trace(String.format(MESSAGE_CONFIG, QUERY));
+
+        final TelemetryConfig config =
+                nullIsNotFound(configService.getConfig(configName), CONFIG_NOT_FOUND);
+        final ObjectNode root = codec(TelemetryConfig.class).encode(config, this);
+        return ok(root).build();
+    }
+
+    /**
+     * Enables the telemetry configuration with the given config name.
+     *
+     * @param configName telemetry configuration name
+     * @return 200 OK with the enabled telemetry config,
+     * 400 BAD_REQUEST if the JSON is malformed,
+     * and 304 NOT_MODIFIED without removing config, due to incorrect
+     * configuration name so that we cannot find the existing config
+     */
+    @PUT
+    @Path("enable/{name}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response enableConfig(@PathParam("name") String configName) {
+        log.trace(String.format(MESSAGE_CONFIG, UPDATE));
+
+        TelemetryConfig config = configService.getConfig(
+                nullIsIllegal(configName, CONFIG_NAME + NOT_NULL_MESSAGE));
+
+        if (config == null) {
+            log.warn("There is no config found to enable for {}", configName);
+            return Response.notModified().build();
+        } else {
+            TelemetryConfig updatedConfig = config.updateEnabled(true);
+            configService.updateTelemetryConfig(updatedConfig);
+            return Response.ok().build();
+        }
+    }
+
+    /**
+     * Disables the telemetry configuration with the given config name.
+     *
+     * @param configName telemetry configuration name
+     * @return 200 OK with the disabled telemetry config
+     * 400 BAD_REQUEST if the JSON is malformed,
+     * and 304 NOT_MODIFIED without removing config, due to incorrect
+     * configuration name so that we cannot find the existing config
+     */
+    @PUT
+    @Path("disable/{name}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response disableConfig(@PathParam("name") String configName) {
+        log.trace(String.format(MESSAGE_CONFIG, UPDATE));
+
+        TelemetryConfig config = configService.getConfig(
+                nullIsIllegal(configName, CONFIG_NAME + NOT_NULL_MESSAGE));
+
+        if (config == null) {
+            log.warn("There is no config found to disable for {}", configName);
+            return Response.notModified().build();
+        } else {
+            TelemetryConfig updatedConfig = config.updateEnabled(false);
+            configService.updateTelemetryConfig(updatedConfig);
+            return Response.ok().build();
+        }
+    }
+}
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebApplication.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebApplication.java
similarity index 88%
rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebApplication.java
rename to apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebApplication.java
index 9dc4e185bb..4deff1c773 100644
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebApplication.java
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebApplication.java
@@ -25,6 +25,7 @@ import java.util.Set;
 public class OpenstackTelemetryWebApplication extends AbstractWebApplication {
     @Override
     public Set> getClasses() {
-        return getClasses(OpenstackTelemetryWebResource.class);
+        return getClasses(OpenstackTelemetryWebResource.class,
+                OpenstackTelemetryConfigWebResource.class);
     }
 }
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebResource.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebResource.java
similarity index 94%
rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebResource.java
rename to apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebResource.java
index 34f8366032..40b5c93165 100644
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebResource.java
+++ b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryWebResource.java
@@ -24,7 +24,7 @@ import org.onosproject.codec.JsonCodec;
 import org.onosproject.openstacktelemetry.api.FlowInfo;
 import org.onosproject.openstacktelemetry.api.StatsFlowRule;
 import org.onosproject.openstacktelemetry.api.StatsFlowRuleAdminService;
-import org.onosproject.openstacktelemetry.codec.FlowInfoJsonCodec;
+import org.onosproject.openstacktelemetry.codec.rest.FlowInfoJsonCodec;
 import org.onosproject.rest.AbstractWebResource;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,7 +51,6 @@ import static org.onlab.util.Tools.readTreeFromStream;
 /**
  * Handles REST API call of openstack telemetry.
  */
-
 @Path("telemetry")
 public class OpenstackTelemetryWebResource extends AbstractWebResource {
 
@@ -138,18 +137,13 @@ public class OpenstackTelemetryWebResource extends AbstractWebResource {
         Set flowInfoSet;
         flowInfoSet = statsFlowRuleService.getOverlayFlowInfos();
 
-        log.info("\n\n======================================================\n" +
-                 "FlowInfo Set: \n{}" +
-                 "\n\n======================================================\n",
-                 flowInfoSet);
-
         JsonCodec flowInfoCodec = new FlowInfoJsonCodec();
 
         ObjectNode nodeJson;
         int idx = 0;
         for (FlowInfo flowInfo: flowInfoSet) {
             nodeJson = flowInfoCodec.encode(flowInfo, this);
-            root.put("FlowInfo" + String.valueOf(idx++), nodeJson.toString());
+            root.put("FlowInfo" + idx++, nodeJson.toString());
         }
         return ok(root).build();
     }
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/package-info.java b/apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/package-info.java
similarity index 100%
rename from apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/web/package-info.java
rename to apps/openstacktelemetry/web/src/main/java/org/onosproject/openstacktelemetry/web/package-info.java
diff --git a/apps/openstacktelemetry/web/src/main/resources/definitions/TelemetryConfig.json b/apps/openstacktelemetry/web/src/main/resources/definitions/TelemetryConfig.json
new file mode 100644
index 0000000000..f4d1288f8c
--- /dev/null
+++ b/apps/openstacktelemetry/web/src/main/resources/definitions/TelemetryConfig.json
@@ -0,0 +1,53 @@
+{
+  "type": "object",
+  "required": [
+    "name",
+    "type",
+    "manufacturer",
+    "swVersion",
+    "enabled",
+    "properties"
+  ],
+  "properties": {
+    "name": {
+      "type": "string",
+      "example": "grpc config"
+    },
+    "type": {
+      "type": "string",
+      "example": "GRPC"
+    },
+    "manufacturer": {
+      "type": "string",
+      "example": "grpc.io"
+    },
+    "swVersion": {
+      "type": "string",
+      "example": "1.0"
+    },
+    "enabled": {
+      "type": "boolean",
+      "example": true
+    },
+    "props": {
+      "type": "array",
+      "items": {
+        "type": "object",
+        "required": [
+          "key",
+          "value"
+        ],
+        "properties": {
+          "key": {
+            "type": "string",
+            "example": "address"
+          },
+          "value": {
+            "type": "string",
+            "example": "127.0.0.1"
+          }
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/apps/openstacktelemetry/app/src/main/webapp/WEB-INF/web.xml b/apps/openstacktelemetry/web/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from apps/openstacktelemetry/app/src/main/webapp/WEB-INF/web.xml
rename to apps/openstacktelemetry/web/src/main/webapp/WEB-INF/web.xml
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonCodecTest.java b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonCodecTest.java
similarity index 96%
rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonCodecTest.java
rename to apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonCodecTest.java
index ee84e59f34..4d3cb47229 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonCodecTest.java
+++ b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonCodecTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacktelemetry.codec;
+package org.onosproject.openstacktelemetry.codec.rest;
 
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -32,8 +32,8 @@ import org.onosproject.core.CoreService;
 import org.onosproject.net.DeviceId;
 import org.onosproject.openstacktelemetry.api.FlowInfo;
 import org.onosproject.openstacktelemetry.api.StatsInfo;
-import org.onosproject.openstacktelemetry.impl.DefaultFlowInfo;
-import org.onosproject.openstacktelemetry.impl.DefaultStatsInfo;
+import org.onosproject.openstacktelemetry.api.DefaultFlowInfo;
+import org.onosproject.openstacktelemetry.api.DefaultStatsInfo;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -44,7 +44,7 @@ import static org.easymock.EasyMock.replay;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.onosproject.net.NetTestTools.APP_ID;
-import static org.onosproject.openstacktelemetry.codec.FlowInfoJsonMatcher.matchesFlowInfo;
+import static org.onosproject.openstacktelemetry.codec.rest.FlowInfoJsonMatcher.matchesFlowInfo;
 
 /**
  * Unit tests for FlowInfo codec.
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonMatcher.java b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonMatcher.java
similarity index 99%
rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonMatcher.java
rename to apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonMatcher.java
index 7574054b30..66ab1bad29 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/FlowInfoJsonMatcher.java
+++ b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/FlowInfoJsonMatcher.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacktelemetry.codec;
+package org.onosproject.openstacktelemetry.codec.rest;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import org.hamcrest.Description;
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/StatsInfoJsonMatcher.java b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/StatsInfoJsonMatcher.java
similarity index 98%
rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/StatsInfoJsonMatcher.java
rename to apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/StatsInfoJsonMatcher.java
index ffebaf58da..4ad86fa7af 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/codec/StatsInfoJsonMatcher.java
+++ b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/StatsInfoJsonMatcher.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.openstacktelemetry.codec;
+package org.onosproject.openstacktelemetry.codec.rest;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import org.hamcrest.Description;
diff --git a/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigCodecTest.java b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigCodecTest.java
new file mode 100644
index 0000000000..626aa02cb0
--- /dev/null
+++ b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigCodecTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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 org.onosproject.openstacktelemetry.codec.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Maps;
+import org.hamcrest.MatcherAssert;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.core.CoreService;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
+import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertTrue;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onosproject.net.NetTestTools.APP_ID;
+import static org.onosproject.openstacktelemetry.codec.rest.TelemetryConfigJsonMatcher.matchesTelemetryConfig;
+
+/**
+ * Unit tests for TelemetryConfig codec.
+ */
+public class TelemetryConfigCodecTest {
+
+    MockCodecContext context;
+
+    JsonCodec telemetryConfigCodec;
+
+    final CoreService mockCoreService = createMock(CoreService.class);
+    private static final String REST_APP_ID = "org.onosproject.rest";
+
+    @Before
+    public void setUp() {
+        context = new MockCodecContext();
+        telemetryConfigCodec = new TelemetryConfigJsonCodec();
+
+        assertThat(telemetryConfigCodec, notNullValue());
+
+        expect(mockCoreService.registerApplication(REST_APP_ID))
+                .andReturn(APP_ID).anyTimes();
+        replay(mockCoreService);
+        context.registerService(CoreService.class, mockCoreService);
+    }
+
+    /**
+     * Tests the telemetry config encoding.
+     */
+    @Test
+    public void testTelemetryConfigEncode() {
+
+        String name = "grpc";
+        TelemetryConfig.ConfigType type = TelemetryConfig.ConfigType.GRPC;
+        String manufacturer = "grpc.io";
+        String swVersion = "1.0";
+        boolean enabled = true;
+
+        Map properties = Maps.newConcurrentMap();
+        properties.put("key1", "value1");
+        properties.put("key2", "value2");
+
+        TelemetryConfig config = new DefaultTelemetryConfig(name, type,
+                ImmutableList.of(), manufacturer, swVersion, enabled, properties);
+
+        ObjectNode configJson = telemetryConfigCodec.encode(config, context);
+        assertThat(configJson, matchesTelemetryConfig(config));
+    }
+
+    /**
+     * Tests the telemetry config decoding.
+     */
+    @Test
+    public void testTelemetryConfigDecode() throws IOException {
+        TelemetryConfig config = getTelemetryConfig("TelemetryConfig.json");
+
+        assertEquals(config.name(), "grpc-config");
+        assertEquals(config.type().name(), "GRPC");
+        assertEquals(config.manufacturer(), "grpc.io");
+        assertEquals(config.swVersion(), "1.0");
+        assertTrue(config.enabled());
+
+        config.properties().forEach((k, v) -> {
+            if (k.equals("address")) {
+                assertEquals(v, "127.0.0.1");
+            }
+            if (k.equals("port")) {
+                assertEquals(v, "9092");
+            }
+        });
+    }
+
+    /**
+     * Reads in a telemetry config from the given resource and decodes it.
+     *
+     * @param resourceName resource to use to read the JSON for the rule
+     * @return decoded telemetry config
+     * @throws IOException if processing the resource fails
+     */
+    private TelemetryConfig getTelemetryConfig(String resourceName) throws IOException {
+        InputStream jsonStream = TelemetryConfigCodecTest.class.getResourceAsStream(resourceName);
+        JsonNode json = context.mapper().readTree(jsonStream);
+        MatcherAssert.assertThat(json, notNullValue());
+        TelemetryConfig config = telemetryConfigCodec.decode((ObjectNode) json, context);
+        assertThat(config, notNullValue());
+        return config;
+    }
+
+    /**
+     * Mock codec context for use in codec unit tests.
+     */
+    private class MockCodecContext implements CodecContext {
+        private final ObjectMapper mapper = new ObjectMapper();
+        private final CodecManager manager = new CodecManager();
+        private final Map, Object> services = new HashMap<>();
+
+        /**
+         * Constructs a new mock codec context.
+         */
+        public MockCodecContext() {
+            manager.activate();
+        }
+
+        @Override
+        public ObjectMapper mapper() {
+            return mapper;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public  JsonCodec codec(Class entityClass) {
+            if (entityClass == TelemetryConfig.class) {
+                return (JsonCodec) telemetryConfigCodec;
+            }
+            return manager.getCodec(entityClass);
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public  T getService(Class serviceClass) {
+            return (T) services.get(serviceClass);
+        }
+
+        // for registering mock services
+        public  void registerService(Class serviceClass, T impl) {
+            services.put(serviceClass, impl);
+        }
+    }
+}
diff --git a/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigJsonMatcher.java b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigJsonMatcher.java
new file mode 100644
index 0000000000..9bc50a20aa
--- /dev/null
+++ b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfigJsonMatcher.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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 org.onosproject.openstacktelemetry.codec.rest;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeDiagnosingMatcher;
+import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
+
+/**
+ * Hamcrest matcher for TelemetryConfig.
+ */
+public final class TelemetryConfigJsonMatcher extends TypeSafeDiagnosingMatcher {
+
+    private final TelemetryConfig telemetryConfig;
+
+    private static final String NAME = "name";
+    private static final String TYPE = "type";
+    private static final String MANUFACTURER = "manufacturer";
+    private static final String SW_VERSION = "swVersion";
+    private static final String ENABLED = "enabled";
+    private static final String PROPS = "props";
+    private static final String KEY = "key";
+    private static final String VALUE = "value";
+
+    private TelemetryConfigJsonMatcher(TelemetryConfig telemetryConfig) {
+        this.telemetryConfig = telemetryConfig;
+    }
+
+    @Override
+    protected boolean matchesSafely(JsonNode jsonNode, Description description) {
+
+        // check name
+        String jsonName = jsonNode.get(NAME).asText();
+        String name = telemetryConfig.name();
+        if (!jsonName.equals(name)) {
+            description.appendText("name was " + jsonName);
+            return false;
+        }
+
+        // check type
+        String jsonType = jsonNode.get(TYPE).asText();
+        String type = telemetryConfig.type().name();
+        if (!jsonType.equalsIgnoreCase(type)) {
+            description.appendText("type was " + jsonType);
+            return false;
+        }
+
+        // check manufacturer
+        String jsonManufacturer = jsonNode.get(MANUFACTURER).asText();
+        String manufacturer = telemetryConfig.manufacturer();
+        if (!jsonManufacturer.equals(manufacturer)) {
+            description.appendText("manufacturer was " + jsonManufacturer);
+            return false;
+        }
+
+        // check software version
+        String jsonSwVersion = jsonNode.get(SW_VERSION).asText();
+        String swVersion = telemetryConfig.swVersion();
+        if (!jsonSwVersion.equals(swVersion)) {
+            description.appendText("SW version was " + jsonSwVersion);
+            return false;
+        }
+
+        // check enabled
+        JsonNode jsonEnabled = jsonNode.get(ENABLED);
+        boolean enabled = telemetryConfig.enabled();
+        if (jsonEnabled == null || jsonEnabled.asBoolean() != enabled) {
+            description.appendText("Enabled was " + jsonEnabled);
+            return false;
+        }
+
+        // check properties
+        JsonNode jsonProperties = jsonNode.get(PROPS);
+        if (jsonProperties != null) {
+            if (jsonProperties.size() != telemetryConfig.properties().size()) {
+                description.appendText("properties size was " + jsonProperties.size());
+                return false;
+            }
+
+            for (String key : telemetryConfig.properties().keySet()) {
+                boolean keyFound = false;
+                boolean valueFound = false;
+                String value = telemetryConfig.properties().get(key);
+                for (int keyIndex = 0; keyIndex < jsonProperties.size(); keyIndex++) {
+                    ObjectNode jsonProperty = get(jsonProperties, keyIndex);
+                    JsonNode jsonKey = jsonProperty.get(KEY);
+                    JsonNode jsonValue = jsonProperty.get(VALUE);
+
+                    if (jsonKey != null && jsonValue != null) {
+                        if (jsonKey.asText().equals(key)) {
+                            keyFound = true;
+                        }
+
+                        if (jsonValue.asText().equals(value)) {
+                            valueFound = true;
+                        }
+
+                        if (keyFound && valueFound) {
+                            break;
+                        }
+                    }
+                }
+
+                if (!keyFound) {
+                    description.appendText("Property key not found " + key);
+                    return false;
+                }
+
+                if (!valueFound) {
+                    description.appendText("Property value not found " + value);
+                    return false;
+                }
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public void describeTo(Description description) {
+        description.appendText(telemetryConfig.toString());
+    }
+
+    /**
+     * Factory to allocate an flow info matcher.
+     *
+     * @param telemetryConfig telemetry config object we are looking for
+     * @return matcher
+     */
+    public static TelemetryConfigJsonMatcher
+                    matchesTelemetryConfig(TelemetryConfig telemetryConfig) {
+        return new TelemetryConfigJsonMatcher(telemetryConfig);
+    }
+
+    private static ObjectNode get(JsonNode parent, int childIndex) {
+        JsonNode node = parent.path(childIndex);
+        return node.isObject() && !node.isNull() ? (ObjectNode) node : null;
+    }
+}
diff --git a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegisterTest.java b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegisterTest.java
similarity index 84%
rename from apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegisterTest.java
rename to apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegisterTest.java
index 683e9c1965..6eee6164dc 100644
--- a/apps/openstacktelemetry/app/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegisterTest.java
+++ b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryCodecRegisterTest.java
@@ -24,9 +24,11 @@ import org.onosproject.codec.JsonCodec;
 import org.onosproject.openstacktelemetry.api.FlowInfo;
 import org.onosproject.openstacktelemetry.api.StatsFlowRule;
 import org.onosproject.openstacktelemetry.api.StatsInfo;
-import org.onosproject.openstacktelemetry.codec.FlowInfoJsonCodec;
-import org.onosproject.openstacktelemetry.codec.StatsFlowRuleJsonCodec;
-import org.onosproject.openstacktelemetry.codec.StatsInfoJsonCodec;
+import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
+import org.onosproject.openstacktelemetry.codec.rest.FlowInfoJsonCodec;
+import org.onosproject.openstacktelemetry.codec.rest.StatsFlowRuleJsonCodec;
+import org.onosproject.openstacktelemetry.codec.rest.StatsInfoJsonCodec;
+import org.onosproject.openstacktelemetry.codec.rest.TelemetryConfigJsonCodec;
 
 import java.util.Map;
 import java.util.Set;
@@ -58,12 +60,15 @@ public final class OpenstackTelemetryCodecRegisterTest {
                 codecService.getCodec(FlowInfo.class).getClass().getName());
         assertEquals(StatsFlowRuleJsonCodec.class.getName(),
                 codecService.getCodec(StatsFlowRule.class).getClass().getName());
+        assertEquals(TelemetryConfigJsonCodec.class.getName(),
+                codecService.getCodec(TelemetryConfig.class).getClass().getName());
 
         register.deactivate();
 
         assertNull(codecService.getCodec(StatsInfo.class));
         assertNull(codecService.getCodec(FlowInfo.class));
         assertNull(codecService.getCodec(StatsFlowRule.class));
+        assertNull(codecService.getCodec(TelemetryConfig.class));
     }
 
     private static class TestCodecService implements CodecService {
diff --git a/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryConfigWebResourceTest.java b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryConfigWebResourceTest.java
new file mode 100644
index 0000000000..ff027bc910
--- /dev/null
+++ b/apps/openstacktelemetry/web/src/test/java/org/onosproject/openstacktelemetry/web/OpenstackTelemetryConfigWebResourceTest.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2018-present Open Networking Foundation
+ *
+ * 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 org.onosproject.openstacktelemetry.web;
+
+import com.google.common.collect.Maps;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.openstacktelemetry.api.DefaultTelemetryConfig;
+import org.onosproject.openstacktelemetry.api.TelemetryConfigAdminService;
+import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
+import org.onosproject.rest.resources.ResourceTest;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.util.Map;
+
+import static junit.framework.TestCase.assertEquals;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.onosproject.openstacktelemetry.api.config.TelemetryConfig.ConfigType.GRPC;
+
+/**
+ * Unit tests for openstack telemetry config REST API.
+ */
+public class OpenstackTelemetryConfigWebResourceTest extends ResourceTest {
+
+    private static final String NAME = "grpc";
+
+    private static final TelemetryConfig.ConfigType TYPE = GRPC;
+
+    private static final String MANUFACTURER = "grpc.io";
+
+    private static final String SW_VERSION = "1.0";
+
+    private static final Map PROP = Maps.newConcurrentMap();
+
+    private static final String PROP_KEY_1 = "key11";
+    private static final String PROP_KEY_2 = "key12";
+    private static final String PROP_VALUE_1 = "value11";
+    private static final String PROP_VALUE_2 = "value12";
+
+    private static final boolean ENABLED = true;
+
+    private final TelemetryConfigAdminService mockConfigAdminService =
+            createMock(TelemetryConfigAdminService.class);
+    private static final String PATH = "config";
+
+    /**
+     * Constructs an openstack telemetry config resource test instance.
+     */
+    public OpenstackTelemetryConfigWebResourceTest() {
+        super(ResourceConfig.forApplicationClass(OpenstackTelemetryWebApplication.class));
+    }
+
+    private TelemetryConfig telemetryConfig;
+
+    /**
+     * Sets up the global values for all the tests.
+     */
+    @Before
+    public void setUpTest() {
+        ServiceDirectory testDirectory =
+                new TestServiceDirectory()
+                        .add(TelemetryConfigAdminService.class,
+                                mockConfigAdminService);
+        setServiceDirectory(testDirectory);
+
+        PROP.put(PROP_KEY_1, PROP_VALUE_1);
+        PROP.put(PROP_KEY_2, PROP_VALUE_2);
+
+        telemetryConfig = new DefaultTelemetryConfig(NAME, TYPE, null,
+                MANUFACTURER, SW_VERSION, ENABLED, PROP);
+    }
+
+    /**
+     * Tests the results of the REST API PUT method by modifying config address.
+     */
+    @Test
+    public void testUpdateConfigAddressWithModifyOperation() {
+        expect(mockConfigAdminService.getConfig(anyString()))
+                .andReturn(telemetryConfig).once();
+        mockConfigAdminService.updateTelemetryConfig(telemetryConfig);
+        replay(mockConfigAdminService);
+
+        final WebTarget wt = target();
+        Response response = wt.path(PATH + "/address/test1/address1")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .put(Entity.json(""));
+        final int status = response.getStatus();
+
+        assertEquals(200, status);
+
+        verify(mockConfigAdminService);
+    }
+
+    /**
+     * Tests the results of the REST API PUT method without modifying config address.
+     */
+    @Test
+    public void testUpdateConfigAddressWithoutOperation() {
+        expect(mockConfigAdminService.getConfig(anyString())).andReturn(null).once();
+        replay(mockConfigAdminService);
+
+        final WebTarget wt = target();
+        Response response = wt.path(PATH + "/address/test1/address1")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .put(Entity.json(""));
+        final int status = response.getStatus();
+
+        assertEquals(304, status);
+
+        verify(mockConfigAdminService);
+    }
+
+    /**
+     * Tests the results of the REST API DELETE method by removing config.
+     */
+    @Test
+    public void testDeleteConfigWithModifyOperation() {
+        expect(mockConfigAdminService.getConfig(anyString()))
+                .andReturn(telemetryConfig).once();
+        mockConfigAdminService.removeTelemetryConfig(anyString());
+        replay(mockConfigAdminService);
+
+        final WebTarget wt = target();
+        Response response = wt.path(PATH + "/test1")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+        final int status = response.getStatus();
+
+        assertEquals(204, status);
+
+        verify(mockConfigAdminService);
+    }
+
+    /**
+     * Tests the results of the REST API DELETE method without removing config.
+     */
+    @Test
+    public void testDeleteConfigWithoutModifyOperation() {
+        expect(mockConfigAdminService.getConfig(anyString())).andReturn(null).once();
+        replay(mockConfigAdminService);
+
+        final WebTarget wt = target();
+        Response response = wt.path(PATH + "/test1")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .delete();
+        final int status = response.getStatus();
+
+        assertEquals(304, status);
+
+        verify(mockConfigAdminService);
+    }
+
+    /**
+     * Tests the results of REST API PUT method with enabling the config.
+     */
+    @Test
+    public void testEnableConfig() {
+        expect(mockConfigAdminService.getConfig(anyString()))
+                .andReturn(telemetryConfig).once();
+        mockConfigAdminService.updateTelemetryConfig(telemetryConfig);
+        replay(mockConfigAdminService);
+
+        final WebTarget wt = target();
+        Response response = wt.path(PATH + "/enable/test1")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .put(Entity.json(""));
+        final int status = response.getStatus();
+
+        assertEquals(200, status);
+
+        verify(mockConfigAdminService);
+    }
+
+    /**
+     * Tests the results of REST API PUT method with disabling the config.
+     */
+    @Test
+    public void testDisableConfig() {
+        expect(mockConfigAdminService.getConfig(anyString()))
+                .andReturn(telemetryConfig).once();
+        mockConfigAdminService.updateTelemetryConfig(telemetryConfig);
+        replay(mockConfigAdminService);
+
+        final WebTarget wt = target();
+        Response response = wt.path(PATH + "/disable/test1")
+                .request(MediaType.APPLICATION_JSON_TYPE)
+                .put(Entity.json(""));
+        final int status = response.getStatus();
+
+        assertEquals(200, status);
+
+        verify(mockConfigAdminService);
+    }
+}
diff --git a/apps/openstacktelemetry/web/src/test/resources/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfig.json b/apps/openstacktelemetry/web/src/test/resources/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfig.json
new file mode 100644
index 0000000000..681cad3592
--- /dev/null
+++ b/apps/openstacktelemetry/web/src/test/resources/org/onosproject/openstacktelemetry/codec/rest/TelemetryConfig.json
@@ -0,0 +1,17 @@
+{
+  "name": "grpc-config",
+  "type": "GRPC",
+  "manufacturer": "grpc.io",
+  "swVersion": "1.0",
+  "enabled": true,
+  "props": [
+    {
+      "key": "address",
+      "value": "127.0.0.1"
+    },
+    {
+      "key": "port",
+      "value": "9092"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/apps/openstacktelemetry/web/src/test/resources/org/onosproject/openstacktelemetry/web/openstack-telemetry-config-address.json b/apps/openstacktelemetry/web/src/test/resources/org/onosproject/openstacktelemetry/web/openstack-telemetry-config-address.json
new file mode 100644
index 0000000000..a4132c51c2
--- /dev/null
+++ b/apps/openstacktelemetry/web/src/test/resources/org/onosproject/openstacktelemetry/web/openstack-telemetry-config-address.json
@@ -0,0 +1,5 @@
+{
+  "config": {
+    "address": "10.10.10.10"
+  }
+}
\ No newline at end of file