Add 'TableStatistics' to SAL and Northbound Statistics API.
[controller.git] / opendaylight / sal / api / src / main / java / org / opendaylight / controller / sal / core / NodeTable.java
diff --git a/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeTable.java b/opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/NodeTable.java
new file mode 100644 (file)
index 0000000..22c3796
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2013 Big Switch Networks, Inc.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.core;
+
+import java.io.Serializable;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.NONE)
+public class NodeTable implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+    public static final Short SPECIALNODETABLEID = (short) 0;
+
+    /**
+     * Enum-like static class created with the purpose of identifing
+     * multiple type of nodes in the SDN network. The type is
+     * necessary to figure out to later on correctly use the
+     * nodeTableID. Using a static class instead of an Enum so we can add
+     * dynamically new types without changing anything in the
+     * surround.
+     */
+    public static final class NodeTableIDType {
+        private static final ConcurrentHashMap<String, Class<? extends Object>> compatibleType =
+                new ConcurrentHashMap<String, Class<? extends Object>>();
+        /**
+         * These are in compliance with the compatibility types in 'Node'
+         */
+        public static String OPENFLOW = "OF";
+        public static String PCEP = "PE";
+        public static String ONEPK = "PK";
+        public static String PRODUCTION = "PR";
+
+        // Pre-populated types, just here for convenience and ease of
+        // unit-testing, but certainly those could live also outside.
+        // Currently we allow these 4. It can be changed later.
+        static {
+            compatibleType.put(OPENFLOW, Byte.class);
+            compatibleType.put(PCEP, UUID.class);
+            compatibleType.put(ONEPK, String.class);
+            compatibleType.put(PRODUCTION, String.class);
+        }
+
+        /**
+         * Return the type of the class expected for the
+         * NodeTableID, it's used for validity check in the constructor
+         *
+         * @param type, the type of the NodeTable for which we
+         * want to retrieve the compatible class to be used as ID.
+         *
+         * @return The Class which is supposed to instantiate the ID
+         * for the NodeTableID
+         */
+        public static Class<?> getClassType(String type) {
+            return compatibleType.get(type);
+        }
+
+        /**
+         * Returns all the registered nodeTableIDTypes currently available
+         *
+         * @return The current registered NodeTableIDTypes
+         */
+        public static Set<String> values() {
+            return compatibleType.keySet();
+        }
+
+        /**
+         * Register a new ID for which NodeTable can be created
+         *
+         * @param type, the new type being registered
+         * @param compatibleID, the type of class to be accepted as ID
+         *
+         * @return true if registered, false otherwise
+         */
+        public static boolean registerIDType(String type,
+                Class<? extends Object> compatibleID) {
+            if (compatibleType.get(type) != null) {
+                return false;
+            }  else {
+                compatibleType.put(type, compatibleID);
+                return true;
+            }
+        }
+
+        /**
+         * UNRegister a new ID for which Node can be created
+         *
+         * @param type, the type being UN-registered
+         *
+         */
+        public static void unRegisterIDType(String type) {
+            compatibleType.remove(type);
+        }
+    }
+
+    // Elements that constitute the NodeTable
+    private Object nodeTableID;
+    private String nodeTableType;
+    @XmlElement(name = "node")
+    private Node nodeTableNode;
+
+    // Helper field for JAXB
+    private String nodeTableIDString;
+
+    /**
+     * Private constructor used for JAXB mapping
+     */
+    private NodeTable() {
+        this.nodeTableIDString = null;
+        this.nodeTableID = null;
+        this.nodeTableType = null;
+        this.nodeTableNode = null;
+    }
+
+    public NodeTable(String nodeTableType, Object id, Node node) throws ConstructionException {
+        if (NodeTableIDType.getClassType(nodeTableType) != null &&
+                NodeTableIDType.getClassType(nodeTableType).isInstance(id) &&
+                node.getType().equals(nodeTableType)) {
+            this.nodeTableType = nodeTableType;
+            this.nodeTableID = id;
+            this.nodeTableNode = node;
+        } else {
+            throw new ConstructionException("Type of incoming object:"
+                    + id.getClass() + " not compatible with expected type:"
+                    + NodeTableIDType.getClassType(nodeTableType)
+                    + " or Node type incompatible:" + node.getType());
+        }
+    }
+
+    /**
+     * Copy constructor for NodeTable
+     *
+     * @param src NodeTable to copy from
+     *
+     */
+    public NodeTable(NodeTable src) throws ConstructionException {
+        if (src != null) {
+            this.nodeTableType = src.getType();
+            // Here we can reference the object because that is
+            // supposed to be an immutable identifier as well like a
+            // UUID/Integer and so on, hence no need to create a copy
+            // of it
+            this.nodeTableID = src.getID();
+            this.nodeTableNode = new Node(src.getNode());
+        } else {
+            throw
+            new ConstructionException("Null incoming object to copy from");
+        }
+    }
+
+    /**
+     * @return the nodeTableID
+     */
+    public Object getID() {
+        return this.nodeTableID;
+    }
+
+    /**
+     * @return the nodeTableType
+     */
+    public String getType() {
+        return this.nodeTableType;
+    }
+
+    /**
+     * @param type the nodeTableType to set
+     *
+     * Private setter for nodeConnectorType to be called by JAXB not by anyone
+     * else, NodeConnector is immutable
+     */
+    private void setType(String type) {
+        this.nodeTableType = type;
+        if (this.nodeTableIDString != null) {
+            this.fillmeFromString(type, this.nodeTableIDString);
+        }
+    }
+
+    /**
+     * @return the nodeTableNode
+     */
+    public Node getNode() {
+        return this.nodeTableNode;
+    }
+
+    /**
+     * @param nodeTableNode the nodeTableNode to set
+     */
+    public void setNodeTableNode(Node nodeTableNode) {
+        this.nodeTableNode = nodeTableNode;
+    }
+
+    /**
+     * @return the nodeTableIDString
+     */
+    @XmlAttribute(name = "id")
+    public String getNodeTableIDString() {
+        return this.nodeTableIDString.toString();
+    }
+
+    /**
+     * @param nodeTableIDString the nodeTableIDString to set
+     */
+    @SuppressWarnings("unused")
+    private void setNodeTableIDString(String IDStr) {
+        this.nodeTableIDString = IDStr;
+        if (this.nodeTableType != null) {
+            this.fillmeFromString(this.nodeTableType, IDStr);
+        }
+    }
+
+    /**
+     * fill the current object from the string parameters passed, will
+     * be only used by JAXB
+     *
+     * @param typeStr string representing the type of the Node
+     * @param IDStr String representation of the ID
+     */
+    private void fillmeFromString(String typeStr, String IDStr) {
+        if (typeStr == null) {
+            return;
+        }
+
+        if (IDStr == null) {
+            return;
+        }
+
+        this.nodeTableType = typeStr;
+        this.nodeTableID = (byte) Byte.parseByte(IDStr);
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result
+                + ((nodeTableID == null) ? 0 : nodeTableID.hashCode());
+        result = prime
+                * result
+                + ((nodeTableNode == null) ? 0 : nodeTableNode
+                        .hashCode());
+        result = prime
+                * result
+                + ((nodeTableType == null) ? 0 : nodeTableType
+                        .hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        NodeTable other = (NodeTable) obj;
+        if (nodeTableID == null) {
+            if (other.nodeTableID != null)
+                return false;
+        } else if (!nodeTableID.equals(other.nodeTableID))
+            return false;
+        if (nodeTableNode == null) {
+            if (other.nodeTableNode != null)
+                return false;
+        } else if (!nodeTableNode.equals(other.nodeTableNode))
+            return false;
+        if (nodeTableType == null) {
+            if (other.nodeTableType != null)
+                return false;
+        } else if (!nodeTableType.equals(other.nodeTableType))
+            return false;
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return this.getNodeTableIdAsString() + "@" + this.nodeTableNode;
+    }
+
+    public String getNodeTableIdAsString() {
+        return this.nodeTableType.toString() + "|"
+                + this.nodeTableID.toString();
+    }
+
+}