add persistance of intents to ramcloud

Change-Id: I9a8b5886cf57da0621dc92e341d46c53d252528a
diff --git a/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java b/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java
new file mode 100755
index 0000000..860b6dd
--- /dev/null
+++ b/src/main/java/net/onrc/onos/intent/persist/PersistIntent.java
@@ -0,0 +1,91 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.intent.persist;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import edu.stanford.ramcloud.JRamCloud;
+import java.io.ByteArrayOutputStream;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import net.onrc.onos.datagrid.web.IntentResource;
+import net.onrc.onos.datastore.RCTable;
+import net.onrc.onos.intent.IntentOperationList;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.IdBlock;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class PersistIntent {
+    private final static org.slf4j.Logger log = LoggerFactory.getLogger(IntentResource.class);
+    private final static long range = 10000;
+    private final IControllerRegistryService controllerRegistry;
+    NetworkGraph graph = null;
+    private final String intentJournal = "G:IntentJournal";
+    private RCTable table;
+    private Kryo kryo = new Kryo();
+    private ByteArrayOutputStream stream;
+    private Output output = null;
+    private AtomicLong nextId = null;
+    private long rangeEnd;
+    private IdBlock idBlock = null;
+    
+    
+    public PersistIntent(final IControllerRegistryService controllerRegistry, INetworkGraphService ng) {
+        this.controllerRegistry = controllerRegistry;
+        this.graph = ng.getNetworkGraph();
+        table = RCTable.getTable(intentJournal);
+        stream = new ByteArrayOutputStream();
+        output = new Output(stream);
+    }
+    
+    public long getKey() {
+        long key;
+        if (idBlock == null) {
+            key = getNextBlock();
+        } else {
+            key = nextId.incrementAndGet();
+            if (key >= rangeEnd) {
+                key = getNextBlock();
+            }
+        }
+        return key;
+    }
+    
+    private long getNextBlock() {
+        idBlock = controllerRegistry.allocateUniqueIdBlock(range);
+        nextId = new AtomicLong(idBlock.getStart());
+        rangeEnd = idBlock.getEnd();
+        return nextId.get();
+    }
+    
+    public boolean persistIfLeader(long key, IntentOperationList operations) {
+        boolean leader = true;
+        boolean ret = false;
+        // TODO call controllerRegistry.isClusterLeader()
+        if (leader) {
+            try {
+                System.out.println("persist operations to ramcloud");
+                kryo.writeObject(output, operations);
+                output.close();
+                byte[] buffer = stream.toByteArray();
+                table.create(String.valueOf(key).getBytes(), buffer);
+                System.out.println("key is " + key);
+                ret = true;
+            } catch (JRamCloud.ObjectExistsException ex) {
+                log.warn("Failed to store intent journal with key " + key);
+            }
+        }
+        return ret;
+    }
+}
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
old mode 100644
new mode 100755
index 4c90a23..3a9c607
--- a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
@@ -23,6 +23,8 @@
 import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
 import net.onrc.onos.ofcontroller.networkgraph.PortEvent;
 import net.onrc.onos.ofcontroller.networkgraph.SwitchEvent;
+import net.onrc.onos.intent.persist.PersistIntent;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
 
 /**
  * @author Toshio Koide (t-koide@onlab.us)
@@ -33,8 +35,10 @@
 	private INetworkGraphService networkGraphService;
 	private IntentMap highLevelIntents;
 	private PathIntentMap pathIntents;
+        private IControllerRegistryService controllerRegistry;
+        private PersistIntent persistIntent;
 
-	private IEventChannel<String, IntentOperationList> eventChannel;
+	private IEventChannel<Long, IntentOperationList> eventChannel;
 	private static final String EVENT_CHANNEL_NAME = "onos.pathintent";
 
 	private void reroutePaths(LinkEvent linkEvent) {
@@ -75,6 +79,7 @@
 	public void init(FloodlightModuleContext context) throws FloodlightModuleException {
 		datagridService = context.getServiceImpl(IDatagridService.class);
 		networkGraphService = context.getServiceImpl(INetworkGraphService.class);
+                controllerRegistry = context.getServiceImpl(IControllerRegistryService.class);
 	}
 
 	@Override
@@ -84,19 +89,22 @@
 		pathIntents = new PathIntentMap();
 		eventChannel = datagridService.createChannel(
 				EVENT_CHANNEL_NAME,
-				String.class,
+				Long.class,
 				IntentOperationList.class);
 		networkGraphService.registerNetworkGraphListener(this);
+                persistIntent = new PersistIntent(controllerRegistry, networkGraphService);
+                
 	}
 
 	@Override
 	public IntentOperationList executeIntentOperations(IntentOperationList list) {
 		highLevelIntents.executeOperations(list);
 		IntentOperationList pathIntentOperations = runtime.calcPathIntents(list, pathIntents);
-		String key = "..."; // TODO generate key
+		long key = persistIntent.getKey();
 		System.out.println(pathIntentOperations);
 		pathIntents.executeOperations(pathIntentOperations);
 		eventChannel.addEntry(key, pathIntentOperations);
+                persistIntent.persistIfLeader(key, pathIntentOperations);
 		return pathIntentOperations;
 	}