Merge "Fixed NullPointerException seen in Hosttracker when fetching the hierarchy...
authorGiovanni Meo <gmeo@cisco.com>
Wed, 14 Aug 2013 13:24:53 +0000 (13:24 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 14 Aug 2013 13:24:53 +0000 (13:24 +0000)
19 files changed:
opendaylight/clustering/services_implementation/pom.xml
opendaylight/clustering/services_implementation/src/main/resources/config/infinispan-config.xml
opendaylight/clustering/test/src/main/java/org/opendaylight/controller/clustering/test/internal/SimpleClient.java
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/Activator.java
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java
opendaylight/distribution/opendaylight/src/main/resources/configuration/logback.xml
opendaylight/northbound/commons/src/main/java/org/opendaylight/controller/northbound/commons/utils/NorthboundUtils.java
opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java
opendaylight/northbound/hosttracker/src/main/java/org/opendaylight/controller/hosttracker/northbound/HostTrackerNorthbound.java
opendaylight/northbound/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/northbound/StaticRoutingNorthbound.java
opendaylight/northbound/subnets/src/main/java/org/opendaylight/controller/subnets/northbound/SubnetsNorthboundJAXRS.java
opendaylight/northbound/switchmanager/src/main/java/org/opendaylight/controller/switchmanager/northbound/SwitchNorthbound.java
opendaylight/northbound/topology/src/main/java/org/opendaylight/controller/topology/northbound/TopologyNorthboundJAXRS.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/packet/ICMP.java
opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java
opendaylight/web/flows/src/main/java/org/opendaylight/controller/flows/web/Flows.java
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebAdmin.java
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebUtil.java

index 1d52c4b..025fbdf 100644 (file)
@@ -39,6 +39,7 @@
         <instructions>
           <Import-Package>
             org.slf4j,
+            !org.apache.logging.log4j.*,
             !bsh*,
             !net.jcip.*,
             !javax.swing,
     <dependency>
       <groupId>org.infinispan</groupId>
       <artifactId>infinispan-core</artifactId>
-      <version>5.2.3.Final</version>
+      <version>5.3.0.Final</version>
     </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
index 16dd579..e917eea 100644 (file)
   <namedCache name="transactional-type">
     <transaction
         transactionManagerLookupClass="org.infinispan.transaction.lookup.JBossStandaloneJTAManagerLookup"
-        syncRollbackPhase="false"
-        syncCommitPhase="false"
+        syncRollbackPhase="true"
+        syncCommitPhase="true"
         cacheStopTimeout="30000"
         use1PcForAutoCommitTransactions="false"
         autoCommit="true"
         lockingMode="OPTIMISTIC"
-        useSynchronization="false"
+        useSynchronization="true"
         transactionMode="TRANSACTIONAL"
         />
   </namedCache>
index f681c35..60be87b 100644 (file)
@@ -9,6 +9,7 @@
 
 package org.opendaylight.controller.clustering.test.internal;
 
+import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.EnumSet;
 import java.util.List;
@@ -268,6 +269,24 @@ public class SimpleClient implements CommandProvider {
         ci.println(cacheName + " is no longer being monitored for updates");
     }
 
+    public void _myController(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        ci.println("This Controller : " +icluster.getMyAddress().getHostAddress());
+    }
+
+    public void _getClusterNodes(CommandInterpreter ci) {
+        if (this.icluster == null) {
+            ci.println("\nNo Clustering services available");
+            return;
+        }
+        for (InetAddress address : icluster.getClusteredControllers()) {
+            ci.println("\t"+address.getHostAddress());
+        }
+    }
+
     public void _listcaches(CommandInterpreter ci) {
         if (this.icluster == null) {
             ci.println("\nNo Clustering services available");
@@ -441,29 +460,6 @@ public class SimpleClient implements CommandProvider {
         }
     }
 
-    @SuppressWarnings("deprecation") //TODO: remove call to deprecated amIStandby
-    public void _getRole(CommandInterpreter ci) {
-        if (this.icluster == null) {
-            ci.println("\nNo Clustering services available");
-            return;
-        }
-        String role = "Active";
-        if (this.icluster.amIStandby()) {
-            role = "Standby";
-        }
-        ci.println("My role is: " + role);
-    }
-
-    @SuppressWarnings("deprecation") //TODO: remove call to deprecated getActiveAddres
-    public void _getActive(CommandInterpreter ci) {
-        if (this.icluster == null) {
-            ci.println("\nNo Clustering services available");
-            return;
-        }
-        ci.println("Current active address is "
-                + this.icluster.getActiveAddress());
-    }
-
     @SuppressWarnings("deprecation") //TODO: remove use of deprecated listenRoleChange
     public void _listenActive(CommandInterpreter ci) {
         if (this.icluster == null) {
@@ -640,16 +636,12 @@ public class SimpleClient implements CommandProvider {
         help.append("\tunlistenActive   - UNListen to Active updates\n");
         help.append("\tdestroy          - Destroy a cache\n");
         help.append("\tcreate           - Create a cache\n");
-        help.append("\tgetRole          - Tell if active or standby\n");
-        help.append("\tgetActive        - Report the IP address of Active\n");
-        help
-                .append("\tputComplex       - Fill a more complex data structure\n");
-        help
-                .append("\tupdateComplex    - Update the value of a more complex data structure\n");
-        help
-                .append("\tgetLogLevel      - Get the loglevel for the logger specified\n");
-        help
-                .append("\tsetLogLevel      - Set the loglevel for the logger specified\n");
+        help.append("\tmyController     - Print this controller's Cluster identifier\n");
+        help.append("\tgetClusterNodes  - Print all the controllers that make this cluster\n");
+        help.append("\tputComplex       - Fill a more complex data structure\n");
+        help.append("\tupdateComplex    - Update the value of a more complex data structure\n");
+        help.append("\tgetLogLevel      - Get the loglevel for the logger specified\n");
+        help.append("\tsetLogLevel      - Set the loglevel for the logger specified\n");
         return help.toString();
     }
 }
index 5ebbfe2..4bee253 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Set;
 import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
 import org.opendaylight.controller.clustering.services.ICoordinatorChangeAware;
+import org.opendaylight.controller.connectionmanager.ConnectionMgmtScheme;
 import org.opendaylight.controller.connectionmanager.IConnectionManager;
 import org.opendaylight.controller.sal.connection.IConnectionListener;
 import org.opendaylight.controller.sal.connection.IConnectionService;
@@ -77,7 +78,9 @@ public class Activator extends ComponentActivatorAbstractBase {
         if (imp.equals(ConnectionManager.class)) {
             Dictionary<String, Object> props = new Hashtable<String, Object>();
             Set<String> propSet = new HashSet<String>();
-            propSet.add("connectionmanager.nodeconnections");
+            for (ConnectionMgmtScheme scheme:ConnectionMgmtScheme.values()) {
+                propSet.add("connectionmanager."+scheme.name()+".nodeconnections");
+            }
             props.put("cachenames", propSet);
             props.put("scope", "Global");
 
index c4b7d4f..fdba533 100644 (file)
@@ -176,9 +176,6 @@ public class ConnectionManager implements IConnectionManager, IConnectionListene
 
     @Override
     public void coordinatorChanged() {
-        AbstractScheme scheme = schemes.get(activeScheme);
-        if (scheme == null) return;
-        scheme.handleClusterViewChanged();
         notifyClusterViewChanged();
     }
 
@@ -202,8 +199,7 @@ public class ConnectionManager implements IConnectionManager, IConnectionListene
 
     @Override
     public void entryCreated(Node key, String cacheName, boolean originLocal) {
-        AbstractScheme scheme = schemes.get(activeScheme);
-        logger.debug("Created : {} cache : {} existingValue : {}", key, cacheName, scheme.getNodeConnections().get(key));
+        if (originLocal) return;
     }
 
     /*
@@ -277,6 +273,9 @@ public class ConnectionManager implements IConnectionManager, IConnectionListene
                         connectionService.notifyNodeDisconnectFromMaster(node);
                         break;
                     case CLUSTER_VIEW_CHANGED:
+                        AbstractScheme scheme = schemes.get(activeScheme);
+                        if (scheme == null) return;
+                        scheme.handleClusterViewChanged();
                         connectionService.notifyClusterViewChanged();
                         break;
                     default:
index a490916..6b20909 100644 (file)
@@ -10,6 +10,8 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
+import javax.transaction.SystemException;
+
 import org.opendaylight.controller.clustering.services.CacheConfigException;
 import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
@@ -82,6 +84,7 @@ public abstract class AbstractScheme {
             }
         }
 
+        boolean retry = false;
         for (InetAddress c : toRemove) {
             log.debug("Removing Controller : {} from the Connections table", c);
             for (Iterator<Node> nodeIterator = nodeConnections.keySet().iterator();nodeIterator.hasNext();) {
@@ -89,23 +92,35 @@ public abstract class AbstractScheme {
                 Set <InetAddress> oldControllers = nodeConnections.get(node);
                 Set <InetAddress> newControllers = new HashSet<InetAddress>(oldControllers);
                 if (newControllers.remove(c)) {
-                    boolean replaced = false;
                     try {
-                        replaced = nodeConnections.replace(node, oldControllers, newControllers);
+                        clusterServices.tbegin();
+                        if (!nodeConnections.replace(node, oldControllers, newControllers)) {
+                            log.debug("Replace Failed for {} ", node.toString());
+                            retry = true;
+                            clusterServices.trollback();
+                            break;
+                        } else {
+                            clusterServices.tcommit();
+                        }
                     } catch (Exception e) {
-                        log.debug("Replace exception : ", e);
-                        replaced = false;
-                    }
-                    if (!replaced) {
+                        log.error("Exception in replacing nodeConnections ", e);
+                        retry = false;
                         try {
-                            Thread.sleep(10);
-                        } catch (InterruptedException e) {
-                        }
-                        handleClusterViewChanged();
+                            clusterServices.trollback();
+                        } catch (Exception e1) {}
+                        break;
                     }
                 }
             }
         }
+        if (retry) {
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            handleClusterViewChanged();
+        }
     }
 
     public Set<Node> getNodes(InetAddress controller) {
@@ -155,24 +170,30 @@ public abstract class AbstractScheme {
         if (oldControllers != null && oldControllers.contains(controller)) {
             Set<InetAddress> newControllers = new HashSet<InetAddress>(oldControllers);
             if (newControllers.remove(controller)) {
-                if (newControllers.size() > 0) {
-                    boolean replaced = false;
-                    try {
-                    replaced = nodeConnections.replace(node, oldControllers, newControllers);
-                    } catch (Exception e) {
-                        log.debug("Replace exception : ", e);
-                        replaced = false;
-                    }
-                    if (!replaced) {
-                        try {
-                            Thread.sleep(10);
-                        } catch (InterruptedException e) {
+                try {
+                    clusterServices.tbegin();
+                    if (newControllers.size() > 0) {
+                        if (!nodeConnections.replace(node, oldControllers, newControllers)) {
+                            clusterServices.trollback();
+                            try {
+                                Thread.sleep(100);
+                            } catch ( InterruptedException e) {}
+                            return removeNodeFromController(node, controller);
                         }
-                        return removeNodeFromController(node, controller);
+                    } else {
+                        nodeConnections.remove(node);
                     }
-                } else {
-                    nodeConnections.remove(node);
+                    clusterServices.tcommit();
+                } catch (Exception e) {
+                    log.error("Excepion in removing Controller from a Node", e);
+                    try {
+                        clusterServices.trollback();
+                    } catch (Exception e1) {
+                        log.error("Error Rolling back the node Connections Changes ", e);
+                    }
+                    return new Status(StatusCode.INTERNALERROR);
                 }
+
             }
         }
         return new Status(StatusCode.SUCCESS);
@@ -206,34 +227,45 @@ public abstract class AbstractScheme {
         }
         newControllers.add(controller);
 
-        if (nodeConnections.putIfAbsent(node, newControllers) != null) {
-            log.debug("PutIfAbsent failed {} to {}", controller.getHostAddress(), node.toString());
-            /*
-             * This check is needed again to take care of the case where some schemes
-             * would not allow nodes to be connected to multiple controllers.
-             * Hence, if putIfAbsent fails, that means, some other controller is competing
-             * with this controller to take hold of a Node.
-             */
-            if (isConnectionAllowed(node)) {
-                log.debug("Trying to replace old={} with new={} for {} to {}", oldControllers.toString(), newControllers.toString(),
-                        controller.getHostAddress(), node.toString());
-                if (!nodeConnections.replace(node, oldControllers, newControllers)) {
-                    try {
-                        Thread.sleep(10);
-                    } catch (InterruptedException e) {
+        try {
+            clusterServices.tbegin();
+            if (nodeConnections.putIfAbsent(node, newControllers) != null) {
+                log.debug("PutIfAbsent failed {} to {}", controller.getHostAddress(), node.toString());
+                /*
+                 * This check is needed again to take care of the case where some schemes
+                 * would not allow nodes to be connected to multiple controllers.
+                 * Hence, if putIfAbsent fails, that means, some other controller is competing
+                 * with this controller to take hold of a Node.
+                 */
+                if (isConnectionAllowed(node)) {
+                    if (!nodeConnections.replace(node, oldControllers, newControllers)) {
+                        clusterServices.trollback();
+                        try {
+                            Thread.sleep(100);
+                        } catch ( InterruptedException e) {}
+                        log.debug("Replace failed... old={} with new={} for {} to {}", oldControllers.toString(), newControllers.toString(),
+                                controller.getHostAddress(), node.toString());
+                        return putNodeToController(node, controller);
+                    } else {
+                        log.debug("Replace successful old={} with new={} for {} to {}", oldControllers.toString(), newControllers.toString(),
+                                controller.getHostAddress(), node.toString());
                     }
-                    log.debug("Replace failed... old={} with new={} for {} to {}", oldControllers.toString(), newControllers.toString(),
-                            controller.getHostAddress(), node.toString());
-                    return putNodeToController(node, controller);
                 } else {
-                    log.debug("Replace successful old={} with new={} for {} to {}", oldControllers.toString(), newControllers.toString(),
-                            controller.getHostAddress(), node.toString());
+                    clusterServices.trollback();
+                    return new Status(StatusCode.CONFLICT);
                 }
             } else {
-                return new Status(StatusCode.CONFLICT);
+                log.debug("Added {} to {}", controller.getHostAddress(), node.toString());
             }
-        } else {
-            log.debug("Added {} to {}", controller.getHostAddress(), node.toString());
+            clusterServices.tcommit();
+        } catch (Exception e) {
+            log.error("Excepion in adding Controller to a Node", e);
+            try {
+                clusterServices.trollback();
+            } catch (Exception e1) {
+                log.error("Error Rolling back the node Connections Changes ", e);
+            }
+            return new Status(StatusCode.INTERNALERROR);
         }
         return new Status(StatusCode.SUCCESS);
     }
@@ -277,7 +309,7 @@ public abstract class AbstractScheme {
         }
 
         try {
-            clusterServices.createCache("connectionmanager."+name+".nodeconnections", EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+            clusterServices.createCache("connectionmanager."+name+".nodeconnections", EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
         } catch (CacheExistException cee) {
             log.error("\nCache already exists - destroy and recreate if needed");
         } catch (CacheConfigException cce) {
index 08dabde..de0a3bc 100644 (file)
@@ -1,4 +1,4 @@
-<configuration scan="true">
+ <configuration scan="true">
 
   <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
     <encoder>
       <maxHistory>1</maxHistory>
     </rollingPolicy>
 
+    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+      <maxFileSize>10MB</maxFileSize>
+    </triggeringPolicy>
+
     <encoder>
       <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} [%thread] %-5level %logger{35} - %msg%n</pattern>
     </encoder>
   </appender>
-
+  <appender name="audit-file" class="ch.qos.logback.core.FileAppender">
+        <file>logs/audit.log</file>
+        <append>true</append>
+        <encoder>
+            <pattern>%date{"yyyy-MM-dd HH:mm:ss.SSS z"} %msg %n</pattern>
+        </encoder>
+  </appender>
   <root level="error">
     <appender-ref ref="STDOUT" />
     <appender-ref ref="opendaylight.log" />
   </root>
 
   <!--  Base log level  -->
-  <logger name="org.opendaylight" level="INFO"/>
+  <logger name="org.opendaylight.controller" level="INFO"/>
 
   <!-- OSGi logging bridge -->
   <logger name="org.opendaylight.controller.logging.bridge" level="WARN"/>
@@ -55,4 +65,8 @@
   <logger name="org.opendaylight.controller.usermanager" level="INFO"/>
   <!-- Web modules -->
   <logger name="org.opendaylight.controller.web" level="INFO"/>
-</configuration>
+  <!-- additivity=false ensures analytics data only goes to the analytics log -->
+  <logger name="audit" level="INFO" additivity="false">
+       <appender-ref ref="audit-file"/>
+  </logger>
+</configuration>
\ No newline at end of file
index f981893..9f47e0c 100644 (file)
@@ -13,6 +13,8 @@ import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.usermanager.IUserManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class NorthboundUtils {
 
@@ -37,6 +39,10 @@ public class NorthboundUtils {
         }
     };
 
+    private static final String AUDIT = "audit";
+
+    private static final Logger logger = LoggerFactory.getLogger(AUDIT);
+
     // Suppress default constructor for noninstantiability
     private NorthboundUtils() {
     }
@@ -114,4 +120,20 @@ public class NorthboundUtils {
         return true;
     }
 
+    public static void auditlog(String moduleName, String user, String action, String resource,
+            String containerName) {
+        String auditMsg = "";
+        String mode = "REST";
+        if (containerName != null) {
+            auditMsg = "Mode: " + mode + " User " + user + " "  + action + " " + moduleName + " " + resource + " in container "
+                    + containerName;
+        } else {
+            auditMsg = "Mode: " + mode + " User " + user + " "  + action + " " + moduleName + " " + resource;
+        }
+        logger.info(auditMsg);
+    }
+
+    public static void auditlog(String moduleName, String user, String action, String resource) {
+        auditlog(moduleName, user, action, resource, null);
+    }
 }
index d3cbc4a..6bccc2d 100644 (file)
@@ -322,7 +322,9 @@ public class FlowProgrammerNorthbound {
         }
 
         Status status = frm.addStaticFlow(flowConfig.getValue());
+
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Flow", username, "added", name, containerName);
             return Response.status(Response.Status.CREATED).build();
         }
         throw new InternalServerErrorException(status.getDescription());
@@ -385,6 +387,7 @@ public class FlowProgrammerNorthbound {
 
         Status status = frm.removeStaticFlow(name, node);
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Flow", username, "removed", name, containerName);
             return Response.ok().build();
         }
         throw new InternalServerErrorException(status.getDescription());
@@ -446,6 +449,7 @@ public class FlowProgrammerNorthbound {
 
         Status status = frm.toggleStaticFlowStatus(staticFlow);
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Flow", username, "toggled", name, containerName);
             return Response.ok().build();
         }
         throw new InternalServerErrorException(status.getDescription());
index 642c5cc..2859675 100644 (file)
@@ -310,6 +310,7 @@ public class HostTrackerNorthbound {
         Status status = hostTracker.addStaticHost(networkAddress,
                 dataLayerAddress, nc, vlan);
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Static Host", username, "added", networkAddress, containerName);
             return Response.status(Response.Status.CREATED).build();
         } else if (status.getCode().equals(StatusCode.BADREQUEST)) {
             throw new UnsupportedMediaTypeException(status.getDescription());
@@ -364,6 +365,7 @@ public class HostTrackerNorthbound {
 
         Status status = hostTracker.removeStaticHost(networkAddress);
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Static Host", username, "removed", networkAddress, containerName);
             return Response.ok().build();
         }
         throw new InternalServerErrorException(status.getDescription());
index b85f564..3deb8df 100644 (file)
@@ -58,8 +58,7 @@ import org.opendaylight.controller.sal.utils.Status;
 @Path("/")
 public class StaticRoutingNorthbound {
 
-
-        private String username;
+    private String username;
 
     @Context
     public void setSecurityContext(SecurityContext context) {
@@ -197,6 +196,7 @@ public class StaticRoutingNorthbound {
                 sRoute.getPrefix(), sRoute.getNextHop());
         Status response = staticRouting.addStaticRoute(cfgObject);
         if (response.isSuccess()) {
+            NorthboundUtils.auditlog("Static Route", username, "added", name, containerName);
             return Response.status(Response.Status.CREATED).build();
         }
         throw new ResourceConflictException(response.getDescription());
@@ -241,6 +241,7 @@ public class StaticRoutingNorthbound {
 
         Status status = staticRouting.removeStaticRoute(name);
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Static Route", username, "removed", name, containerName);
             return Response.ok().build();
         }
         throw new ResourceNotFoundException(status.getDescription());
index 17780fc..8c555f2 100644 (file)
@@ -160,6 +160,7 @@ public class SubnetsNorthboundJAXRS {
         SubnetConfig cfgObject = new SubnetConfig(subnetName, subnet, new HashSet<String>(0));
         Status status = switchManager.addSubnet(cfgObject);
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Subnet Gateway", username, "added", subnetName, containerName);
             return Response.status(Response.Status.CREATED).build();
         }
         throw new InternalServerErrorException(status.getDescription());
@@ -198,6 +199,7 @@ public class SubnetsNorthboundJAXRS {
         }
         Status status = switchManager.removeSubnet(subnetName);
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("Subnet Gateway", username, "removed", subnetName, containerName);
             return Response.status(Response.Status.OK).build();
         }
         throw new InternalServerErrorException(status.getDescription());
@@ -274,6 +276,9 @@ public class SubnetsNorthboundJAXRS {
             for (String s : newPorts) {
                 Status st = switchManager.addPortsToSubnet(name, s);
                 successful = successful && st.isSuccess();
+                if(successful){
+                    NorthboundUtils.auditlog("Subnet Gateway", username, "added", s +" to "+name, containerName);
+                }
             }
         }
 
@@ -393,6 +398,9 @@ public class SubnetsNorthboundJAXRS {
                 for (String port : ports) {
                     st = switchManager.addPortsToSubnet(name, port);
                     successful = successful && st.isSuccess();
+                    if(successful){
+                        NorthboundUtils.auditlog("Subnet Gateway", username, "added",  st +" to "+name, containerName);
+                    }
                 }
             } else if (action.equals("delete")) {
                 // delete existing ports
@@ -400,6 +408,9 @@ public class SubnetsNorthboundJAXRS {
                 for (String port : ports) {
                     st = switchManager.removePortsFromSubnet(name, port);
                     successful = successful && st.isSuccess();
+                    if(successful){
+                        NorthboundUtils.auditlog("Subnet Gateway", username, "removed",  st +" from "+name, containerName);
+                    }
                 }
             } else {
                 return Response.status(Response.Status.BAD_REQUEST).build();
index d6d9be9..e67d1b7 100644 (file)
@@ -303,6 +303,9 @@ public class SwitchNorthbound {
                 nodeProperties.remove(propertyName.toLowerCase());
                 SwitchConfig newSwitchConfig = new SwitchConfig(node.toString(), nodeProperties);
                 status = switchManager.updateNodeConfig(newSwitchConfig);
+                if(status.isSuccess()){
+                    NorthboundUtils.auditlog("Static Route", username, "updated", nodeId, containerName);
+                }
             }
         }
         return NorthboundUtils.getResponse(status);
@@ -519,6 +522,7 @@ public class SwitchNorthbound {
                 .fromStringNoNode(nodeConnectorType, nodeConnectorId, node);
         Status ret = switchManager.removeNodeConnectorProp(nc, propertyName);
         if (ret.isSuccess()) {
+            NorthboundUtils.auditlog("Node Connector Property", username, "removed", nc + " from " + nodeConnectorId, containerName);
             return Response.ok().build();
         }
         throw new ResourceNotFoundException(ret.getDescription());
index 323e2d2..fb4e822 100644 (file)
@@ -195,6 +195,7 @@ public class TopologyNorthboundJAXRS {
 
         Status status = topologyManager.addUserLink(userLinkConfig.getValue());
         if (status.isSuccess()) {
+            NorthboundUtils.auditlog("User Link", username, "added", userLinkConfig.getValue().getName(), containerName);
             return Response.status(Response.Status.CREATED).build();
         }
         throw new InternalServerErrorException(status.getDescription());
@@ -236,6 +237,7 @@ public class TopologyNorthboundJAXRS {
 
         Status ret = topologyManager.deleteUserLink(name);
         if (ret.isSuccess()) {
+            NorthboundUtils.auditlog("User Link", username, "removed", name, containerName);
             return Response.ok().build();
         }
         throw new ResourceNotFoundException(ret.getDescription());
index 5075e58..b2a1cfe 100644 (file)
@@ -147,10 +147,11 @@ public class ICMP extends Packet {
     short computeChecksum(byte[] data, int start) {
         int sum = 0, carry = 0, finalSum = 0;
         int wordData;
-        int end = start + this.getHeaderSize() / NetUtils.NumBitsInAByte
-                + rawPayload.length;
-        int checksumStartByte = start + getfieldOffset(CHECKSUM)
-                / NetUtils.NumBitsInAByte;
+        int end = start + this.getHeaderSize() / NetUtils.NumBitsInAByte;
+        if (rawPayload != null) {
+            end += rawPayload.length;
+        }
+        int checksumStartByte = start + getfieldOffset(CHECKSUM) / NetUtils.NumBitsInAByte;
 
         for (int i = start; i <= (end - 1); i = i + 2) {
             // Skip, if the current bytes are checkSum bytes
index f92e92e..15ad9e9 100644 (file)
@@ -256,6 +256,7 @@ public class Devices implements IDaylightWeb {
             } else {
                 resultBean.setStatus(true);
                 resultBean.setMessage("Updated node information successfully");
+                DaylightWebUtil.auditlog("Node", userName, "updated", nodeId + " to "+ nodeName, containerName);
             }
         } catch (Exception e) {
             resultBean.setStatus(false);
@@ -338,6 +339,7 @@ public class Devices implements IDaylightWeb {
             if (addStaticRouteResult.isSuccess()) {
                 result.setStatus(true);
                 result.setMessage("Static Route saved successfully");
+                DaylightWebUtil.auditlog("Static Route", userName, "added", routeName, containerName);
             } else {
                 result.setStatus(false);
                 result.setMessage(addStaticRouteResult.getDescription());
@@ -381,6 +383,7 @@ public class Devices implements IDaylightWeb {
                     resultBean.setMessage(result.getDescription());
                     break;
                 }
+                DaylightWebUtil.auditlog("Static Route", userName, "removed", route, containerName);
             }
         } catch (Exception e) {
             resultBean.setStatus(false);
@@ -451,6 +454,7 @@ public class Devices implements IDaylightWeb {
             if (result.isSuccess()) {
                 resultBean.setStatus(true);
                 resultBean.setMessage("Added gateway address successfully");
+                DaylightWebUtil.auditlog("Subnet Gateway", userName, "added", gatewayName, containerName);
             } else {
                 resultBean.setStatus(false);
                 resultBean.setMessage(result.getDescription());
@@ -491,6 +495,7 @@ public class Devices implements IDaylightWeb {
                     resultBean.setMessage(result.getDescription());
                     break;
                 }
+                DaylightWebUtil.auditlog("Subnet Gateway", userName, "removed", subnet, containerName);
             }
         } catch (Exception e) {
             resultBean.setStatus(false);
@@ -526,6 +531,7 @@ public class Devices implements IDaylightWeb {
                 resultBean.setStatus(true);
                 resultBean
                         .setMessage("Added ports to subnet gateway address successfully");
+                DaylightWebUtil.auditlog("Ports to Subnet Gateway", userName, "added",nodeId+"/"+ ports, containerName);
             } else {
                 resultBean.setStatus(false);
                 resultBean.setMessage(result.getDescription());
@@ -564,6 +570,7 @@ public class Devices implements IDaylightWeb {
                 resultBean.setStatus(true);
                 resultBean
                         .setMessage("Deleted port from subnet gateway address successfully");
+                DaylightWebUtil.auditlog("Ports from Subnet Gateway", userName, "removed", nodePort, containerName);
             } else {
                 resultBean.setStatus(false);
                 resultBean.setMessage(result.getDescription());
@@ -695,6 +702,7 @@ public class Devices implements IDaylightWeb {
             if (result.isSuccess()) {
                 resultBean.setStatus(true);
                 resultBean.setMessage("SPAN Port added successfully");
+                DaylightWebUtil.auditlog("SPAN Port", userName, "added", cfgObject.getNodeId(), containerName);
             } else {
                 resultBean.setStatus(false);
                 resultBean.setMessage(result.getDescription());
@@ -740,6 +748,7 @@ public class Devices implements IDaylightWeb {
                         resultBean.setMessage(result.getDescription());
                         break;
                     }
+                    DaylightWebUtil.auditlog("SPAN Port", userName, "removed", cfgObject.getNodeId(), containerName);
                 }
             }
         } catch (Exception e) {
index 4396c95..9444360 100644 (file)
@@ -47,6 +47,7 @@ import com.google.gson.Gson;
 public class Flows implements IDaylightWeb {
     private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
     private static final String WEB_NAME = "Flows";
+
     private static final String WEB_ID = "flows";
     private static final short WEB_ORDER = 2;
 
@@ -237,6 +238,7 @@ public class Flows implements IDaylightWeb {
         Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
         if (action.equals("add")) {
             result = frm.addStaticFlow(flow);
+            DaylightWebUtil.auditlog("Flow", userName, "added", flow.getName(), containerName);
         }
 
         return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result
@@ -270,8 +272,14 @@ public class Flows implements IDaylightWeb {
         }
         if (action.equals("remove")) {
             result = frm.removeStaticFlow(name, node);
+            if(result.isSuccess()) {
+                DaylightWebUtil.auditlog("Flow", userName, "removed", name, containerName);
+            }
         } else if (action.equals("toggle")) {
             result = frm.toggleStaticFlowStatus(name, node);
+            if(result.isSuccess()) {
+                DaylightWebUtil.auditlog("Flow", userName, "toggled", name, containerName);
+            }
         } else {
             result = new Status(StatusCode.BADREQUEST, "Unknown action");
         }
index ba2075d..524cb62 100644 (file)
@@ -30,6 +30,9 @@ import com.google.gson.Gson;
 @Controller
 @RequestMapping("/admin")
 public class DaylightWebAdmin {
+
+
+
     @RequestMapping("/users")
     @ResponseBody
     public List<UserConfig> getUsers() {
@@ -69,7 +72,11 @@ public class DaylightWebAdmin {
 
         Status result = (action.equals("add")) ? userManager
                 .addLocalUser(config) : userManager.removeLocalUser(config);
-
+        if(result.getCode().equals(StatusCode.SUCCESS)) {
+            String userAction=(action.equals("add")) ? "added":"removed";
+            DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), userAction, config.getUser());
+            return "Success";
+        }
         return result.getDescription();
     }
 
@@ -93,7 +100,12 @@ public class DaylightWebAdmin {
             return "Operation not permitted";
         }
 
-        return userManager.removeLocalUser(userName).getDescription();
+        Status result = userManager.removeLocalUser(userName);
+        if(result.getCode().equals(StatusCode.SUCCESS)) {
+            DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "removed", userName);
+            return "Success";
+        }
+        return result.getDescription();
     }
 
     @RequestMapping(value = "/users/password/{username}", method = RequestMethod.POST)
@@ -115,7 +127,9 @@ public class DaylightWebAdmin {
         }
 
         Status status = userManager.changeLocalUserPassword(username, currentPassword, newPassword);
-
+        if(status.isSuccess()){
+            DaylightWebUtil.auditlog("User", request.getUserPrincipal().getName(), "changed password for", username);
+        }
         return status;
     }
 
index ab2abe9..3add0e6 100644 (file)
@@ -5,9 +5,14 @@ import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.usermanager.IUserManager;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class DaylightWebUtil {
 
+    private static final String AUDIT = "audit";
+    private static final Logger logger = LoggerFactory.getLogger(AUDIT);
+
     /**
      * Returns the access privilege the user has on the specified container
      *
@@ -52,4 +57,21 @@ public class DaylightWebUtil {
 
         return Privilege.NONE;
     }
+
+    public static void auditlog(String moduleName, String user, String action, String resource,
+            String containerName) {
+        String auditMsg = "";
+        String mode = "WEB";
+        if (containerName != null) {
+            auditMsg = "Mode: " + mode + " User " + user + " "  + action + " " + moduleName + " " + resource + " in container "
+                    + containerName;
+        } else {
+            auditMsg = "Mode: " + mode + " User " + user + " "  + action + " " + moduleName + " " + resource;
+        }
+        logger.info(auditMsg);
+    }
+
+    public static void auditlog(String moduleName, String user, String action, String resource) {
+        auditlog(moduleName, user, action, resource, null);
+    }
 }
\ No newline at end of file