+ @Override
+ public Status updateNodeConfig(SwitchConfig switchConfig) {
+ Status status = switchConfig.validate();
+ if (!status.isSuccess()) {
+ return status;
+ }
+
+ Map<String, Property> updateProperties = switchConfig.getNodeProperties();
+ String nodeId = switchConfig.getNodeId();
+ ForwardingMode mode = (ForwardingMode) updateProperties.get(ForwardingMode.name);
+ if (mode != null) {
+ if (isDefaultContainer) {
+ if (!mode.isValid()) {
+ return new Status(StatusCode.BADREQUEST, "Invalid Forwarding Mode Value.");
+ }
+ } else {
+ return new Status(StatusCode.NOTACCEPTABLE,
+ "Forwarding Mode modification is allowed only in default container");
+ }
+ }
+ boolean modeChange = false;
+ SwitchConfig sc = nodeConfigList.get(nodeId);
+ Map<String, Property> prevNodeProperties = new HashMap<String, Property>();
+ if (sc == null) {
+ if ((mode != null) && mode.isProactive()) {
+ modeChange = true;
+ }
+ if (!updateProperties.isEmpty()) {
+ if (nodeConfigList.putIfAbsent(nodeId, switchConfig) != null) {
+ return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration");
+ }
+ }
+ } else {
+ prevNodeProperties = new HashMap<String, Property>(sc.getNodeProperties());
+ ForwardingMode prevMode = (ForwardingMode) sc.getProperty(ForwardingMode.name);
+ if (mode == null) {
+ if ((prevMode != null) && (prevMode.isProactive())) {
+ modeChange = true;
+ }
+ } else {
+ if (((prevMode != null) && (prevMode.getValue() != mode.getValue()))
+ || (prevMode == null && mode.isProactive())) {
+ modeChange = true;
+ }
+ }
+ if (updateProperties.isEmpty()) {
+ nodeConfigList.remove(nodeId);
+ } else {
+ if (!nodeConfigList.replace(nodeId, sc, switchConfig)) {
+ return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration");
+ }
+ }
+ }
+ Node node = Node.fromString(nodeId);
+ Map<String, Property> propMapCurr = nodeProps.get(node);
+ if (propMapCurr == null) {
+ return new Status(StatusCode.SUCCESS);
+ }
+ Map<String, Property> propMap = new HashMap<String, Property>(propMapCurr);
+ if (!prevNodeProperties.isEmpty()) {
+ for (String prop : prevNodeProperties.keySet()) {
+ if (!updateProperties.containsKey(prop)) {
+ if (prop.equals(Description.propertyName)) {
+ Map<Node, Map<String, Property>> nodeProp = this.inventoryService.getNodeProps();
+ if (nodeProp.get(node) != null) {
+ propMap.put(Description.propertyName, nodeProp.get(node).get(Description.propertyName));
+ continue;
+ }
+ }
+ propMap.remove(prop);
+ }
+ }
+ }
+ propMap.putAll(updateProperties);
+ if (!nodeProps.replace(node, propMapCurr, propMap)) {
+ // TODO rollback using Transactionality
+ return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration.");
+ }
+ if (modeChange) {
+ notifyModeChange(node, (mode == null) ? false : mode.isProactive());
+ }
+ return new Status(StatusCode.SUCCESS);
+ }
+
+ @Override
+ public Status removeNodeConfig(String nodeId) {
+ if ((nodeId == null) || (nodeId.isEmpty())) {
+ return new Status(StatusCode.BADREQUEST, "nodeId cannot be empty.");
+ }
+ Map<String, Property> nodeProperties = getSwitchConfig(nodeId).getNodeProperties();
+ Node node = Node.fromString(nodeId);
+ Map<String, Property> propMapCurr = nodeProps.get(node);
+ if ((propMapCurr != null) && (nodeProperties != null) && (!nodeProperties.isEmpty())) {
+ Map<String, Property> propMap = new HashMap<String, Property>(propMapCurr);
+ for (String prop : nodeProperties.keySet()) {
+ if (prop.equals(Description.propertyName)) {
+ Map<Node, Map<String, Property>> nodeProp = this.inventoryService.getNodeProps();
+ if (nodeProp.get(node) != null) {
+ propMap.put(Description.propertyName, nodeProp.get(node).get(Description.propertyName));
+ continue;
+ }
+ }
+ propMap.remove(prop);
+ }
+ if (!nodeProps.replace(node, propMapCurr, propMap)) {
+ return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration.");
+ }
+ }
+ if (nodeConfigList != null) {
+ nodeConfigList.remove(nodeId);
+ }
+ return new Status(StatusCode.SUCCESS);
+ }
+