[ONOS-6199] Huawei driver create and instance delete.

Change-Id: I61e1a8518e9bd2a1a5ed9430052a3e6d3233f148
diff --git a/drivers/huawei/driver/src/main/java/org/onosproject/drivers/huawei/IntConstructionUtil.java b/drivers/huawei/driver/src/main/java/org/onosproject/drivers/huawei/IntConstructionUtil.java
new file mode 100644
index 0000000..da4a85c
--- /dev/null
+++ b/drivers/huawei/driver/src/main/java/org/onosproject/drivers/huawei/IntConstructionUtil.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2017-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.drivers.huawei;
+
+import org.onosproject.yang.gen.v1.l3vpn.comm.type.rev20141225.nel3vpncommtype.Ipv4Address;
+import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.DeviceKeys;
+import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.DefaultL3Vpn;
+import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.DefaultL3Vpncomm;
+import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.DefaultL3VpnInstances;
+import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.DefaultL3VpnInstance;
+import org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225.nel3vpnapi.devices.device.l3vpn.l3vpncomm.l3vpninstances.L3VpnInstanceKeys;
+import org.onosproject.yang.gen.v1.ne.l3vpn.comm.rev20141225.nel3vpncomm.l3vpnifs.DefaultL3VpnIfs;
+import org.onosproject.yang.gen.v1.ne.l3vpn.comm.rev20141225.nel3vpncomm.l3vpnifs.L3VpnIfs;
+import org.onosproject.yang.gen.v1.ne.l3vpn.comm.rev20141225.nel3vpncomm.l3vpnifs.l3vpnifs.DefaultL3VpnIf;
+import org.onosproject.yang.gen.v1.ne.l3vpn.comm.rev20141225.nel3vpncomm.l3vpnifs.l3vpnifs.L3VpnIf;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.DefaultDevices;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.Device;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.Interfaces;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.interfaces.DefaultYangAutoPrefixInterface;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev20140508.ietfinterfaces.devices.device.interfaces.YangAutoPrefixInterface;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.Ipv4;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.ipv4.Address;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev20140616.ietfip.devices.device.interfaces.yangautoprefixinterface.augmentedifinterface.ipv4.address.subnet.PrefixLength;
+import org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.network.instance.rev20160623.ietfnetworkinstance.devices.device.interfaces.yangautoprefixinterface.DefaultAugmentedIfInterface;
+import org.onosproject.yang.model.InnerModelObject;
+import org.onosproject.yang.model.ModelObjectData;
+import org.onosproject.yang.model.ModelObjectId;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.onosproject.drivers.huawei.DriverUtil.DEVICE_NULL;
+import static org.onosproject.drivers.huawei.DriverUtil.OBJECT_NULL;
+import static org.onosproject.drivers.huawei.DriverUtil.getData;
+import static org.onosproject.drivers.huawei.DriverUtil.getIdFromModId;
+import static org.onosproject.drivers.huawei.DriverUtil.getObjFromModData;
+import static org.onosproject.yang.gen.v1.l3vpn.comm.type.rev20141225.nel3vpncommtype.Ipv4Address.fromString;
+
+/**
+ * Representation of utility for interface creation and deletion.
+ */
+public final class IntConstructionUtil {
+
+    /**
+     * Error message for illegal length of mask.
+     */
+    private static final String ILLEGAL_MASK_LENGTH = "Illegal length of mask" +
+            " is not allowed.";
+
+    // No instantiation.
+    private IntConstructionUtil() {
+    }
+
+    /**
+     * Returns the created model object data of VPN bounded interface of huawei
+     * device from the standard model object data.
+     *
+     * @param modObj model object data
+     * @return driver interface model object data
+     */
+    static ModelObjectData getCreateInt(ModelObjectData modObj) {
+        boolean isModIdAvail = true;
+        String id = getIdFromModId(modObj.identifier());
+        Object obj = getObjFromModData(modObj);
+        if (id == null) {
+            isModIdAvail = false;
+            id = getIdFromRootObj(obj);
+            obj = getObjFromDevObj(obj);
+        }
+        if (obj == null) {
+            throw new IllegalArgumentException(OBJECT_NULL);
+        }
+        List<YangAutoPrefixInterface> intList = ((Interfaces) obj)
+                .yangAutoPrefixInterface();
+        YangAutoPrefixInterface l3Int = intList.get(0);
+        DefaultAugmentedIfInterface ifInt =
+                ((DefaultYangAutoPrefixInterface) l3Int).augmentation(
+                        DefaultAugmentedIfInterface.class);
+        String insName = ifInt.bindNetworkInstanceName();
+        L3VpnIfs l3VpnIfs = getDriverInterfaces(l3Int);
+        return getDriModObj(id, insName, l3VpnIfs, isModIdAvail);
+    }
+
+    /**
+     * Returns the driver model object data, according to the levels it has
+     * to be constructed.
+     *
+     * @param id           device id
+     * @param insName      VPN name
+     * @param l3VpnIfs     driver VPN if object
+     * @param isModIdAvail model id availability
+     * @return driver model object data
+     */
+    private static ModelObjectData getDriModObj(String id, String insName,
+                                                L3VpnIfs l3VpnIfs,
+                                                boolean isModIdAvail) {
+        List<L3VpnIf> intList = l3VpnIfs.l3VpnIf();
+        Iterator<L3VpnIf> it = intList.iterator();
+        L3VpnIf l3VpnIf = it.next();
+        ModelObjectData data;
+        ModelObjectId.Builder objId = getModIdBuilder(id, insName);
+        if (isModIdAvail) {
+            objId.addChild(DefaultL3VpnIfs.class);
+            data = getData(objId.build(), (InnerModelObject) l3VpnIf);
+        } else {
+            data = getData(objId.build(), (InnerModelObject) l3VpnIfs);
+        }
+        return data;
+    }
+
+    private static ModelObjectId.Builder getModIdBuilder(String id,
+                                                         String vpnName) {
+        DeviceKeys key = new DeviceKeys();
+        key.deviceid(id);
+        L3VpnInstanceKeys insKey = new L3VpnInstanceKeys();
+        insKey.vrfName(vpnName);
+        return ModelObjectId.builder()
+                .addChild(org.onosproject.yang.gen.v1.ne.l3vpn.api.rev20141225
+                                  .nel3vpnapi.DefaultDevices.class)
+                .addChild(org.onosproject.yang.gen.v1.ne.l3vpn.api
+                                  .rev20141225.nel3vpnapi.devices
+                                  .DefaultDevice.class, key)
+                .addChild(DefaultL3Vpn.class)
+                .addChild(DefaultL3Vpncomm.class)
+                .addChild(DefaultL3VpnInstances.class)
+                .addChild(DefaultL3VpnInstance.class, insKey);
+    }
+
+    /**
+     * Returns the driver interfaces from the standard device model interfaces.
+     *
+     * @param ifs standard device model interfaces
+     * @return driver interfaces
+     */
+    private static L3VpnIfs getDriverInterfaces(YangAutoPrefixInterface ifs) {
+        L3VpnIfs l3VpnIfs = new DefaultL3VpnIfs();
+        L3VpnIf l3VpnIf = new DefaultL3VpnIf();
+        List<L3VpnIf> l3VpnIfList = new LinkedList<>();
+        l3VpnIf.ifName(ifs.name());
+        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip
+                .rev20140616.ietfip.devices.device.interfaces
+                .yangautoprefixinterface.DefaultAugmentedIfInterface ipAug =
+                ((DefaultYangAutoPrefixInterface) ifs).augmentation(
+                        org.onosproject.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                                .ietf.ip.rev20140616.ietfip.devices.device
+                                .interfaces.yangautoprefixinterface
+                                .DefaultAugmentedIfInterface.class);
+
+        if (ipAug != null && ipAug.ipv4() != null) {
+            Ipv4 ipAddress = ipAug.ipv4();
+            for (Address add : ipAddress.address()) {
+                Ipv4Address v4Add = fromString(add.ip().ipv4Address()
+                                                       .toString());
+                Ipv4Address subnet = fromString(getSubnet(
+                        ((PrefixLength) add.subnet()).prefixLength()));
+                l3VpnIf.ipv4Addr(v4Add);
+                l3VpnIf.subnetMask(subnet);
+            }
+        }
+        l3VpnIfList.add(l3VpnIf);
+        l3VpnIfs.l3VpnIf(l3VpnIfList);
+        return l3VpnIfs;
+    }
+
+    /**
+     * Returns the device id from the root object.
+     *
+     * @param obj root object
+     * @return device id
+     */
+    private static String getIdFromRootObj(Object obj) {
+        Device dev = getDevFromRootObj(obj);
+        return dev.deviceid();
+    }
+
+    /**
+     * Returns the device from the root object.
+     *
+     * @param obj root object
+     * @return device object
+     */
+    private static Device getDevFromRootObj(Object obj) {
+        List<Device> deviceList = ((DefaultDevices) obj).device();
+        Iterator<Device> it = deviceList.iterator();
+        if (it.hasNext()) {
+            return it.next();
+        }
+        throw new IllegalArgumentException(DEVICE_NULL);
+    }
+
+    /**
+     * Returns the interfaces object from the root object.
+     *
+     * @param obj root object
+     * @return interfaces object
+     */
+    private static Interfaces getObjFromDevObj(Object obj) {
+        Device dev = getDevFromRootObj(obj);
+        return dev.interfaces();
+    }
+
+    /**
+     * Returns the subnet address from the mask value.
+     *
+     * @param mask mask value
+     * @return subnet address
+     */
+    private static String getSubnet(short mask) {
+        int value = 0xffffffff << (32 - mask);
+        byte[] bytes = new byte[]{
+                (byte) (value >>> 24), (byte) (value >> 16 & 0xff),
+                (byte) (value >> 8 & 0xff), (byte) (value & 0xff)};
+        InetAddress netAdd;
+        try {
+            netAdd = InetAddress.getByAddress(bytes);
+        } catch (UnknownHostException e) {
+            throw new IllegalArgumentException(ILLEGAL_MASK_LENGTH);
+        }
+        return netAdd.getHostAddress();
+    }
+}