CORD-131 Added XOS vtn service and port APIs

Change-Id: Ide34212eeb593af5af8db218c6dd2af7d5ab4eaa
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPort.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPort.java
new file mode 100644
index 0000000..9a22552
--- /dev/null
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPort.java
@@ -0,0 +1,146 @@
+/*
+ * 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 org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Representation of port in a CORD VTN controlled network, it can be for VM
+ * or container.
+ */
+public final class VtnPort {
+
+    private final VtnPortId id;
+    private final String name;
+    private final VtnServiceId serviceId;
+    private final MacAddress mac;
+    private final IpAddress ip;
+    // TODO remove this when XOS provides vSG information
+    private final Map<IpAddress, MacAddress> addressPairs;
+
+
+    /**
+     * Creates a new vtn port with the specified entities.
+     *
+     * @param id vtn port id
+     * @param name vtn port name
+     * @param serviceId id of the service this port is in
+     * @param mac mac address
+     * @param ip ip address
+     * @param addressPairs ip and mac pairs of nested container
+     */
+    public VtnPort(VtnPortId id,
+                        String name,
+                        VtnServiceId serviceId,
+                        MacAddress mac,
+                        IpAddress ip,
+                        Map<IpAddress, MacAddress> addressPairs) {
+        this.id = id;
+        this.name = name;
+        this.serviceId = serviceId;
+        this.mac = mac;
+        this.ip = ip;
+        this.addressPairs = addressPairs;
+    }
+
+    /**
+     * Returns vtn port ID.
+     *
+     * @return vtn port id
+     */
+    public VtnPortId id() {
+        return id;
+    }
+
+    /**
+     * Returns vtn port name.
+     *
+     * @return vtn port name
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Returns the ID of the service this port is in.
+     *
+     * @return vtn service id
+     */
+    public VtnServiceId serviceId() {
+        return serviceId;
+    }
+
+    /**
+     * Returns MAC address of this port.
+     *
+     * @return mac address
+     */
+    public MacAddress mac() {
+        return mac;
+    }
+
+    /**
+     * Returns IP address of this port.
+     *
+     * @return ip address
+     */
+    public IpAddress ip() {
+        return ip;
+    }
+
+    /**
+     * Returns address pairs of the nested containers inside.
+     *
+     * @return map of ip and address
+     */
+    public Map<IpAddress, MacAddress> addressPairs() {
+        return addressPairs;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof VtnPort)) {
+            return false;
+        }
+        final VtnPort other = (VtnPort) obj;
+        return Objects.equals(this.id, other.id);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("id", id)
+                .add("name", name)
+                .add("serviceId", serviceId)
+                .add("mac", mac)
+                .add("ip", ip)
+                .add("addressPairs", addressPairs)
+                .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
new file mode 100644
index 0000000..593f32e
--- /dev/null
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortApi.java
@@ -0,0 +1,47 @@
+/*
+ * 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 java.util.Set;
+
+/**
+ * Service for interacting with XOS VTN ports.
+ */
+public interface VtnPortApi {
+
+    /**
+     * Returns all ports.
+     *
+     * @return set of ports
+     */
+    Set<VtnPort> vtnPorts();
+
+    /**
+     * Returns all ports with a given service.
+     *
+     * @param serviceId service id
+     * @return set of ports
+     */
+    Set<VtnPort> vtnPorts(VtnServiceId serviceId);
+
+    /**
+     * Returns port information with port id.
+     *
+     * @param portId port id
+     * @return vtn port; null if it fails to get port information
+     */
+    VtnPort vtnPort(VtnPortId portId);
+}
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortId.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortId.java
new file mode 100644
index 0000000..ef2416b
--- /dev/null
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnPortId.java
@@ -0,0 +1,42 @@
+/*
+ * 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.Strings;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Representation of VTN port ID.
+ */
+public final class VtnPortId extends Identifier<String> {
+
+    private VtnPortId(String id) {
+        super(id);
+    }
+
+    /**
+     * Returns vtn port identifier with value.
+     *
+     * @param id id
+     * @return instance port id
+     */
+    public static VtnPortId of(String id) {
+        checkArgument(!Strings.isNullOrEmpty(id));
+        return new VtnPortId(id);
+    }
+}
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnService.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnService.java
new file mode 100644
index 0000000..b7d1c9c
--- /dev/null
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnService.java
@@ -0,0 +1,200 @@
+/*
+ * 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 com.google.common.collect.Sets;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+import java.util.Objects;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Representation of CORD VTN controlled network service.
+ */
+public final class VtnService {
+
+    public enum NetworkType {
+        PRIVATE,
+        PUBLIC,
+        MANAGEMENT
+    }
+
+    public enum ServiceType {
+        VSG,
+        OLT_AGENT,
+        DUMMY
+    }
+
+    private final VtnServiceId id;
+    private final String name;
+    private final ServiceType serviceType;
+    private final NetworkType networkType;
+    private final long vni;
+    private final IpPrefix subnet;
+    private final IpAddress serviceIp;
+    private final Set<VtnServiceId> providerServices;
+    private final Set<VtnServiceId> tenantServices;
+
+    /**
+     * Creates a new VTN service with the specified entities.
+     *
+     * @param id service id
+     * @param name user friendly name
+     * @param serviceType service type
+     * @param networkType network type
+     * @param vni vni of this service network
+     * @param subnet service network subnet range
+     * @param serviceIp service ip for indirect service access
+     * @param providerServices provider services
+     * @param tenantServices tenant services
+     */
+    public VtnService(VtnServiceId id,
+                      String name,
+                      ServiceType serviceType,
+                      NetworkType networkType,
+                      long vni,
+                      IpPrefix subnet,
+                      IpAddress serviceIp,
+                      Set<VtnServiceId> providerServices,
+                      Set<VtnServiceId> tenantServices) {
+        this.id = checkNotNull(id);
+        this.name = name;
+        this.serviceType = serviceType;
+        this.networkType = networkType;
+        this.vni = vni;
+        this.subnet = checkNotNull(subnet);
+        this.serviceIp = checkNotNull(serviceIp);
+        this.providerServices = providerServices == null ? Sets.newHashSet() : providerServices;
+        this.tenantServices = tenantServices == null ? Sets.newHashSet() : tenantServices;
+    }
+
+    /**
+     * Returns service ID.
+     *
+     * @return service id
+     */
+    public VtnServiceId id() {
+        return id;
+    }
+
+    /**
+     * Returns service name.
+     *
+     * @return name
+     */
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Returns service type.
+     *
+     * @return service type
+     */
+    public ServiceType serviceType() {
+        return serviceType;
+    }
+
+    /**
+     * Returns segmentation ID of this service.
+     *
+     * @return segmentation id
+     */
+    public long vni() {
+        return vni;
+    }
+
+    /**
+     * Returns network type.
+     *
+     * @return network type
+     */
+    public NetworkType networkType() {
+        return networkType;
+    }
+
+    /**
+     * Returns service IP range.
+     *
+     * @return subnet cidr
+     */
+    public IpPrefix subnet() {
+        return subnet;
+    }
+
+    /**
+     * Returns service IP address.
+     *
+     * @return ip address
+     */
+    public IpAddress serviceIp() {
+        return serviceIp;
+    }
+
+    /**
+     * Returns provider service IDs.
+     *
+     * @return list of provider service id
+     */
+    public Set<VtnServiceId> providerServices() {
+        return providerServices;
+    }
+
+    /**
+     * Returns tenant service IDs.
+     *
+     * @return list of tenant service id
+     */
+    public Set<VtnServiceId> tenantServices() {
+        return tenantServices;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof VtnService)) {
+            return false;
+        }
+        final VtnService other = (VtnService) obj;
+        return Objects.equals(this.id, other.id);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("id", id)
+                .add("name", name)
+                .add("serviceType", serviceType)
+                .add("networkType", networkType)
+                .add("vni", vni)
+                .add("subnet", subnet)
+                .add("serviceIp", serviceIp)
+                .add("providerServices", providerServices)
+                .add("tenantServices", tenantServices)
+                .toString();
+    }
+}
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 86e94da..7ef3de0 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
@@ -27,21 +27,29 @@
      *
      * @return service list
      */
-    Set<String> services();
+    Set<VtnServiceId> services();
+
+    /**
+     * Returns VTN service.
+     *
+     * @param serviceId service id
+     * @return vtn service
+     */
+    VtnService service(VtnServiceId serviceId);
 
     /**
      * Returns dependent tenant services of a given provider service.
      *
-     * @param pServiceId service id
-     * @return service list
+     * @param pServiceId vtn service id
+     * @return set of service ids
      */
-    Set<String> getTenantServices(String pServiceId);
+    Set<VtnServiceId> tenantServices(VtnServiceId pServiceId);
 
     /**
      * Returns dependent provider services of a given tenant service.
      *
-     * @param tServiceId service id
-     * @return set of services
+     * @param tServiceId vtn service id
+     * @return set of service ids
      */
-    Set<String> getProviderServices(String tServiceId);
+    Set<VtnServiceId> providerServices(VtnServiceId tServiceId);
 }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceId.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceId.java
new file mode 100644
index 0000000..5850696
--- /dev/null
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/VtnServiceId.java
@@ -0,0 +1,45 @@
+/*
+ * 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 org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Representation of VTN service identifier.
+ */
+public final class VtnServiceId extends Identifier<String> {
+    /**
+     * Default constructor.
+     *
+     * @param id service identifier
+     */
+    private VtnServiceId(String id) {
+        super(id);
+    }
+
+    /**
+     * Returns the VtnServiceId with value.
+     *
+     * @param id service id
+     * @return CordServiceId
+     */
+    public static VtnServiceId of(String id) {
+        checkNotNull(id);
+        return new VtnServiceId(id);
+    }
+}
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/XosClientService.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/XosClientService.java
index d7c9e83..c198a94 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/api/XosClientService.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/api/XosClientService.java
@@ -28,19 +28,26 @@
     XosAccess access();
 
     /**
-     * Sets the XOS API access information to the client service.
+     * Returns XOS client with access.
      *
      * @param xosAccess xos access information
-     * @return true if it is set and authenticated, otherwise false
+     * @return xos client; null if access fails authentication
      */
-    boolean setAccess(XosAccess xosAccess);
+    XosClientService getClient(XosAccess xosAccess);
 
     /**
-     * Returns CORD VTN service API.
+     * Returns CORD VTN service and service dependency API.
      *
      * @return cord vtn service api
      */
-    VtnServiceApi vtnServiceApi();
+    VtnServiceApi vtnService();
+
+    /**
+     * Returns CORD VTN port API.
+     *
+     * @return cord vtn port api
+     */
+    VtnPortApi vtnPort();
 
     /*
      * adds more XOS service APIs below.
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
new file mode 100644
index 0000000..672c81f
--- /dev/null
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/DefaultVtnPortApi.java
@@ -0,0 +1,58 @@
+/*
+ * 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.impl;
+
+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 java.util.Set;
+
+/**
+ * Provides CORD VTN port APIs.
+ */
+public class DefaultVtnPortApi extends XosApi implements VtnPortApi {
+
+    /**
+     * Default constructor.
+     *
+     * @param baseUrl base url
+     * @param access xos access
+     */
+    public DefaultVtnPortApi(String baseUrl, XosAccess access) {
+        super(baseUrl, access);
+    }
+
+    @Override
+    public Set<VtnPort> vtnPorts() {
+        // TODO implement this when XOS provides this information
+        return null;
+    }
+
+    @Override
+    public Set<VtnPort> vtnPorts(VtnServiceId serviceId) {
+        // TODO implement this when XOS provides this information
+        return null;
+    }
+
+    @Override
+    public VtnPort vtnPort(VtnPortId portId) {
+        // TODO implement this when XOS provides this information
+        return null;
+    }
+}
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 d327dae..94d8bbc 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,19 +17,18 @@
 
 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.onosproject.xosclient.api.VtnServiceApi;
 import org.onosproject.xosclient.api.XosAccess;
+import org.onosproject.xosclient.api.VtnService;
+import org.onosproject.xosclient.api.VtnServiceId;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.IOException;
-import java.util.Iterator;
-import java.util.Map;
 import java.util.Set;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -39,63 +38,52 @@
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
-    private static DefaultVtnServiceApi instance = null;
-
     /**
      * Default constructor.
+     *
+     * @param baseUrl base url
+     * @param access xos access
      */
-    private DefaultVtnServiceApi(String baseUrl, XosAccess access) {
+    public DefaultVtnServiceApi(String baseUrl, XosAccess access) {
         super(baseUrl, access);
     }
 
-    /**
-     * Returns VTN service API instance. Creates a new instance only if base url or
-     * access has been changed.
-     *
-     * @param baseUrl base url
-     * @param access access
-     * @return vtn service api
-     */
-    public static synchronized DefaultVtnServiceApi getInstance(String baseUrl, XosAccess access) {
-        checkNotNull(access, "XOS access information is null");
-        checkArgument(!Strings.isNullOrEmpty(baseUrl), "VTN service API base url is null or empty");
-
-        if (instance == null ||
-                !instance.baseUrl.equals(baseUrl) ||
-                !instance.access.equals(access)) {
-            instance = new DefaultVtnServiceApi(baseUrl, access);
-        }
-        return instance;
-    }
-
     @Override
-    public Set<String> services() {
+    public Set<VtnServiceId> services() {
         String response = restGet(EMPTY_STRING);
         log.trace("Get services {}", response);
 
         ObjectMapper mapper = new ObjectMapper();
+        Set<VtnServiceId> services = Sets.newHashSet();
+
         try {
             JsonNode nodes = mapper.readTree(response);
-            return Sets.newHashSet(nodes.fieldNames());
+            nodes.fieldNames().forEachRemaining(id -> services.add(VtnServiceId.of(id)));
         } catch (IOException e) {
             log.warn("Failed to get service list");
-            return Sets.newHashSet();
         }
+        return services;
     }
 
     @Override
-    public Set<String> getProviderServices(String tServiceId) {
+    public VtnService service(VtnServiceId serviceId) {
+        // TODO implement this when XOS provides this API
+        return null;
+    }
+
+    @Override
+    public Set<VtnServiceId> providerServices(VtnServiceId tServiceId) {
         checkNotNull(tServiceId);
 
-        String response = restGet(tServiceId);
+        String response = restGet(tServiceId.id());
         log.trace("Get provider services {}", response);
 
         ObjectMapper mapper = new ObjectMapper();
-        Set<String> pServices = Sets.newHashSet();
+        Set<VtnServiceId> pServices = Sets.newHashSet();
 
         try {
             JsonNode nodes = mapper.readTree(response);
-            nodes.forEach(node -> pServices.add(node.asText()));
+            nodes.forEach(node -> pServices.add(VtnServiceId.of(node.asText())));
         } catch (IOException e) {
             log.warn("Failed to get service dependency");
         }
@@ -103,26 +91,23 @@
     }
 
     @Override
-    public Set<String> getTenantServices(String tServiceId) {
+    public Set<VtnServiceId> tenantServices(VtnServiceId tServiceId) {
         checkNotNull(tServiceId);
 
         String response = restGet(EMPTY_STRING);
         log.trace("Get tenant services {}", response);
 
         ObjectMapper mapper = new ObjectMapper();
-        Set<String> tServices = Sets.newHashSet();
+        Set<VtnServiceId> tServices = Sets.newHashSet();
+
         try {
             JsonNode nodes = mapper.readTree(response);
-            Iterator<Map.Entry<String, JsonNode>> iterator = nodes.fields();
-
-            while (iterator.hasNext()) {
-                Map.Entry<String, JsonNode> entry = iterator.next();
-                entry.getValue().forEach(pService -> {
-                    if (pService.asText().equals(tServiceId)) {
-                        tServices.add(entry.getKey());
-                    }
-                });
-            }
+            nodes.fields().forEachRemaining(entry -> entry.getValue().forEach(
+                    pService -> {
+                        if (pService.asText().equals(tServiceId.id())) {
+                            tServices.add(VtnServiceId.of(entry.getKey()));
+                        }
+                    }));
         } catch (IOException e) {
             log.warn("Failed to get service list");
         }
diff --git a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/XosClient.java b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/XosClient.java
index dfa7610..61643af 100644
--- a/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/XosClient.java
+++ b/apps/xosclient/src/main/java/org/onosproject/xosclient/impl/XosClient.java
@@ -33,6 +33,7 @@
 import org.onosproject.net.config.NetworkConfigListener;
 import org.onosproject.net.config.NetworkConfigRegistry;
 import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.xosclient.api.VtnPortApi;
 import org.onosproject.xosclient.api.VtnServiceApi;
 import org.onosproject.xosclient.api.XosAccess;
 import org.onosproject.xosclient.api.XosAccessConfig;
@@ -41,6 +42,7 @@
 import org.slf4j.Logger;
 
 import java.util.Dictionary;
+import java.util.Objects;
 
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -55,8 +57,11 @@
 
     protected final Logger log = getLogger(getClass());
 
-    private static final String VTN_BASE_URL = "vtnBaseUrl";
-    private static final String DEFAULT_VTN_BASE_URL = "/api/service/vtn/services/";
+    private static final String VTN_SERVICE_URL = "vtnServiceBaseUrl";
+    private static final String DEFAULT_VTN_SERVICE_URL = "/api/service/vtn/services/";
+
+    private static final String VTN_PORT_URL = "vtnPortBaseUrl";
+    private static final String DEFAULT_VTN_PORT_URL = "/api/service/vtn/ports/";
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
@@ -67,9 +72,13 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected NetworkConfigRegistry configRegistry;
 
-    @Property(name = VTN_BASE_URL, value = DEFAULT_VTN_BASE_URL,
+    @Property(name = VTN_SERVICE_URL, value = DEFAULT_VTN_SERVICE_URL,
             label = "XOS VTN service API base url")
-    private String vtnBaseUrl = DEFAULT_VTN_BASE_URL;
+    private String vtnServiceUrl = DEFAULT_VTN_SERVICE_URL;
+
+    @Property(name = VTN_PORT_URL, value = DEFAULT_VTN_PORT_URL,
+            label = "XOS VTN port API base url")
+    private String vtnPortUrl = DEFAULT_VTN_PORT_URL;
 
     private final ConfigFactory configFactory =
             new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, XosAccessConfig.class, "xosclient") {
@@ -84,6 +93,13 @@
     private ApplicationId appId;
     private XosAccess access = null;
 
+    private VtnServiceApi vtnServiceApi = null;
+    private VtnPortApi vtnPortApi = null;
+
+    /*
+     * adds more XOS service APIs below.
+     */
+
     @Activate
     protected void activate(ComponentContext context) {
         appId = coreService.registerApplication("org.onosproject.xosclient");
@@ -99,16 +115,27 @@
 
     @Deactivate
     protected void deactivate() {
+        configRegistry.unregisterConfigFactory(configFactory);
+        configRegistry.removeListener(configListener);
+
         log.info("Stopped");
     }
 
     @Modified
     protected void modified(ComponentContext context) {
         Dictionary<?, ?> properties = context.getProperties();
+        String updatedUrl;
 
-        String updatedUrl = Tools.get(properties, VTN_BASE_URL);
-        if (!Strings.isNullOrEmpty(updatedUrl)) {
-            vtnBaseUrl = updatedUrl;
+        updatedUrl = Tools.get(properties, VTN_SERVICE_URL);
+        if (!Strings.isNullOrEmpty(updatedUrl) && !updatedUrl.equals(vtnServiceUrl)) {
+            vtnServiceUrl = updatedUrl;
+            vtnServiceApi = new DefaultVtnServiceApi(vtnServiceUrl, access);
+        }
+
+       updatedUrl = Tools.get(properties, VTN_PORT_URL);
+        if (!Strings.isNullOrEmpty(updatedUrl) && !updatedUrl.equals(vtnPortUrl)) {
+            vtnPortUrl = updatedUrl;
+            vtnPortApi = new DefaultVtnPortApi(vtnPortUrl, access);
         }
 
         log.info("Modified");
@@ -120,18 +147,29 @@
     }
 
     @Override
-    public synchronized boolean setAccess(XosAccess xosAccess) {
-        checkNotNull(xosAccess);
+    public synchronized XosClient getClient(XosAccess access) {
+        checkNotNull(access);
 
-        // TODO authentication later before using the access
-        access = xosAccess;
-        return true;
+        if (!Objects.equals(this.access, access)) {
+            // TODO do authentication before return
+            this.access = access;
+
+            vtnServiceApi = new DefaultVtnServiceApi(vtnServiceUrl, access);
+            vtnPortApi = new DefaultVtnPortApi(vtnPortUrl, access);
+        }
+        return this;
     }
 
     @Override
-    public VtnServiceApi vtnServiceApi() {
-        checkNotNull(access, "XOS API access is not set");
-        return DefaultVtnServiceApi.getInstance(vtnBaseUrl, access);
+    public VtnServiceApi vtnService() {
+        checkNotNull(vtnServiceApi, "VtnServiceApi is null");
+        return vtnServiceApi;
+    }
+
+    @Override
+    public VtnPortApi vtnPort() {
+        checkNotNull(vtnPortApi, "VtnPortApi is null");
+        return vtnPortApi;
     }
 
     /*
@@ -144,8 +182,7 @@
             log.debug("No configuration found");
             return;
         }
-
-        setAccess(config.xosAccess());
+        getClient(config.xosAccess());
     }
 
     private class InternalConfigListener implements NetworkConfigListener {