mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-01 05:11:34 +02:00
Delete the SnapshotRepositoryBuilder and WLBridgedProject abominations. Set accessed time after update and push.
This commit is contained in:
committed by
Michael Mazour
parent
c459cd57af
commit
dd5694104d
@@ -3,6 +3,8 @@ 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.db.ProjectState;
|
||||
import uk.ac.ic.wlgitbridge.bridge.lock.LockGuard;
|
||||
import uk.ac.ic.wlgitbridge.bridge.lock.ProjectLock;
|
||||
import uk.ac.ic.wlgitbridge.bridge.repo.RepoStore;
|
||||
import uk.ac.ic.wlgitbridge.bridge.resource.ResourceCache;
|
||||
@@ -30,6 +32,8 @@ import uk.ac.ic.wlgitbridge.snapshot.push.exception.*;
|
||||
import uk.ac.ic.wlgitbridge.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -110,62 +114,109 @@ public class Bridge {
|
||||
swapJob.start();
|
||||
}
|
||||
|
||||
/* TODO: Remove these when WLBridged is moved into RepoStore */
|
||||
public void lockForProject(String projectName) {
|
||||
lock.lockForProject(projectName);
|
||||
}
|
||||
|
||||
public void unlockForProject(String projectName) {
|
||||
lock.unlockForProject(projectName);
|
||||
}
|
||||
|
||||
public boolean repositoryExists(Credential oauth2, String projectName)
|
||||
throws ServiceMayNotContinueException, GitUserException {
|
||||
lockForProject(projectName);
|
||||
GetDocRequest getDocRequest = new GetDocRequest(oauth2, projectName);
|
||||
getDocRequest.request();
|
||||
try {
|
||||
public boolean projectExists(
|
||||
Credential oauth2,
|
||||
String projectName
|
||||
) throws ServiceMayNotContinueException,
|
||||
GitUserException {
|
||||
try (LockGuard __ = lock.lockGuard(projectName)) {
|
||||
GetDocRequest getDocRequest = new GetDocRequest(
|
||||
oauth2,
|
||||
projectName
|
||||
);
|
||||
getDocRequest.request();
|
||||
getDocRequest.getResult().getVersionID();
|
||||
return true;
|
||||
} catch (InvalidProjectException e) {
|
||||
return false;
|
||||
} finally {
|
||||
unlockForProject(projectName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void getWritableRepositories(
|
||||
public void updateRepository(
|
||||
Credential oauth2,
|
||||
ProjectRepo repo
|
||||
) throws IOException,
|
||||
GitUserException {
|
||||
Log.info("[{}] Fetching", repo.getProjectName());
|
||||
updateProjectWithName(oauth2, repo);
|
||||
) throws IOException, GitUserException {
|
||||
String projectName = repo.getProjectName();
|
||||
try (LockGuard __ = lock.lockGuard(projectName)) {
|
||||
Log.info("[{}] Updating", projectName);
|
||||
updateRepositoryCritical(oauth2, repo);
|
||||
}
|
||||
}
|
||||
|
||||
public void
|
||||
putDirectoryContentsToProjectWithName(Credential oauth2,
|
||||
String projectName,
|
||||
RawDirectory directoryContents,
|
||||
RawDirectory oldDirectoryContents,
|
||||
String hostname)
|
||||
throws SnapshotPostException, IOException, ForbiddenException {
|
||||
lock.lockForProject(projectName);
|
||||
CandidateSnapshot candidate = null;
|
||||
try {
|
||||
Log.info("[{}] Pushing", projectName);
|
||||
String postbackKey = postbackManager.makeKeyForProject(projectName);
|
||||
Log.info(
|
||||
"[{}] Created postback key: {}",
|
||||
private void updateRepositoryCritical(
|
||||
Credential oauth2,
|
||||
ProjectRepo repo
|
||||
) throws IOException, GitUserException {
|
||||
String projectName = repo.getProjectName();
|
||||
ProjectState state = dbStore.getProjectState(projectName);
|
||||
switch (state) {
|
||||
case NOT_PRESENT:
|
||||
repo.initRepo(repoStore);
|
||||
break;
|
||||
case SWAPPED:
|
||||
swapJob.restore(projectName);
|
||||
/* Fallthrough */
|
||||
default:
|
||||
repo.useExistingRepository(repoStore);
|
||||
}
|
||||
updateProject(oauth2, repo);
|
||||
dbStore.setLastAccessedTime(
|
||||
projectName,
|
||||
Timestamp.valueOf(LocalDateTime.now())
|
||||
);
|
||||
}
|
||||
|
||||
public void putDirectoryContentsToProjectWithName(
|
||||
Credential oauth2,
|
||||
String projectName,
|
||||
RawDirectory directoryContents,
|
||||
RawDirectory oldDirectoryContents,
|
||||
String hostname
|
||||
) throws SnapshotPostException, IOException, ForbiddenException {
|
||||
try (LockGuard __ = lock.lockGuard(projectName)) {
|
||||
pushToProjectCritical(
|
||||
oauth2,
|
||||
projectName,
|
||||
postbackKey
|
||||
directoryContents,
|
||||
oldDirectoryContents
|
||||
);
|
||||
candidate =
|
||||
createCandidateSnapshot(
|
||||
projectName,
|
||||
directoryContents,
|
||||
oldDirectoryContents
|
||||
);
|
||||
} catch (SevereSnapshotPostException e) {
|
||||
Log.warn("[" + projectName + "] Failed to put to Overleaf", e);
|
||||
throw e;
|
||||
} catch (SnapshotPostException e) {
|
||||
/* Stack trace should be printed further up */
|
||||
Log.warn(
|
||||
"[{}] Exception when waiting for postback: {}",
|
||||
projectName,
|
||||
e.getClass().getSimpleName()
|
||||
);
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
Log.warn("[{}] IOException on put", projectName);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void pushToProjectCritical(
|
||||
Credential oauth2,
|
||||
String projectName,
|
||||
RawDirectory directoryContents,
|
||||
RawDirectory oldDirectoryContents
|
||||
) throws IOException, ForbiddenException, SnapshotPostException {
|
||||
Log.info("[{}] Pushing", projectName);
|
||||
String postbackKey = postbackManager.makeKeyForProject(projectName);
|
||||
Log.info(
|
||||
"[{}] Created postback key: {}",
|
||||
projectName,
|
||||
postbackKey
|
||||
);
|
||||
try (
|
||||
CandidateSnapshot candidate = createCandidateSnapshot(
|
||||
projectName,
|
||||
directoryContents,
|
||||
oldDirectoryContents
|
||||
);
|
||||
) {
|
||||
Log.info(
|
||||
"[{}] Candindate snapshot created: {}",
|
||||
projectName,
|
||||
@@ -197,6 +248,10 @@ public class Bridge {
|
||||
projectName,
|
||||
versionID
|
||||
);
|
||||
dbStore.setLastAccessedTime(
|
||||
projectName,
|
||||
Timestamp.valueOf(LocalDateTime.now())
|
||||
);
|
||||
} else {
|
||||
Log.warn(
|
||||
"[{}] Went out of date while waiting for push",
|
||||
@@ -204,31 +259,6 @@ public class Bridge {
|
||||
);
|
||||
throw new OutOfDateException();
|
||||
}
|
||||
} catch (SevereSnapshotPostException e) {
|
||||
Log.warn("[" + projectName + "] Failed to put to Overleaf", e);
|
||||
throw e;
|
||||
} catch (SnapshotPostException e) {
|
||||
/* Stack trace should be printed further up */
|
||||
Log.warn(
|
||||
"[{}] Exception when waiting for postback: {}",
|
||||
projectName,
|
||||
e.getClass().getSimpleName()
|
||||
);
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
Log.warn("[{}] IOException on put", projectName);
|
||||
throw e;
|
||||
} finally {
|
||||
if (candidate != null) {
|
||||
candidate.deleteServletFiles();
|
||||
} else {
|
||||
Log.error(
|
||||
"[{}] Candidate snapshot was null: " +
|
||||
"this should never happen.",
|
||||
projectName
|
||||
);
|
||||
}
|
||||
lock.unlockForProject(projectName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,7 +298,7 @@ public class Bridge {
|
||||
|
||||
/* PRIVATE */
|
||||
|
||||
private void updateProjectWithName(
|
||||
private void updateProject(
|
||||
Credential oauth2,
|
||||
ProjectRepo repo
|
||||
) throws IOException, GitUserException {
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
package uk.ac.ic.wlgitbridge.bridge;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.lib.PersonIdent;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
||||
import uk.ac.ic.wlgitbridge.bridge.repo.RepoStore;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.GitDirectoryContents;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
|
||||
import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker;
|
||||
import uk.ac.ic.wlgitbridge.util.Log;
|
||||
import uk.ac.ic.wlgitbridge.util.Project;
|
||||
import uk.ac.ic.wlgitbridge.util.Util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by winston on 20/08/2016.
|
||||
*/
|
||||
public class GitProjectRepo implements ProjectRepo {
|
||||
|
||||
private final Repository repository;
|
||||
private final String projectName;
|
||||
private Optional<Repository> repository;
|
||||
|
||||
public GitProjectRepo(Repository repository, String projectName) {
|
||||
this.repository = repository;
|
||||
public GitProjectRepo(String projectName) {
|
||||
Preconditions.checkArgument(Project.isValidProjectName(projectName));
|
||||
this.projectName = projectName;
|
||||
repository = Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -35,11 +38,34 @@ public class GitProjectRepo implements ProjectRepo {
|
||||
return projectName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initRepo(
|
||||
RepoStore repoStore
|
||||
) throws IOException {
|
||||
initRepositoryField(repoStore);
|
||||
Preconditions.checkState(repository.isPresent());
|
||||
Repository repo = this.repository.get();
|
||||
Preconditions.checkState(!repo.getObjectDatabase().exists());
|
||||
repo.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useExistingRepository(
|
||||
RepoStore repoStore
|
||||
) throws IOException {
|
||||
initRepositoryField(repoStore);
|
||||
Preconditions.checkState(repository.isPresent());
|
||||
Preconditions.checkState(
|
||||
repository.get().getObjectDatabase().exists()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, RawFile> getFiles()
|
||||
throws IOException, GitUserException {
|
||||
Preconditions.checkState(repository.isPresent());
|
||||
return new RepositoryObjectTreeWalker(
|
||||
repository
|
||||
repository.get()
|
||||
).getDirectoryContents().getFileTable();
|
||||
}
|
||||
|
||||
@@ -54,13 +80,33 @@ public class GitProjectRepo implements ProjectRepo {
|
||||
}
|
||||
}
|
||||
|
||||
public Repository getJGitRepository() {
|
||||
return repository.get();
|
||||
}
|
||||
|
||||
private void initRepositoryField(RepoStore repoStore) throws IOException {
|
||||
Preconditions.checkNotNull(repoStore);
|
||||
Preconditions.checkArgument(Project.isValidProjectName(projectName));
|
||||
Preconditions.checkState(!repository.isPresent());
|
||||
repository = Optional.of(createJGitRepository(repoStore, projectName));
|
||||
}
|
||||
|
||||
private Repository createJGitRepository(
|
||||
RepoStore repoStore,
|
||||
String projName
|
||||
) throws IOException {
|
||||
File repoDir = new File(repoStore.getRootDirectory(), projName);
|
||||
return new FileRepositoryBuilder().setWorkTree(repoDir).build();
|
||||
}
|
||||
|
||||
private Collection<String> doCommitAndGetMissing(
|
||||
GitDirectoryContents contents
|
||||
) throws IOException, GitAPIException {
|
||||
Preconditions.checkState(repository.isPresent());
|
||||
String name = getProjectName();
|
||||
Log.info("[{}] Writing commit", name);
|
||||
contents.write();
|
||||
Git git = new Git(repository);
|
||||
Git git = new Git(repository.get());
|
||||
Log.info("[{}] Getting missing files", name);
|
||||
Set<String> missingFiles = git.status().call().getMissing();
|
||||
for (String missing : missingFiles) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package uk.ac.ic.wlgitbridge.bridge;
|
||||
|
||||
import uk.ac.ic.wlgitbridge.bridge.repo.RepoStore;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.GitDirectoryContents;
|
||||
import uk.ac.ic.wlgitbridge.data.filestore.RawFile;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
|
||||
@@ -15,6 +16,14 @@ public interface ProjectRepo {
|
||||
|
||||
String getProjectName();
|
||||
|
||||
void initRepo(
|
||||
RepoStore repoStore
|
||||
) throws IOException;
|
||||
|
||||
void useExistingRepository(
|
||||
RepoStore repoStore
|
||||
) throws IOException;
|
||||
|
||||
Map<String, RawFile> getFiles() throws IOException, GitUserException;
|
||||
|
||||
Collection<String> commitAndGetMissing(
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
package uk.ac.ic.wlgitbridge.bridge;
|
||||
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.getdoc.exception.InvalidProjectException;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Winston on 05/11/14.
|
||||
*/
|
||||
public class WLBridgedProject {
|
||||
|
||||
private final Repository repository;
|
||||
private final String name;
|
||||
private final Bridge bridgeAPI;
|
||||
|
||||
public WLBridgedProject(Repository repository, String name, Bridge bridgeAPI) {
|
||||
this.repository = repository;
|
||||
this.name = name;
|
||||
this.bridgeAPI = bridgeAPI;
|
||||
}
|
||||
|
||||
public void buildRepository(Credential oauth2) throws RepositoryNotFoundException, ServiceMayNotContinueException, GitUserException {
|
||||
bridgeAPI.lockForProject(name);
|
||||
try {
|
||||
if (repository.getObjectDatabase().exists()) {
|
||||
updateRepositoryFromSnapshots(oauth2, repository);
|
||||
} else {
|
||||
buildRepositoryFromScratch(oauth2, repository);
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
e.printStackTrace();
|
||||
throw new ServiceMayNotContinueException(e);
|
||||
} finally {
|
||||
bridgeAPI.unlockForProject(name);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRepositoryFromSnapshots(
|
||||
Credential oauth2,
|
||||
Repository repository
|
||||
) throws RepositoryNotFoundException,
|
||||
ServiceMayNotContinueException,
|
||||
GitUserException {
|
||||
try {
|
||||
bridgeAPI.getWritableRepositories(
|
||||
oauth2,
|
||||
new GitProjectRepo(repository, name)
|
||||
);
|
||||
} catch (InvalidProjectException e) {
|
||||
throw new RepositoryNotFoundException(name);
|
||||
} catch (IOException e) {
|
||||
throw new ServiceMayNotContinueException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void buildRepositoryFromScratch(Credential oauth2, Repository repository) throws RepositoryNotFoundException, ServiceMayNotContinueException, GitUserException {
|
||||
if (!bridgeAPI.repositoryExists(oauth2, name)) {
|
||||
throw new RepositoryNotFoundException(name);
|
||||
}
|
||||
try {
|
||||
repository.create();
|
||||
} catch (IOException e) {
|
||||
throw new ServiceMayNotContinueException(e);
|
||||
}
|
||||
updateRepositoryFromSnapshots(oauth2, repository);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,6 +26,8 @@ public interface DBStore {
|
||||
|
||||
int getNumUnswappedProjects();
|
||||
|
||||
ProjectState getProjectState(String projectName);
|
||||
|
||||
/**
|
||||
* Sets the last accessed time for the given project name.
|
||||
* @param projectName the project's name
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package uk.ac.ic.wlgitbridge.bridge.db;
|
||||
|
||||
/**
|
||||
* Created by winston on 24/08/2016.
|
||||
*/
|
||||
public enum ProjectState {
|
||||
|
||||
NOT_PRESENT,
|
||||
PRESENT,
|
||||
SWAPPED
|
||||
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package uk.ac.ic.wlgitbridge.bridge.db.sqlite;
|
||||
|
||||
import uk.ac.ic.wlgitbridge.bridge.db.DBInitException;
|
||||
import uk.ac.ic.wlgitbridge.bridge.db.DBStore;
|
||||
import uk.ac.ic.wlgitbridge.bridge.db.ProjectState;
|
||||
import uk.ac.ic.wlgitbridge.bridge.db.sqlite.query.*;
|
||||
import uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.create.*;
|
||||
import uk.ac.ic.wlgitbridge.bridge.db.sqlite.update.delete.DeleteFilesForProjectSQLUpdate;
|
||||
@@ -91,6 +92,11 @@ public class SqliteDBStore implements DBStore {
|
||||
return query(new GetNumUnswappedProjects());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectState getProjectState(String projectName) {
|
||||
return query(new GetProjectState(projectName));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastAccessedTime(
|
||||
String projectName,
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package uk.ac.ic.wlgitbridge.bridge.db.sqlite.query;
|
||||
|
||||
import uk.ac.ic.wlgitbridge.bridge.db.ProjectState;
|
||||
import uk.ac.ic.wlgitbridge.bridge.db.sqlite.SQLQuery;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Created by winston on 24/08/2016.
|
||||
*/
|
||||
public class GetProjectState implements SQLQuery<ProjectState> {
|
||||
|
||||
private static final String GET_PROJECT_STATE =
|
||||
"SELECT `last_accessed`\n" +
|
||||
" FROM `swap_table`\n" +
|
||||
" WHERE `project_name` = ?";
|
||||
|
||||
private final String projectName;
|
||||
|
||||
public GetProjectState(String projectName) {
|
||||
this.projectName = projectName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSQL() {
|
||||
return GET_PROJECT_STATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProjectState processResultSet(ResultSet resultSet) throws SQLException {
|
||||
while (resultSet.next()) {
|
||||
if (resultSet.getTimestamp("last_accessed") == null) {
|
||||
return ProjectState.SWAPPED;
|
||||
}
|
||||
return ProjectState.PRESENT;
|
||||
}
|
||||
return ProjectState.NOT_PRESENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addParametersToStatement(PreparedStatement statement) throws SQLException {
|
||||
statement.setString(1, projectName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,12 +18,12 @@ import static uk.ac.ic.wlgitbridge.util.Util.deleteInDirectoryApartFrom;
|
||||
/**
|
||||
* Created by winston on 20/08/2016.
|
||||
*/
|
||||
public class FSRepoStore implements RepoStore {
|
||||
public class FSGitRepoStore implements RepoStore {
|
||||
|
||||
private final String repoStorePath;
|
||||
private final File rootDirectory;
|
||||
|
||||
public FSRepoStore(String repoStorePath) {
|
||||
public FSGitRepoStore(String repoStorePath) {
|
||||
this.repoStorePath = repoStorePath;
|
||||
rootDirectory = initRootGitDirectory(repoStorePath);
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import java.util.Map.Entry;
|
||||
/**
|
||||
* Created by Winston on 16/11/14.
|
||||
*/
|
||||
public class CandidateSnapshot {
|
||||
public class CandidateSnapshot implements AutoCloseable {
|
||||
|
||||
private final String projectName;
|
||||
private final int currentVersion;
|
||||
@@ -25,14 +25,22 @@ public class CandidateSnapshot {
|
||||
private final List<String> deleted;
|
||||
private File attsDirectory;
|
||||
|
||||
public CandidateSnapshot(String projectName, int currentVersion, RawDirectory directoryContents, RawDirectory oldDirectoryContents) {
|
||||
public CandidateSnapshot(
|
||||
String projectName,
|
||||
int currentVersion,
|
||||
RawDirectory directoryContents,
|
||||
RawDirectory oldDirectoryContents
|
||||
) {
|
||||
this.projectName = projectName;
|
||||
this.currentVersion = currentVersion;
|
||||
files = diff(directoryContents, oldDirectoryContents);
|
||||
deleted = deleted(directoryContents, oldDirectoryContents);
|
||||
}
|
||||
|
||||
private List<ServletFile> diff(RawDirectory directoryContents, RawDirectory oldDirectoryContents) {
|
||||
private List<ServletFile> diff(
|
||||
RawDirectory directoryContents,
|
||||
RawDirectory oldDirectoryContents
|
||||
) {
|
||||
List<ServletFile> files = new LinkedList<ServletFile>();
|
||||
Map<String, RawFile> fileTable = directoryContents.getFileTable();
|
||||
Map<String, RawFile> oldFileTable = oldDirectoryContents.getFileTable();
|
||||
@@ -43,10 +51,16 @@ public class CandidateSnapshot {
|
||||
return files;
|
||||
}
|
||||
|
||||
private List<String> deleted(RawDirectory directoryContents, RawDirectory oldDirectoryContents) {
|
||||
private List<String> deleted(
|
||||
RawDirectory directoryContents,
|
||||
RawDirectory oldDirectoryContents
|
||||
) {
|
||||
List<String> deleted = new LinkedList<String>();
|
||||
Map<String, RawFile> fileTable = directoryContents.getFileTable();
|
||||
for (Entry<String, RawFile> entry : oldDirectoryContents.getFileTable().entrySet()) {
|
||||
for (
|
||||
Entry<String, RawFile> entry :
|
||||
oldDirectoryContents.getFileTable().entrySet()
|
||||
) {
|
||||
String path = entry.getKey();
|
||||
RawFile newFile = fileTable.get(path);
|
||||
if (newFile == null) {
|
||||
@@ -57,7 +71,10 @@ public class CandidateSnapshot {
|
||||
}
|
||||
|
||||
public void writeServletFiles(File rootGitDirectory) throws IOException {
|
||||
attsDirectory = new File(rootGitDirectory, ".wlgb/atts/" + projectName);
|
||||
attsDirectory = new File(
|
||||
rootGitDirectory,
|
||||
".wlgb/atts/" + projectName
|
||||
);
|
||||
for (ServletFile file : files) {
|
||||
if (file.isChanged()) {
|
||||
file.writeToDisk(attsDirectory);
|
||||
@@ -90,11 +107,18 @@ public class CandidateSnapshot {
|
||||
return filesArray;
|
||||
}
|
||||
|
||||
private JsonObject getFileAsJson(ServletFile file, String projectURL, String postbackKey) {
|
||||
private JsonObject getFileAsJson(
|
||||
ServletFile file,
|
||||
String projectURL,
|
||||
String postbackKey
|
||||
) {
|
||||
JsonObject jsonFile = new JsonObject();
|
||||
jsonFile.addProperty("name", file.getPath());
|
||||
if (file.isChanged()) {
|
||||
jsonFile.addProperty("url", projectURL + "/" + file.getPath() + "?key=" + postbackKey);
|
||||
jsonFile.addProperty(
|
||||
"url",
|
||||
projectURL + "/" + file.getPath() + "?key=" + postbackKey
|
||||
);
|
||||
}
|
||||
return jsonFile;
|
||||
}
|
||||
@@ -119,4 +143,9 @@ public class CandidateSnapshot {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
deleteServletFiles();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,11 +33,13 @@ public class ProjectLockImpl implements ProjectLock {
|
||||
setWaiter(waiter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lockForProject(String projectName) {
|
||||
getLockForProjectName(projectName).lock();
|
||||
rlock.lock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unlockForProject(String projectName) {
|
||||
getLockForProjectName(projectName).unlock();
|
||||
rlock.unlock();
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
package uk.ac.ic.wlgitbridge.data;
|
||||
|
||||
import com.google.api.client.auth.oauth2.Credential;
|
||||
import org.eclipse.jgit.errors.RepositoryNotFoundException;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
||||
import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||
import uk.ac.ic.wlgitbridge.bridge.Bridge;
|
||||
import uk.ac.ic.wlgitbridge.bridge.WLBridgedProject;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.push.exception.InternalErrorException;
|
||||
import uk.ac.ic.wlgitbridge.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Winston on 03/11/14.
|
||||
*/
|
||||
public class SnapshotRepositoryBuilder {
|
||||
|
||||
private final Bridge bridgeAPI;
|
||||
|
||||
public SnapshotRepositoryBuilder(Bridge bridgeAPI) {
|
||||
this.bridgeAPI = bridgeAPI;
|
||||
}
|
||||
|
||||
public Repository getRepositoryWithNameAtRootDirectory(String name, File rootDirectory, Credential oauth2) throws RepositoryNotFoundException, ServiceMayNotContinueException, GitUserException {
|
||||
if (!bridgeAPI.repositoryExists(oauth2, name)) {
|
||||
throw new RepositoryNotFoundException(name);
|
||||
}
|
||||
File repositoryDirectory = new File(rootDirectory, name);
|
||||
|
||||
Repository repository = null;
|
||||
try {
|
||||
repository = new FileRepositoryBuilder().setWorkTree(repositoryDirectory).build();
|
||||
new WLBridgedProject(repository, name, bridgeAPI).buildRepository(oauth2);
|
||||
} catch (IOException e) {
|
||||
Log.warn(
|
||||
"IOException when trying to get repo: " +
|
||||
name +
|
||||
", at: "
|
||||
+ rootDirectory.getAbsolutePath(),
|
||||
e
|
||||
);
|
||||
throw new ServiceMayNotContinueException(
|
||||
new InternalErrorException().getDescriptionLines().get(0)
|
||||
);
|
||||
}
|
||||
return repository;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,35 +7,48 @@ import org.eclipse.jgit.transport.ServiceMayNotContinueException;
|
||||
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||
import uk.ac.ic.wlgitbridge.data.SnapshotRepositoryBuilder;
|
||||
import uk.ac.ic.wlgitbridge.bridge.Bridge;
|
||||
import uk.ac.ic.wlgitbridge.bridge.GitProjectRepo;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.GitUserException;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.InvalidRootDirectoryPathException;
|
||||
import uk.ac.ic.wlgitbridge.server.Oauth2Filter;
|
||||
import uk.ac.ic.wlgitbridge.snapshot.base.ForbiddenException;
|
||||
import uk.ac.ic.wlgitbridge.util.Log;
|
||||
import uk.ac.ic.wlgitbridge.util.Util;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Winston on 02/11/14.
|
||||
*/
|
||||
public class WLRepositoryResolver implements RepositoryResolver<HttpServletRequest> {
|
||||
public class WLRepositoryResolver
|
||||
implements RepositoryResolver<HttpServletRequest> {
|
||||
|
||||
private File rootGitDirectory;
|
||||
private SnapshotRepositoryBuilder snapshotRepositoryBuilder;
|
||||
private final Bridge bridge;
|
||||
|
||||
public WLRepositoryResolver(String rootGitDirectoryPath, SnapshotRepositoryBuilder repositorySource) throws InvalidRootDirectoryPathException {
|
||||
this.snapshotRepositoryBuilder = repositorySource;
|
||||
initRootGitDirectory(rootGitDirectoryPath);
|
||||
public WLRepositoryResolver(Bridge bridge) {
|
||||
this.bridge = bridge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository open(HttpServletRequest httpServletRequest, String name) throws RepositoryNotFoundException, ServiceNotAuthorizedException, ServiceNotEnabledException, ServiceMayNotContinueException {
|
||||
Credential oauth2 = (Credential) httpServletRequest.getAttribute(Oauth2Filter.ATTRIBUTE_KEY);
|
||||
public Repository open(
|
||||
HttpServletRequest httpServletRequest,
|
||||
String name
|
||||
) throws RepositoryNotFoundException,
|
||||
ServiceNotAuthorizedException,
|
||||
ServiceNotEnabledException,
|
||||
ServiceMayNotContinueException {
|
||||
Credential oauth2 = (Credential) httpServletRequest.getAttribute(
|
||||
Oauth2Filter.ATTRIBUTE_KEY
|
||||
);
|
||||
String projName = Util.removeAllSuffixes(name, "/", ".git");
|
||||
try {
|
||||
return snapshotRepositoryBuilder.getRepositoryWithNameAtRootDirectory(Util.removeAllSuffixes(name, "/", ".git"), rootGitDirectory, oauth2);
|
||||
if (!bridge.projectExists(oauth2, projName)) {
|
||||
throw new RepositoryNotFoundException(projName);
|
||||
}
|
||||
GitProjectRepo repo = new GitProjectRepo(projName);
|
||||
bridge.updateRepository(oauth2, repo);
|
||||
return repo.getJGitRepository();
|
||||
} catch (RepositoryNotFoundException e) {
|
||||
Log.info("Repository not found: " + name);
|
||||
throw e;
|
||||
@@ -45,7 +58,8 @@ public class WLRepositoryResolver implements RepositoryResolver<HttpServletReque
|
||||
} catch (ServiceNotEnabledException e) {
|
||||
cannot occur
|
||||
*/
|
||||
} catch (ServiceMayNotContinueException e) { /* Such as FailedConnectionException */
|
||||
} catch (ServiceMayNotContinueException e) {
|
||||
/* Such as FailedConnectionException */
|
||||
throw e;
|
||||
} catch (RuntimeException e) {
|
||||
Log.warn("Runtime exception when trying to open repo", e);
|
||||
@@ -54,16 +68,9 @@ public class WLRepositoryResolver implements RepositoryResolver<HttpServletReque
|
||||
throw new ServiceNotAuthorizedException();
|
||||
} catch (GitUserException e) {
|
||||
throw new ServiceMayNotContinueException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initRootGitDirectory(String rootGitDirectoryPath) throws InvalidRootDirectoryPathException {
|
||||
rootGitDirectory = new File(rootGitDirectoryPath);
|
||||
/* throws SecurityException */
|
||||
rootGitDirectory.mkdirs();
|
||||
rootGitDirectory.getAbsolutePath();
|
||||
if (!rootGitDirectory.isDirectory()) {
|
||||
throw new InvalidRootDirectoryPathException();
|
||||
} catch (IOException e) {
|
||||
Log.warn("IOException when trying to open repo", e);
|
||||
throw new ServiceMayNotContinueException("Internal server error.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,12 +2,11 @@ package uk.ac.ic.wlgitbridge.git.servlet;
|
||||
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jgit.http.server.GitServlet;
|
||||
import uk.ac.ic.wlgitbridge.bridge.Bridge;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.InvalidRootDirectoryPathException;
|
||||
import uk.ac.ic.wlgitbridge.git.handler.WLReceivePackFactory;
|
||||
import uk.ac.ic.wlgitbridge.git.handler.WLRepositoryResolver;
|
||||
import uk.ac.ic.wlgitbridge.git.handler.WLUploadPackFactory;
|
||||
import uk.ac.ic.wlgitbridge.data.SnapshotRepositoryBuilder;
|
||||
import uk.ac.ic.wlgitbridge.bridge.Bridge;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
@@ -16,11 +15,14 @@ import javax.servlet.ServletException;
|
||||
*/
|
||||
public class WLGitServlet extends GitServlet {
|
||||
|
||||
public WLGitServlet(ServletContextHandler servletContextHandler, Bridge bridgeAPI, String rootGitDirectoryPath) throws ServletException, InvalidRootDirectoryPathException {
|
||||
setRepositoryResolver(new WLRepositoryResolver(rootGitDirectoryPath, new SnapshotRepositoryBuilder(bridgeAPI)));
|
||||
setReceivePackFactory(new WLReceivePackFactory(bridgeAPI));
|
||||
public WLGitServlet(
|
||||
ServletContextHandler ctxHandler,
|
||||
Bridge bridge
|
||||
) throws ServletException, InvalidRootDirectoryPathException {
|
||||
setRepositoryResolver(new WLRepositoryResolver(bridge));
|
||||
setReceivePackFactory(new WLReceivePackFactory(bridge));
|
||||
setUploadPackFactory(new WLUploadPackFactory());
|
||||
init(new WLGitServletConfig(servletContextHandler));
|
||||
init(new WLGitServletConfig(ctxHandler));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ public class WLGitServletConfig implements ServletConfig {
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
public WLGitServletConfig(ServletContextHandler servletContextHandler) {
|
||||
servletContext = servletContextHandler.getServletContext();
|
||||
public WLGitServletConfig(ServletContextHandler ctxHandler) {
|
||||
servletContext = ctxHandler.getServletContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,7 +11,7 @@ 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.sqlite.SqliteDBStore;
|
||||
import uk.ac.ic.wlgitbridge.bridge.repo.FSRepoStore;
|
||||
import uk.ac.ic.wlgitbridge.bridge.repo.FSGitRepoStore;
|
||||
import uk.ac.ic.wlgitbridge.bridge.repo.RepoStore;
|
||||
import uk.ac.ic.wlgitbridge.bridge.swap.store.SwapStore;
|
||||
import uk.ac.ic.wlgitbridge.git.exception.InvalidRootDirectoryPathException;
|
||||
@@ -51,7 +51,7 @@ public class GitBridgeServer {
|
||||
org.eclipse.jetty.util.log.Log.setLog(new NullLogger());
|
||||
this.port = config.getPort();
|
||||
this.rootGitDirectoryPath = config.getRootGitDirectory();
|
||||
RepoStore repoStore = new FSRepoStore(rootGitDirectoryPath);
|
||||
RepoStore repoStore = new FSGitRepoStore(rootGitDirectoryPath);
|
||||
DBStore dbStore = new SqliteDBStore(
|
||||
Paths.get(
|
||||
repoStore.getRootDirectory().getAbsolutePath()
|
||||
@@ -143,8 +143,7 @@ public class GitBridgeServer {
|
||||
new ServletHolder(
|
||||
new WLGitServlet(
|
||||
servletContextHandler,
|
||||
bridgeAPI,
|
||||
rootGitDirectoryPath
|
||||
bridgeAPI
|
||||
)
|
||||
),
|
||||
"/*"
|
||||
|
||||
Reference in New Issue
Block a user