diff --git a/web/api/src/main/java/org/onosproject/rest/resources/ConfigProvider.java b/web/api/src/main/java/org/onosproject/rest/resources/ConfigProvider.java
deleted file mode 100644
index 453f206..0000000
--- a/web/api/src/main/java/org/onosproject/rest/resources/ConfigProvider.java
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * 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.rest.resources;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.base.Strings;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import org.onlab.packet.ChassisId;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onlab.util.Frequency;
-import org.onlab.util.Spectrum;
-import org.onosproject.net.AnnotationKeys;
-import org.onosproject.net.ChannelSpacing;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.GridType;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.Link;
-import org.onosproject.net.MastershipRole;
-import org.onosproject.net.OchSignal;
-import org.onosproject.net.OduSignalType;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.SparseAnnotations;
-import org.onosproject.net.device.DefaultDeviceDescription;
-import org.onosproject.net.device.DefaultPortDescription;
-import org.onosproject.net.device.DeviceDescription;
-import org.onosproject.net.device.DeviceEvent;
-import org.onosproject.net.device.DeviceListener;
-import org.onosproject.net.device.DeviceProvider;
-import org.onosproject.net.device.DeviceProviderRegistry;
-import org.onosproject.net.device.DeviceProviderService;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.device.PortDescription;
-import org.onosproject.net.host.DefaultHostDescription;
-import org.onosproject.net.host.HostProvider;
-import org.onosproject.net.host.HostProviderRegistry;
-import org.onosproject.net.host.HostProviderService;
-import org.onosproject.net.link.DefaultLinkDescription;
-import org.onosproject.net.link.LinkProvider;
-import org.onosproject.net.link.LinkProviderRegistry;
-import org.onosproject.net.link.LinkProviderService;
-import org.onosproject.net.optical.OchPort;
-import org.onosproject.net.optical.OduCltPort;
-import org.onosproject.net.optical.OmsPort;
-import org.onosproject.net.provider.ProviderId;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.net.DeviceId.deviceId;
-import static org.onosproject.net.PortNumber.portNumber;
-import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_ADDED;
-import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
-import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription;
-import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
-import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription;
-import static org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView;
-
-/**
- * Provider of devices and links parsed from a JSON configuration structure.
- *
- * @deprecated in 1.5.0 (Falcon)
- */
-@Deprecated
-class ConfigProvider implements DeviceProvider, LinkProvider, HostProvider {
-
-    private final Logger log = LoggerFactory.getLogger(getClass());
-
-    private static final ProviderId PID =
-            new ProviderId("cfg", "org.onosproject.rest", true);
-
-    private static final String UNKNOWN = "unknown";
-
-    // C-band has 4.4 THz (4,400 GHz) total bandwidth
-    private static final Frequency TOTAL = Frequency.ofGHz(4_400);
-
-    private CountDownLatch deviceLatch;
-
-    private final JsonNode cfg;
-    private final DeviceService deviceService;
-
-    private final DeviceProviderRegistry deviceProviderRegistry;
-    private final LinkProviderRegistry linkProviderRegistry;
-    private final HostProviderRegistry hostProviderRegistry;
-
-    private DeviceProviderService deviceProviderService;
-    private LinkProviderService linkProviderService;
-    private HostProviderService hostProviderService;
-
-    private DeviceListener deviceEventCounter = new DeviceEventCounter();
-    private List<ConnectPoint> connectPoints = Lists.newArrayList();
-    private Map<ConnectPoint, PortDescription> descriptions = Maps.newHashMap();
-
-    /**
-     * Creates a new configuration provider.
-     *
-     * @param cfg                    JSON configuration
-     * @param deviceService          device service
-     * @param deviceProviderRegistry device provider registry
-     * @param linkProviderRegistry   link provider registry
-     * @param hostProviderRegistry   host provider registry
-     */
-    ConfigProvider(JsonNode cfg,
-                   DeviceService deviceService,
-                   DeviceProviderRegistry deviceProviderRegistry,
-                   LinkProviderRegistry linkProviderRegistry,
-                   HostProviderRegistry hostProviderRegistry) {
-        this.cfg = checkNotNull(cfg, "Configuration cannot be null");
-        this.deviceService = opticalView(checkNotNull(deviceService, "Device service cannot be null"));
-        this.deviceProviderRegistry = checkNotNull(deviceProviderRegistry, "Device provider registry cannot be null");
-        this.linkProviderRegistry = checkNotNull(linkProviderRegistry, "Link provider registry cannot be null");
-        this.hostProviderRegistry = checkNotNull(hostProviderRegistry, "Host provider registry cannot be null");
-    }
-
-    /**
-     * Parses the given JSON and provides links as configured.
-     */
-    void parse() {
-        try {
-            register();
-            parseDevices();
-            parseLinks();
-            parseHosts();
-            addMissingPorts();
-        } finally {
-            unregister();
-        }
-    }
-
-    private void register() {
-        deviceProviderService = deviceProviderRegistry.register(this);
-        linkProviderService = linkProviderRegistry.register(this);
-        hostProviderService = hostProviderRegistry.register(this);
-    }
-
-    private void unregister() {
-        deviceProviderRegistry.unregister(this);
-        linkProviderRegistry.unregister(this);
-        hostProviderRegistry.unregister(this);
-    }
-
-    // Parses the given JSON and provides devices.
-    private void parseDevices() {
-        try {
-            JsonNode nodes = cfg.get("devices");
-            if (nodes != null) {
-                prepareForDeviceEvents(nodes.size());
-                for (JsonNode node : nodes) {
-                    parseDevice(node);
-
-                    // FIXME: hack to make sure device attributes take
-                    // This will be fixed when GossipDeviceStore uses ECM
-                    parseDevice(node);
-                }
-            }
-        } finally {
-            waitForDeviceEvents();
-        }
-    }
-
-    // Parses the given node with device data and supplies the device.
-    private void parseDevice(JsonNode node) {
-        URI uri = URI.create(get(node, "uri"));
-        Device.Type type = Device.Type.valueOf(get(node, "type", "SWITCH"));
-        String mfr = get(node, "mfr", UNKNOWN);
-        String hw = get(node, "hw", UNKNOWN);
-        String sw = get(node, "sw", UNKNOWN);
-        String serial = get(node, "serial", UNKNOWN);
-        ChassisId cid = new ChassisId(get(node, "mac", "000000000000"));
-        SparseAnnotations annotations = annotations(node.get("annotations"));
-
-        DeviceDescription desc =
-                new DefaultDeviceDescription(uri, type, mfr, hw, sw, serial,
-                                             cid, annotations);
-        DeviceId deviceId = deviceId(uri);
-        deviceProviderService.deviceConnected(deviceId, desc);
-
-        JsonNode ports = node.get("ports");
-        if (ports != null) {
-            parsePorts(deviceId, ports);
-        }
-    }
-
-    // Parses the given node with list of device ports.
-    private void parsePorts(DeviceId deviceId, JsonNode nodes) {
-        List<PortDescription> ports = new ArrayList<>();
-        for (JsonNode node : nodes) {
-            ports.add(parsePort(deviceId, node));
-        }
-        deviceProviderService.updatePorts(deviceId, ports);
-    }
-
-    // Parses the given node with port information.
-    private PortDescription parsePort(DeviceId deviceId, JsonNode node) {
-        Port.Type type = Port.Type.valueOf(node.path("type").asText("COPPER"));
-        // TL1-based ports have a name
-        PortNumber port = null;
-        if (node.has("name")) {
-            for (Port p : deviceService.getPorts(deviceId)) {
-                if (p.number().name().equals(node.get("name").asText())) {
-                    port = p.number();
-                    break;
-                }
-            }
-        } else {
-            port = portNumber(node.path("port").asLong(0));
-        }
-
-        if (port == null) {
-            log.error("Cannot find port given in node {}", node);
-            return null;
-        }
-
-        String portName = Strings.emptyToNull(port.name());
-        SparseAnnotations annotations  = null;
-        if (portName != null) {
-            annotations = DefaultAnnotations.builder()
-                    .set(AnnotationKeys.PORT_NAME, portName).build();
-        }
-        switch (type) {
-            case COPPER:
-                return new DefaultPortDescription(port, node.path("enabled").asBoolean(true),
-                                                  type, node.path("speed").asLong(1_000),
-                                                  annotations);
-            case FIBER:
-                // Currently, assume OMS when FIBER. Provide sane defaults.
-                annotations = annotations(node.get("annotations"));
-                return omsPortDescription(port, node.path("enabled").asBoolean(true),
-                        Spectrum.CENTER_FREQUENCY, Spectrum.CENTER_FREQUENCY.add(TOTAL),
-                                              Frequency.ofGHz(100), annotations);
-            case ODUCLT:
-                annotations = annotations(node.get("annotations"));
-                OduCltPort oduCltPort = (OduCltPort) deviceService.getPort(deviceId, port);
-                return oduCltPortDescription(port, node.path("enabled").asBoolean(true),
-                        oduCltPort.signalType(), annotations);
-            case OCH:
-                annotations = annotations(node.get("annotations"));
-                OchPort ochPort = (OchPort) deviceService.getPort(deviceId, port);
-                return ochPortDescription(port, node.path("enabled").asBoolean(true),
-                        ochPort.signalType(), ochPort.isTunable(),
-                        ochPort.lambda(), annotations);
-            case OMS:
-                annotations = annotations(node.get("annotations"));
-                OmsPort omsPort = (OmsPort) deviceService.getPort(deviceId, port);
-                return omsPortDescription(port, node.path("enabled").asBoolean(true),
-                        omsPort.minFrequency(), omsPort.maxFrequency(), omsPort.grid(), annotations);
-            default:
-                log.warn("{}: Unsupported Port Type");
-        }
-        return new DefaultPortDescription(port, node.path("enabled").asBoolean(true),
-                                          type, node.path("speed").asLong(1_000),
-                                          annotations);
-    }
-
-    // Parses the given JSON and provides links as configured.
-    private void parseLinks() {
-        JsonNode nodes = cfg.get("links");
-        if (nodes != null) {
-            for (JsonNode node : nodes) {
-                parseLink(node, false);
-                if (!node.has("halfplex")) {
-                    parseLink(node, true);
-                }
-            }
-        }
-    }
-
-    // Parses the given node with link data and supplies the link.
-    private void parseLink(JsonNode node, boolean reverse) {
-        ConnectPoint src = connectPoint(get(node, "src"));
-        ConnectPoint dst = connectPoint(get(node, "dst"));
-        Link.Type type = Link.Type.valueOf(get(node, "type", "DIRECT"));
-        SparseAnnotations annotations = annotations(node.get("annotations"));
-        // take annotations to update optical ports with correct attributes.
-        updatePorts(src, dst, annotations);
-        DefaultLinkDescription desc = reverse ?
-                new DefaultLinkDescription(dst, src, type, annotations) :
-                new DefaultLinkDescription(src, dst, type, annotations);
-        linkProviderService.linkDetected(desc);
-
-        connectPoints.add(src);
-        connectPoints.add(dst);
-    }
-
-    private void updatePorts(ConnectPoint src, ConnectPoint dst, SparseAnnotations annotations) {
-        final String linkType = annotations.value("optical.type");
-        if ("cross-connect".equals(linkType)) {
-            String value = annotations.value("bandwidth").trim();
-            try {
-                double bw = Double.parseDouble(value);
-                updateOchPort(bw, src, dst);
-            } catch (NumberFormatException e) {
-                log.warn("Invalid bandwidth ({}), can't configure port(s)", value);
-                return;
-            }
-        } else if ("WDM".equals(linkType)) {
-            String value = annotations.value("optical.waves").trim();
-            try {
-                int numChls = Integer.parseInt(value);
-                updateOmsPorts(numChls, src, dst);
-            } catch (NumberFormatException e) {
-                log.warn("Invalid channel ({}), can't configure port(s)", value);
-                return;
-            }
-        }
-    }
-
-    // uses 'bandwidth' annotation to determine the channel spacing.
-    private void updateOchPort(double bw, ConnectPoint srcCp, ConnectPoint dstCp) {
-        Device src = deviceService.getDevice(srcCp.deviceId());
-        Device dst = deviceService.getDevice(dstCp.deviceId());
-        // bandwidth in MHz (assuming Hz - linc is not clear if that or Mb).
-        Frequency spacing = Frequency.ofMHz(bw);
-        // channel bandwidth is smaller than smallest standard channel spacing.
-        ChannelSpacing chsp = null;
-        if (spacing.compareTo(ChannelSpacing.CHL_6P25GHZ.frequency()) <= 0) {
-            chsp = ChannelSpacing.CHL_6P25GHZ;
-        }
-        for (int i = 1; i < ChannelSpacing.values().length; i++) {
-            Frequency val = ChannelSpacing.values()[i].frequency();
-            // pick the next highest or equal channel interval.
-            if (val.isLessThan(spacing)) {
-                chsp = ChannelSpacing.values()[i - 1];
-                break;
-            }
-        }
-        if (chsp == null) {
-            log.warn("Invalid channel spacing ({}), can't configure port(s)", spacing);
-            return;
-        }
-        OchSignal signal = new OchSignal(GridType.DWDM, chsp, 1, 1);
-        if (src.type() == Device.Type.ROADM) {
-            PortDescription portDesc = ochPortDescription(srcCp.port(), true,
-                    OduSignalType.ODU4, true, signal);
-            descriptions.put(srcCp, portDesc);
-            deviceProviderService.portStatusChanged(srcCp.deviceId(), portDesc);
-        }
-        if (dst.type() == Device.Type.ROADM) {
-            PortDescription portDesc = ochPortDescription(dstCp.port(), true,
-                    OduSignalType.ODU4, true, signal);
-            descriptions.put(dstCp, portDesc);
-            deviceProviderService.portStatusChanged(dstCp.deviceId(), portDesc);
-        }
-    }
-
-    private void updateOmsPorts(int numChls, ConnectPoint srcCp, ConnectPoint dstCp) {
-        // round down to largest slot that allows numChl channels to fit into C band range
-        ChannelSpacing chl = null;
-        Frequency perChl = TOTAL.floorDivision(numChls);
-        for (int i = 0; i < ChannelSpacing.values().length; i++) {
-            Frequency val = ChannelSpacing.values()[i].frequency();
-            if (val.isLessThan(perChl)) {
-                chl = ChannelSpacing.values()[i];
-                break;
-            }
-        }
-        if (chl == null) {
-            chl = ChannelSpacing.CHL_6P25GHZ;
-        }
-
-        // if true, there was less channels than can be tightly packed.
-        Frequency grid = chl.frequency();
-        // say Linc's 1st slot starts at CENTER and goes up from there.
-        Frequency min = Spectrum.CENTER_FREQUENCY.add(grid);
-        Frequency max = Spectrum.CENTER_FREQUENCY.add(grid.multiply(numChls));
-
-        PortDescription srcPortDesc = omsPortDescription(srcCp.port(), true, min, max, grid);
-        PortDescription dstPortDesc = omsPortDescription(dstCp.port(), true, min, max, grid);
-        descriptions.put(srcCp, srcPortDesc);
-        descriptions.put(dstCp, dstPortDesc);
-        deviceProviderService.portStatusChanged(srcCp.deviceId(), srcPortDesc);
-        deviceProviderService.portStatusChanged(dstCp.deviceId(), dstPortDesc);
-    }
-
-    // Parses the given JSON and provides hosts as configured.
-    private void parseHosts() {
-        try {
-            JsonNode nodes = cfg.get("hosts");
-            if (nodes != null) {
-                for (JsonNode node : nodes) {
-                    parseHost(node);
-
-                    // FIXME: hack to make sure host attributes take
-                    // This will be fixed when GossipHostStore uses ECM
-                    parseHost(node);
-                }
-            }
-        } finally {
-            hostProviderRegistry.unregister(this);
-        }
-    }
-
-    // Parses the given node with host data and supplies the host.
-    private void parseHost(JsonNode node) {
-        MacAddress mac = MacAddress.valueOf(get(node, "mac"));
-        VlanId vlanId = VlanId.vlanId((short) node.get("vlan").asInt(VlanId.UNTAGGED));
-        HostId hostId = HostId.hostId(mac, vlanId);
-        SparseAnnotations annotations = annotations(node.get("annotations"));
-        HostLocation location = new HostLocation(connectPoint(get(node, "location")), 0);
-
-        String[] ipStrings = get(node, "ip", "").split(",");
-        Set<IpAddress> ips = new HashSet<>();
-        for (String ip : ipStrings) {
-            ips.add(IpAddress.valueOf(ip.trim()));
-        }
-
-        DefaultHostDescription desc =
-                new DefaultHostDescription(mac, vlanId, location, ips, annotations);
-        hostProviderService.hostDetected(hostId, desc, false);
-
-        connectPoints.add(location);
-    }
-
-    // Adds any missing device ports for configured links and host locations.
-    private void addMissingPorts() {
-        deviceService.getDevices().forEach(this::addMissingPorts);
-    }
-
-    // Adds any missing device ports.
-    private void addMissingPorts(Device device) {
-        try {
-            List<Port> ports = deviceService.getPorts(device.id());
-            Set<ConnectPoint> existing = ports.stream()
-                    .map(p -> new ConnectPoint(device.id(), p.number()))
-                    .collect(Collectors.toSet());
-            Set<ConnectPoint> missing = connectPoints.stream()
-                    .filter(cp -> cp.deviceId().equals(device.id()))
-                    .filter(cp -> !existing.contains(cp))
-                    .collect(Collectors.toSet());
-
-            if (!missing.isEmpty()) {
-                List<PortDescription> newPorts = Stream.concat(
-                        ports.stream().map(this::description),
-                        missing.stream().map(this::description)
-                ).collect(Collectors.toList());
-                deviceProviderService.updatePorts(device.id(), newPorts);
-            }
-        } catch (IllegalArgumentException e) {
-            log.warn("Error pushing ports: {}", e.getMessage());
-        }
-    }
-
-    // Creates a port description from the specified port.
-    private PortDescription description(Port p) {
-        switch (p.type()) {
-            case OMS:
-                OmsPort op = (OmsPort) p;
-                return omsPortDescription(
-                        op.number(), op.isEnabled(), op.minFrequency(), op.maxFrequency(), op.grid());
-            case OCH:
-                OchPort ochp = (OchPort) p;
-                return ochPortDescription(
-                        ochp.number(), ochp.isEnabled(), ochp.signalType(), ochp.isTunable(), ochp.lambda());
-            case ODUCLT:
-                OduCltPort odup = (OduCltPort) p;
-                return oduCltPortDescription(
-                        odup.number(), odup.isEnabled(), odup.signalType());
-            default:
-                return new DefaultPortDescription(p.number(), p.isEnabled(), p.type(), p.portSpeed());
-        }
-    }
-
-    // Creates a port description from the specified connection point if none created earlier.
-    private PortDescription description(ConnectPoint cp) {
-        PortDescription saved = descriptions.get(cp);
-        if (saved != null) {
-            return saved;
-        }
-        Port p = deviceService.getPort(cp.deviceId(), cp.port());
-        if (p == null) {
-            return new DefaultPortDescription(cp.port(), true);
-        }
-        return description(p);
-    }
-
-    // Produces set of annotations from the given JSON node.
-    private SparseAnnotations annotations(JsonNode node) {
-        if (node == null) {
-            return DefaultAnnotations.EMPTY;
-        }
-
-        DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
-        Iterator<String> it = node.fieldNames();
-        while (it.hasNext()) {
-            String k = it.next();
-            builder.set(k, node.get(k).asText());
-        }
-        return builder.build();
-    }
-
-    // Produces a connection point from the specified uri/port text.
-    private ConnectPoint connectPoint(String text) {
-        int i = text.lastIndexOf("/");
-        String portName = text.substring(i + 1);
-        DeviceId deviceId = deviceId(text.substring(0, i));
-
-        for (Port port : deviceService.getPorts(deviceId)) {
-            PortNumber pn = port.number();
-            if (pn.name().equals(portName)) {
-                return new ConnectPoint(deviceId, pn);
-            }
-        }
-
-        long portNum;
-        try {
-            portNum = Long.parseLong(portName);
-        } catch (NumberFormatException e) {
-            portNum = 0;
-        }
-
-        return new ConnectPoint(deviceId, portNumber(portNum, portName));
-    }
-
-    // Returns string form of the named property in the given JSON object.
-    private String get(JsonNode node, String name) {
-        return node.path(name).asText();
-    }
-
-    // Returns string form of the named property in the given JSON object.
-    private String get(JsonNode node, String name, String defaultValue) {
-        return node.path(name).asText(defaultValue);
-    }
-
-    @Override
-    public void roleChanged(DeviceId device, MastershipRole newRole) {
-        deviceProviderService.receivedRoleReply(device, newRole, newRole);
-    }
-
-    @Override
-    public void triggerProbe(DeviceId deviceId) {
-    }
-
-    @Override
-    public void triggerProbe(Host host) {
-    }
-
-    @Override
-    public void changePortState(DeviceId deviceId, PortNumber portNumber,
-                                boolean enable) {
-    }
-
-    @Override
-    public ProviderId id() {
-        return PID;
-    }
-
-    @Override
-    public boolean isReachable(DeviceId device) {
-        return true;
-    }
-
-    /**
-     * Prepares to count device added/available/removed events.
-     *
-     * @param count number of events to count
-     */
-    protected void prepareForDeviceEvents(int count) {
-        deviceLatch = new CountDownLatch(count);
-        deviceService.addListener(deviceEventCounter);
-    }
-
-    /**
-     * Waits for all expected device added/available/removed events.
-     */
-    protected void waitForDeviceEvents() {
-        try {
-            deviceLatch.await(2, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            log.warn("Device events did not arrive in time");
-        }
-        deviceService.removeListener(deviceEventCounter);
-    }
-
-    // Counts down number of device added/available/removed events.
-    private class DeviceEventCounter implements DeviceListener {
-        @Override
-        public void event(DeviceEvent event) {
-            DeviceEvent.Type type = event.type();
-            if (type == DEVICE_ADDED || type == DEVICE_AVAILABILITY_CHANGED) {
-                deviceLatch.countDown();
-            }
-        }
-    }
-
-
-
-}
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/ConfigWebResource.java b/web/api/src/main/java/org/onosproject/rest/resources/ConfigWebResource.java
deleted file mode 100644
index 0c75c17..0000000
--- a/web/api/src/main/java/org/onosproject/rest/resources/ConfigWebResource.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * 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.rest.resources;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.onlab.rest.BaseResource;
-import org.onosproject.net.device.DeviceProviderRegistry;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.host.HostProviderRegistry;
-import org.onosproject.net.link.LinkProviderRegistry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.io.InputStream;
-
-import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
-
-/**
- * Inject devices, ports, links and end-station hosts.
- */
-@Path("config")
-public class ConfigWebResource extends BaseResource {
-
-    private static Logger log = LoggerFactory.getLogger(ConfigWebResource.class);
-
-    /**
-     * Upload device, port, link and host data.
-     *
-     * @param input JSON blob
-     * @return 200 OK
-     */
-    @POST
-    @Path("topology")
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response topology(InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode cfg = mapper.readTree(input);
-            new ConfigProvider(cfg, get(DeviceService.class),
-                               get(DeviceProviderRegistry.class),
-                               get(LinkProviderRegistry.class),
-                               get(HostProviderRegistry.class)).parse();
-            return Response.ok().build();
-        } catch (Exception e) {
-            log.error("Unable to parse topology configuration", e);
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString()).build();
-        }
-    }
-
-}
diff --git a/web/api/src/main/java/org/onosproject/rest/resources/CoreWebApplication.java b/web/api/src/main/java/org/onosproject/rest/resources/CoreWebApplication.java
index 2a03671..3a4170b 100644
--- a/web/api/src/main/java/org/onosproject/rest/resources/CoreWebApplication.java
+++ b/web/api/src/main/java/org/onosproject/rest/resources/CoreWebApplication.java
@@ -40,7 +40,6 @@
                 GroupsWebResource.class,
                 MetersWebResource.class,
                 TopologyWebResource.class,
-                ConfigWebResource.class,
                 PathsWebResource.class,
                 StatisticsWebResource.class,
                 MetricsWebResource.class,
