Refactored bridge config to take bridge description

OVSDB provides lots of bridge configuration options but the exisisting
bridge config implementation only allows some of them by overloading
addBridge method. Also some of the bridge properties were set static
and unable to configure. This patch fixes these limitations.

- Added some bridge config options to the bridge description
- Deprecated multiple overloaded addBridge methods
- Some code clean up

Change-Id: Ibc828177b210bd4b215aea0b63cc359776c13e03
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/DefaultBridgeDescription.java b/core/api/src/main/java/org/onosproject/net/behaviour/DefaultBridgeDescription.java
index 6bd73a8..f35b646 100644
--- a/core/api/src/main/java/org/onosproject/net/behaviour/DefaultBridgeDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/DefaultBridgeDescription.java
@@ -15,73 +15,158 @@
  */
 package org.onosproject.net.behaviour;
 
-import java.util.Objects;
-
-import org.onosproject.net.AbstractDescription;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.SparseAnnotations;
 
-import com.google.common.base.MoreObjects;
+import java.util.List;
+import java.util.Optional;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
  * The default implementation of bridge.
  */
-public final class DefaultBridgeDescription extends AbstractDescription
-        implements BridgeDescription {
+public final class DefaultBridgeDescription implements BridgeDescription {
 
-    private final BridgeName name;
-    private final DeviceId deviceId;
-    private final DeviceId controllerId;
+    private final String name;
 
-    public DefaultBridgeDescription(BridgeName name, DeviceId controllerId,
-                                    DeviceId deviceId,
-                                    SparseAnnotations... annotations) {
-        super(annotations);
-        this.name = name;
-        this.deviceId = deviceId;
-        this.controllerId = controllerId;
+    /* Optional OpenFlow configurations */
+    private final List<ControllerInfo> controllers;
+    private final boolean enableLocalController;
+    private final Optional<FailMode> failMode;
+    private final Optional<String> datapathId;
+    private final Optional<Boolean> disableInBand;
+
+    /* Adds more configurations */
+
+    private DefaultBridgeDescription(String name,
+                                     List<ControllerInfo> controllers,
+                                     boolean enableLocalController,
+                                     Optional<FailMode> failMode,
+                                     Optional<String> datapathId,
+                                     Optional<Boolean> disableInBand) {
+        this.name = checkNotNull(name);
+        this.controllers = controllers;
+        this.enableLocalController = enableLocalController;
+        this.failMode = failMode;
+        this.datapathId = datapathId;
+        this.disableInBand = disableInBand;
     }
 
     @Override
-    public BridgeName bridgeName() {
+    public SparseAnnotations annotations() {
+        return null;
+    }
+
+    @Override
+    public String name() {
         return name;
     }
 
     @Override
-    public DeviceId deviceId() {
-        return deviceId;
+    public List<ControllerInfo> controllers() {
+        return controllers;
     }
 
     @Override
-    public DeviceId cotrollerDeviceId() {
-        return controllerId;
+    public boolean enableLocalController() {
+        return enableLocalController;
     }
 
     @Override
-    public int hashCode() {
-        return Objects.hash(name, deviceId, controllerId);
+    public Optional<FailMode> failMode() {
+        return failMode;
     }
 
     @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
+    public Optional<String> datapathId() {
+        return datapathId;
+    }
+
+    @Override
+    public Optional<DeviceId> deviceId() {
+        if (datapathId.isPresent()) {
+            return Optional.of(DeviceId.deviceId("of:" + datapathId.get()));
+        } else {
+            return Optional.empty();
         }
-        if (obj instanceof DefaultBridgeDescription) {
-            final DefaultBridgeDescription that = (DefaultBridgeDescription) obj;
-            return this.getClass() == that.getClass()
-                    && Objects.equals(this.name, that.name)
-                    && Objects.equals(this.deviceId, that.deviceId)
-                    && Objects.equals(this.controllerId, that.controllerId);
-        }
-        return false;
     }
 
     @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("name", name)
-                .add("deviceId", deviceId).add("controllerId", controllerId)
-                .toString();
+    public Optional<Boolean> disableInBand() {
+        return disableInBand;
     }
 
+    /**
+     * Creates and returns a new builder instance.
+     *
+     * @return new builder
+     */
+    public static BridgeDescription.Builder builder() {
+        return new Builder();
+    }
+
+    public static final class Builder implements BridgeDescription.Builder {
+
+        private String name;
+        private List<ControllerInfo> controllers = Lists.newArrayList();
+        private boolean enableLocalController = false;
+        private Optional<FailMode> failMode = Optional.empty();
+        private Optional<String> datapathId = Optional.empty();
+        private Optional<Boolean> disableInBand = Optional.empty();
+
+        private Builder() {
+        }
+
+        @Override
+        public BridgeDescription build() {
+            return new DefaultBridgeDescription(name, controllers,
+                                                enableLocalController,
+                                                failMode,
+                                                datapathId,
+                                                disableInBand);
+        }
+
+        @Override
+        public Builder name(String name) {
+            checkArgument(!Strings.isNullOrEmpty(name));
+            this.name = name;
+            return this;
+        }
+
+        @Override
+        public Builder controllers(List<ControllerInfo> controllers) {
+            if (controllers != null) {
+                this.controllers = Lists.newArrayList(controllers);
+            }
+            return this;
+        }
+
+        @Override
+        public Builder enableLocalController() {
+            this.enableLocalController = true;
+            return this;
+        }
+
+        @Override
+        public Builder failMode(FailMode failMode) {
+            this.failMode = Optional.ofNullable(failMode);
+            return this;
+        }
+
+        @Override
+        public Builder datapathId(String datapathId) {
+            this.datapathId = Optional.ofNullable(datapathId);
+            return this;
+        }
+
+        @Override
+        public Builder disableInBand() {
+            this.disableInBand = Optional.of(Boolean.TRUE);
+            return this;
+        }
+    }
 }