Add REST API for query/update/delete/enable/disable telemetry config

1. Add unit test for newly added REST APIs
2. Add codec and unit tests for TelemetryConfig
3. Split web package out from app package due to dep conflict

Change-Id: I85f52b2a7d059622e98832843bc9613cb8befa98
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java
deleted file mode 100644
index b0d3aad..0000000
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultFlowInfo.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * 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.impl;
-
-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.
- */
-public final class DefaultFlowInfo implements FlowInfo {
-    private static final String INGRESS_STATS = "Ingress Port :";
-    private static final String EGRESS_STATS = "Egress Port :";
-
-    private final byte flowType;
-    private final DeviceId deviceId;
-    private final int inputInterfaceId;
-    private final int outputInterfaceId;
-    private final VlanId vlanId;
-    private final short vxlanId;
-    private final IpPrefix srcIp;
-    private final IpPrefix dstIp;
-    private final TpPort srcPort;
-    private final TpPort dstPort;
-    private final byte protocol;
-    private final MacAddress srcMac;
-    private final MacAddress dstMac;
-    private final StatsInfo statsInfo;
-
-    private DefaultFlowInfo(byte flowType, DeviceId deviceId,
-                            int inputInterfaceId, int outputInterfaceId,
-                            VlanId vlanId, short vxlanId, IpPrefix srcIp,
-                            IpPrefix dstIp, TpPort srcPort, TpPort dstPort,
-                            byte protocol, MacAddress srcMac, MacAddress dstMac,
-                            StatsInfo statsInfo) {
-        this.flowType = flowType;
-        this.deviceId = deviceId;
-        this.inputInterfaceId = inputInterfaceId;
-        this.outputInterfaceId = outputInterfaceId;
-        this.vlanId = vlanId;
-        this.vxlanId = vxlanId;
-        this.srcIp = srcIp;
-        this.dstIp = dstIp;
-        this.srcPort = srcPort;
-        this.dstPort = dstPort;
-        this.protocol = protocol;
-        this.srcMac = srcMac;
-        this.dstMac = dstMac;
-        this.statsInfo = statsInfo;
-    }
-
-    @Override
-    public byte flowType() {
-        return flowType;
-    }
-
-    @Override
-    public DeviceId deviceId() {
-        return deviceId;
-    }
-
-    @Override
-    public int inputInterfaceId() {
-        return inputInterfaceId;
-    }
-
-    @Override
-    public int outputInterfaceId() {
-        return outputInterfaceId;
-    }
-
-    @Override
-    public VlanId vlanId() {
-        return vlanId;
-    }
-
-    @Override
-    public short vxlanId() {
-        return vxlanId;
-    }
-
-    @Override
-    public IpPrefix srcIp() {
-        return srcIp;
-    }
-
-    @Override
-    public IpPrefix dstIp() {
-        return dstIp;
-    }
-
-    @Override
-    public TpPort srcPort() {
-        return srcPort;
-    }
-
-    @Override
-    public TpPort dstPort() {
-        return dstPort;
-    }
-
-    @Override
-    public byte protocol() {
-        return protocol;
-    }
-
-    @Override
-    public MacAddress srcMac() {
-        return srcMac;
-    }
-
-    @Override
-    public MacAddress dstMac() {
-        return dstMac;
-    }
-
-    @Override
-    public StatsInfo statsInfo() {
-        return statsInfo;
-    }
-
-    @Override
-    public boolean roughEquals(FlowInfo flowInfo) {
-        final DefaultFlowInfo other = (DefaultFlowInfo) flowInfo;
-        return Objects.equals(this.deviceId, other.deviceId) &&
-                Objects.equals(this.srcIp, other.srcIp) &&
-                Objects.equals(this.dstIp, other.dstIp) &&
-                Objects.equals(this.srcPort, other.srcPort) &&
-                Objects.equals(this.dstPort, other.dstPort) &&
-                Objects.equals(this.protocol, other.protocol);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (obj instanceof DefaultFlowInfo) {
-            final DefaultFlowInfo other = (DefaultFlowInfo) obj;
-            return Objects.equals(this.flowType, other.flowType) &&
-                    Objects.equals(this.deviceId, other.deviceId) &&
-                    Objects.equals(this.inputInterfaceId, other.inputInterfaceId) &&
-                    Objects.equals(this.outputInterfaceId, other.outputInterfaceId) &&
-                    Objects.equals(this.vlanId, other.vlanId) &&
-                    Objects.equals(this.vxlanId, other.vxlanId) &&
-                    Objects.equals(this.srcIp, other.srcIp) &&
-                    Objects.equals(this.dstIp, other.dstIp) &&
-                    Objects.equals(this.srcPort, other.srcPort) &&
-                    Objects.equals(this.dstPort, other.dstPort) &&
-                    Objects.equals(this.protocol, other.protocol) &&
-                    Objects.equals(this.srcMac, other.srcMac) &&
-                    Objects.equals(this.dstMac, other.dstMac) &&
-                    Objects.equals(this.statsInfo, other.statsInfo);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(flowType, deviceId, inputInterfaceId,
-                outputInterfaceId, vlanId, vxlanId, srcIp, dstIp, srcPort, dstPort,
-                protocol, srcMac, dstMac, statsInfo);
-    }
-
-    @Override
-    public String uniqueFlowInfoKey() {
-        if (srcIp.address().isZero() || dstIp.address().isZero()) {
-            if (!srcIp.address().isZero()) {
-                return INGRESS_STATS + srcIp.toString();
-            }
-            if (!dstIp.address().isZero()) {
-                return EGRESS_STATS + dstIp.toString();
-            }
-        }
-        return srcIp.toString() + ":" +
-                ((srcPort == null) ? "any" : srcPort.toString()) +
-                " -> " +
-                dstIp.toString() + ":" +
-                ((dstPort == null) ? "any" : dstPort.toString()) +
-                " (" + getProtocolNameFromType(protocol) + ")";
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this)
-                .add("flowType", flowType)
-                .add("deviceId", deviceId)
-                .add("inputInterfaceId", inputInterfaceId)
-                .add("outputInterfaceId", outputInterfaceId)
-                .add("vlanId", vlanId)
-                .add("vxlanId", vxlanId)
-                .add("srcIp", srcIp)
-                .add("dstIp", dstIp)
-                .add("srcPort", srcPort)
-                .add("dstPort", dstPort)
-                .add("protocol", protocol)
-                .add("srcMac", srcMac)
-                .add("dstMac", dstMac)
-                .add("statsInfo", statsInfo)
-                .toString();
-    }
-
-    /**
-     * Obtains a default flow info builder object.
-     *
-     * @return flow info builder object
-     */
-    public static Builder builder() {
-        return new DefaultBuilder();
-    }
-
-    /**
-     * Builder class of DefaultFlowInfo.
-     */
-    public static final class DefaultBuilder implements FlowInfo.Builder {
-
-        private byte flowType;
-        private DeviceId deviceId;
-        private int inputInterfaceId;
-        private int outputInterfaceId;
-        private VlanId vlanId;
-        private short vxlanId;
-        private IpPrefix srcIp;
-        private IpPrefix dstIp;
-        private TpPort srcPort;
-        private TpPort dstPort;
-        private byte protocol;
-        private MacAddress srcMac;
-        private MacAddress dstMac;
-        private StatsInfo statsInfo;
-
-        @Override
-        public Builder withFlowType(byte flowType) {
-            this.flowType = flowType;
-            return this;
-        }
-
-        @Override
-        public Builder withDeviceId(DeviceId deviceId) {
-            this.deviceId = deviceId;
-            return this;
-        }
-
-        @Override
-        public Builder withInputInterfaceId(int inputInterfaceId) {
-            this.inputInterfaceId = inputInterfaceId;
-            return this;
-        }
-
-        @Override
-        public Builder withOutputInterfaceId(int outputInterfaceId) {
-            this.outputInterfaceId = outputInterfaceId;
-            return this;
-        }
-
-        @Override
-        public Builder withVlanId(VlanId vlanId) {
-            this.vlanId = vlanId;
-            return this;
-        }
-
-        @Override
-        public Builder withVxlanId(short vxlanId) {
-            this.vxlanId = vxlanId;
-            return this;
-        }
-
-        @Override
-        public Builder withSrcIp(IpPrefix srcIp) {
-            this.srcIp = srcIp;
-            return this;
-        }
-
-        @Override
-        public Builder withDstIp(IpPrefix dstIp) {
-            this.dstIp = dstIp;
-            return this;
-        }
-
-        @Override
-        public Builder withSrcPort(TpPort srcPort) {
-            this.srcPort = srcPort;
-            return this;
-        }
-
-        @Override
-        public Builder withDstPort(TpPort dstPort) {
-            this.dstPort = dstPort;
-            return this;
-        }
-
-        @Override
-        public Builder withProtocol(byte protocol) {
-            this.protocol = protocol;
-            return this;
-        }
-
-        @Override
-        public Builder withSrcMac(MacAddress srcMac) {
-            this.srcMac = srcMac;
-            return this;
-        }
-
-        @Override
-        public Builder withDstMac(MacAddress dstMac) {
-            this.dstMac = dstMac;
-            return this;
-        }
-
-        @Override
-        public Builder withStatsInfo(StatsInfo statsInfo) {
-            this.statsInfo = statsInfo;
-            return this;
-        }
-
-        @Override
-        public FlowInfo build() {
-
-            // TODO: need to check the null value for more properties
-            checkNotNull(srcIp, "Source IP address cannot be null");
-            checkNotNull(dstIp, "Destination IP address cannot be null");
-            checkNotNull(statsInfo, "StatsInfo cannot be null");
-
-            return new DefaultFlowInfo(flowType, deviceId, inputInterfaceId,
-                    outputInterfaceId, vlanId, vxlanId, srcIp, dstIp, srcPort, dstPort,
-                    protocol, srcMac, dstMac, statsInfo);
-        }
-    }
-}
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRule.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRule.java
deleted file mode 100644
index 9ee84f8..0000000
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsFlowRule.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * 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.impl;
-
-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;
-
-import static com.google.common.base.Preconditions.checkArgument;
-
-/**
- * Implementation of StatsFlowRule.
- */
-public final class DefaultStatsFlowRule implements StatsFlowRule {
-    private final IpPrefix srcIpPrefix;
-    private final IpPrefix dstIpPrefix;
-    private final byte     ipProtocol;
-    private final TpPort   srcTpPort;
-    private final TpPort   dstTpPort;
-
-    private static final String NOT_NULL_MSG = "Element % cannot be null";
-
-    protected DefaultStatsFlowRule(IpPrefix srcIpPrefix,
-                                   IpPrefix dstIpPrefix,
-                                   byte ipProtoco,
-                                   TpPort srcTpPort,
-                                   TpPort dstTpPort) {
-        this.srcIpPrefix = srcIpPrefix;
-        this.dstIpPrefix = dstIpPrefix;
-        this.ipProtocol  = ipProtoco;
-        this.srcTpPort   = srcTpPort;
-        this.dstTpPort   = dstTpPort;
-    }
-
-    @Override
-    public IpPrefix srcIpPrefix() {
-        return srcIpPrefix;
-    }
-
-    @Override
-    public IpPrefix dstIpPrefix() {
-        return dstIpPrefix;
-    }
-
-    @Override
-    public byte ipProtocol() {
-        return ipProtocol;
-    }
-
-    @Override
-    public TpPort srcTpPort() {
-        return srcTpPort;
-    }
-
-    @Override
-    public TpPort dstTpPort() {
-        return dstTpPort;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("srcIpPrefix", srcIpPrefix)
-                .add("dstIpPrefix", dstIpPrefix)
-                .add("ipProtocol", ipProtocol)
-                .add("srcTpPort", srcTpPort)
-                .add("dstTpPort", dstTpPort)
-                .toString();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (obj instanceof DefaultStatsFlowRule) {
-            final DefaultStatsFlowRule other = (DefaultStatsFlowRule) obj;
-            return Objects.equals(this.srcIpPrefix, other.srcIpPrefix) &&
-                    Objects.equals(this.dstIpPrefix, other.dstIpPrefix) &&
-                    Objects.equals(this.srcTpPort, other.srcTpPort) &&
-                    Objects.equals(this.dstTpPort, other.dstTpPort) &&
-                    Objects.equals(this.ipProtocol, other.ipProtocol);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(srcIpPrefix, dstIpPrefix, srcTpPort, dstTpPort, ipProtocol);
-    }
-
-    /**
-     * Obtains a default stats flow rule builder object.
-     *
-     * @return flow rule builder object
-     */
-    public static Builder builder() {
-        return new Builder();
-    }
-
-    /**
-     * Obtains the builder object existing flow rule.
-     *
-     * @param flowRule flow rule
-     * @return builder object
-     */
-    public static Builder from(StatsFlowRule flowRule) {
-        return new Builder()
-                .srcIpPrefix(flowRule.srcIpPrefix())
-                .dstIpPrefix(flowRule.dstIpPrefix())
-                .ipProtocol(flowRule.ipProtocol())
-                .srcTpPort(flowRule.srcTpPort())
-                .dstTpPort(flowRule.dstTpPort());
-    }
-
-    /**
-     * A builder class for openstack flow rule.
-     */
-    public static final class Builder implements StatsFlowRule.Builder {
-        private IpPrefix srcIpPrefix;
-        private IpPrefix dstIpPrefix;
-        private byte     ipProtocol;
-        private TpPort   srcTpPort;
-        private TpPort   dstTpPort;
-
-        // private constructor not intended to use from external
-        private Builder() {
-        }
-
-        @Override
-        public DefaultStatsFlowRule build() {
-            checkArgument(srcIpPrefix != null, NOT_NULL_MSG, "Source IP Prefix");
-            checkArgument(dstIpPrefix != null, NOT_NULL_MSG, "Destination IP Prefix");
-
-            return new DefaultStatsFlowRule(srcIpPrefix,
-                                                dstIpPrefix,
-                                                ipProtocol,
-                                                srcTpPort,
-                                                dstTpPort);
-        }
-
-        @Override
-        public Builder srcIpPrefix(IpPrefix srcIpPrefix) {
-            this.srcIpPrefix = srcIpPrefix;
-            return this;
-        }
-
-        @Override
-        public Builder dstIpPrefix(IpPrefix dstIpPrefix) {
-            this.dstIpPrefix = dstIpPrefix;
-            return this;
-        }
-
-        @Override
-        public Builder ipProtocol(byte ipProtocol) {
-            this.ipProtocol = ipProtocol;
-            return this;
-        }
-
-        @Override
-        public Builder srcTpPort(TpPort srcTpPort) {
-            this.srcTpPort = srcTpPort;
-            return this;
-        }
-
-        @Override
-        public Builder dstTpPort(TpPort dstTpPort) {
-            this.dstTpPort = dstTpPort;
-            return this;
-        }
-    }
-}
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java
deleted file mode 100644
index 6e085a2..0000000
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultStatsInfo.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * 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.impl;
-
-import org.onosproject.openstacktelemetry.api.StatsInfo;
-
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-/**
- * Implementation class of StatsInfo.
- */
-public final class DefaultStatsInfo implements StatsInfo {
-
-    private final long startupTime;
-    private final long fstPktArrTime;
-    private final int lstPktOffset;
-    private final long prevAccBytes;
-    private final int prevAccPkts;
-    private final long currAccBytes;
-    private final int currAccPkts;
-    private final short errorPkts;
-    private final short dropPkts;
-
-    private DefaultStatsInfo(long startupTime, long fstPktArrTime, int lstPktOffset,
-                             long prevAccBytes, int prevAccPkts, long currAccBytes,
-                             int currAccPkts, short errorPkts, short dropPkts) {
-        this.startupTime = startupTime;
-        this.fstPktArrTime = fstPktArrTime;
-        this.lstPktOffset = lstPktOffset;
-        this.prevAccBytes = prevAccBytes;
-        this.prevAccPkts = prevAccPkts;
-        this.currAccBytes = currAccBytes;
-        this.currAccPkts = currAccPkts;
-        this.errorPkts = errorPkts;
-        this.dropPkts = dropPkts;
-    }
-
-    @Override
-    public long startupTime() {
-        return startupTime;
-    }
-
-    @Override
-    public long fstPktArrTime() {
-        return fstPktArrTime;
-    }
-
-    @Override
-    public int lstPktOffset() {
-        return lstPktOffset;
-    }
-
-    @Override
-    public long prevAccBytes() {
-        return prevAccBytes;
-    }
-
-    @Override
-    public int prevAccPkts() {
-        return prevAccPkts;
-    }
-
-    @Override
-    public long currAccBytes() {
-        return currAccBytes;
-    }
-
-    @Override
-    public int currAccPkts() {
-        return currAccPkts;
-    }
-
-    @Override
-    public short errorPkts() {
-        return errorPkts;
-    }
-
-    @Override
-    public short dropPkts() {
-        return dropPkts;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        if (obj instanceof DefaultStatsInfo) {
-            final DefaultStatsInfo other = (DefaultStatsInfo) obj;
-            return Objects.equals(this.startupTime, other.startupTime) &&
-                    Objects.equals(this.fstPktArrTime, other.fstPktArrTime) &&
-                    Objects.equals(this.lstPktOffset, other.lstPktOffset) &&
-                    Objects.equals(this.prevAccBytes, other.prevAccBytes) &&
-                    Objects.equals(this.prevAccPkts, other.prevAccPkts) &&
-                    Objects.equals(this.currAccBytes, other.currAccBytes) &&
-                    Objects.equals(this.currAccPkts, other.currAccPkts) &&
-                    Objects.equals(this.errorPkts, other.errorPkts) &&
-                    Objects.equals(this.dropPkts, other.dropPkts);
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(startupTime, fstPktArrTime, lstPktOffset,
-                prevAccBytes, prevAccPkts, currAccBytes, currAccPkts,
-                errorPkts, dropPkts);
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this)
-                .add("startupTime", startupTime)
-                .add("fstPktArrTime", fstPktArrTime)
-                .add("lstPktOffset", lstPktOffset)
-                .add("prevAccBytes", prevAccBytes)
-                .add("prevAccPkts", prevAccPkts)
-                .add("currAccBytes", currAccBytes)
-                .add("currAccPkts", currAccPkts)
-                .add("errorPkts", errorPkts)
-                .add("dropPkts", dropPkts)
-                .toString();
-    }
-
-    /**
-     * Builder class of DefaultStatsInfo.
-     */
-    public static final class DefaultBuilder implements StatsInfo.Builder {
-        private long startupTime;
-        private long fstPktArrTime;
-        private int lstPktOffset;
-        private long prevAccBytes;
-        private int prevAccPkts;
-        private long currAccBytes;
-        private int currAccPkts;
-        private short errorPkts;
-        private short dropPkts;
-
-        @Override
-        public Builder withStartupTime(long startupTime) {
-            this.startupTime = startupTime;
-            return this;
-        }
-
-        @Override
-        public Builder withFstPktArrTime(long fstPktArrTime) {
-            this.fstPktArrTime = fstPktArrTime;
-            return this;
-        }
-
-        @Override
-        public Builder withLstPktOffset(int lstPktOffset) {
-            this.lstPktOffset = lstPktOffset;
-            return this;
-        }
-
-        @Override
-        public Builder withPrevAccBytes(long prevAccBytes) {
-            this.prevAccBytes = prevAccBytes;
-            return this;
-        }
-
-        @Override
-        public Builder withPrevAccPkts(int prevAccPkts) {
-            this.prevAccPkts = prevAccPkts;
-            return this;
-        }
-
-        @Override
-        public Builder withCurrAccBytes(long currAccBytes) {
-            this.currAccBytes = currAccBytes;
-            return this;
-        }
-
-        @Override
-        public Builder withCurrAccPkts(int currAccPkts) {
-            this.currAccPkts = currAccPkts;
-            return this;
-        }
-
-        @Override
-        public Builder withErrorPkts(short errorPkts) {
-            this.errorPkts = errorPkts;
-            return this;
-        }
-
-        @Override
-        public Builder withDropPkts(short dropPkts) {
-            this.dropPkts = dropPkts;
-            return this;
-        }
-
-        @Override
-        public StatsInfo build() {
-
-            return new DefaultStatsInfo(startupTime, fstPktArrTime, lstPktOffset,
-                    prevAccBytes, prevAccPkts, currAccBytes, currAccPkts,
-                    errorPkts, dropPkts);
-        }
-    }
-}
diff --git a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfig.java b/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfig.java
deleted file mode 100644
index d130446..0000000
--- a/apps/openstacktelemetry/app/src/main/java/org/onosproject/openstacktelemetry/impl/DefaultTelemetryConfig.java
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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.impl;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import org.onosproject.openstacktelemetry.api.config.TelemetryConfig;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Queue;
-import java.util.Set;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.collect.ImmutableMap.copyOf;
-
-/**
- * Implementation of TelemetryConfig.
- */
-public final class DefaultTelemetryConfig implements TelemetryConfig {
-    private final String name;
-    private final ConfigType type;
-    private final List<TelemetryConfig> parents;
-
-    private final String manufacturer;
-    private final String swVersion;
-    private final boolean enabled;
-
-    private final Map<String, String> properties;
-
-    /**
-     * Creates a configuration with the specified name.
-     *
-     * @param name          configuration name
-     * @param type          configuration type
-     * @param parents       optional parent configurations
-     * @param manufacturer  off-platform application manufacturer
-     * @param swVersion     off-platform application software version
-     * @param enabled       service enable flag
-     * @param properties    properties for telemetry configuration
-     */
-    public DefaultTelemetryConfig(String name, ConfigType type,
-                                  List<TelemetryConfig> parents,
-                                  String manufacturer, String swVersion,
-                                  boolean enabled, Map<String, String> properties) {
-        this.name = checkNotNull(name, "Name cannot be null");
-        this.type = checkNotNull(type, "type cannot be null");
-        this.parents = parents == null ? ImmutableList.of() : ImmutableList.copyOf(parents);
-        this.manufacturer = checkNotNull(manufacturer, "Manufacturer cannot be null");
-        this.swVersion = checkNotNull(swVersion, "SW version cannot be null");
-        this.properties = copyOf(checkNotNull(properties, "Properties cannot be null"));
-        this.enabled = enabled;
-    }
-
-    @Override
-    public String name() {
-        return name;
-    }
-
-    @Override
-    public ConfigType type() {
-        return type;
-    }
-
-    @Override
-    public List<TelemetryConfig> parents() {
-        if (parents == null) {
-            return ImmutableList.of();
-        } else {
-            return ImmutableList.copyOf(parents);
-        }
-    }
-
-    @Override
-    public String manufacturer() {
-        return manufacturer;
-    }
-
-    @Override
-    public String swVersion() {
-        return swVersion;
-    }
-
-    @Override
-    public boolean enabled() {
-        return enabled;
-    }
-
-    @Override
-    public Map<String, String> properties() {
-        if (properties == null) {
-            return ImmutableMap.of();
-        } else {
-            return ImmutableMap.copyOf(properties);
-        }
-    }
-
-    @Override
-    public String getProperty(String name) {
-        Queue<TelemetryConfig> queue = new LinkedList<>();
-        queue.add(this);
-        while (!queue.isEmpty()) {
-            TelemetryConfig config = queue.remove();
-            String property = config.properties().get(name);
-            if (property != null) {
-                return property;
-            } else if (config.parents() != null) {
-                queue.addAll(config.parents());
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public TelemetryConfig merge(TelemetryConfig other) {
-        // merge the properties
-        ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
-        properties.putAll(other.properties());
-
-        // remove duplicated properties from this configuration and merge
-        this.properties().entrySet().stream()
-                .filter(e -> !other.properties().containsKey(e.getKey()))
-                .forEach(properties::put);
-
-        List<TelemetryConfig> completeParents = new ArrayList<>();
-
-        if (parents != null) {
-            parents.forEach(parent -> other.parents().forEach(otherParent -> {
-                if (otherParent.name().equals(parent.name())) {
-                    completeParents.add(parent.merge(otherParent));
-                } else if (!completeParents.contains(otherParent)) {
-                    completeParents.add(otherParent);
-                } else if (!completeParents.contains(parent)) {
-                    completeParents.add(parent);
-                }
-            }));
-        }
-
-        return new DefaultTelemetryConfig(name, type,
-                !completeParents.isEmpty() ? completeParents : other.parents(),
-                manufacturer, swVersion, enabled, properties.build());
-    }
-
-    @Override
-    public TelemetryConfig updateProperties(Map<String, String> properties) {
-
-        return new DefaultTelemetryConfig(name, type, parents, manufacturer,
-                swVersion, enabled, properties);
-    }
-
-    @Override
-    public TelemetryConfig updateEnabled(boolean enabled) {
-        return new DefaultTelemetryConfig(name, type, parents, manufacturer,
-                swVersion, enabled, properties);
-    }
-
-    @Override
-    public Set<String> keys() {
-        return properties.keySet();
-    }
-
-    @Override
-    public String value(String key) {
-        return properties.get(key);
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this)
-                .add("name", name)
-                .add("type", type)
-                .add("parents", parents)
-                .add("manufacturer", manufacturer)
-                .add("swVersion", swVersion)
-                .add("enabled", enabled)
-                .add("properties", properties)
-                .toString();
-    }
-
-    @Override
-    public boolean equals(Object configToBeCompared) {
-        if (this == configToBeCompared) {
-            return true;
-        }
-
-        if (configToBeCompared == null || getClass() != configToBeCompared.getClass()) {
-            return false;
-        }
-
-        DefaultTelemetryConfig telemetryConfig =
-                                    (DefaultTelemetryConfig) configToBeCompared;
-        return name.equals(telemetryConfig.name());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hashCode(name);
-    }
-}
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 8fc31a6..d066d85 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 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 962779a..38dd2b8 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 @@
 
             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 152bfde..06936ca 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 @@
 
     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 @@
         Set<Future<RecordMetadata>> 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 @@
             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 3d9f577..30faac7 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.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 3ae2504..9832ad3 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.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 @@
 
     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()
@@ -175,6 +177,14 @@
     }
 
     @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 39a5df0..c9c6e9f 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 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 @@
  * </p>
  * <pre>
  *     &lt;configs&gt;
- *         &lt;config name=“...” [manufacturer="..." swVersion="..."]&gt;
- *            [&lt;property name=“key”&gt;value&lt;/key&gt;]
+ *         &lt;config name="..." [manufacturer="..." swVersion="..."]&gt;
+ *            [&lt;property name="key"&gt;value&lt;/key&gt;]
  *            ...
  *        &lt;/config&gt;
  *        ...
@@ -203,10 +204,16 @@
         ImmutableMap.Builder<String, String> properties = ImmutableMap.builder();
 
         // note that, we only allow the inheritance from single source
-        Map<String, String> parentConfigs = Maps.newHashMap();
+        final Map<String, String> 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 @@
         for (HierarchicalConfiguration b : config.configurationsAt(PROPERTY)) {
             properties.put(b.getString(NAME), (String) b.getRootNode().getValue());
         }
+
         return properties.build();
     }
 }