Changed to use XOS client to get service and port information

XOS client still gets these information from OpenStack temporarily
until XOS provides these APIs

Change-Id: I1ef9302f719a18a7377221f63b84431c2cdface8
diff --git a/apps/cordvtn/BUCK b/apps/cordvtn/BUCK
index af9c811..07e1fc0 100644
--- a/apps/cordvtn/BUCK
+++ b/apps/cordvtn/BUCK
@@ -6,13 +6,9 @@
     '//lib:org.apache.karaf.shell.console',
     '//lib:javax.ws.rs-api',
     '//lib:jsch',
-    '//lib:openstack4j-core',
-    '//lib:openstack4j-http-connector',
-    '//lib:openstack4j-httpclient',
     '//utils/rest:onlab-rest',
     '//cli:onos-cli',
     '//core/store/serializers:onos-core-serializers',
-    '//apps/openstackinterface/api:onos-apps-openstackinterface-api',
     '//apps/dhcp/api:onos-apps-dhcp-api',
     '//apps/xosclient:onos-apps-xosclient',
     '//protocols/ovsdb/api:onos-protocols-ovsdb-api',
@@ -20,11 +16,7 @@
 ]
 
 BUNDLES = [
-    '//apps/openstackinterface/api:onos-apps-openstackinterface-api',
     '//apps/cordvtn:onos-apps-cordvtn',
-    '//lib:openstack4j-core',
-    '//lib:openstack4j-http-connector',
-    '//lib:openstack4j-httpclient',
 ]
 
 EXCLUDED_BUNDLES = [
@@ -43,5 +35,5 @@
     included_bundles = BUNDLES,
     excluded_bundles = EXCLUDED_BUNDLES,
     description = 'APIs for interacting with the CORD VTN application.',
-    required_apps = [ 'org.onosproject.xosclient', 'org.onosproject.dhcp', 'org.onosproject.ovsdb', 'org.onosproject.openstackinterface' ],
+    required_apps = [ 'org.onosproject.xosclient', 'org.onosproject.dhcp', 'org.onosproject.ovsdb' ],
 )
diff --git a/apps/cordvtn/pom.xml b/apps/cordvtn/pom.xml
index 705a9b4..7dce52c 100644
--- a/apps/cordvtn/pom.xml
+++ b/apps/cordvtn/pom.xml
@@ -112,21 +112,6 @@
             <artifactId>jsch</artifactId>
             <version>0.1.53</version>
         </dependency>
-        <dependency>
-            <groupId>org.pacesys</groupId>
-            <artifactId>openstack4j-core</artifactId>
-            <version>2.11</version>
-        </dependency>
-        <dependency>
-            <groupId>org.pacesys.openstack4j.connectors</groupId>
-            <artifactId>openstack4j-http-connector</artifactId>
-            <version>2.11</version>
-        </dependency>
-        <dependency>
-            <groupId>org.pacesys.openstack4j.connectors</groupId>
-            <artifactId>openstack4j-httpclient</artifactId>
-            <version>2.11</version>
-        </dependency>
     </dependencies>
 
     <build>
@@ -146,15 +131,8 @@
                             ${project.groupId}.${project.artifactId}
                         </Bundle-SymbolicName>
                         <Import-Package>
-                            !org.apache.http.*,
-                            !com.fasterxml.jackson.dataformat.*,
                             *,org.glassfish.jersey.servlet
                         </Import-Package>
-                        <Embed-Dependency>
-                            openstack4j-core,
-                            openstack4j-http-connector,
-                            openstack4j-httpclient
-                        </Embed-Dependency>
                         <Web-ContextPath>${web.context}</Web-ContextPath>
                     </instructions>
                 </configuration>
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordService.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordService.java
deleted file mode 100644
index 604e707..0000000
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordService.java
+++ /dev/null
@@ -1,191 +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.cordvtn.api;
-
-import com.google.common.base.MoreObjects;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onosproject.net.Host;
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.Subnet;
-
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-public final class CordService {
-
-    public enum ServiceType {
-        PRIVATE,
-        PUBLIC,
-        MANAGEMENT
-    }
-
-    private final CordServiceId id;
-    private final long segmentationId;
-    private final ServiceType serviceType;
-    private final IpPrefix serviceIpRange;
-    private final IpAddress serviceIp;
-    private final Map<Host, IpAddress> hosts;
-    private final Set<CordServiceId> tenantServices;
-    private final Set<CordServiceId> providerServices;
-
-    /**
-     * Default constructor.
-     *
-     * @param osNet OpenStack network
-     * @param osSubnet OpenStack subnet
-     * @param hosts host and tunnel ip map
-     * @param tenantServices list of tenant service ids
-     * @param providerServices list of provider service ids
-     */
-    public CordService(Network osNet, Subnet osSubnet,
-                       Map<Host, IpAddress> hosts, Set<CordServiceId> tenantServices,
-                       Set<CordServiceId> providerServices) {
-        this.id = CordServiceId.of(osNet.getId());
-        this.segmentationId = Long.parseLong(osNet.getProviderSegID());
-        this.serviceType = getServiceType(osNet.getName());
-        this.serviceIpRange = IpPrefix.valueOf(osSubnet.getCidr());
-        this.serviceIp = IpAddress.valueOf(osSubnet.getGateway());
-        this.hosts = hosts;
-        this.tenantServices = tenantServices;
-        this.providerServices = providerServices;
-    }
-
-    /**
-     * Returns service ID.
-     *
-     * @return service id
-     */
-    public CordServiceId id() {
-        return id;
-    }
-
-    /**
-     * Returns segmentation ID of this service.
-     *
-     * @return segmentation id
-     */
-    public long segmentationId() {
-        return segmentationId;
-    }
-
-    /**
-     * Returns service type.
-     *
-     * @return service type
-     */
-    public ServiceType serviceType() {
-        return serviceType;
-    }
-
-    /**
-     * Returns service IP range.
-     *
-     * @return CIDR
-     */
-    public IpPrefix serviceIpRange() {
-        return serviceIpRange;
-    }
-
-    /**
-     * Returns service IP address.
-     *
-     * @return ip address
-     */
-    public IpAddress serviceIp() {
-        return serviceIp;
-    }
-
-    /**
-     * Returns hosts associated with this service.
-     *
-     * @return list of hosts
-     */
-    public Map<Host, IpAddress> hosts() {
-        return hosts;
-    }
-
-    /**
-     * Returns tenant service IDs.
-     *
-     * @return list of tenant service id
-     */
-    public Set<CordServiceId> tenantServices() {
-        return tenantServices;
-    }
-
-    /**
-     * Returns provider service IDs.
-     *
-     * @return list of provider service id
-     */
-    public Set<CordServiceId> providerServices() {
-        return providerServices;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (!(obj instanceof CordService)) {
-            return false;
-        }
-        final CordService other = (CordService) obj;
-        return Objects.equals(this.id, other.id);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(this)
-                .add("id", id)
-                .add("segmentationId", segmentationId)
-                .add("serviceType", serviceType)
-                .add("serviceIpRange", serviceIpRange)
-                .add("serviceIp", serviceIp)
-                .add("tenantServices", tenantServices)
-                .add("providerServices", providerServices)
-                .toString();
-    }
-
-    /**
-     * Returns network type from network name.
-     * It assumes that network name contains network type.
-     *
-     * @param netName network name
-     * @return network type, or PRIVATE if it doesn't match any type
-     */
-    private ServiceType getServiceType(String netName) {
-        checkNotNull(netName);
-
-        String name = netName.toUpperCase();
-        if (name.contains(ServiceType.PUBLIC.toString())) {
-            return ServiceType.PUBLIC;
-        } else if (name.contains(ServiceType.MANAGEMENT.toString())) {
-            return ServiceType.MANAGEMENT;
-        } else {
-            return ServiceType.PRIVATE;
-        }
-    }
-}
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordServiceId.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordServiceId.java
deleted file mode 100644
index b8a22a2..0000000
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordServiceId.java
+++ /dev/null
@@ -1,45 +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.cordvtn.api;
-
-import org.onlab.util.Identifier;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Representation of service identifier.
- */
-public final class CordServiceId extends Identifier<String> {
-    /**
-     * Default constructor.
-     *
-     * @param id service identifier
-     */
-    private CordServiceId(String id) {
-        super(id);
-    }
-
-    /**
-     * Returns the CordServiceId with value.
-     *
-     * @param id service id
-     * @return CordServiceId
-     */
-    public static CordServiceId of(String id) {
-        checkNotNull(id);
-        return new CordServiceId(id);
-    }
-}
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java
index 2055e34..b50d6fc 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordVtnConfig.java
@@ -25,6 +25,7 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.config.Config;
+import org.onosproject.xosclient.api.OpenStackAccess;
 import org.onosproject.xosclient.api.XosAccess;
 import org.slf4j.Logger;
 
@@ -209,9 +210,9 @@
     /**
      * Returns OpenStack API access information.
      *
-     * @return openstack config
+     * @return openstack access
      */
-    public OpenStackConfig openstackConfig() {
+    public OpenStackAccess openstackAccess() {
         JsonNode jsonNode = object.get(OPENSTACK);
         if (jsonNode == null) {
             log.error("Failed to get OpenStack configurations");
@@ -219,7 +220,7 @@
         }
 
         try {
-            return new OpenStackConfig(
+            return new OpenStackAccess(
                     jsonNode.path(ENDPOINT).asText(),
                     jsonNode.path(TENANT).asText(),
                     jsonNode.path(USER).asText(),
@@ -229,66 +230,4 @@
             return null;
         }
     }
-
-    /**
-     * Configuration for OpenStack API access.
-     */
-    public static class OpenStackConfig {
-
-        private final String endpoint;
-        private final String tenant;
-        private final String user;
-        private final String password;
-
-        /**
-         * Default constructor.
-         *
-         * @param endpoint Keystone endpoint
-         * @param tenant tenant name
-         * @param user user name
-         * @param password passwowrd
-         */
-        public OpenStackConfig(String endpoint, String tenant, String user, String password) {
-            this.endpoint = endpoint;
-            this.tenant = tenant;
-            this.user = user;
-            this.password = password;
-        }
-
-        /**
-         * Returns OpenStack API endpoint.
-         *
-         * @return endpoint
-         */
-        public String endpoint() {
-            return this.endpoint;
-        }
-
-        /**
-         * Returns OpenStack tenant name.
-         *
-         * @return tenant name
-         */
-        public String tenant() {
-            return this.tenant;
-        }
-
-        /**
-         * Returns OpenStack user.
-         *
-         * @return user name
-         */
-        public String user() {
-            return this.user;
-        }
-
-        /**
-         * Returns OpenStack password for the user.
-         *
-         * @return password
-         */
-        public String password() {
-            return this.password;
-        }
-    }
 }
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java
index 5950670..bd25b0f 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/api/CordVtnService.java
@@ -19,6 +19,7 @@
 import org.onlab.packet.MacAddress;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.HostId;
+import org.onosproject.xosclient.api.VtnServiceId;
 
 import java.util.Map;
 
@@ -51,8 +52,7 @@
      * @param pServiceId id of the service which provide dependency
      * @param isBidirectional true to enable bidirectional connectivity between two services
      */
-    void createServiceDependency(CordServiceId tServiceId,
-                                 CordServiceId pServiceId,
+    void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId,
                                  boolean isBidirectional);
 
     /**
@@ -61,7 +61,7 @@
      * @param tServiceId id of the service which has a dependency
      * @param pServiceId id of the service which provide dependency
      */
-    void removeServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId);
+    void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId);
 
     /**
      * Updates virtual service gateways.
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
index f694019..cfcdc4b 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtn.java
@@ -15,6 +15,7 @@
  */
 package org.onosproject.cordvtn.impl;
 
+import com.google.common.base.Strings;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
@@ -29,8 +30,6 @@
 import org.onlab.packet.IpAddress;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
-import org.onosproject.cordvtn.api.CordService;
-import org.onosproject.cordvtn.api.CordServiceId;
 import org.onosproject.cordvtn.api.CordVtnConfig;
 import org.onosproject.cordvtn.api.CordVtnNode;
 import org.onosproject.cordvtn.api.CordVtnService;
@@ -48,7 +47,6 @@
 import org.onosproject.net.config.NetworkConfigEvent;
 import org.onosproject.net.config.NetworkConfigListener;
 import org.onosproject.net.config.NetworkConfigRegistry;
-import org.onosproject.net.config.NetworkConfigService;
 import org.onosproject.net.config.basics.SubjectFactories;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.FlowRuleService;
@@ -66,16 +64,15 @@
 import org.onosproject.net.packet.PacketService;
 import org.onosproject.net.provider.AbstractProvider;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.xosclient.api.OpenStackAccess;
+import org.onosproject.xosclient.api.VtnPort;
+import org.onosproject.xosclient.api.VtnPortApi;
+import org.onosproject.xosclient.api.VtnPortId;
+import org.onosproject.xosclient.api.VtnService;
 import org.onosproject.xosclient.api.VtnServiceApi;
 import org.onosproject.xosclient.api.VtnServiceId;
 import org.onosproject.xosclient.api.XosAccess;
 import org.onosproject.xosclient.api.XosClientService;
-import org.openstack4j.api.OSClient;
-import org.openstack4j.api.exceptions.AuthenticationException;
-import org.openstack4j.model.identity.Access;
-import org.openstack4j.model.network.Network;
-import org.openstack4j.model.network.Subnet;
-import org.openstack4j.openstack.OSFactory;
 import org.slf4j.Logger;
 
 import java.util.List;
@@ -108,9 +105,6 @@
     protected NetworkConfigRegistry configRegistry;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected NetworkConfigService configService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected HostProviderRegistry hostProviderRegistry;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -145,14 +139,17 @@
                 }
             };
 
+    private static final String XOS_ACCESS_ERROR = "XOS access is not configured";
+    private static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured";
+
     private static final String DEFAULT_TUNNEL = "vxlan";
     private static final String SERVICE_ID = "serviceId";
-    private static final String OPENSTACK_PORT_ID = "openstackPortId";
+    private static final String PORT_ID = "vtnPortId";
     private static final String DATA_PLANE_IP = "dataPlaneIp";
     private static final String DATA_PLANE_INTF = "dataPlaneIntf";
     private static final String S_TAG = "stag";
     private static final String VSG_HOST_ID = "vsgHostId";
-    private static final String CREATED_TIME = "createdTime";
+    private static final String CREATE_TIME = "createTime";
 
     private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8");
 
@@ -169,7 +166,7 @@
     private CordVtnArpProxy arpProxy;
 
     private volatile XosAccess xosAccess = null;
-    private volatile Access osAccess = null;
+    private volatile OpenStackAccess osAccess = null;
     private volatile MacAddress privateGatewayMac = MacAddress.NONE;
 
     /**
@@ -185,6 +182,7 @@
         ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService,
                                                  deviceService,
                                                  groupService,
+                                                 hostService,
                                                  configRegistry,
                                                  DEFAULT_TUNNEL);
 
@@ -196,7 +194,7 @@
         hostProvider = hostProviderRegistry.register(this);
 
         configRegistry.registerConfigFactory(configFactory);
-        configService.addListener(configListener);
+        configRegistry.addListener(configListener);
 
         log.info("Started");
     }
@@ -209,7 +207,7 @@
         packetService.removeProcessor(packetProcessor);
 
         configRegistry.unregisterConfigFactory(configFactory);
-        configService.removeListener(configListener);
+        configRegistry.removeListener(configListener);
 
         eventExecutor.shutdown();
         log.info("Stopped");
@@ -224,88 +222,85 @@
     }
 
     @Override
-    public void createServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId,
+    public void createServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId,
                                         boolean isBidirectional) {
-        CordService tService = getCordService(tServiceId);
-        CordService pService = getCordService(pServiceId);
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
+
+        // TODO remove openstack access when XOS provides all information
+        VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
+        VtnService tService = serviceApi.service(tServiceId, osAccess);
+        VtnService pService = serviceApi.service(pServiceId, osAccess);
 
         if (tService == null || pService == null) {
-            log.error("Failed to create CordService for {}", tServiceId.id());
+            log.error("Failed to create dependency between {} and {}",
+                      tServiceId, pServiceId);
             return;
         }
 
-        log.info("Service dependency from {} to {} created.", tService.id().id(), pService.id().id());
+        log.info("Created dependency between {} and {}", tService.name(), pService.name());
         ruleInstaller.populateServiceDependencyRules(tService, pService, isBidirectional, true);
     }
 
     @Override
-    public void removeServiceDependency(CordServiceId tServiceId, CordServiceId pServiceId) {
-        CordService tService = getCordService(tServiceId);
-        CordService pService = getCordService(pServiceId);
+    public void removeServiceDependency(VtnServiceId tServiceId, VtnServiceId pServiceId) {
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
+
+        // TODO remove openstack access when XOS provides all information
+        VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
+        VtnService tService = serviceApi.service(tServiceId, osAccess);
+        VtnService pService = serviceApi.service(pServiceId, osAccess);
 
         if (tService == null || pService == null) {
-            log.error("Failed to create CordService for {}", tServiceId.id());
+            log.error("Failed to remove dependency between {} and {}",
+                      tServiceId, pServiceId);
             return;
         }
 
-        log.info("Service dependency from {} to {} removed.", tService.id().id(), pService.id().id());
+        log.info("Removed dependency between {} and {}", tService.name(), pService.name());
         ruleInstaller.populateServiceDependencyRules(tService, pService, true, false);
     }
 
     @Override
     public void addServiceVm(CordVtnNode node, ConnectPoint connectPoint) {
-        checkNotNull(osAccess, "OpenStack access is not set");
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
 
-        OSClient osClient = OSFactory.clientFromAccess(osAccess);
         Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
-        org.openstack4j.model.network.Port osPort = osClient.networking().port().list()
-                .stream()
-                .filter(p -> p.getId().contains(getPortName(port).substring(3)))
-                .findFirst().orElse(null);
-        if (osPort == null) {
-            log.warn("Failed to get OpenStack port for {}", getPortName(port));
+        String portName = port.annotations().value("portName");
+
+        // TODO remove openstack access when XOS provides all information
+        VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort();
+        VtnPort vtnPort = portApi.vtnPort(portName, osAccess);
+        if (vtnPort == null) {
+            log.warn("Failed to get port information of {}", portName);
             return;
         }
 
-        MacAddress mac = MacAddress.valueOf(osPort.getMacAddress());
-        HostId hostId = HostId.hostId(mac);
-
-        Host existingHost = hostService.getHost(hostId);
-        if (existingHost != null) {
-            String serviceId = existingHost.annotations().value(SERVICE_ID);
-            if (serviceId == null || !serviceId.equals(osPort.getNetworkId())) {
-                // this host is not injected by cordvtn or a stale host, remove it
-                hostProvider.hostVanished(existingHost.id());
-            }
-        }
-
-        // Included CREATED_TIME to annotation intentionally to trigger HOST_UPDATED
-        // event so that the flow rule population for this host can happen.
-        // This ensures refreshing data plane by pushing network config always make
-        // the data plane synced.
-        Set<IpAddress> fixedIps = osPort.getFixedIps().stream()
-                .map(ip -> IpAddress.valueOf(ip.getIpAddress()))
-                .collect(Collectors.toSet());
-
+        // Added CREATE_TIME intentionally to trigger HOST_UPDATED event for the
+        // existing instances.
         DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
-                .set(SERVICE_ID, osPort.getNetworkId())
-                .set(OPENSTACK_PORT_ID, osPort.getId())
+                .set(SERVICE_ID, vtnPort.serviceId().id())
+                .set(PORT_ID, vtnPort.id().id())
                 .set(DATA_PLANE_IP, node.dpIp().ip().toString())
                 .set(DATA_PLANE_INTF, node.dpIntf())
-                .set(CREATED_TIME, String.valueOf(System.currentTimeMillis()));
+                .set(CREATE_TIME, String.valueOf(System.currentTimeMillis()));
 
-        String serviceVlan = getServiceVlan(osPort);
-        if (serviceVlan != null) {
+        // TODO address service specific task in a separate package
+        String serviceVlan = getServiceVlan(vtnPort);
+        if (!Strings.isNullOrEmpty(serviceVlan)) {
             annotations.set(S_TAG, serviceVlan);
         }
 
         HostDescription hostDesc = new DefaultHostDescription(
-                mac,
+                vtnPort.mac(),
                 VlanId.NONE,
                 new HostLocation(connectPoint, System.currentTimeMillis()),
-                fixedIps,
+                Sets.newHashSet(vtnPort.ip()),
                 annotations.build());
 
+        HostId hostId = HostId.hostId(vtnPort.mac());
         hostProvider.hostDetected(hostId, hostDesc, false);
     }
 
@@ -317,6 +312,7 @@
     }
 
     @Override
+    // TODO address service specific task in a separate package
     public void updateVirtualSubscriberGateways(HostId vSgHostId, String serviceVlan,
                                                 Map<IpAddress, MacAddress> vSgs) {
         Host vSgHost = hostService.getHost(vSgHostId);
@@ -351,6 +347,7 @@
      * @param vSgMac vSG mac address
      * @param serviceVlan service vlan
      */
+    // TODO address service specific task in a separate package
     private void addVirtualSubscriberGateway(Host vSgHost, IpAddress vSgIp, MacAddress vSgMac,
                                              String serviceVlan) {
         log.info("vSG with IP({}) MAC({}) added", vSgIp.toString(), vSgMac.toString());
@@ -359,7 +356,7 @@
         DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
                 .set(S_TAG, serviceVlan)
                 .set(VSG_HOST_ID, vSgHost.id().toString())
-                .set(CREATED_TIME, String.valueOf(System.currentTimeMillis()));
+                .set(CREATE_TIME, String.valueOf(System.currentTimeMillis()));
 
         HostDescription hostDesc = new DefaultHostDescription(
                 vSgMac,
@@ -377,125 +374,45 @@
      * @param vSgHost vSG host
      * @return map of ip and mac address, or empty map
      */
+    // TODO address service specific task in a separate package
     private Map<IpAddress, MacAddress> getSubscriberGateways(Host vSgHost) {
-        checkNotNull(osAccess, "OpenStack access is not set");
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
 
-        String osPortId = vSgHost.annotations().value(OPENSTACK_PORT_ID);
-        String serviceVlan = vSgHost.annotations().value(S_TAG);
+        String vtnPortId = vSgHost.annotations().value(PORT_ID);
+        String sTag = vSgHost.annotations().value(S_TAG);
 
-        OSClient osClient = OSFactory.clientFromAccess(osAccess);
-        org.openstack4j.model.network.Port osPort = osClient.networking().port().get(osPortId);
-        if (osPort == null) {
-            log.warn("Failed to get OpenStack port {} for VM {}", osPortId, vSgHost.id());
+        if (Strings.isNullOrEmpty(vtnPortId) || Strings.isNullOrEmpty(sTag)) {
+            log.warn("PORT_ID and S_TAG is not set, ignore {}", vSgHost);
             return Maps.newHashMap();
         }
 
-        if (!serviceVlan.equals(getServiceVlan(osPort))) {
-            log.error("Host({}) s-tag does not match with OpenStack port s-tag", vSgHost.id());
+        // TODO remove openstack access when XOS provides all information
+        VtnPortApi portApi = xosClient.getClient(xosAccess).vtnPort();
+        VtnPort vtnPort = portApi.vtnPort(VtnPortId.of(vtnPortId), osAccess);
+        if (vtnPort == null) {
+            log.warn("Failed to get port information of {}", vSgHost);
             return Maps.newHashMap();
         }
 
-        Map<IpAddress, MacAddress> addressPairs = Maps.newHashMap();
-        osPort.getAllowedAddressPairs()
-                .stream().forEach(p -> addressPairs.put(
-                IpAddress.valueOf(p.getIpAddress()),
-                MacAddress.valueOf(p.getMacAddress())));
-
-        return addressPairs;
-    }
-
-    /**
-     * Returns CordService by service ID.
-     *
-     * @param serviceId service id
-     * @return cord service, or null if it fails to get network from OpenStack
-     */
-    private CordService getCordService(CordServiceId serviceId) {
-        checkNotNull(osAccess, "OpenStack access is not set");
-
-        OSClient osClient = OSFactory.clientFromAccess(osAccess);
-        Network osNet = osClient.networking().network().get(serviceId.id());
-        if (osNet == null) {
-            log.warn("Couldn't find OpenStack network for service {}", serviceId.id());
-            return null;
+        if (!sTag.equals(getServiceVlan(vtnPort))) {
+            log.error("Host({}) s-tag does not match with VTN port s-tag", vSgHost);
+            return Maps.newHashMap();
         }
-
-        return getCordService(osNet);
+        return vtnPort.addressPairs();
     }
 
     /**
-     * Returns CordService by OpenStack network.
+     * Returns s-tag from a given VTN port.
      *
-     * @param osNet OpenStack network
-     * @return cord service
-     */
-    private CordService getCordService(Network osNet) {
-        checkNotNull(osNet);
-
-        CordServiceId serviceId = CordServiceId.of(osNet.getId());
-        // here it assumes all cord service networks has only one subnet
-        Subnet osSubnet = osNet.getNeutronSubnets().stream()
-                .findFirst().orElse(null);
-        if (osSubnet == null) {
-            log.warn("Couldn't find OpenStack subnet for network {}", serviceId.id());
-            return null;
-        }
-
-        Map<Host, IpAddress> hosts = getHostsWithOpenstackNetwork(osNet)
-                .stream()
-                .collect(Collectors.toMap(host -> host, this::getTunnelIp));
-
-        // allows working without XOS for now
-        Set<CordServiceId> tServices = Sets.newHashSet();
-        Set<CordServiceId> pServices = Sets.newHashSet();
-
-        if (xosAccess != null) {
-            VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService();
-            tServices = vtnServiceApi.tenantServices(VtnServiceId.of(serviceId.id()))
-                    .stream()
-                    .map(id -> CordServiceId.of(id.id()))
-                    .collect(Collectors.toSet());
-
-            pServices = vtnServiceApi.providerServices(VtnServiceId.of(serviceId.id()))
-                    .stream()
-                    .map(id -> CordServiceId.of(id.id()))
-                    .collect(Collectors.toSet());
-        }
-
-        return new CordService(osNet, osSubnet, hosts, tServices, pServices);
-    }
-
-    /**
-     * Returns IP address for tunneling for a given host.
-     *
-     * @param host host
-     * @return ip address, or null
-     */
-    private IpAddress getTunnelIp(Host host) {
-        String ip = host.annotations().value(DATA_PLANE_IP);
-        return ip == null ? null : IpAddress.valueOf(ip);
-    }
-
-    /**
-     * Returns port name.
-     *
-     * @param port port
-     * @return port name
-     */
-    private String getPortName(Port port) {
-        return port.annotations().value("portName");
-    }
-
-    /**
-     * Returns s-tag from a given OpenStack port.
-     *
-     * @param osPort openstack port
+     * @param vtnPort vtn port
      * @return s-tag string
      */
-    private String getServiceVlan(org.openstack4j.model.network.Port osPort) {
-        checkNotNull(osPort);
+    // TODO address service specific task in a separate package
+    private String getServiceVlan(VtnPort vtnPort) {
+        checkNotNull(vtnPort);
 
-        String portName = osPort.getName();
+        String portName = vtnPort.name();
         if (portName != null && portName.startsWith(S_TAG)) {
             return portName.split("-")[1];
         } else {
@@ -504,27 +421,16 @@
     }
 
     /**
-     * Returns service ID of this host.
+     * Returns instances with a given network service.
      *
-     * @param host host
-     * @return service id, or null if not found
-     */
-    private String getServiceId(Host host) {
-        return host.annotations().value(SERVICE_ID);
-    }
-
-    /**
-     * Returns hosts associated with a given OpenStack network.
-     *
-     * @param osNet openstack network
+     * @param serviceId service id
      * @return set of hosts
      */
-    private Set<Host> getHostsWithOpenstackNetwork(Network osNet) {
-        checkNotNull(osNet);
-
-        String osNetId = osNet.getId();
+    private Set<Host> getInstances(VtnServiceId serviceId) {
         return StreamSupport.stream(hostService.getHosts().spliterator(), false)
-                .filter(host -> Objects.equals(osNetId, getServiceId(host)))
+                .filter(host -> Objects.equals(
+                        serviceId.id(),
+                        host.annotations().value(SERVICE_ID)))
                 .collect(Collectors.toSet());
     }
 
@@ -534,9 +440,9 @@
      * @param host host
      * @param service cord service
      */
-    private void registerDhcpLease(Host host, CordService service) {
+    private void registerDhcpLease(Host host, VtnService service) {
         List<Ip4Address> options = Lists.newArrayList();
-        options.add(Ip4Address.makeMaskPrefix(service.serviceIpRange().prefixLength()));
+        options.add(Ip4Address.makeMaskPrefix(service.subnet().prefixLength()));
         options.add(service.serviceIp().getIp4Address());
         options.add(service.serviceIp().getIp4Address());
         options.add(DEFAULT_DNS);
@@ -554,28 +460,32 @@
      * @param host host
      */
     private void serviceVmAdded(Host host) {
-        checkNotNull(osAccess, "OpenStack access is not set");
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
 
+        // TODO address service specific task in a separate package
         String serviceVlan = host.annotations().value(S_TAG);
         if (serviceVlan != null) {
             virtualSubscriberGatewayAdded(host, serviceVlan);
         }
 
         String serviceId = host.annotations().value(SERVICE_ID);
-        if (serviceId == null) {
-            // ignore this host, it is not a service VM
+        if (Strings.isNullOrEmpty(serviceId)) {
+            // ignore this host, it is not a service instance
             return;
         }
 
-        log.info("VM is detected, MAC: {} IP: {}", host.mac(), host.ipAddresses());
+        log.info("Instance is detected {}", host);
 
-        CordService service = getCordService(CordServiceId.of(serviceId));
+        // TODO remove openstack access when XOS provides all information
+        VtnServiceApi serviceApi = xosClient.getClient(xosAccess).vtnService();
+        VtnService service = serviceApi.service(VtnServiceId.of(serviceId), osAccess);
         if (service == null) {
-            log.warn("Failed to get CordService for {}", serviceId);
+            log.warn("Failed to get VtnService for {}", serviceId);
             return;
         }
 
-        switch (service.serviceType()) {
+        switch (service.networkType()) {
             case MANAGEMENT:
                 ruleInstaller.populateManagementNetworkRules(host, service);
                 break;
@@ -606,32 +516,36 @@
      * @param host host
      */
     private void serviceVmRemoved(Host host) {
-        checkNotNull(osAccess, "OpenStack access is not set");
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
 
+        // TODO address service specific task in a separate package
         if (host.annotations().value(S_TAG) != null) {
             virtualSubscriberGatewayRemoved(host);
         }
 
         String serviceId = host.annotations().value(SERVICE_ID);
-        if (serviceId == null) {
-            // ignore it, it's not a service VM
+        if (Strings.isNullOrEmpty(serviceId)) {
+            // ignore this host, it is not a service instance
             return;
         }
 
-        log.info("VM is vanished, MAC: {} IP: {}", host.mac(), host.ipAddresses());
+        log.info("Instance is vanished {}", host);
 
-        CordService service = getCordService(CordServiceId.of(serviceId));
+        // TODO remove openstack access when XOS provides all information
+        VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService();
+        VtnService service = vtnServiceApi.service(VtnServiceId.of(serviceId), osAccess);
         if (service == null) {
-            log.warn("Failed to get CORD service for {}", serviceId);
+            log.warn("Failed to get VtnService for {}", serviceId);
             return;
         }
-        // TODO need to consider the case that the network is removed also
 
-        switch (service.serviceType()) {
+        // TODO need to consider the case that the service is removed also
+        switch (service.networkType()) {
             case MANAGEMENT:
                 break;
             case PRIVATE:
-                if (service.hosts().isEmpty()) {
+                if (getInstances(VtnServiceId.of(serviceId)).isEmpty()) {
                     arpProxy.removeGateway(service.serviceIp());
                 }
             case PUBLIC:
@@ -656,13 +570,14 @@
      * @param host new host with stag, it can be vsg VM or vsg
      * @param serviceVlan service vlan
      */
+    // TODO address service specific task in a separate package
     private void virtualSubscriberGatewayAdded(Host host, String serviceVlan) {
         Map<IpAddress, MacAddress> vSgs;
         Host vSgHost;
 
         String vSgHostId = host.annotations().value(VSG_HOST_ID);
         if (vSgHostId == null) {
-            log.debug("vSG VM detected {}", host.id());
+            log.info("vSG VM detected {}", host.id());
 
             vSgHost = host;
             vSgs = getSubscriberGateways(vSgHost);
@@ -677,7 +592,7 @@
                 return;
             }
 
-            log.debug("vSG detected {}", host.id());
+            log.info("vSG detected {}", host.id());
             vSgs = getSubscriberGateways(vSgHost);
         }
 
@@ -689,6 +604,7 @@
      *
      * @param vSg vsg host to remove
      */
+    // TODO address service specific task in a separate package
     private void virtualSubscriberGatewayRemoved(Host vSg) {
         String vSgHostId = vSg.annotations().value(VSG_HOST_ID);
         if (vSgHostId == null) {
@@ -712,7 +628,8 @@
      * @param newMac mac address to update
      */
     private void setPrivateGatewayMac(MacAddress newMac) {
-        checkNotNull(osAccess, "OpenStack access is not set");
+        checkNotNull(osAccess, OPENSTACK_ACCESS_ERROR);
+        checkNotNull(xosAccess, XOS_ACCESS_ERROR);
 
         if (newMac == null || newMac.equals(privateGatewayMac)) {
             // no updates, do nothing
@@ -722,14 +639,12 @@
         privateGatewayMac = newMac;
         log.debug("Set service gateway MAC address to {}", privateGatewayMac.toString());
 
-        OSClient osClient = OSFactory.clientFromAccess(osAccess);
-        List<Network> vNets = Lists.newArrayList(osClient.networking().network().list().iterator());
-
-        vNets.stream().forEach(vNet -> {
-            CordService service = getCordService(vNet);
+        VtnServiceApi vtnServiceApi = xosClient.getClient(xosAccess).vtnService();
+        vtnServiceApi.services().stream().forEach(serviceId -> {
+            VtnService service = vtnServiceApi.service(serviceId, osAccess);
             if (service != null) {
                 arpProxy.addGateway(service.serviceIp(), privateGatewayMac);
-                arpProxy.sendGratuitousArpForGateway(service.serviceIp(), service.hosts().keySet());
+                arpProxy.sendGratuitousArpForGateway(service.serviceIp(), getInstances(serviceId));
             }
         });
     }
@@ -751,51 +666,6 @@
     }
 
     /**
-     * Sets OpenStack access information.
-     * Access is the entity returned when authenticated and provides a singleton client
-     * between multiple threads.
-     *
-     * @param osConfig openstack config
-     */
-    private void setOpenstackAccess(CordVtnConfig.OpenStackConfig osConfig) {
-        checkNotNull(osConfig, "OpenStack access is not configured");
-
-        log.debug("Get OpenStack access with Endpoint: {} Tenant: {} User: {} Passwd: {}",
-                  osConfig.endpoint(),
-                  osConfig.tenant(),
-                  osConfig.user(),
-                  osConfig.password());
-        try {
-            osAccess = OSFactory.builder()
-                    .endpoint(osConfig.endpoint())
-                    .credentials(osConfig.user(), osConfig.password())
-                    .tenantName(osConfig.tenant())
-                    .authenticate()
-                    .getAccess();
-        } catch (AuthenticationException e) {
-            log.error("Failed to get OpenStack Access");
-        }
-    }
-
-    /**
-     * Sets XOS access information.
-     *
-     * @param xosAccess xos access
-     */
-    private void setXosAccess(XosAccess xosAccess) {
-        if (xosAccess == null) {
-            log.warn("XOS access is not configured");
-            return;
-        }
-
-        log.debug("Set XOS access with Endpoint: {} User: {} Passwd: {}",
-                  xosAccess.endpoint(),
-                  xosAccess.username(),
-                  xosAccess.password());
-        this.xosAccess = xosAccess;
-    }
-
-    /**
      * Updates configurations.
      */
     private void readConfiguration() {
@@ -805,8 +675,9 @@
             return;
         }
 
-        setXosAccess(config.xosAccess());
-        setOpenstackAccess(config.openstackConfig());
+        xosAccess = config.xosAccess();
+        osAccess = config.openstackAccess();
+
         setPrivateGatewayMac(config.privateGatewayMac());
         setPublicGatewayMac(config.publicGateways());
     }
@@ -824,10 +695,10 @@
             switch (event.type()) {
                 case HOST_UPDATED:
                 case HOST_ADDED:
-                    eventExecutor.submit(() -> serviceVmAdded(host));
+                    eventExecutor.execute(() -> serviceVmAdded(host));
                     break;
                 case HOST_REMOVED:
-                    eventExecutor.submit(() -> serviceVmRemoved(host));
+                    eventExecutor.execute(() -> serviceVmRemoved(host));
                     break;
                 default:
                     break;
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java
index acdd018..a3e7bd4 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnNodeManager.java
@@ -237,6 +237,7 @@
         ruleInstaller = new CordVtnRuleInstaller(appId, flowRuleService,
                                                  deviceService,
                                                  groupService,
+                                                 hostService,
                                                  configRegistry,
                                                  DEFAULT_TUNNEL);
 
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java
index ada68a9..e2be9a6 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/impl/CordVtnRuleInstaller.java
@@ -28,8 +28,6 @@
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
 import org.onlab.util.ItemNotFoundException;
-import org.onosproject.cordvtn.api.CordService;
-import org.onosproject.cordvtn.api.CordServiceId;
 import org.onosproject.cordvtn.api.CordVtnConfig;
 import org.onosproject.cordvtn.api.CordVtnNode;
 import org.onosproject.core.ApplicationId;
@@ -68,6 +66,9 @@
 import org.onosproject.net.group.GroupDescription;
 import org.onosproject.net.group.GroupKey;
 import org.onosproject.net.group.GroupService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.xosclient.api.VtnService;
+import org.onosproject.xosclient.api.VtnServiceId;
 import org.slf4j.Logger;
 
 import java.util.ArrayList;
@@ -76,6 +77,7 @@
 import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onosproject.net.flow.criteria.Criterion.Type.IPV4_DST;
@@ -112,11 +114,13 @@
     private static final String DATA_PLANE_INTF = "dataPlaneIntf";
     private static final String DATA_PLANE_IP = "dataPlaneIp";
     private static final String S_TAG = "stag";
+    private static final String SERVICE_ID = "serviceId";
 
     private final ApplicationId appId;
     private final FlowRuleService flowRuleService;
     private final DeviceService deviceService;
     private final GroupService groupService;
+    private final HostService hostService;
     private final NetworkConfigRegistry configRegistry;
     private final String tunnelType;
 
@@ -134,12 +138,14 @@
                                 FlowRuleService flowRuleService,
                                 DeviceService deviceService,
                                 GroupService groupService,
+                                HostService hostService,
                                 NetworkConfigRegistry configRegistry,
                                 String tunnelType) {
         this.appId = appId;
         this.flowRuleService = flowRuleService;
         this.deviceService = deviceService;
         this.groupService = groupService;
+        this.hostService = hostService;
         this.configRegistry = configRegistry;
         this.tunnelType = checkNotNull(tunnelType);
     }
@@ -177,7 +183,7 @@
      * @param service cord service
      * @param install true to install or false to remove
      */
-    public void populateBasicConnectionRules(Host host, CordService service, boolean install) {
+    public void populateBasicConnectionRules(Host host, VtnService service, boolean install) {
         checkNotNull(host);
         checkNotNull(service);
 
@@ -186,8 +192,8 @@
         MacAddress dstMac = host.mac();
         IpAddress hostIp = host.ipAddresses().stream().findFirst().get();
 
-        long tunnelId = service.segmentationId();
-        Ip4Prefix serviceIpRange = service.serviceIpRange().getIp4Prefix();
+        long tunnelId = service.vni();
+        Ip4Prefix serviceIpRange = service.subnet().getIp4Prefix();
 
         populateLocalInPortRule(deviceId, inPort, hostIp, install);
         populateDstIpRule(deviceId, inPort, dstMac, hostIp, tunnelId, getTunnelIp(host), install);
@@ -196,7 +202,7 @@
         if (install) {
             populateDirectAccessRule(serviceIpRange, serviceIpRange, true);
             populateServiceIsolationRule(serviceIpRange, true);
-        } else if (service.hosts().isEmpty()) {
+        } else if (getInstances(service.id()).isEmpty()) {
             // removes network related rules only if there's no hosts left in this network
             populateDirectAccessRule(serviceIpRange, serviceIpRange, false);
             populateServiceIsolationRule(serviceIpRange, false);
@@ -211,13 +217,13 @@
      * @param isBidirectional true to enable bidirectional connection between two services
      * @param install true to install or false to remove
      */
-    public void populateServiceDependencyRules(CordService tService, CordService pService,
+    public void populateServiceDependencyRules(VtnService tService, VtnService pService,
                                                boolean isBidirectional, boolean install) {
         checkNotNull(tService);
         checkNotNull(pService);
 
-        Ip4Prefix srcRange = tService.serviceIpRange().getIp4Prefix();
-        Ip4Prefix dstRange = pService.serviceIpRange().getIp4Prefix();
+        Ip4Prefix srcRange = tService.subnet().getIp4Prefix();
+        Ip4Prefix dstRange = pService.subnet().getIp4Prefix();
         Ip4Address serviceIp = pService.serviceIp().getIp4Address();
 
         Map<DeviceId, GroupId> outGroups = Maps.newHashMap();
@@ -227,7 +233,7 @@
             GroupId groupId = createServiceGroup(deviceId, pService);
             outGroups.put(deviceId, groupId);
 
-            Set<PortNumber> tServiceVms = tService.hosts().keySet()
+            Set<PortNumber> tServiceVms = getInstances(tService.id())
                     .stream()
                     .filter(host -> host.location().deviceId().equals(deviceId))
                     .map(host -> host.location().port())
@@ -248,7 +254,7 @@
      *
      * @param service cord service
      */
-    public void updateProviderServiceGroup(CordService service) {
+    public void updateProviderServiceGroup(VtnService service) {
         checkNotNull(service);
 
         GroupKey groupKey = getGroupKey(service.id());
@@ -262,7 +268,7 @@
 
             List<GroupBucket> oldBuckets = group.buckets().buckets();
             List<GroupBucket> newBuckets = getServiceGroupBuckets(
-                    deviceId, service.segmentationId(), service.hosts()).buckets();
+                    deviceId, service.vni(), getInstances(service.id())).buckets();
 
             if (oldBuckets.equals(newBuckets)) {
                 continue;
@@ -296,7 +302,7 @@
      * @param host removed vm
      * @param service tenant service
      */
-    public void updateTenantServiceVm(Host host, CordService service) {
+    public void updateTenantServiceVm(Host host, VtnService service) {
         checkNotNull(host);
         checkNotNull(service);
 
@@ -320,7 +326,7 @@
      * @param host host which has management network interface
      * @param mService management network service
      */
-    public void populateManagementNetworkRules(Host host, CordService mService) {
+    public void populateManagementNetworkRules(Host host, VtnService mService) {
         checkNotNull(mService);
 
         DeviceId deviceId = host.location().deviceId();
@@ -372,7 +378,7 @@
         selector = DefaultTrafficSelector.builder()
                 .matchInPort(PortNumber.LOCAL)
                 .matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(mService.serviceIpRange())
+                .matchIPDst(mService.subnet())
                 .build();
 
         treatment = DefaultTrafficTreatment.builder()
@@ -1237,7 +1243,7 @@
      * @param service cord service
      * @return group id, or null if it fails to create
      */
-    private GroupId createServiceGroup(DeviceId deviceId, CordService service) {
+    private GroupId createServiceGroup(DeviceId deviceId, VtnService service) {
         checkNotNull(service);
 
         GroupKey groupKey = getGroupKey(service.id());
@@ -1250,7 +1256,7 @@
         }
 
         GroupBuckets buckets = getServiceGroupBuckets(
-                deviceId, service.segmentationId(), service.hosts());
+                deviceId, service.vni(), getInstances(service.id()));
         GroupDescription groupDescription = new DefaultGroupDescription(
                 deviceId,
                 GroupDescription.Type.SELECT,
@@ -1273,33 +1279,26 @@
      * @return group buckets
      */
     private GroupBuckets getServiceGroupBuckets(DeviceId deviceId, long tunnelId,
-                                                Map<Host, IpAddress> hosts) {
+                                                Set<Host> hosts) {
         List<GroupBucket> buckets = Lists.newArrayList();
 
-        for (Map.Entry<Host, IpAddress> entry : hosts.entrySet()) {
-            Host host = entry.getKey();
-            Ip4Address remoteIp = entry.getValue().getIp4Address();
+        hosts.stream().forEach(host -> {
+            Ip4Address tunnelIp = getTunnelIp(host).getIp4Address();
             DeviceId hostDevice = host.location().deviceId();
 
             TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
                     .builder()
                     .setEthDst(host.mac());
-
             if (deviceId.equals(hostDevice)) {
                 tBuilder.setOutput(host.location().port());
             } else {
-                ExtensionTreatment tunnelDst = getTunnelDst(deviceId, remoteIp);
-                if (tunnelDst == null) {
-                    continue;
-                }
-
+                ExtensionTreatment tunnelDst = getTunnelDst(deviceId, tunnelIp);
                 tBuilder.extension(tunnelDst, deviceId)
                         .setTunnelId(tunnelId)
                         .setOutput(getTunnelPort(hostDevice));
             }
-
             buckets.add(DefaultGroupBucket.createSelectGroupBucket(tBuilder.build()));
-        }
+        });
 
         return new GroupBuckets(buckets);
     }
@@ -1311,7 +1310,7 @@
      * @param deviceId device id
      * @return group id
      */
-    private GroupId getGroupId(CordServiceId serviceId, DeviceId deviceId) {
+    private GroupId getGroupId(VtnServiceId serviceId, DeviceId deviceId) {
         return new DefaultGroupId(Objects.hash(serviceId, deviceId));
     }
 
@@ -1321,7 +1320,7 @@
      * @param serviceId service id
      * @return group key
      */
-    private GroupKey getGroupKey(CordServiceId serviceId) {
+    private GroupKey getGroupKey(VtnServiceId serviceId) {
         return new DefaultGroupKey(serviceId.id().getBytes());
     }
 
@@ -1370,5 +1369,19 @@
         return config.cordVtnNodes().stream()
                 .map(CordVtnNode::intBrId).collect(Collectors.toSet());
     }
+
+    /**
+     * Returns instances with a given network service.
+     *
+     * @param serviceId service id
+     * @return set of hosts
+     */
+    private Set<Host> getInstances(VtnServiceId serviceId) {
+        return StreamSupport.stream(hostService.getHosts().spliterator(), false)
+                .filter(host -> Objects.equals(
+                        serviceId.id(),
+                        host.annotations().value(SERVICE_ID)))
+                .collect(Collectors.toSet());
+    }
 }
 
diff --git a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
index c4b7c52..f7ddf96 100644
--- a/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
+++ b/apps/cordvtn/src/main/java/org/onosproject/cordvtn/rest/ServiceDependencyWebResource.java
@@ -16,8 +16,8 @@
 package org.onosproject.cordvtn.rest;
 
 import org.onosproject.cordvtn.api.CordVtnService;
-import org.onosproject.cordvtn.api.CordServiceId;
 import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.xosclient.api.VtnServiceId;
 
 import javax.ws.rs.DELETE;
 import javax.ws.rs.POST;
@@ -48,8 +48,8 @@
     @Produces(MediaType.APPLICATION_JSON)
     public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId,
                                             @PathParam("providerServiceId") String pServiceId) {
-        service.createServiceDependency(CordServiceId.of(tServiceId),
-                                        CordServiceId.of(pServiceId),
+        service.createServiceDependency(VtnServiceId.of(tServiceId),
+                                        VtnServiceId.of(pServiceId),
                                         false);
         return Response.status(Response.Status.OK).build();
     }
@@ -68,8 +68,8 @@
     public Response createServiceDependency(@PathParam("tenantServiceId") String tServiceId,
                                             @PathParam("providerServiceId") String pServiceId,
                                             @PathParam("direction") String direction) {
-        service.createServiceDependency(CordServiceId.of(tServiceId),
-                                        CordServiceId.of(pServiceId),
+        service.createServiceDependency(VtnServiceId.of(tServiceId),
+                                        VtnServiceId.of(pServiceId),
                                         direction.equals(BIDIRECTION));
         return Response.status(Response.Status.OK).build();
     }
@@ -85,7 +85,7 @@
     @Path("{tenantServiceId}/{providerServiceId}")
     public Response removeServiceDependency(@PathParam("tenantServiceId") String tServiceId,
                                             @PathParam("providerServiceId") String pServiceId) {
-        service.removeServiceDependency(CordServiceId.of(tServiceId), CordServiceId.of(pServiceId));
+        service.removeServiceDependency(VtnServiceId.of(tServiceId), VtnServiceId.of(pServiceId));
         return Response.noContent().build();
     }
 }
diff --git a/apps/xosclient/BUCK b/apps/xosclient/BUCK
index ec03b7b..406b0a0 100644
--- a/apps/xosclient/BUCK
+++ b/apps/xosclient/BUCK
@@ -1,6 +1,9 @@
 COMPILE_DEPS = [
     '//lib:CORE_DEPS',
     '//lib:javax.ws.rs-api',
+    '//lib:openstack4j-core',
+    '//lib:openstack4j-http-connector',
+    '//lib:openstack4j-httpclient',
 ]
 
 osgi_jar_with_tests (
diff --git a/apps/xosclient/pom.xml b/apps/xosclient/pom.xml
index f57decc..cb3a987 100644
--- a/apps/xosclient/pom.xml
+++ b/apps/xosclient/pom.xml
@@ -49,6 +49,45 @@
             <artifactId>onlab-misc</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.pacesys</groupId>
+            <artifactId>openstack4j-core</artifactId>
+            <version>2.11</version>
+        </dependency>
+        <dependency>
+            <groupId>org.pacesys.openstack4j.connectors</groupId>
+            <artifactId>openstack4j-http-connector</artifactId>
+            <version>2.11</version>
+        </dependency>
+        <dependency>
+            <groupId>org.pacesys.openstack4j.connectors</groupId>
+            <artifactId>openstack4j-httpclient</artifactId>
+            <version>2.11</version>
+        </dependency>
     </dependencies>
 
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            !org.apache.http.*,
+                            !com.fasterxml.jackson.dataformat.*,
+                            !javax.annotation,*
+                        </Import-Package>
+                        <Embed-Dependency>
+                            openstack4j-core,
+                            openstack4j-http-connector,
+                            openstack4j-httpclient
+                        </Embed-Dependency>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
 </project>
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/OpenStackAccess.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/OpenStackAccess.java
new file mode 100644
index 0000000..259ba55
--- /dev/null
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/OpenStackAccess.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2016-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.xosclient.api;
+
+import com.google.common.base.MoreObjects;
+
+import java.util.Objects;
+
+/**
+ * Object holding OpenStack API access information.
+ */
+// TODO remove this when XOS provides this information
+public class OpenStackAccess {
+
+    private final String endpoint;
+    private final String tenant;
+    private final String user;
+    private final String password;
+
+    /**
+     * Default constructor.
+     *
+     * @param endpoint Keystone endpoint
+     * @param tenant tenant name
+     * @param user user name
+     * @param password password
+     */
+    public OpenStackAccess(String endpoint, String tenant, String user, String password) {
+        this.endpoint = endpoint;
+        this.tenant = tenant;
+        this.user = user;
+        this.password = password;
+    }
+
+    /**
+     * Returns OpenStack API endpoint.
+     *
+     * @return endpoint
+     */
+    public String endpoint() {
+        return this.endpoint;
+    }
+
+    /**
+     * Returns OpenStack tenant name.
+     *
+     * @return tenant name
+     */
+    public String tenant() {
+        return this.tenant;
+    }
+
+    /**
+     * Returns OpenStack user.
+     *
+     * @return user name
+     */
+    public String user() {
+        return this.user;
+    }
+
+    /**
+     * Returns OpenStack password for the user.
+     *
+     * @return password
+     */
+    public String password() {
+        return this.password;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(endpoint, tenant, user, password);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if ((obj instanceof OpenStackAccess)) {
+            OpenStackAccess that = (OpenStackAccess) obj;
+            if (Objects.equals(endpoint, that.endpoint) &&
+                    Objects.equals(tenant, that.tenant) &&
+                    Objects.equals(user, that.user) &&
+                    Objects.equals(password, that.password)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("endpoint", endpoint)
+                .add("tenant", tenant)
+                .add("user", user)
+                .add("password", password)
+                .toString();
+    }
+}
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortApi.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortApi.java
index 593f32e..e4e56d3 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortApi.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortApi.java
@@ -44,4 +44,22 @@
      * @return vtn port; null if it fails to get port information
      */
     VtnPort vtnPort(VtnPortId portId);
+
+    /**
+     * Returns port information from OpenStack with port id.
+     *
+     * @param portId port id
+     * @return vtn port; null if it fails to get port information
+     */
+    // TODO remove this when XOS provides port information
+    VtnPort vtnPort(VtnPortId portId, OpenStackAccess osAccess);
+
+    /**
+     * Returns port information from OpenStack with port name.
+     *
+     * @param portName port name
+     * @return vtn port; null if it fails to get port information
+     */
+    // TODO remove this when XOS provides port information
+    VtnPort vtnPort(String portName, OpenStackAccess osAccess);
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceApi.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceApi.java
index 7ef3de0..11687f7 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceApi.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceApi.java
@@ -52,4 +52,14 @@
      * @return set of service ids
      */
     Set<VtnServiceId> providerServices(VtnServiceId tServiceId);
+
+    /**
+     * Returns VTN service from OpenStack.
+     *
+     * @param serviceId service id
+     * @param osAccess openstack access
+     * @return vtn service
+     */
+    // TODO remove this when XOS provides service information
+    VtnService service(VtnServiceId serviceId, OpenStackAccess osAccess);
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java
index 672c81f..baff814 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java
@@ -15,18 +15,33 @@
  */
 package org.onosproject.xosclient.impl;
 
+import com.google.common.collect.Maps;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.xosclient.api.OpenStackAccess;
 import org.onosproject.xosclient.api.VtnPort;
 import org.onosproject.xosclient.api.VtnPortApi;
 import org.onosproject.xosclient.api.VtnPortId;
 import org.onosproject.xosclient.api.VtnServiceId;
 import org.onosproject.xosclient.api.XosAccess;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.model.network.IP;
+import org.openstack4j.model.network.Port;
+import org.openstack4j.openstack.OSFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import java.util.Map;
 import java.util.Set;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 /**
  * Provides CORD VTN port APIs.
  */
-public class DefaultVtnPortApi extends XosApi implements VtnPortApi {
+public final class DefaultVtnPortApi extends XosApi implements VtnPortApi {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
 
     /**
      * Default constructor.
@@ -55,4 +70,72 @@
         // TODO implement this when XOS provides this information
         return null;
     }
+
+    @Override
+    // TODO remove this when XOS provides this information
+    public VtnPort vtnPort(String portName, OpenStackAccess osAccess) {
+        checkNotNull(osAccess);
+
+        OSClient osClient = getOpenStackClient(osAccess);
+        Port osPort = osClient.networking().port().list()
+                .stream()
+                .filter(p -> p.getId().contains(portName.substring(3)))
+                .findFirst().orElse(null);
+        if (osPort == null) {
+            log.warn("Failed to get OpenStack port for {}", portName);
+            return null;
+        }
+        return getVtnPort(osPort);
+    }
+
+    @Override
+    // TODO remove this when XOS provides this information
+    public VtnPort vtnPort(VtnPortId portId, OpenStackAccess osAccess) {
+        checkNotNull(osAccess);
+
+        OSClient osClient = getOpenStackClient(osAccess);
+        Port osPort = osClient.networking().port().get(portId.id());
+        if (osPort == null) {
+            log.warn("Failed to get OpenStack port {}", portId);
+            return null;
+        }
+        return getVtnPort(osPort);
+    }
+
+    // TODO remove this when XOS provides this information
+    private VtnPort getVtnPort(Port osPort) {
+        checkNotNull(osPort);
+
+        // assumes all vtn port has single IP address
+        IP ipAddr = osPort.getFixedIps().stream().findFirst().orElse(null);
+        if (ipAddr == null) {
+            log.warn("Failed to get IP address for {}", osPort);
+            return null;
+        }
+
+        Map<IpAddress, MacAddress> addressPairs = Maps.newHashMap();
+        osPort.getAllowedAddressPairs().stream().forEach(
+                pair -> addressPairs.put(IpAddress.valueOf(pair.getIpAddress()),
+                                         MacAddress.valueOf(pair.getMacAddress())));
+
+        return new VtnPort(VtnPortId.of(osPort.getId()),
+                           osPort.getName(),
+                           VtnServiceId.of(osPort.getNetworkId()),
+                           MacAddress.valueOf(osPort.getMacAddress()),
+                           IpAddress.valueOf(ipAddr.getIpAddress()),
+                           addressPairs);
+    }
+
+    // TODO remove this when XOS provides this information
+    private OSClient getOpenStackClient(OpenStackAccess osAccess) {
+        checkNotNull(osAccess);
+
+        // creating a client every time must be inefficient, but this method
+        // will be removed once XOS provides equivalent APIs
+        return OSFactory.builder()
+                .endpoint(osAccess.endpoint())
+                .credentials(osAccess.user(), osAccess.password())
+                .tenantName(osAccess.tenant())
+                .authenticate();
+    }
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnServiceApi.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnServiceApi.java
index 94d8bbc..b83333c 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnServiceApi.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnServiceApi.java
@@ -17,12 +17,22 @@
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.Strings;
 import com.google.common.collect.Sets;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onosproject.xosclient.api.OpenStackAccess;
+import org.onosproject.xosclient.api.VtnService.NetworkType;
+import org.onosproject.xosclient.api.VtnService.ServiceType;
 import org.onosproject.xosclient.api.VtnServiceApi;
 import org.onosproject.xosclient.api.XosAccess;
 import org.onosproject.xosclient.api.VtnService;
 import org.onosproject.xosclient.api.VtnServiceId;
 
+import org.openstack4j.api.OSClient;
+import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.Subnet;
+import org.openstack4j.openstack.OSFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -30,6 +40,9 @@
 import java.util.Set;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+import static org.onosproject.xosclient.api.VtnService.NetworkType.*;
+import static org.onosproject.xosclient.api.VtnService.ServiceType.*;
 
 /**
  * Provides CORD VTN service and service dependency APIs.
@@ -113,4 +126,76 @@
         }
         return tServices;
     }
+
+    @Override
+    // TODO remove this when XOS provides this information
+    public VtnService service(VtnServiceId serviceId, OpenStackAccess osAccess) {
+        checkNotNull(osAccess);
+
+        OSClient osClient = getOpenStackClient(osAccess);
+        Network osNet = osClient.networking().network().get(serviceId.id());
+        if (osNet == null) {
+            log.warn("Failed to get OpenStack network {}", serviceId);
+            return null;
+        }
+
+        // assumes all cord service networks has single subnet
+        Subnet osSubnet = osNet.getNeutronSubnets().stream()
+                .findFirst().orElse(null);
+        if (osSubnet == null) {
+            log.warn("Failed to get OpenStack subnet of network {}", serviceId);
+            return null;
+        }
+
+        return new VtnService(serviceId,
+                              osNet.getName(),
+                              serviceType(osNet.getName()),
+                              networkType(osNet.getName()),
+                              Long.parseLong(osNet.getProviderSegID()),
+                              IpPrefix.valueOf(osSubnet.getCidr()),
+                              IpAddress.valueOf(osSubnet.getGateway()),
+                              providerServices(serviceId),
+                              tenantServices(serviceId));
+    }
+
+    // TODO remove this when XOS provides this information
+    private OSClient getOpenStackClient(OpenStackAccess osAccess) {
+        checkNotNull(osAccess);
+
+        // creating a client every time must be inefficient, but this method
+        // will be removed once XOS provides equivalent APIs
+        return OSFactory.builder()
+                .endpoint(osAccess.endpoint())
+                .credentials(osAccess.user(), osAccess.password())
+                .tenantName(osAccess.tenant())
+                .authenticate();
+    }
+
+    // TODO remove this when XOS provides this information
+    private NetworkType networkType(String netName) {
+        checkArgument(!Strings.isNullOrEmpty(netName));
+
+        String name = netName.toUpperCase();
+        if (name.contains(PUBLIC.toString())) {
+            return PUBLIC;
+        } else if (name.contains(MANAGEMENT.toString())) {
+            return MANAGEMENT;
+        } else {
+            return PRIVATE;
+        }
+    }
+
+    // TODO remove this when XOS provides this information
+    private ServiceType serviceType(String netName) {
+        checkArgument(!Strings.isNullOrEmpty(netName));
+
+        String name = netName.toUpperCase();
+        if (name.contains(VSG.toString())) {
+            return VSG;
+        } else if (name.contains(OLT_AGENT.toString())) {
+            return OLT_AGENT;
+        } else {
+            return DUMMY;
+        }
+    }
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/XosApi.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/XosApi.java
index 85f312d..4a9ec09 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/XosApi.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/XosApi.java
@@ -81,13 +81,15 @@
     public String restGet(String path) {
         WebTarget wt = client.target(access.endpoint() + baseUrl).path(path);
         Invocation.Builder builder = wt.request(JSON_UTF_8.toString());
-
-        Response response = builder.get();
-        if (response.getStatus() != HTTP_OK) {
-            log.warn("Failed to get resource {}", access.endpoint() + baseUrl + path);
+        try {
+            Response response = builder.get();
+            if (response.getStatus() != HTTP_OK) {
+                log.warn("Failed to get resource {}", access.endpoint() + baseUrl + path);
+                return EMPTY_JSON_STRING;
+            }
+        } catch (javax.ws.rs.ProcessingException e) {
             return EMPTY_JSON_STRING;
         }
-
         return builder.get(String.class);
     }
 }