diff --git a/services/git-bridge/pom.xml b/services/git-bridge/pom.xml
index a1e87cfdd4..5666ad925b 100644
--- a/services/git-bridge/pom.xml
+++ b/services/git-bridge/pom.xml
@@ -134,5 +134,11 @@
3.10.4
test
+
+
+ org.mockito
+ mockito-core
+ 1.10.19
+
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java
index 9586c7f521..294a5df50a 100644
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/Bridge.java
@@ -2,15 +2,27 @@ package uk.ac.ic.wlgitbridge.bridge;
import com.google.api.client.auth.oauth2.Credential;
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
+import uk.ac.ic.wlgitbridge.bridge.db.DBStore;
+import uk.ac.ic.wlgitbridge.bridge.lock.ProjectLock;
+import uk.ac.ic.wlgitbridge.bridge.repo.RepoStore;
+import uk.ac.ic.wlgitbridge.bridge.resource.ResourceCache;
+import uk.ac.ic.wlgitbridge.bridge.resource.UrlResourceCache;
+import uk.ac.ic.wlgitbridge.bridge.snapshot.NetSnapshotAPI;
+import uk.ac.ic.wlgitbridge.bridge.snapshot.SnapshotAPI;
+import uk.ac.ic.wlgitbridge.bridge.swap.SwapJob;
+import uk.ac.ic.wlgitbridge.bridge.swap.SwapJobImpl;
+import uk.ac.ic.wlgitbridge.bridge.swap.SwapStore;
import uk.ac.ic.wlgitbridge.data.CandidateSnapshot;
-import uk.ac.ic.wlgitbridge.data.ProjectLock;
-import uk.ac.ic.wlgitbridge.data.ShutdownHook;
+import uk.ac.ic.wlgitbridge.data.ProjectLockImpl;
+import uk.ac.ic.wlgitbridge.data.filestore.GitDirectoryContents;
import uk.ac.ic.wlgitbridge.data.filestore.RawDirectory;
-import uk.ac.ic.wlgitbridge.data.model.DataStore;
+import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
+import uk.ac.ic.wlgitbridge.data.model.Snapshot;
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException;
import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocRequest;
import uk.ac.ic.wlgitbridge.snapshot.getdoc.exception.InvalidProjectException;
+import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotAttachment;
import uk.ac.ic.wlgitbridge.snapshot.push.PostbackManager;
import uk.ac.ic.wlgitbridge.snapshot.push.PushRequest;
import uk.ac.ic.wlgitbridge.snapshot.push.PushResult;
@@ -18,29 +30,91 @@ import uk.ac.ic.wlgitbridge.snapshot.push.exception.*;
import uk.ac.ic.wlgitbridge.util.Log;
import java.io.IOException;
+import java.util.*;
/**
* Created by Winston on 16/11/14.
*/
public class Bridge {
- private final DataStore dataStore;
- private final PostbackManager postbackManager;
- private final ProjectLock mainProjectLock;
+ private final ProjectLock lock;
- public Bridge(String rootGitDirectoryPath) {
- dataStore = new DataStore(rootGitDirectoryPath);
- postbackManager = new PostbackManager();
- mainProjectLock = new ProjectLock();
- Runtime.getRuntime().addShutdownHook(new ShutdownHook(mainProjectLock));
+ private final RepoStore repoStore;
+ private final DBStore dbStore;
+ private final SwapStore swapStore;
+
+ private final SnapshotAPI snapshotAPI;
+ private final ResourceCache resourceCache;
+
+ private final SwapJob swapJob;
+
+ private final PostbackManager postbackManager;
+
+ public static Bridge make(
+ RepoStore repoStore,
+ DBStore dbStore,
+ SwapStore swapStore
+ ) {
+ ProjectLock lock = new ProjectLockImpl((int threads) ->
+ Log.info("Waiting for " + threads + " projects...")
+ );
+ return new Bridge(
+ lock,
+ repoStore,
+ dbStore,
+ swapStore,
+ new NetSnapshotAPI(),
+ new UrlResourceCache(dbStore),
+ new SwapJobImpl(
+ lock,
+ repoStore,
+ dbStore,
+ swapStore
+ )
+ );
}
+ Bridge(
+ ProjectLock lock,
+ RepoStore repoStore,
+ DBStore dbStore,
+ SwapStore swapStore,
+ SnapshotAPI snapshotAPI,
+ ResourceCache resourceCache,
+ SwapJob swapJob
+ ) {
+ this.lock = lock;
+ this.repoStore = repoStore;
+ this.dbStore = dbStore;
+ this.swapStore = swapStore;
+ this.snapshotAPI = snapshotAPI;
+ this.resourceCache = resourceCache;
+ this.swapJob = swapJob;
+ postbackManager = new PostbackManager();
+ Runtime.getRuntime().addShutdownHook(new Thread(this::doShutdown));
+ repoStore.purgeNonexistentProjects(dbStore.getProjectNames());
+ }
+
+ void doShutdown() {
+ Log.info("Shutdown received.");
+ Log.info("Stopping SwapJob");
+ swapJob.stop();
+ Log.info("Waiting for projects");
+ lock.lockAll();
+ Log.info("Bye");
+ }
+
+ public void startSwapJob(int intervalMillis) {
+ swapJob.start(intervalMillis);
+ }
+
+ /* TODO: Remove these when WLBridged is moved into RepoStore */
public void lockForProject(String projectName) {
- mainProjectLock.lockForProject(projectName);
+ lock.lockForProject(projectName);
}
public void unlockForProject(String projectName) {
- mainProjectLock.unlockForProject(projectName);
+ lock.unlockForProject(projectName);
}
public boolean repositoryExists(Credential oauth2, String projectName)
@@ -64,7 +138,7 @@ public class Bridge {
) throws IOException,
GitUserException {
Log.info("[{}] Fetching", repo.getProjectName());
- dataStore.updateProjectWithName(oauth2, repo);
+ updateProjectWithName(oauth2, repo);
}
public void
@@ -74,7 +148,7 @@ public class Bridge {
RawDirectory oldDirectoryContents,
String hostname)
throws SnapshotPostException, IOException, ForbiddenException {
- mainProjectLock.lockForProject(projectName);
+ lock.lockForProject(projectName);
CandidateSnapshot candidate = null;
try {
Log.info("[{}] Pushing", projectName);
@@ -85,7 +159,7 @@ public class Bridge {
postbackKey
);
candidate =
- dataStore.createCandidateSnapshot(
+ createCandidateSnapshot(
projectName,
directoryContents,
oldDirectoryContents
@@ -115,7 +189,7 @@ public class Bridge {
projectName,
versionID
);
- dataStore.approveSnapshot(versionID, candidate);
+ approveSnapshot(versionID, candidate);
Log.info(
"[{}] Approved version ID: {}",
projectName,
@@ -152,7 +226,7 @@ public class Bridge {
projectName
);
}
- mainProjectLock.unlockForProject(projectName);
+ lock.unlockForProject(projectName);
}
}
@@ -190,4 +264,100 @@ public class Bridge {
);
}
+ /* PRIVATE */
+
+ private void updateProjectWithName(
+ Credential oauth2,
+ ProjectRepo repo
+ ) throws IOException, GitUserException {
+ String projectName = repo.getProjectName();
+ Deque snapshots =
+ snapshotAPI.getSnapshotsForProjectAfterVersion(
+ oauth2,
+ projectName,
+ dbStore.getLatestVersionForProject(projectName)
+ );
+
+ makeCommitsFromSnapshots(repo, snapshots);
+
+ if (!snapshots.isEmpty()) {
+ dbStore.setLatestVersionForProject(
+ projectName,
+ snapshots.getLast().getVersionID()
+ );
+ }
+ }
+
+ private void makeCommitsFromSnapshots(ProjectRepo repo,
+ Collection snapshots)
+ throws IOException, GitUserException {
+ String name = repo.getProjectName();
+ for (Snapshot snapshot : snapshots) {
+ Map fileTable = repo.getFiles();
+ List files = new LinkedList<>();
+ files.addAll(snapshot.getSrcs());
+ Map fetchedUrls = new HashMap<>();
+ for (SnapshotAttachment snapshotAttachment : snapshot.getAtts()) {
+ files.add(
+ resourceCache.get(
+ name,
+ snapshotAttachment.getUrl(),
+ snapshotAttachment.getPath(),
+ fileTable,
+ fetchedUrls
+ )
+ );
+ }
+ Log.info(
+ "[{}] Committing version ID: {}",
+ name,
+ snapshot.getVersionID()
+ );
+ Collection missingFiles = repo.commitAndGetMissing(
+ new GitDirectoryContents(
+ files,
+ repoStore.getRootDirectory(),
+ name,
+ snapshot
+ )
+ );
+ dbStore.deleteFilesForProject(
+ name,
+ missingFiles.toArray(new String[missingFiles.size()])
+ );
+ }
+ }
+
+ private CandidateSnapshot createCandidateSnapshot(
+ String projectName,
+ RawDirectory directoryContents,
+ RawDirectory oldDirectoryContents
+ ) throws IOException {
+ CandidateSnapshot candidateSnapshot = new CandidateSnapshot(
+ projectName,
+ dbStore.getLatestVersionForProject(projectName),
+ directoryContents,
+ oldDirectoryContents
+ );
+ candidateSnapshot.writeServletFiles(repoStore.getRootDirectory());
+ return candidateSnapshot;
+ }
+
+ private void approveSnapshot(
+ int versionID,
+ CandidateSnapshot candidateSnapshot
+ ) {
+ List deleted = candidateSnapshot.getDeleted();
+ dbStore.setLatestVersionForProject(
+ candidateSnapshot.getProjectName(),
+ versionID
+ );
+ dbStore.deleteFilesForProject(
+ candidateSnapshot.getProjectName(),
+ deleted.toArray(new String[deleted.size()])
+ );
+ }
+
+
+
}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WLBridgedProject.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WLBridgedProject.java
index 7afc1bff9f..7040d11373 100644
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WLBridgedProject.java
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WLBridgedProject.java
@@ -40,7 +40,12 @@ public class WLBridgedProject {
}
}
- private void updateRepositoryFromSnapshots(Credential oauth2, Repository repository) throws RepositoryNotFoundException, ServiceMayNotContinueException, GitUserException {
+ private void updateRepositoryFromSnapshots(
+ Credential oauth2,
+ Repository repository
+ ) throws RepositoryNotFoundException,
+ ServiceMayNotContinueException,
+ GitUserException {
try {
bridgeAPI.getWritableRepositories(
oauth2,
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/DBStore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/DBStore.java
new file mode 100644
index 0000000000..33075444cf
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/DBStore.java
@@ -0,0 +1,22 @@
+package uk.ac.ic.wlgitbridge.bridge.db;
+
+import java.util.List;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public interface DBStore {
+
+ List getProjectNames();
+
+ void setLatestVersionForProject(String project, int versionID);
+
+ int getLatestVersionForProject(String project);
+
+ void addURLIndexForProject(String projectName, String url, String path);
+
+ void deleteFilesForProject(String project, String... files);
+
+ String getPathForURLInProject(String projectName, String url);
+
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/db/SqlitePersistentStore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/SqliteDBStore.java
similarity index 89%
rename from services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/db/SqlitePersistentStore.java
rename to services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/SqliteDBStore.java
index 40b5d53ca9..4838479b8d 100644
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/db/SqlitePersistentStore.java
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/db/SqliteDBStore.java
@@ -1,4 +1,4 @@
-package uk.ac.ic.wlgitbridge.data.model.db;
+package uk.ac.ic.wlgitbridge.bridge.db;
import uk.ac.ic.wlgitbridge.data.model.db.sql.SQLiteWLDatabase;
import uk.ac.ic.wlgitbridge.util.Log;
@@ -9,15 +9,15 @@ import java.util.Arrays;
import java.util.List;
/**
- * Created by Winston on 19/11/14.
+ * Created by winston on 20/08/2016.
*/
-public class SqlitePersistentStore implements PersistentStore {
+public class SqliteDBStore implements DBStore {
private final SQLiteWLDatabase database;
- public SqlitePersistentStore(File rootGitDirectory) {
+ public SqliteDBStore(File rootDirectory) {
try {
- database = new SQLiteWLDatabase(rootGitDirectory);
+ database = new SQLiteWLDatabase(rootDirectory);
} catch (SQLException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/lock/ProjectLock.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/lock/ProjectLock.java
new file mode 100644
index 0000000000..a8157e86b6
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/lock/ProjectLock.java
@@ -0,0 +1,12 @@
+package uk.ac.ic.wlgitbridge.bridge.lock;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public interface ProjectLock {
+ void lockAll();
+
+ void lockForProject(String projectName);
+
+ void unlockForProject(String projectName);
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/FSRepoStore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/FSRepoStore.java
new file mode 100644
index 0000000000..8f431fce07
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/FSRepoStore.java
@@ -0,0 +1,52 @@
+package uk.ac.ic.wlgitbridge.bridge.repo;
+
+import uk.ac.ic.wlgitbridge.util.Util;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public class FSRepoStore implements RepoStore {
+
+ private final String repoStorePath;
+ private final File rootDirectory;
+
+ public FSRepoStore(String repoStorePath) {
+ this.repoStorePath = repoStorePath;
+ rootDirectory = initRootGitDirectory(repoStorePath);
+ }
+
+ @Override
+ public String getRepoStorePath() {
+ return repoStorePath;
+ }
+
+ @Override
+ public File getRootDirectory() {
+ return rootDirectory;
+ }
+
+ @Override
+ public void purgeNonexistentProjects(
+ Collection existingProjectNames
+ ) {
+ List excludedFromDeletion =
+ new ArrayList<>(existingProjectNames);
+ excludedFromDeletion.add(".wlgb");
+ Util.deleteInDirectoryApartFrom(
+ rootDirectory,
+ excludedFromDeletion.toArray(new String[] {})
+ );
+ }
+
+ private File initRootGitDirectory(String rootGitDirectoryPath) {
+ File rootGitDirectory = new File(rootGitDirectoryPath);
+ rootGitDirectory.mkdirs();
+ return rootGitDirectory;
+ }
+
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/RepoStore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/RepoStore.java
new file mode 100644
index 0000000000..9d9d6482d7
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/repo/RepoStore.java
@@ -0,0 +1,22 @@
+package uk.ac.ic.wlgitbridge.bridge.repo;
+
+import uk.ac.ic.wlgitbridge.bridge.db.DBStore;
+
+import java.io.File;
+import java.util.Collection;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public interface RepoStore {
+
+ String getRepoStorePath();
+
+ File getRootDirectory();
+
+
+ void purgeNonexistentProjects(
+ Collection existingProjectNames
+ );
+
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/resource/ResourceCache.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/resource/ResourceCache.java
new file mode 100644
index 0000000000..cd57b57896
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/resource/ResourceCache.java
@@ -0,0 +1,13 @@
+package uk.ac.ic.wlgitbridge.bridge.resource;
+
+import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public interface ResourceCache {
+ RawFile get(String projectName, String url, String newPath, Map fileTable, Map fetchedUrls) throws IOException;
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/resource/UrlResourceCache.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/resource/UrlResourceCache.java
new file mode 100644
index 0000000000..aee7ee9730
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/resource/UrlResourceCache.java
@@ -0,0 +1,107 @@
+package uk.ac.ic.wlgitbridge.bridge.resource;
+
+import com.ning.http.client.AsyncCompletionHandler;
+import com.ning.http.client.HttpResponseBodyPart;
+import com.ning.http.client.Response;
+import uk.ac.ic.wlgitbridge.bridge.db.DBStore;
+import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
+import uk.ac.ic.wlgitbridge.data.filestore.RepositoryFile;
+import uk.ac.ic.wlgitbridge.snapshot.base.Request;
+import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException;
+import uk.ac.ic.wlgitbridge.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public class UrlResourceCache implements ResourceCache {
+
+ private final DBStore dbStore;
+
+ public UrlResourceCache(DBStore dbStore) {
+ this.dbStore = dbStore;
+ }
+
+ @Override
+ public RawFile get(String projectName, String url, String newPath, Map fileTable, Map fetchedUrls) throws IOException {
+ String path = dbStore.getPathForURLInProject(projectName, url);
+ byte[] contents;
+ if (path == null) {
+ path = newPath;
+ contents = fetch(projectName, url, path);
+ fetchedUrls.put(url, contents);
+ } else {
+ Log.info("Found (" + projectName + "): " + url);
+ Log.info("At (" + projectName + "): " + path);
+ contents = fetchedUrls.get(url);
+ if (contents == null) {
+ RawFile rawFile = fileTable.get(path);
+ if (rawFile == null) {
+ Log.warn(
+ "File " + path + " was not in the current commit, or the git tree, yet path was not null. " +
+ "File url is: " + url
+ );
+ contents = fetch(projectName, url, path);
+ } else {
+ contents = rawFile.getContents();
+ }
+ }
+ }
+ return new RepositoryFile(newPath, contents);
+ }
+
+ private byte[] fetch(String projectName, final String url, String path) throws FailedConnectionException {
+ byte[] contents;
+ Log.info("GET -> " + url);
+ try {
+ contents = Request.httpClient.prepareGet(url).execute(new AsyncCompletionHandler() {
+
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+
+ @Override
+ public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
+ bytes.write(bodyPart.getBodyPartBytes());
+ return STATE.CONTINUE;
+ }
+
+ @Override
+ public byte[] onCompleted(Response response) throws Exception {
+ byte[] data = bytes.toByteArray();
+ bytes.close();
+ Log.info(response.getStatusCode() + " " + response.getStatusText() + " (" + data.length + "B) -> " + url);
+ return data;
+ }
+
+ }).get();
+ } catch (InterruptedException e) {
+ Log.warn(
+ "Interrupted when fetching project: " +
+ projectName +
+ ", url: " +
+ url +
+ ", path: " +
+ path,
+ e
+ );
+ throw new FailedConnectionException();
+ } catch (ExecutionException e) {
+ Log.warn(
+ "ExecutionException when fetching project: " +
+ projectName +
+ ", url: " +
+ url +
+ ", path: " +
+ path,
+ e
+ );
+ throw new FailedConnectionException();
+ }
+ dbStore.addURLIndexForProject(projectName, url, path);
+ return contents;
+ }
+
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/NetSnapshotAPI.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/NetSnapshotAPI.java
new file mode 100644
index 0000000000..34540e6eea
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/NetSnapshotAPI.java
@@ -0,0 +1,79 @@
+package uk.ac.ic.wlgitbridge.bridge.snapshot;
+
+import com.google.api.client.auth.oauth2.Credential;
+import uk.ac.ic.wlgitbridge.data.model.Snapshot;
+import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
+import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException;
+import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException;
+import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocRequest;
+import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult;
+import uk.ac.ic.wlgitbridge.snapshot.getforversion.GetForVersionRequest;
+import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotData;
+import uk.ac.ic.wlgitbridge.snapshot.getsavedvers.GetSavedVersRequest;
+import uk.ac.ic.wlgitbridge.snapshot.getsavedvers.SnapshotInfo;
+
+import java.util.*;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public class NetSnapshotAPI implements SnapshotAPI {
+
+ @Override
+ public Deque getSnapshotsForProjectAfterVersion(Credential oauth2, String projectName, int version) throws FailedConnectionException, GitUserException {
+ List snapshotInfos = getSnapshotInfosAfterVersion(oauth2, projectName, version);
+ List snapshotDatas = getMatchingSnapshotData(oauth2, projectName, snapshotInfos);
+ LinkedList snapshots = combine(snapshotInfos, snapshotDatas);
+ return snapshots;
+ }
+
+ private List getSnapshotInfosAfterVersion(Credential oauth2, String projectName, int version) throws FailedConnectionException, GitUserException {
+ SortedSet versions = new TreeSet();
+ GetDocRequest getDoc = new GetDocRequest(oauth2, projectName);
+ GetSavedVersRequest getSavedVers = new GetSavedVersRequest(oauth2, projectName);
+ getDoc.request();
+ getSavedVers.request();
+ GetDocResult latestDoc = getDoc.getResult();
+ int latest = latestDoc.getVersionID();
+ if (latest > version) {
+ for (SnapshotInfo snapshotInfo : getSavedVers.getResult().getSavedVers()) {
+ if (snapshotInfo.getVersionId() > version) {
+ versions.add(snapshotInfo);
+ }
+ }
+ versions.add(new SnapshotInfo(latest, latestDoc.getCreatedAt(), latestDoc.getName(), latestDoc.getEmail()));
+
+ }
+ return new LinkedList(versions);
+ }
+
+ private List getMatchingSnapshotData(Credential oauth2, String projectName, List snapshotInfos) throws FailedConnectionException, ForbiddenException {
+ List firedRequests = fireDataRequests(oauth2, projectName, snapshotInfos);
+ List snapshotDataList = new LinkedList();
+ for (GetForVersionRequest fired : firedRequests) {
+ snapshotDataList.add(fired.getResult().getSnapshotData());
+ }
+ return snapshotDataList;
+ }
+
+ private List fireDataRequests(Credential oauth2, String projectName, List snapshotInfos) {
+ List requests = new LinkedList();
+ for (SnapshotInfo snapshotInfo : snapshotInfos) {
+ GetForVersionRequest request = new GetForVersionRequest(oauth2, projectName, snapshotInfo.getVersionId());
+ requests.add(request);
+ request.request();
+ }
+ return requests;
+ }
+
+ private LinkedList combine(List snapshotInfos, List snapshotDatas) {
+ LinkedList snapshots = new LinkedList();
+ Iterator infos = snapshotInfos.iterator();
+ Iterator datas = snapshotDatas.iterator();
+ while (infos.hasNext()) {
+ snapshots.add(new Snapshot(infos.next(), datas.next()));
+ }
+ return snapshots;
+ }
+
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotAPI.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotAPI.java
new file mode 100644
index 0000000000..d2c1cbc435
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/snapshot/SnapshotAPI.java
@@ -0,0 +1,21 @@
+package uk.ac.ic.wlgitbridge.bridge.snapshot;
+
+import com.google.api.client.auth.oauth2.Credential;
+import uk.ac.ic.wlgitbridge.data.model.Snapshot;
+import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
+import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException;
+
+import java.util.Deque;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public interface SnapshotAPI {
+
+ Deque getSnapshotsForProjectAfterVersion(
+ Credential oauth2,
+ String projectName,
+ int latestVersion
+ ) throws FailedConnectionException, GitUserException;
+
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapJob.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapJob.java
new file mode 100644
index 0000000000..04a52e4108
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapJob.java
@@ -0,0 +1,12 @@
+package uk.ac.ic.wlgitbridge.bridge.swap;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public interface SwapJob {
+
+ void start(int intervalMillis);
+
+ void stop();
+
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapJobImpl.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapJobImpl.java
new file mode 100644
index 0000000000..ea26962dd5
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapJobImpl.java
@@ -0,0 +1,53 @@
+package uk.ac.ic.wlgitbridge.bridge.swap;
+
+import uk.ac.ic.wlgitbridge.bridge.db.DBStore;
+import uk.ac.ic.wlgitbridge.bridge.lock.ProjectLock;
+import uk.ac.ic.wlgitbridge.bridge.repo.RepoStore;
+import uk.ac.ic.wlgitbridge.util.Util;
+
+import java.util.Timer;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public class SwapJobImpl implements SwapJob {
+
+ private final ProjectLock lock;
+ private final RepoStore repoStore;
+ private final SwapStore swapStore;
+ private final DBStore dbStore;
+
+ private final Timer timer;
+
+ public SwapJobImpl(
+ ProjectLock lock,
+ RepoStore repoStore,
+ DBStore dbStore, SwapStore swapStore
+ ) {
+
+ this.lock = lock;
+ this.repoStore = repoStore;
+ this.swapStore = swapStore;
+ this.dbStore = dbStore;
+ timer = new Timer();
+ }
+
+ @Override
+ public void start(int intervalMillis) {
+ timer.scheduleAtFixedRate(
+ Util.makeTimerTask(this::doSwap),
+ 0,
+ intervalMillis
+ );
+ }
+
+ @Override
+ public void stop() {
+ timer.cancel();
+ }
+
+ private void doSwap() {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapStore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapStore.java
new file mode 100644
index 0000000000..d230de00ad
--- /dev/null
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/swap/SwapStore.java
@@ -0,0 +1,7 @@
+package uk.ac.ic.wlgitbridge.bridge.swap;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public interface SwapStore {
+}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ProjectLock.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ProjectLockImpl.java
similarity index 87%
rename from services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ProjectLock.java
rename to services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ProjectLockImpl.java
index 7ae5b09839..803ba89e9f 100644
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ProjectLock.java
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ProjectLockImpl.java
@@ -1,5 +1,7 @@
package uk.ac.ic.wlgitbridge.data;
+import uk.ac.ic.wlgitbridge.bridge.lock.ProjectLock;
+
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
@@ -9,7 +11,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Created by Winston on 20/11/14.
*/
-public class ProjectLock {
+public class ProjectLockImpl implements ProjectLock {
private final Map projectLocks;
private final ReentrantReadWriteLock rwlock;
@@ -18,7 +20,7 @@ public class ProjectLock {
private LockAllWaiter waiter;
private boolean waiting;
- public ProjectLock() {
+ public ProjectLockImpl() {
projectLocks = new HashMap();
rwlock = new ReentrantReadWriteLock();
rlock = rwlock.readLock();
@@ -26,6 +28,11 @@ public class ProjectLock {
waiting = false;
}
+ public ProjectLockImpl(LockAllWaiter waiter) {
+ this();
+ setWaiter(waiter);
+ }
+
public void lockForProject(String projectName) {
getLockForProjectName(projectName).lock();
rlock.lock();
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ShutdownHook.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ShutdownHook.java
deleted file mode 100644
index 9b7b6b247b..0000000000
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/ShutdownHook.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package uk.ac.ic.wlgitbridge.data;
-
-import uk.ac.ic.wlgitbridge.util.Log;
-
-/**
- * Created by Winston on 21/02/15.
- */
-public class ShutdownHook extends Thread implements LockAllWaiter {
-
- private final ProjectLock projectLock;
-
- public ShutdownHook(ProjectLock projectLock) {
- this.projectLock = projectLock;
- projectLock.setWaiter(this);
- }
-
- @Override
- public void run() {
- Log.info("Shutdown received.");
- projectLock.lockAll();
- Log.info("No projects to wait for.");
- Log.info("Bye");
- }
-
- @Override
- public void threadsRemaining(int threads) {
- Log.info("Waiting for " + threads + " projects...");
- }
-
-}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/SnapshotFetcher.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/SnapshotFetcher.java
index 532411489d..32c68776c7 100644
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/SnapshotFetcher.java
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/SnapshotFetcher.java
@@ -1,78 +1,10 @@
package uk.ac.ic.wlgitbridge.data;
-import com.google.api.client.auth.oauth2.Credential;
-import uk.ac.ic.wlgitbridge.data.model.Snapshot;
-import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
-import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException;
-import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocRequest;
-import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult;
-import uk.ac.ic.wlgitbridge.snapshot.getforversion.GetForVersionRequest;
-import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotData;
-import uk.ac.ic.wlgitbridge.snapshot.getsavedvers.GetSavedVersRequest;
-import uk.ac.ic.wlgitbridge.snapshot.getsavedvers.SnapshotInfo;
-
-import java.util.*;
-
/**
* Created by Winston on 07/11/14.
*/
public class SnapshotFetcher {
- public LinkedList getSnapshotsForProjectAfterVersion(Credential oauth2, String projectName, int version) throws FailedConnectionException, GitUserException {
- List snapshotInfos = getSnapshotInfosAfterVersion(oauth2, projectName, version);
- List snapshotDatas = getMatchingSnapshotData(oauth2, projectName, snapshotInfos);
- LinkedList snapshots = combine(snapshotInfos, snapshotDatas);
- return snapshots;
- }
- private List getSnapshotInfosAfterVersion(Credential oauth2, String projectName, int version) throws FailedConnectionException, GitUserException {
- SortedSet versions = new TreeSet();
- GetDocRequest getDoc = new GetDocRequest(oauth2, projectName);
- GetSavedVersRequest getSavedVers = new GetSavedVersRequest(oauth2, projectName);
- getDoc.request();
- getSavedVers.request();
- GetDocResult latestDoc = getDoc.getResult();
- int latest = latestDoc.getVersionID();
- if (latest > version) {
- for (SnapshotInfo snapshotInfo : getSavedVers.getResult().getSavedVers()) {
- if (snapshotInfo.getVersionId() > version) {
- versions.add(snapshotInfo);
- }
- }
- versions.add(new SnapshotInfo(latest, latestDoc.getCreatedAt(), latestDoc.getName(), latestDoc.getEmail()));
-
- }
- return new LinkedList(versions);
- }
-
- private List getMatchingSnapshotData(Credential oauth2, String projectName, List snapshotInfos) throws FailedConnectionException, ForbiddenException {
- List firedRequests = fireDataRequests(oauth2, projectName, snapshotInfos);
- List snapshotDataList = new LinkedList();
- for (GetForVersionRequest fired : firedRequests) {
- snapshotDataList.add(fired.getResult().getSnapshotData());
- }
- return snapshotDataList;
- }
-
- private List fireDataRequests(Credential oauth2, String projectName, List snapshotInfos) {
- List requests = new LinkedList();
- for (SnapshotInfo snapshotInfo : snapshotInfos) {
- GetForVersionRequest request = new GetForVersionRequest(oauth2, projectName, snapshotInfo.getVersionId());
- requests.add(request);
- request.request();
- }
- return requests;
- }
-
- private LinkedList combine(List snapshotInfos, List snapshotDatas) {
- LinkedList snapshots = new LinkedList();
- Iterator infos = snapshotInfos.iterator();
- Iterator datas = snapshotDatas.iterator();
- while (infos.hasNext()) {
- snapshots.add(new Snapshot(infos.next(), datas.next()));
- }
- return snapshots;
- }
}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/DataStore.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/DataStore.java
deleted file mode 100644
index 302edaa9ff..0000000000
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/DataStore.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package uk.ac.ic.wlgitbridge.data.model;
-
-import com.google.api.client.auth.oauth2.Credential;
-import uk.ac.ic.wlgitbridge.bridge.ProjectRepo;
-import uk.ac.ic.wlgitbridge.data.CandidateSnapshot;
-import uk.ac.ic.wlgitbridge.data.SnapshotFetcher;
-import uk.ac.ic.wlgitbridge.data.filestore.GitDirectoryContents;
-import uk.ac.ic.wlgitbridge.data.filestore.RawDirectory;
-import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
-import uk.ac.ic.wlgitbridge.data.model.db.PersistentStore;
-import uk.ac.ic.wlgitbridge.data.model.db.SqlitePersistentStore;
-import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
-import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotAttachment;
-import uk.ac.ic.wlgitbridge.snapshot.push.exception.SnapshotPostException;
-import uk.ac.ic.wlgitbridge.util.Log;
-import uk.ac.ic.wlgitbridge.util.Util;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
-/**
- * Created by Winston on 06/11/14.
- */
-public class DataStore {
-
- private final File rootGitDirectory;
- private final PersistentStore persistentStore;
- private final SnapshotFetcher snapshotFetcher;
- private final ResourceFetcher resourceFetcher;
-
- public DataStore(String rootGitDirectoryPath) {
- rootGitDirectory = initRootGitDirectory(rootGitDirectoryPath);
- persistentStore = new SqlitePersistentStore(rootGitDirectory);
- List excludedFromDeletion = persistentStore.getProjectNames();
- excludedFromDeletion.add(".wlgb");
- Util.deleteInDirectoryApartFrom(
- rootGitDirectory,
- excludedFromDeletion.toArray(new String[] {})
- );
-
- snapshotFetcher = new SnapshotFetcher();
- resourceFetcher = new ResourceFetcher(persistentStore);
- }
-
- public void updateProjectWithName(
- Credential oauth2,
- ProjectRepo repo
- ) throws IOException, GitUserException {
- String projectName = repo.getProjectName();
- LinkedList snapshots =
- snapshotFetcher.getSnapshotsForProjectAfterVersion(
- oauth2,
- projectName,
- persistentStore.getLatestVersionForProject(projectName)
- );
-
- makeCommitsFromSnapshots(repo, snapshots);
-
- if (!snapshots.isEmpty()) {
- persistentStore.setLatestVersionForProject(
- projectName,
- snapshots.getLast().getVersionID()
- );
- }
- }
-
- private void makeCommitsFromSnapshots(ProjectRepo repo,
- List snapshots)
- throws IOException, GitUserException {
- String name = repo.getProjectName();
- for (Snapshot snapshot : snapshots) {
- Map fileTable = repo.getFiles();
- List files = new LinkedList<>();
- files.addAll(snapshot.getSrcs());
- Map fetchedUrls = new HashMap<>();
- for (SnapshotAttachment snapshotAttachment : snapshot.getAtts()) {
- files.add(
- resourceFetcher.get(
- name,
- snapshotAttachment.getUrl(),
- snapshotAttachment.getPath(),
- fileTable,
- fetchedUrls
- )
- );
- }
- Log.info(
- "[{}] Committing version ID: {}",
- name,
- snapshot.getVersionID()
- );
- Collection missingFiles = repo.commitAndGetMissing(
- new GitDirectoryContents(
- files,
- rootGitDirectory,
- name,
- snapshot
- )
- );
- persistentStore.deleteFilesForProject(
- name,
- missingFiles.toArray(new String[missingFiles.size()])
- );
- }
- }
-
- public CandidateSnapshot createCandidateSnapshot(
- String projectName,
- RawDirectory directoryContents,
- RawDirectory oldDirectoryContents
- ) throws SnapshotPostException,
- IOException {
- CandidateSnapshot candidateSnapshot = new CandidateSnapshot(
- projectName,
- persistentStore.getLatestVersionForProject(projectName),
- directoryContents,
- oldDirectoryContents
- );
- candidateSnapshot.writeServletFiles(rootGitDirectory);
- return candidateSnapshot;
- }
-
- public void approveSnapshot(int versionID,
- CandidateSnapshot candidateSnapshot) {
- List deleted = candidateSnapshot.getDeleted();
- persistentStore.setLatestVersionForProject(
- candidateSnapshot.getProjectName(),
- versionID
- );
- persistentStore.deleteFilesForProject(
- candidateSnapshot.getProjectName(),
- deleted.toArray(new String[deleted.size()])
- );
- }
-
- private File initRootGitDirectory(String rootGitDirectoryPath) {
- File rootGitDirectory = new File(rootGitDirectoryPath);
- rootGitDirectory.mkdirs();
- return rootGitDirectory;
- }
-
-}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/ResourceFetcher.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/ResourceFetcher.java
index a689cf7153..26e315a5c9 100644
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/ResourceFetcher.java
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/data/model/ResourceFetcher.java
@@ -1,105 +1,9 @@
package uk.ac.ic.wlgitbridge.data.model;
-import com.ning.http.client.AsyncCompletionHandler;
-import com.ning.http.client.HttpResponseBodyPart;
-import com.ning.http.client.Response;
-import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
-import uk.ac.ic.wlgitbridge.data.filestore.RepositoryFile;
-import uk.ac.ic.wlgitbridge.data.model.db.PersistentStore;
-import uk.ac.ic.wlgitbridge.snapshot.base.Request;
-import uk.ac.ic.wlgitbridge.snapshot.exception.FailedConnectionException;
-import uk.ac.ic.wlgitbridge.util.Log;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-
/**
* Created by Winston on 21/02/15.
*/
public class ResourceFetcher {
- private final PersistentStore persistentStore;
- public ResourceFetcher(PersistentStore persistentStore) {
- this.persistentStore = persistentStore;
- }
-
- public RawFile get(String projectName, String url, String newPath, Map fileTable, Map fetchedUrls) throws IOException {
- String path = persistentStore.getPathForURLInProject(projectName, url);
- byte[] contents;
- if (path == null) {
- path = newPath;
- contents = fetch(projectName, url, path);
- fetchedUrls.put(url, contents);
- } else {
- Log.info("Found (" + projectName + "): " + url);
- Log.info("At (" + projectName + "): " + path);
- contents = fetchedUrls.get(url);
- if (contents == null) {
- RawFile rawFile = fileTable.get(path);
- if (rawFile == null) {
- Log.warn(
- "File " + path + " was not in the current commit, or the git tree, yet path was not null. " +
- "File url is: " + url
- );
- contents = fetch(projectName, url, path);
- } else {
- contents = rawFile.getContents();
- }
- }
- }
- return new RepositoryFile(newPath, contents);
- }
-
- private byte[] fetch(String projectName, final String url, String path) throws FailedConnectionException {
- byte[] contents;
- Log.info("GET -> " + url);
- try {
- contents = Request.httpClient.prepareGet(url).execute(new AsyncCompletionHandler() {
-
- ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-
- @Override
- public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
- bytes.write(bodyPart.getBodyPartBytes());
- return STATE.CONTINUE;
- }
-
- @Override
- public byte[] onCompleted(Response response) throws Exception {
- byte[] data = bytes.toByteArray();
- bytes.close();
- Log.info(response.getStatusCode() + " " + response.getStatusText() + " (" + data.length + "B) -> " + url);
- return data;
- }
-
- }).get();
- } catch (InterruptedException e) {
- Log.warn(
- "Interrupted when fetching project: " +
- projectName +
- ", url: " +
- url +
- ", path: " +
- path,
- e
- );
- throw new FailedConnectionException();
- } catch (ExecutionException e) {
- Log.warn(
- "ExecutionException when fetching project: " +
- projectName +
- ", url: " +
- url +
- ", path: " +
- path,
- e
- );
- throw new FailedConnectionException();
- }
- persistentStore.addURLIndexForProject(projectName, url, path);
- return contents;
- }
}
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/GitBridgeServer.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/GitBridgeServer.java
index dd4a8c671f..739fa9130f 100644
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/GitBridgeServer.java
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/server/GitBridgeServer.java
@@ -9,6 +9,11 @@ import org.eclipse.jetty.servlet.ServletHolder;
import uk.ac.ic.wlgitbridge.application.config.Config;
import uk.ac.ic.wlgitbridge.application.jetty.NullLogger;
import uk.ac.ic.wlgitbridge.bridge.Bridge;
+import uk.ac.ic.wlgitbridge.bridge.db.DBStore;
+import uk.ac.ic.wlgitbridge.bridge.db.SqliteDBStore;
+import uk.ac.ic.wlgitbridge.bridge.repo.FSRepoStore;
+import uk.ac.ic.wlgitbridge.bridge.repo.RepoStore;
+import uk.ac.ic.wlgitbridge.bridge.swap.SwapStore;
import uk.ac.ic.wlgitbridge.git.exception.InvalidRootDirectoryPathException;
import uk.ac.ic.wlgitbridge.git.servlet.WLGitServlet;
import uk.ac.ic.wlgitbridge.snapshot.base.SnapshotAPIRequest;
@@ -43,7 +48,14 @@ public class GitBridgeServer {
org.eclipse.jetty.util.log.Log.setLog(new NullLogger());
this.port = config.getPort();
this.rootGitDirectoryPath = config.getRootGitDirectory();
- bridgeAPI = new Bridge(rootGitDirectoryPath);
+ RepoStore repoStore = new FSRepoStore(rootGitDirectoryPath);
+ DBStore dbStore = new SqliteDBStore(repoStore.getRootDirectory());
+ SwapStore swapStore = new SwapStore() {};
+ bridgeAPI = Bridge.make(
+ repoStore,
+ dbStore,
+ swapStore
+ );
jettyServer = new Server(port);
configureJettyServer(config);
SnapshotAPIRequest.setBasicAuth(config.getUsername(), config.getPassword());
diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/util/Util.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/util/Util.java
index 97440a9ff5..3654561f9f 100644
--- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/util/Util.java
+++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/util/Util.java
@@ -19,6 +19,15 @@ public class Util {
private static String POSTBACK_URL;
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSS");
+ public static TimerTask makeTimerTask(Runnable lamb) {
+ return new TimerTask() {
+ @Override
+ public void run() {
+ lamb.run();
+ }
+ };
+ }
+
public static String entries(int entries) {
if (entries == 1) {
return "entry";
diff --git a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/bridge/BridgeTest.java b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/bridge/BridgeTest.java
new file mode 100644
index 0000000000..68236e3735
--- /dev/null
+++ b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/bridge/BridgeTest.java
@@ -0,0 +1,58 @@
+package uk.ac.ic.wlgitbridge.bridge;
+
+import org.junit.Before;
+import org.junit.Test;
+import uk.ac.ic.wlgitbridge.bridge.db.DBStore;
+import uk.ac.ic.wlgitbridge.bridge.lock.ProjectLock;
+import uk.ac.ic.wlgitbridge.bridge.repo.RepoStore;
+import uk.ac.ic.wlgitbridge.bridge.resource.ResourceCache;
+import uk.ac.ic.wlgitbridge.bridge.snapshot.SnapshotAPI;
+import uk.ac.ic.wlgitbridge.bridge.swap.SwapJob;
+import uk.ac.ic.wlgitbridge.bridge.swap.SwapStore;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Created by winston on 20/08/2016.
+ */
+public class BridgeTest {
+
+ private Bridge bridge;
+
+ private ProjectLock lock;
+ private RepoStore repoStore;
+ private DBStore dbStore;
+ private SwapStore swapStore;
+ private SnapshotAPI snapshotAPI;
+ private ResourceCache resourceCache;
+ private SwapJob swapJob;
+
+ @Before
+ public void setup() {
+ lock = mock(ProjectLock.class);
+ repoStore = mock(RepoStore.class);
+ dbStore = mock(DBStore.class);
+ swapStore = mock(SwapStore.class);
+ snapshotAPI = mock(SnapshotAPI.class);
+ swapJob = mock(SwapJob.class);
+ bridge = new Bridge(
+ lock,
+ repoStore,
+ dbStore,
+ swapStore,
+ snapshotAPI,
+ resourceCache,
+ swapJob
+ );
+ }
+
+ @Test
+ public void shutdownStopsSwapJob() {
+ bridge.startSwapJob(1000);
+ bridge.doShutdown();
+ verify(swapJob).start(1000);
+ verify(swapJob).stop();
+ }
+
+}
\ No newline at end of file
diff --git a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/data/model/ResourceFetcherTest.java b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/data/model/ResourceFetcherTest.java
index f4ba462ba0..488b861253 100644
--- a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/data/model/ResourceFetcherTest.java
+++ b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/data/model/ResourceFetcherTest.java
@@ -9,8 +9,10 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockserver.client.server.MockServerClient;
import org.mockserver.junit.MockServerRule;
+import uk.ac.ic.wlgitbridge.bridge.db.DBStore;
+import uk.ac.ic.wlgitbridge.bridge.resource.ResourceCache;
+import uk.ac.ic.wlgitbridge.bridge.resource.UrlResourceCache;
import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
-import uk.ac.ic.wlgitbridge.data.model.db.PersistentStore;
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker;
@@ -50,23 +52,23 @@ public class ResourceFetcherTest {
);
final Mockery context = new Mockery();
- final PersistentStore persistentStore = context.mock(PersistentStore.class);
+ final DBStore dbStore = context.mock(DBStore.class);
context.checking(new Expectations() {{
// It should fetch the file once it finds it is missing.
- oneOf(persistentStore).getPathForURLInProject(testProjectName, testUrl);
+ oneOf(dbStore).getPathForURLInProject(testProjectName, testUrl);
will(returnValue(oldTestPath));
// It should update the URL index store once it has fetched; at present, it does not actually change the stored path.
- oneOf(persistentStore).addURLIndexForProject(testProjectName, testUrl, oldTestPath);
+ oneOf(dbStore).addURLIndexForProject(testProjectName, testUrl, oldTestPath);
}});
- ResourceFetcher resourceFetcher = new ResourceFetcher(persistentStore);
+ ResourceCache resources = new UrlResourceCache(dbStore);
TemporaryFolder repositoryFolder = new TemporaryFolder();
repositoryFolder.create();
Repository repository = new FileRepositoryBuilder().setWorkTree(repositoryFolder.getRoot()).build();
Map fileTable = new RepositoryObjectTreeWalker(repository).getDirectoryContents().getFileTable();
Map fetchedUrls = new HashMap();
- resourceFetcher.get(testProjectName, testUrl, newTestPath, fileTable, fetchedUrls);
+ resources.get(testProjectName, testUrl, newTestPath, fileTable, fetchedUrls);
// We don't bother caching in this case, at present.
assertEquals(0, fetchedUrls.size());
diff --git a/services/git-bridge/writelatex-git-bridge.iml b/services/git-bridge/writelatex-git-bridge.iml
index ad352655dc..87a4714796 100644
--- a/services/git-bridge/writelatex-git-bridge.iml
+++ b/services/git-bridge/writelatex-git-bridge.iml
@@ -13,7 +13,7 @@
-
+
@@ -107,5 +107,7 @@
+
+
\ No newline at end of file