Adding EVPN App code

Change-Id: Id3b2192f56f054cadcd8384092245b8757a781a9
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortEvent.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortEvent.java
new file mode 100755
index 0000000..acb762a
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortEvent.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.evpnopenflow.rsc.baseport;
+
+import org.onosproject.event.AbstractEvent;
+import org.onosproject.evpnopenflow.rsc.BasePort;
+
+/**
+ * Describes base port event.
+ */
+public class BasePortEvent extends AbstractEvent<BasePortEvent.Type,
+        BasePort> {
+    /**
+     * Type of base port events.
+     */
+    public enum Type {
+        /**
+         * Signifies that base port has been created.
+         */
+        BASE_PORT_PUT,
+        /**
+         * Signifies that base port has been deleted.
+         */
+        BASE_PORT_DELETE,
+        /**
+         * Signifies that base port has been updated.
+         */
+        BASE_PORT_UPDATE
+    }
+
+    /**
+     * Creates an event of a given type and for the specified base port.
+     *
+     * @param type     base port event type
+     * @param basePort base port subject
+     */
+    public BasePortEvent(Type type, BasePort basePort) {
+        super(type, basePort);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified base port.
+     *
+     * @param type     base port event type
+     * @param basePort base port subject
+     * @param time     occurrence time
+     */
+    public BasePortEvent(Type type, BasePort basePort, long time) {
+        super(type, basePort, time);
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortListener.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortListener.java
new file mode 100755
index 0000000..2822bb3
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortListener.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.evpnopenflow.rsc.baseport;
+
+import org.onosproject.event.EventListener;
+
+/**
+ * Entity capable of base port related events.
+ */
+public interface BasePortListener extends EventListener<BasePortEvent> {
+
+}
\ No newline at end of file
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortService.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortService.java
new file mode 100755
index 0000000..c3bdb2b
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/BasePortService.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.evpnopenflow.rsc.baseport;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.evpnopenflow.rsc.BasePort;
+import org.onosproject.evpnopenflow.rsc.BasePortId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+
+import java.util.Collection;
+
+
+/**
+ * Service for interacting with the inventory of basePort.
+ */
+public interface BasePortService {
+    /**
+     * Returns if the basePort is existed.
+     *
+     * @param basePortId basePort identifier
+     * @return true or false if one with the given identifier is not existed.
+     */
+    boolean exists(BasePortId basePortId);
+
+    /**
+     * Returns the basePort with the identifier.
+     *
+     * @param basePortId basePort ID
+     * @return BasePort or null if one with the given ID is not know.
+     */
+    BasePort getPort(BasePortId basePortId);
+
+    /**
+     * Returns the basePort associated with the fixedIP.
+     *
+     * @param fixedIP the fixedIP identifier
+     * @return basePort.
+     */
+    BasePort getPort(FixedIp fixedIP);
+
+    /**
+     * Returns the basePort associated with the mac address.
+     *
+     * @param mac the mac address
+     * @return basePort.
+     */
+    BasePort getPort(MacAddress mac);
+
+    /**
+     * Returns the basePort associated with the networkId and ip.
+     *
+     * @param networkId the TenantNetworkId identifier
+     * @param ip        the ip identifier
+     * @return basePort.
+     */
+    BasePort getPort(TenantNetworkId networkId, IpAddress ip);
+
+    /**
+     * Returns the collection of the currently known basePort.
+     *
+     * @return collection of BasePort.
+     */
+    Collection<BasePort> getPorts();
+
+    /**
+     * Returns the collection of the basePorts associated with the networkId.
+     *
+     * @param networkId the network identifer
+     * @return collection of basePort.
+     */
+    Collection<BasePort> getPorts(TenantNetworkId networkId);
+
+    /**
+     * Returns the collection of the basePorts associated with the tenantId.
+     *
+     * @param tenantId the tenant identifier
+     * @return collection of basePorts.
+     */
+    Collection<BasePort> getPorts(TenantId tenantId);
+
+    /**
+     * Returns the collection of the basePorts associated with the deviceId.
+     *
+     * @param deviceId the device identifier
+     * @return collection of basePort.
+     */
+    Collection<BasePort> getPorts(DeviceId deviceId);
+
+    /**
+     * Creates basePorts by basePorts.
+     *
+     * @param basePorts the iterable collection of basePorts
+     * @return true if all given identifiers created successfully.
+     */
+    boolean createPorts(Iterable<BasePort> basePorts);
+
+    /**
+     * Updates basePorts by basePorts.
+     *
+     * @param basePorts the iterable  collection of basePorts
+     * @return true if all given identifiers updated successfully.
+     */
+    boolean updatePorts(Iterable<BasePort> basePorts);
+
+    /**
+     * Deletes basePortIds by basePortIds.
+     *
+     * @param basePortIds the iterable collection of basePort identifiers
+     * @return true or false if one with the given identifier to delete is
+     * successfully.
+     */
+    boolean removePorts(Iterable<BasePortId> basePortIds);
+
+    /**
+     * process gluon config for vpn port information.
+     *
+     * @param action can be either update or delete
+     * @param key    can contain the id and also target information
+     * @param value  content of the vpn port configuration
+     */
+    void processGluonConfig(String action, String key, JsonNode value);
+
+    /**
+     * Adds the specified listener to Vpn Port manager.
+     *
+     * @param listener Vpn Port listener
+     */
+    void addListener(BasePortListener listener);
+
+    /**
+     * Removes the specified listener to Vpn Port manager.
+     *
+     * @param listener Vpn Port listener
+     */
+    void removeListener(BasePortListener listener);
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/BasePortManager.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/BasePortManager.java
new file mode 100755
index 0000000..29c4d66
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/BasePortManager.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.evpnopenflow.rsc.baseport.impl;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.evpnopenflow.rsc.BasePort;
+import org.onosproject.evpnopenflow.rsc.BasePortId;
+import org.onosproject.evpnopenflow.rsc.DefaultBasePort;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortEvent;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortListener;
+import org.onosproject.evpnopenflow.rsc.baseport.BasePortService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.MultiValuedTimestamp;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.DefaultFloatingIp;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.FloatingIp;
+import org.onosproject.vtnrsc.FloatingIpId;
+import org.onosproject.vtnrsc.RouterId;
+import org.onosproject.vtnrsc.SecurityGroup;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.TenantRouter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.APP_ID;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.BASE_PORT_STORE;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.LISTENER_NOT_NULL;
+import static org.onosproject.evpnopenflow.rsc.EvpnConstants.RESPONSE_NOT_NULL;
+
+/**
+ * Provides implementation of the BasePort APIs.
+ */
+@Component(immediate = true)
+@Service
+public class BasePortManager implements BasePortService {
+
+    private final Set<BasePortListener> listeners = Sets
+            .newCopyOnWriteArraySet();
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String BASEPORT_ID_NULL = "BasePort ID cannot be " +
+            "null";
+    private static final String BASEPORT_NOT_NULL = "BasePort  cannot be " +
+            "null";
+    private static final String TENANTID_NOT_NULL = "TenantId  cannot be null";
+    private static final String NETWORKID_NOT_NULL = "NetworkId  cannot be null";
+    private static final String DEVICEID_NOT_NULL = "DeviceId  cannot be null";
+    private static final String FIXEDIP_NOT_NULL = "FixedIp  cannot be null";
+    private static final String MAC_NOT_NULL = "Mac address  cannot be null";
+    private static final String IP_NOT_NULL = "Ip  cannot be null";
+    private static final String EVENT_NOT_NULL = "event cannot be null";
+    private static final String SET = "set";
+    private static final String UPDATE = "update";
+    private static final String DELETE = "delete";
+    private static final String SLASH = "/";
+    private static final String PROTON_BASE_PORT = "Port";
+    private static final String JSON_NOT_NULL = "JsonNode can not be null";
+
+    protected EventuallyConsistentMap<BasePortId, BasePort> vPortStore;
+    protected ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Activate
+    public void activate() {
+
+        appId = coreService.registerApplication(APP_ID);
+
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API)
+                .register(MultiValuedTimestamp.class)
+                .register(TenantNetworkId.class)
+                .register(Host.class)
+                .register(TenantNetwork.class)
+                .register(TenantNetworkId.class)
+                .register(TenantId.class)
+                .register(SubnetId.class)
+                .register(BasePortId.class)
+                .register(BasePort.State.class)
+                .register(AllowedAddressPair.class)
+                .register(FixedIp.class)
+                .register(FloatingIp.class)
+                .register(FloatingIpId.class)
+                .register(FloatingIp.Status.class)
+                .register(UUID.class)
+                .register(DefaultFloatingIp.class)
+                .register(BindingHostId.class)
+                .register(SecurityGroup.class)
+                .register(IpAddress.class)
+                .register(DefaultBasePort.class)
+                .register(RouterId.class)
+                .register(TenantRouter.class)
+                .register(BasePort.class);
+        vPortStore = storageService
+                .<BasePortId, BasePort>eventuallyConsistentMapBuilder()
+                .withName(BASE_PORT_STORE).withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        vPortStore.destroy();
+        log.info("Stoppped");
+    }
+
+    @Override
+    public boolean exists(BasePortId vPortId) {
+        checkNotNull(vPortId, BASEPORT_ID_NULL);
+        return vPortStore.containsKey(vPortId);
+    }
+
+    @Override
+    public BasePort getPort(BasePortId vPortId) {
+        checkNotNull(vPortId, BASEPORT_ID_NULL);
+        return vPortStore.get(vPortId);
+    }
+
+    @Override
+    public BasePort getPort(FixedIp fixedIP) {
+        checkNotNull(fixedIP, FIXEDIP_NOT_NULL);
+        List<BasePort> vPorts = new ArrayList<>();
+        vPortStore.values().forEach(p -> {
+            for (FixedIp fixedIp : p.fixedIps()) {
+                if (fixedIp.equals(fixedIP)) {
+                    vPorts.add(p);
+                    break;
+                }
+            }
+        });
+        if (vPorts.size() == 0) {
+            return null;
+        }
+        return vPorts.get(0);
+    }
+
+    @Override
+    public BasePort getPort(MacAddress mac) {
+        checkNotNull(mac, MAC_NOT_NULL);
+        List<BasePort> vPorts = new ArrayList<>();
+        vPortStore.values().forEach(p -> {
+            if (p.macAddress().equals(mac)) {
+                vPorts.add(p);
+            }
+        });
+        if (vPorts.size() == 0) {
+            return null;
+        }
+        return vPorts.get(0);
+    }
+
+    @Override
+    public BasePort getPort(TenantNetworkId networkId, IpAddress ip) {
+        checkNotNull(networkId, NETWORKID_NOT_NULL);
+        checkNotNull(ip, IP_NOT_NULL);
+        List<BasePort> vPorts = new ArrayList<>();
+        vPortStore.values().stream().filter(p -> p.networkId().equals(networkId))
+                .forEach(p -> {
+                    for (FixedIp fixedIp : p.fixedIps()) {
+                        if (fixedIp.ip().equals(ip)) {
+                            vPorts.add(p);
+                            break;
+                        }
+                    }
+                });
+        if (vPorts.size() == 0) {
+            return null;
+        }
+        return vPorts.get(0);
+    }
+
+    @Override
+    public Collection<BasePort> getPorts() {
+        return Collections.unmodifiableCollection(vPortStore.values());
+    }
+
+    @Override
+    public Collection<BasePort> getPorts(TenantNetworkId networkId) {
+        checkNotNull(networkId, NETWORKID_NOT_NULL);
+        return vPortStore.values().stream().filter(d -> d.networkId().equals(networkId))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public Collection<BasePort> getPorts(TenantId tenantId) {
+        checkNotNull(tenantId, TENANTID_NOT_NULL);
+        return vPortStore.values().stream().filter(d -> d.tenantId().equals(tenantId))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public Collection<BasePort> getPorts(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICEID_NOT_NULL);
+        return vPortStore.values().stream().filter(d -> d.deviceId().equals(deviceId))
+                .collect(Collectors.toList());
+    }
+
+    @Override
+    public boolean createPorts(Iterable<BasePort> vPorts) {
+        checkNotNull(vPorts, BASEPORT_NOT_NULL);
+        for (BasePort vPort : vPorts) {
+            log.info("vPortId is  {} ", vPort.portId().toString());
+            vPortStore.put(vPort.portId(), vPort);
+            if (!vPortStore.containsKey(vPort.portId())) {
+                log.info("The basePort is created failed whose identifier is" +
+                                 " {} ",
+                         vPort.portId().toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updatePorts(Iterable<BasePort> vPorts) {
+        checkNotNull(vPorts, BASEPORT_NOT_NULL);
+        for (BasePort vPort : vPorts) {
+            vPortStore.put(vPort.portId(), vPort);
+            if (!vPortStore.containsKey(vPort.portId())) {
+                log.info("The basePort is not exist whose identifier is {}",
+                         vPort.portId().toString());
+                return false;
+            }
+
+            vPortStore.put(vPort.portId(), vPort);
+
+            if (!vPort.equals(vPortStore.get(vPort.portId()))) {
+                log.info("The basePort is updated failed whose  identifier " +
+                                 "is {}",
+                         vPort.portId().toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removePorts(Iterable<BasePortId> vPortIds) {
+        checkNotNull(vPortIds, BASEPORT_ID_NULL);
+        for (BasePortId vPortId : vPortIds) {
+            vPortStore.remove(vPortId);
+            if (vPortStore.containsKey(vPortId)) {
+                log.info("The basePort is removed failed whose identifier is" +
+                                 " {}",
+                         vPortId.toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns a collection of basePorts from subnetNodes.
+     *
+     * @param vPortNodes the basePort json node
+     * @return BasePort collection of vpn ports
+     */
+    private Collection<BasePort> changeJsonToSub(JsonNode vPortNodes) {
+        checkNotNull(vPortNodes, JSON_NOT_NULL);
+        Set<FixedIp> fixedIps = null;
+        TenantNetworkId tenantNetworkId = null;
+        Map<BasePortId, BasePort> vportMap = new HashMap<>();
+        Map<String, String> strMap = new HashMap<>();
+        BasePortId basePortId = BasePortId.portId(vPortNodes.get("id").asText());
+        String name = vPortNodes.get("name").asText();
+        TenantId tenantId = TenantId
+                .tenantId(vPortNodes.get("tenant_id").asText());
+        Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
+        String state = vPortNodes.get("status").asText();
+        MacAddress macAddress = MacAddress
+                .valueOf(vPortNodes.get("mac_address").asText());
+        DeviceId deviceId = DeviceId
+                .deviceId(vPortNodes.get("device_id").asText());
+        String deviceOwner = vPortNodes.get("device_owner").asText();
+        BindingHostId bindingHostId = BindingHostId
+                .bindingHostId(vPortNodes.get("host_id").asText());
+        String bindingVnicType = vPortNodes.get("vnic_type").asText();
+        String bindingVifType = vPortNodes.get("vif_type").asText();
+        String bindingVifDetails = vPortNodes.get("vif_details").asText();
+        strMap.put("name", name);
+        strMap.put("deviceOwner", deviceOwner);
+        strMap.put("bindingVnicType", bindingVnicType);
+        strMap.put("bindingVifType", bindingVifType);
+        strMap.put("bindingVifDetails", bindingVifDetails);
+        BasePort prevBasePort = getPort(basePortId);
+        if (prevBasePort != null) {
+            fixedIps = prevBasePort.fixedIps();
+            tenantNetworkId = prevBasePort.networkId();
+        }
+        BasePort vPort = new DefaultBasePort(basePortId,
+                                             tenantNetworkId,
+                                             adminStateUp,
+                                             strMap, state,
+                                             macAddress, tenantId,
+                                             deviceId, fixedIps,
+                                             bindingHostId,
+                                             null,
+                                             null);
+        vportMap.put(basePortId, vPort);
+
+        return Collections.unmodifiableCollection(vportMap.values());
+    }
+
+    /**
+     * Returns BasePort State.
+     *
+     * @param state the base port state
+     * @return the basePort state
+     */
+    private BasePort.State isState(String state) {
+        if (state.equals("ACTIVE")) {
+            return BasePort.State.ACTIVE;
+        } else {
+            return BasePort.State.DOWN;
+        }
+
+    }
+
+    /**
+     * process Etcd response for port information.
+     *
+     * @param action can be either update or delete
+     * @param key    can contain the id and also target information
+     * @param value  content of the port configuration
+     */
+    @Override
+    public void processGluonConfig(String action, String key, JsonNode value) {
+        Collection<BasePort> basePorts;
+        switch (action) {
+            case DELETE:
+                String[] list = key.split(SLASH);
+                BasePortId basePortId
+                        = BasePortId.portId(list[list.length - 1]);
+                Set<BasePortId> basePortIds = Sets.newHashSet(basePortId);
+                removePorts(basePortIds);
+                break;
+            case SET:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                basePorts = changeJsonToSub(value);
+                createPorts(basePorts);
+                break;
+            case UPDATE:
+                checkNotNull(value, RESPONSE_NOT_NULL);
+                basePorts = changeJsonToSub(value);
+                updatePorts(basePorts);
+                break;
+            default:
+                log.info("Invalid action is received while processing VPN " +
+                                 "port configuration");
+        }
+    }
+
+    private void parseEtcdResponse(JsonNode jsonNode,
+                                   String key,
+                                   String action) {
+        JsonNode modifyValue = null;
+        if (action.equals(SET)) {
+            modifyValue = jsonNode.get(key);
+        }
+        String[] list = key.split(SLASH);
+        String target = list[list.length - 2];
+        if (target.equals(PROTON_BASE_PORT)) {
+            processGluonConfig(action, key, modifyValue);
+        }
+    }
+
+    @Override
+    public void addListener(BasePortListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(BasePortListener listener) {
+        checkNotNull(listener, LISTENER_NOT_NULL);
+        listeners.remove(listener);
+    }
+
+    /**
+     * Notifies specify event to all listeners.
+     *
+     * @param event vpn af config event
+     */
+    private void notifyListeners(BasePortEvent event) {
+        checkNotNull(event, EVENT_NOT_NULL);
+        listeners.forEach(listener -> listener.event(event));
+    }
+}
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/package-info.java
new file mode 100755
index 0000000..366dc00
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * VPN resources that used by l3vpn.
+ */
+package org.onosproject.evpnopenflow.rsc.baseport.impl;
diff --git a/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/package-info.java b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/package-info.java
new file mode 100755
index 0000000..52f5d0c
--- /dev/null
+++ b/apps/evpnopenflow/src/main/java/org/onosproject/evpnopenflow/rsc/baseport/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * VPN resources that used by l3vpn.
+ */
+package org.onosproject.evpnopenflow.rsc.baseport;