+
+ private def Future<RpcResult<TransactionStatus>> writeFlowAsync(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow flow, NodeKey nodeKey){
+ val modification = this._dataBrokerService.beginTransaction();
+ val flowPath = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, nodeKey)
+ .augmentation(FlowCapableNode)
+ .child(Table, new TableKey(flow.getTableId()))
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
+ .build;
+ modification.putConfigurationData(flowPath, flow);
+ return modification.commit();
+ }
+
+ private def Future<RpcResult<TransactionStatus>> internalAddFlowAsync(Node node, Flow flow, long rid){
+ var flowId = getCache().get(flow);
+ if(flowId != null) {
+ removeFlow(node, flow);
+ return internalAddFlowAsync(node, flow, rid);
+ }
+
+ flowId = UUID.randomUUID();
+ getCache().put(flow, flowId);
+
+ return writeFlowAsync(flow.toMDFlow(flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString())));
+ }
+
+ private def Future<RpcResult<TransactionStatus>> internalModifyFlowAsync(Node node, Flow oldFlow, Flow newFlow, long rid) {
+ var flowId = getCache().remove(oldFlow);
+ if(flowId == null){
+ LOG.error("oldFlow not found in cache : " + oldFlow.hashCode);
+ flowId = UUID.randomUUID();
+ getCache().put(oldFlow, flowId);
+ }
+
+ getCache().put(newFlow, flowId);
+ return writeFlowAsync(newFlow.toMDFlow(flowId.toString()), new NodeKey(new NodeId(node.getNodeIDString())));
+ }
+
+
+ private def Future<RpcResult<TransactionStatus>> internalRemoveFlowAsync(Node node, Flow adflow, long rid){
+ val flowId = getCache().remove(adflow);
+ if(flowId == null){
+ //throw new IllegalArgumentException("adflow not found in cache : " + adflow.hashCode);
+ LOG.error("adflow not found in cache : " + adflow.hashCode);
+ return null;
+ }
+ val flow = adflow.toMDFlow(flowId.toString());
+ val modification = this._dataBrokerService.beginTransaction();
+ val flowPath = InstanceIdentifier.builder(Nodes)
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node, new NodeKey(new NodeId(node.getNodeIDString())))
+ .augmentation(FlowCapableNode)
+ .child(Table, new TableKey(flow.getTableId()))
+ .child(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow, new FlowKey(flow.id))
+ .build;
+ modification.removeConfigurationData(flowPath);
+ return modification.commit();
+ }
+
+ private def toFutureStatus(Future<RpcResult<TransactionStatus>> future){
+ if(future == null){
+ return toStatus(true);
+ }
+
+ try {
+ val result = future.get();
+ return toStatus(result);
+ } catch (InterruptedException e) {
+ return processException(e);
+ } catch (ExecutionException e) {
+ return processException(e);
+ } catch (Exception e){
+ processException(e);
+ }
+ return toStatus(false);
+ }
+
+ private def Map<Flow, UUID> getCache(){
+ if(clusterGlobalServices == null){
+ return new ConcurrentHashMap<Flow, UUID>();
+ }
+
+ var cache = clusterGlobalServices.getCache(CACHE_NAME);
+
+ if(cache == null) {
+ try {
+ cache = clusterGlobalServices.createCache(CACHE_NAME, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+ } catch (CacheExistException e) {
+ cache = clusterGlobalServices.getCache(CACHE_NAME);
+ }
+ }
+ return cache as Map<Flow, UUID>;
+
+ }
+