Skip to content
This repository has been archived by the owner on Aug 19, 2020. It is now read-only.

Commit

Permalink
Merge pull request #108 from erickt/history
Browse files Browse the repository at this point in the history
Initial backend support for dendrite commits to feed into git
  • Loading branch information
erickt committed Mar 26, 2014
2 parents 1b45154 + 7ff88c6 commit 1354923
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 37 deletions.
10 changes: 10 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,13 @@
<artifactId>blueprints-graph-jung</artifactId>
<version>2.4.0</version>
</dependency>

<!-- History dependencies -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>3.2.0.201312181205-r</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down Expand Up @@ -585,6 +592,9 @@
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>${tomcat.url}</url>
<server>${tomcat.server}</server>
<path>/dendrite</path>
<additionalClasspathDirs>
<additionalClasspathDir>${HADOOP_CONF_DIR}</additionalClasspathDir>
</additionalClasspathDirs>
Expand Down
36 changes: 29 additions & 7 deletions src/main/java/org/lab41/dendrite/services/HistoryService.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.lab41.dendrite.metagraph.DendriteGraph;
import org.lab41.dendrite.metagraph.models.ProjectMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -18,7 +22,9 @@
@Service
public class HistoryService {

Logger logger = LoggerFactory.getLogger(HistoryService.class);
private static Logger logger = LoggerFactory.getLogger(HistoryService.class);

private String historyStorage;

@Autowired(required = true)
public HistoryService(@Value("${history.properties}") String pathToProperties, ResourceLoader resourceLoader) throws IOException, ConfigurationException {
Expand All @@ -31,13 +37,29 @@ public HistoryService(@Value("${history.properties}") String pathToProperties, R

// create directory
historyStorage = configuration.getString("history.storage");
File file = new File(historyStorage);
file.mkdirs();
}

public String getHistoryStorage() {
return historyStorage;
// Make sure the directory exists.
new File(historyStorage).mkdirs();
}

private String historyStorage;
public Git projectGitRepository(ProjectMetadata projectMetadata) throws GitAPIException, IOException {
File gitDir = new File(historyStorage, projectMetadata.getId());

// Make the target directory.
Git git;
if (gitDir.exists() && new File(gitDir, ".git").exists()) {
git = Git.open(gitDir);
} else {
logger.debug("Creating git repository: %s", gitDir);

gitDir.mkdirs();

git = Git.init()
.setDirectory(gitDir)
.setBare(false)
.call();
}

return git;
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package org.lab41.dendrite.web.controller;

import org.codehaus.jettison.json.JSONObject;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.NoMessageException;
import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
import org.lab41.dendrite.jobs.BranchCommitJob;
import org.lab41.dendrite.jobs.BranchCommitSubsetJob;
import org.lab41.dendrite.metagraph.DendriteGraph;
import org.lab41.dendrite.metagraph.models.BranchMetadata;
import org.lab41.dendrite.metagraph.models.GraphMetadata;
import org.lab41.dendrite.metagraph.models.JobMetadata;
import org.lab41.dendrite.metagraph.models.ProjectMetadata;
import org.lab41.dendrite.metagraph.MetaGraphTx;
import org.lab41.dendrite.services.HistoryService;
import org.lab41.dendrite.services.MetaGraphService;
import org.lab41.dendrite.web.beans.CreateBranchBean;
import org.lab41.dendrite.web.beans.CreateBranchSubsetNStepsBean;
Expand All @@ -19,6 +22,8 @@
import org.springframework.core.task.TaskExecutor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -27,6 +32,7 @@
import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

Expand All @@ -40,6 +46,9 @@ public class BranchController {
@Autowired
TaskExecutor taskExecutor;

@Autowired
HistoryService historyService;

@RequestMapping(value = "/branches", method = RequestMethod.GET)
public ResponseEntity<Map<String, Object>> getBranches() {

Expand Down Expand Up @@ -87,6 +96,7 @@ public ResponseEntity<Map<String, Object>> deleteBranch(@PathVariable String bra

Map<String, Object> response = new HashMap<>();
MetaGraphTx tx = metaGraphService.newTransaction();

BranchMetadata branchMetadata = tx.getBranch(branchId);

if (branchMetadata == null) {
Expand All @@ -96,19 +106,38 @@ public ResponseEntity<Map<String, Object>> deleteBranch(@PathVariable String bra
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}

String branchName = branchMetadata.getName();

try {
tx.deleteBranch(branchMetadata);

Git git = historyService.projectGitRepository(branchMetadata.getProject());
try {
git.branchDelete()
.setBranchNames(branchName)
.call();
} finally {
git.close();
}

tx.commit();
} catch (Exception e) {
response.put("status", "error");
response.put("msg", e.toString());
tx.rollback();
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

response.put("msg", "deleted");
try {

// Commit must come after all branch access.
tx.commit();
response.put("msg", "deleted");

// Commit must come after all branch access.
tx.commit();
} catch (Throwable t) {
tx.rollback();
throw t;
}

return new ResponseEntity<>(response, HttpStatus.OK);
}
Expand Down Expand Up @@ -176,7 +205,7 @@ public ResponseEntity<Map<String, Object>> getBranch(@PathVariable String projec
public ResponseEntity<Map<String, Object>> createBranch(@PathVariable String projectId,
@PathVariable String branchName,
@Valid @RequestBody CreateBranchBean item,
BindingResult result) {
BindingResult result) throws GitAPIException, IOException {

Map<String, Object> response = new HashMap<>();

Expand Down Expand Up @@ -216,6 +245,15 @@ public ResponseEntity<Map<String, Object>> createBranch(@PathVariable String pro

JobMetadata jobMetadata = tx.createJob(projectMetadata);

Git git = historyService.projectGitRepository(projectMetadata);
try {
git.branchCreate()
.setName(branchName)
.call();
} finally {
git.close();
}

// Commit must come after all branch access.
tx.commit();

Expand Down Expand Up @@ -269,7 +307,7 @@ public ResponseEntity<Map<String, Object>> getCurrentBranch(@PathVariable String
@RequestMapping(value = "/projects/{projectId}/current-branch", method = RequestMethod.PUT)
public ResponseEntity<Map<String, Object>> getCurrentBranch(@PathVariable String projectId,
@Valid @RequestBody UpdateCurrentBranchBean item,
BindingResult result) {
BindingResult result) throws GitAPIException, IOException {

Map<String, Object> response = new HashMap<>();

Expand Down Expand Up @@ -300,6 +338,15 @@ public ResponseEntity<Map<String, Object>> getCurrentBranch(@PathVariable String

projectMetadata.setCurrentBranch(branchMetadata);

Git git = historyService.projectGitRepository(projectMetadata);
try {
git.checkout()
.setName(branchName)
.call();
} finally {
git.close();
}

response.put("msg", "current branch changed");

// Commit must come after all branch access.
Expand All @@ -309,7 +356,9 @@ public ResponseEntity<Map<String, Object>> getCurrentBranch(@PathVariable String
}

@RequestMapping(value = "/projects/{projectId}/current-branch/commit", method = RequestMethod.POST)
public ResponseEntity<Map<String, Object>> commitBranch(@PathVariable String projectId) {
public ResponseEntity<Map<String, Object>> commitBranch(@PathVariable String projectId) throws GitAPIException, IOException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

Map<String, Object> response = new HashMap<>();

MetaGraphTx tx = metaGraphService.newTransaction();
Expand All @@ -332,6 +381,22 @@ public ResponseEntity<Map<String, Object>> commitBranch(@PathVariable String pro

JobMetadata jobMetadata = tx.createJob(projectMetadata);

try {
Git git = historyService.projectGitRepository(projectMetadata);
try {
git.commit()
.setAuthor(authentication.getName(), "")
.setMessage("commit")
.call();
} finally {
git.close();
}

} catch (Throwable t) {
tx.rollback();
throw t;
}

tx.commit();

// We can't pass the values directly because they'll live in a separate thread.
Expand All @@ -350,6 +415,7 @@ public ResponseEntity<Map<String, Object>> commitBranch(@PathVariable String pro
return new ResponseEntity<>(response, HttpStatus.OK);
}

/*
@RequestMapping(value = "/projects/{projectId}/branches/{branchName}/commit", method = RequestMethod.POST)
public ResponseEntity<Map<String, Object>> commitBranch(@PathVariable String projectId,
@PathVariable String branchName) {
Expand Down Expand Up @@ -392,6 +458,7 @@ public ResponseEntity<Map<String, Object>> commitBranch(@PathVariable String pro
return new ResponseEntity<>(response, HttpStatus.OK);
}
*/

@RequestMapping(value = "/projects/{projectId}/current-branch/commit-subset", method = RequestMethod.POST)
public ResponseEntity<Map<String, Object>> commitSubsetBranch(@PathVariable String projectId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@
import com.tinkerpop.blueprints.util.io.graphml.GraphMLWriter;
import com.tinkerpop.blueprints.util.io.graphson.GraphSONWriter;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.lab41.dendrite.metagraph.DendriteGraph;
import org.lab41.dendrite.metagraph.DendriteGraphTx;
import org.lab41.dendrite.metagraph.MetaGraphTx;
import org.lab41.dendrite.metagraph.models.GraphMetadata;
import org.lab41.dendrite.services.HistoryService;
import org.lab41.dendrite.services.MetaGraphService;
import org.lab41.dendrite.web.beans.GraphExportBean;
Expand All @@ -32,6 +36,8 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
Expand Down Expand Up @@ -113,7 +119,8 @@ public ResponseEntity<byte[]> export(@PathVariable String graphId,
@RequestMapping(value = "/api/graphs/{graphId}/file-save", method = RequestMethod.POST)
public ResponseEntity<Map<String, Object>> save(@PathVariable String graphId,
@Valid GraphExportBean item,
BindingResult result) {
BindingResult result) throws IOException, GitAPIException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

Map<String, Object> response = new HashMap<>();

Expand All @@ -123,6 +130,19 @@ public ResponseEntity<Map<String, Object>> save(@PathVariable String graphId,
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}

MetaGraphTx metaGraphTx = metaGraphService.buildTransaction().readOnly().start();
GraphMetadata graphMetadata;
Git git;

try {
graphMetadata = metaGraphTx.getGraph(graphId);
git = historyService.projectGitRepository(graphMetadata.getProject());
metaGraphTx.commit();
} catch (Throwable t) {
metaGraphTx.rollback();
throw t;
}

DendriteGraph graph = metaGraphService.getGraph(graphId);
if (graph == null) {
response.put("status", "error");
Expand All @@ -134,30 +154,40 @@ public ResponseEntity<Map<String, Object>> save(@PathVariable String graphId,

// extract the storage location for the history
String format = item.getFormat();
String projectId = item.getProjectId();
String historyStorageLocation = historyService.getHistoryStorage() + "/" + projectId;

// Make the target directory.
new File(historyStorageLocation).mkdirs();

DendriteGraphTx tx = graph.buildTransaction().readOnly().start();

try {
if (format.equalsIgnoreCase("GraphSON")) {
String path = new File(historyStorageLocation, graphId + ".json").getPath();
GraphSONWriter.outputGraph(tx, path);
} else if (format.equalsIgnoreCase("GraphML")) {
String path = new File(historyStorageLocation, graphId + ".xml").getPath();
GraphMLWriter.outputGraph(tx, path);
} else if (format.equalsIgnoreCase("GML")) {
String path = new File(historyStorageLocation, graphId + ".gml").getPath();
GMLWriter.outputGraph(tx, path);
} else {
tx.rollback();

response.put("status", "error");
response.put("msg", "unknown format '" + format + "'");
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
try {
String path;

if (format.equalsIgnoreCase("GraphSON")) {
path = new File(git.getRepository().getDirectory(), graphId + ".json").getPath();
GraphSONWriter.outputGraph(tx, path);
} else if (format.equalsIgnoreCase("GraphML")) {
path = new File(git.getRepository().getDirectory(), graphId + ".xml").getPath();
GraphMLWriter.outputGraph(tx, path);
} else if (format.equalsIgnoreCase("GML")) {
path = new File(git.getRepository().getDirectory(), graphId + ".gml").getPath();
GMLWriter.outputGraph(tx, path);
} else {
tx.rollback();

response.put("status", "error");
response.put("msg", "unknown format '" + format + "'");
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
}

git.add()
.addFilepattern(".")
.call();

git.commit()
.setAuthor(authentication.getName(), "")
.setMessage("commit")
.call();
} finally {
git.close();
}
} catch (IOException e) {
tx.rollback();
Expand Down

0 comments on commit 1354923

Please sign in to comment.