Organize intent packages

- Removed unused Intent classes
- Changed package of PersistIntent class from intent.persist to intent.runtime

Change-Id: I5dc72b272e6ad47c41f4ee0493e4a8a7e783fc61
diff --git a/src/main/java/net/onrc/onos/intent/runtime/IntentRuntime.java b/src/main/java/net/onrc/onos/intent/runtime/IntentRuntime.java
deleted file mode 100644
index 567986e..0000000
--- a/src/main/java/net/onrc/onos/intent/runtime/IntentRuntime.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package net.onrc.onos.intent.runtime;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
-
-public class IntentRuntime implements IFloodlightModule {
-    protected volatile IFloodlightProviderService floodlightProvider;
-    protected volatile INetworkGraphService networkGraph;
-    protected volatile IRestApiService restApi;
-
-    @Override
-    public void init(FloodlightModuleContext context)
-	    throws FloodlightModuleException {
-	floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
-	networkGraph = context.getServiceImpl(INetworkGraphService.class);
-	restApi = context.getServiceImpl(IRestApiService.class);
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-	restApi.addRestletRoutable(new IntentWebRoutable());
-    }
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-	Collection<Class<? extends IFloodlightService>> l =
-		new ArrayList<Class<? extends IFloodlightService>>();
-	l.add(IFloodlightProviderService.class);
-	l.add(INetworkGraphService.class);
-	l.add(IRestApiService.class);
-	return l;
-    }
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-	// TODO Auto-generated method stub
-	return null;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-	// TODO Auto-generated method stub
-	return null;
-    }
-
-}
diff --git a/src/main/java/net/onrc/onos/intent/runtime/IntentWebRoutable.java b/src/main/java/net/onrc/onos/intent/runtime/IntentWebRoutable.java
deleted file mode 100644
index 533b55b..0000000
--- a/src/main/java/net/onrc/onos/intent/runtime/IntentWebRoutable.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package net.onrc.onos.intent.runtime;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-public class IntentWebRoutable implements RestletRoutable {
-
-    @Override
-    public Restlet getRestlet(Context context) {
-	Router router = new Router(context);
-	// TODO: add routes
-	return router;
-    }
-
-    @Override
-    public String basePath() {
-	return "/wm/onos/intent";
-    }
-
-}
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
index f93e4ae..e5fded0 100755
--- a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
@@ -29,7 +29,6 @@
 import net.onrc.onos.intent.PathIntent;
 import net.onrc.onos.intent.PathIntentMap;
 import net.onrc.onos.intent.ShortestPathIntent;
-import net.onrc.onos.intent.persist.PersistIntent;
 import net.onrc.onos.ofcontroller.networkgraph.DeviceEvent;
 import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphListener;
 import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PersistIntent.java b/src/main/java/net/onrc/onos/intent/runtime/PersistIntent.java
new file mode 100755
index 0000000..16e6ea4
--- /dev/null
+++ b/src/main/java/net/onrc/onos/intent/runtime/PersistIntent.java
@@ -0,0 +1,129 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package net.onrc.onos.intent.runtime;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.io.Output;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicLong;
+
+import net.onrc.onos.datagrid.web.IntentResource;
+import net.onrc.onos.datastore.DataStoreClient;
+import net.onrc.onos.datastore.IKVTable;
+import net.onrc.onos.datastore.ObjectExistsException;
+import net.onrc.onos.intent.IntentOperationList;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+import net.onrc.onos.ofcontroller.util.serializers.KryoFactory;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+import net.onrc.onos.registry.controller.IdBlock;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author nickkaranatsios
+ */
+public class PersistIntent {
+    private final static Logger log = LoggerFactory.getLogger(IntentResource.class);
+    private long range = 10000L;
+    private final IControllerRegistryService controllerRegistry;
+    NetworkGraph graph = null;
+    private final static String intentJournal = "G:IntentJournal";
+    private final static int valueStoreLimit = 1024 * 1024;
+    private IKVTable table;
+    private Kryo 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 = DataStoreClient.getClient().getTable(intentJournal);
+        stream = new ByteArrayOutputStream(1024);
+        output = new Output(stream);
+        kryo = (new KryoFactory()).newKryo();
+    }
+
+    public long getKey() {
+        long key;
+        if (idBlock == null) {
+            key = getNextBlock();
+        } else {
+            key = nextId.incrementAndGet();
+            if (key >= rangeEnd) {
+                key = getNextBlock();
+            }
+        }
+        return key;
+    }
+
+    private long getNextBlock() {
+        // XXX This method is not thread safe, may lose allocated IdBlock
+        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 {
+                // reserve key 10 entries for multi-write if size over 1MB
+                key *= 10;
+                kryo.writeObject(output, operations);
+                output.close();
+                ByteBuffer keyBytes = ByteBuffer.allocate(8).putLong(key);
+                byte[] buffer = stream.toByteArray();
+                int total = buffer.length;
+                if ((total >= valueStoreLimit )) {
+                    int writeCount = total / valueStoreLimit;
+                    int remainder = total % valueStoreLimit;
+                    int upperIndex = 0;
+                    for (int i = 0; i < writeCount; i++, key++) {
+                        keyBytes.clear();
+                        keyBytes.putLong(key);
+                        keyBytes.flip();
+                        upperIndex = (i * valueStoreLimit + valueStoreLimit) - 1;
+                        log.debug("writing using indexes {}:{}", (i*valueStoreLimit) ,upperIndex);
+                        table.create(keyBytes.array(), Arrays.copyOfRange(buffer, i * valueStoreLimit, upperIndex));
+                    }
+                    if (remainder > 0) {
+                        keyBytes.clear();
+                        keyBytes.putLong(key);
+                        keyBytes.flip();
+                        log.debug("writing using indexes {}:{}" ,upperIndex ,total);
+                        table.create(keyBytes.array(), Arrays.copyOfRange(buffer, upperIndex + 1, total - 1));
+                    }
+                } else {
+                    keyBytes.flip();
+                    table.create(keyBytes.array(), buffer);
+                }
+                log.debug("key is {} value length is {}", key, buffer.length);
+                stream.reset();
+                stream.close();
+                log.debug("persist operations to ramcloud size of operations: {}", operations.size());
+                ret = true;
+            } catch (ObjectExistsException ex) {
+                log.warn("Failed to store intent journal with key " + key);
+            } catch (IOException ex) {
+                log.error("Failed to close the stream");
+            }
+        }
+        return ret;
+    }
+}