Explorar o código

Implemented mock snapshot server.

Winston Li %!s(int64=11) %!d(string=hai) anos
pai
achega
26e2b1262d
Modificáronse 51 ficheiros con 1030 adicións e 156 borrados
  1. 2 2
      services/git-bridge/bin/config.json
  2. 17 18
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/application/AttsResourceHandler.java
  3. 40 15
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/application/SnapshotPushPostbackHandler.java
  4. 2 3
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/RepositorySource.java
  5. 7 9
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WLBridgedProject.java
  6. 9 3
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/git/handler/WLRepositoryResolver.java
  7. 15 12
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/git/handler/hook/WriteLatexPutHook.java
  8. 17 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/Main.java
  9. 0 46
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/SnapshotDummyServer.java
  10. 12 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/exception/InvalidAPICallException.java
  11. 14 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/SnapshotResponse.java
  12. 57 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/SnapshotResponseBuilder.java
  13. 22 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/getdoc/SnapshotGetDocResponse.java
  14. 22 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/getforver/SnapshotGetForVerResponse.java
  15. 22 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/getsavedver/SnapshotGetSavedVersResponse.java
  16. 34 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/SnapshotPushResponse.java
  17. 31 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/data/SnapshotPushResult.java
  18. 17 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/data/SnapshotPushResultOutOfDate.java
  19. 17 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/data/SnapshotPushResultSuccess.java
  20. 22 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequest.java
  21. 21 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestError.java
  22. 32 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestInvalidFiles.java
  23. 33 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestInvalidProject.java
  24. 21 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestOutOfDate.java
  25. 24 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestSuccess.java
  26. 25 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/invalidfile/InvalidFileError.java
  27. 17 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/invalidfile/InvalidFileErrorDefault.java
  28. 17 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/invalidfile/InvalidFileErrorDisallowed.java
  29. 29 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/invalidfile/InvalidFileErrorUnclean.java
  30. 40 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/server/MockSnapshotRequestHandler.java
  31. 37 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/server/MockSnapshotServer.java
  32. 45 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/server/PostbackThread.java
  33. 44 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/state/SnapshotAPIState.java
  34. 6 13
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/SnapshotRepositoryBuilder.java
  35. 1 3
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java
  36. 9 1
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/base/Result.java
  37. 1 1
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/base/SnapshotAPIRequest.java
  38. 9 1
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/exception/FailedConnectionException.java
  39. 19 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getdoc/SnapshotGetDocResult.java
  40. 13 3
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getdoc/exception/InvalidProjectException.java
  41. 14 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotAttachment.java
  42. 21 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotData.java
  43. 15 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotFile.java
  44. 9 1
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotGetForVersionResult.java
  45. 24 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getsavedvers/SnapshotGetSavedVersResult.java
  46. 6 2
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getsavedvers/SnapshotInfo.java
  47. 48 20
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/PostbackContents.java
  48. 7 3
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/PostbackManager.java
  49. 5 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/SnapshotPushRequestResult.java
  50. 30 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/exception/InternalErrorException.java
  51. 29 0
      services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/exception/PostbackTimeoutException.java

+ 2 - 2
services/git-bridge/bin/config.json

@@ -1,9 +1,9 @@
 {
 	"port": 80,
 	"rootGitDirectory": "/var/wlgb/git",
-	"apiBaseUrl": "https://www.overleaf.com/api/v0",
+	"apiBaseUrl": "http://127.0.0.1:60000/api/v0",
 	"username": "REDACTED",
 	"password": "REDACTED",
-	"postbackBaseUrl": "http://your-server-name-for-postbacks",
+	"postbackBaseUrl": "http://127.0.0.1",
 	"serviceName": "Overleaf"
 }

+ 17 - 18
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/application/AttsResourceHandler.java

@@ -25,25 +25,24 @@ public class AttsResourceHandler extends ResourceHandler {
 
     @Override
     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
-        HttpURI uri = baseRequest.getUri();
-        System.out.println(baseRequest.getMethod() + " " + uri);
-        MultiMap<String> multimap = new MultiMap<String>();
-        uri.decodeQueryTo(multimap);
-        String[] pathSections = uri.getPath().split("/");
-        String key = multimap.getString("key");
-        if (key == null || pathSections.length < 2) {
-            throw new ServletException();
+        String method = baseRequest.getMethod();
+        if (method.equals("GET")) {
+            HttpURI uri = baseRequest.getUri();
+            System.out.println(method + " " + uri);
+            MultiMap<String> multimap = new MultiMap<String>();
+            uri.decodeQueryTo(multimap);
+            String[] pathSections = uri.getPath().split("/");
+            String key = multimap.getString("key");
+            if (key == null || pathSections.length < 2) {
+                throw new ServletException();
+            }
+            try {
+                writeLatexDataSource.checkPostbackKey(pathSections[1], key);
+            } catch (InvalidPostbackKeyException e) {
+                throw new ServletException();
+            }
+            super.handle(target, baseRequest, request, response);
         }
-        try {
-            writeLatexDataSource.checkPostbackKey(pathSections[1], key);
-        } catch (InvalidPostbackKeyException e) {
-            throw new ServletException();
-        }
-
-        if (false) {
-            throw new ServletException();
-        }
-        super.handle(target, baseRequest, request, response);
     }
 
 }

+ 40 - 15
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/application/SnapshotPushPostbackHandler.java

@@ -1,5 +1,7 @@
 package uk.ac.ic.wlgitbridge.application;
 
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.server.handler.AbstractHandler;
 import uk.ac.ic.wlgitbridge.bridge.WriteLatexDataSource;
@@ -24,22 +26,45 @@ public class SnapshotPushPostbackHandler extends AbstractHandler {
 
     @Override
     public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
-        if (request.getMethod().equals("POST") && request.getPathInfo().endsWith("postback")) {
-            String contents = Util.getContentsOfReader(request.getReader());
-            String[] parts = request.getRequestURI().split("/");
-            if (parts.length < 4) {
-                throw new ServletException();
-            }
-            String projectName = parts[1];
-            String postbackKey = parts[2];
-            System.out.println("Postback received for project: " + projectName);
-            SnapshotPushPostbackContents postbackContents = new SnapshotPushPostbackContents(writeLatexDataSource, projectName, postbackKey, contents);
-            try {
-                postbackContents.processPostback();
-            } catch (UnexpectedPostbackException e) {
-                throw new ServletException();
+
+        try {
+            if (request.getMethod().equals("POST") && target.endsWith("postback")) {
+                response.setContentType("application/json");
+                String contents = Util.getContentsOfReader(request.getReader());
+                String[] parts = request.getRequestURI().split("/");
+                if (parts.length < 4) {
+                    System.out.println("Invalid postback url");
+                    throw new ServletException();
+                }
+                String projectName = parts[1];
+                String postbackKey = parts[2];
+                System.out.println("Postback received for project: " + projectName);
+                SnapshotPushPostbackContents postbackContents = new SnapshotPushPostbackContents(writeLatexDataSource, projectName, postbackKey, contents);
+                JsonObject body = new JsonObject();
+
+                try {
+                    postbackContents.processPostback();
+                } catch (UnexpectedPostbackException e) {
+                    response.setStatus(HttpServletResponse.SC_CONFLICT);
+                    body.add("code", new JsonPrimitive("unexpectedPostback"));
+                    response.getWriter().println(body);
+                    baseRequest.setHandled(true);
+                    return;
+                }
+                response.setStatus(HttpServletResponse.SC_OK);
+                body.add("code", new JsonPrimitive("success"));
+                response.getWriter().println(body);
+                baseRequest.setHandled(true);
             }
-            baseRequest.setHandled(true);
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw e;
+        } catch (ServletException e) {
+            e.printStackTrace();
+            throw e;
+        } catch (RuntimeException e) {
+            e.printStackTrace();
+            throw e;
         }
     }
 

+ 2 - 3
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/RepositorySource.java

@@ -2,8 +2,7 @@ package uk.ac.ic.wlgitbridge.bridge;
 
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
+import org.eclipse.jgit.transport.ServiceMayNotContinueException;
 
 import java.io.File;
 
@@ -12,6 +11,6 @@ import java.io.File;
  */
 public interface RepositorySource {
 
-    public Repository getRepositoryWithNameAtRootDirectory(String name, File rootDirectory) throws RepositoryNotFoundException, ServiceNotEnabledException;
+    public Repository getRepositoryWithNameAtRootDirectory(String name, File rootDirectory) throws RepositoryNotFoundException, ServiceMayNotContinueException;
 
 }

+ 7 - 9
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/bridge/WLBridgedProject.java

@@ -5,8 +5,7 @@ import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
+import org.eclipse.jgit.transport.ServiceMayNotContinueException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception.InvalidProjectException;
 import uk.ac.ic.wlgitbridge.writelatex.filestore.store.WLFileStore;
 
@@ -29,7 +28,7 @@ public class WLBridgedProject {
         this.writeLatexDataSource = writeLatexDataSource;
     }
 
-    public void buildRepository() throws RepositoryNotFoundException, ServiceNotEnabledException, FailedConnectionException {
+    public void buildRepository() throws RepositoryNotFoundException, ServiceMayNotContinueException {
         writeLatexDataSource.lockForProject(name);
         if (repository.getObjectDatabase().exists()) {
             updateRepositoryFromSnapshots(repository);
@@ -39,7 +38,7 @@ public class WLBridgedProject {
         writeLatexDataSource.unlockForProject(name);
     }
 
-    private void updateRepositoryFromSnapshots(Repository repository) throws ServiceNotEnabledException, RepositoryNotFoundException, FailedConnectionException {
+    private void updateRepositoryFromSnapshots(Repository repository) throws RepositoryNotFoundException, ServiceMayNotContinueException {
         List<WritableRepositoryContents> writableRepositories;
         try {
             writableRepositories = writeLatexDataSource.getWritableRepositories(name);
@@ -54,24 +53,23 @@ public class WLBridgedProject {
                 git.commit().setAuthor(new PersonIdent(contents.getUserName(), contents.getUserEmail(), contents.getWhen(), TimeZone.getDefault()))
                             .setMessage(contents.getCommitMessage())
                             .call();
-                System.out.println(repository.getDirectory());
                 WLFileStore.deleteInDirectoryApartFrom(contents.getDirectory(), ".git");
             }
         } catch (GitAPIException e) {
-            throw new ServiceNotEnabledException();
+            throw new ServiceMayNotContinueException(e);
         } catch (IOException e) {
-            throw new ServiceNotEnabledException();
+            throw new ServiceMayNotContinueException(e);
         }
     }
 
-    private void buildRepositoryFromScratch(Repository repository) throws RepositoryNotFoundException, ServiceNotEnabledException, FailedConnectionException {
+    private void buildRepositoryFromScratch(Repository repository) throws RepositoryNotFoundException, ServiceMayNotContinueException {
         if (!writeLatexDataSource.repositoryExists(name)) {
             throw new RepositoryNotFoundException(name);
         }
         try {
             repository.create();
         } catch (IOException e) {
-            throw new ServiceNotEnabledException();
+            throw new ServiceMayNotContinueException(e);
         }
         updateRepositoryFromSnapshots(repository);
     }

+ 9 - 3
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/git/handler/WLRepositoryResolver.java

@@ -32,14 +32,20 @@ public class WLRepositoryResolver implements RepositoryResolver<HttpServletReque
         try {
             return repositorySource.getRepositoryWithNameAtRootDirectory(Util.removeAllSuffixes(name, "/", ".git"), rootGitDirectory);
         } catch (RepositoryNotFoundException e) {
+            e.printStackTrace();
             throw e;
+            /*
+        } catch (ServiceNotAuthorizedException e) {
+            cannot occur
         } catch (ServiceNotEnabledException e) {
+            cannot occur
+            */
+        } catch (ServiceMayNotContinueException e) { /* Such as FailedConnectionException */
             e.printStackTrace();
             throw e;
-        } catch (Throwable e) {
+        } catch (RuntimeException e) {
             e.printStackTrace();
-            System.out.println("An exception occurred");
-            throw new ServiceNotEnabledException();
+            throw new ServiceMayNotContinueException(e);
         }
     }
 

+ 15 - 12
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/git/handler/hook/WriteLatexPutHook.java

@@ -10,9 +10,10 @@ import uk.ac.ic.wlgitbridge.bridge.WriteLatexDataSource;
 import uk.ac.ic.wlgitbridge.git.handler.hook.exception.ForcedPushException;
 import uk.ac.ic.wlgitbridge.git.handler.hook.exception.WrongBranchException;
 import uk.ac.ic.wlgitbridge.git.util.RepositoryObjectTreeWalker;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.InternalErrorException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.OutOfDateException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
 
 import java.io.IOException;
 import java.util.Collection;
@@ -36,26 +37,28 @@ public class WriteLatexPutHook implements PreReceiveHook {
             try {
                 handleReceiveCommand(receivePack.getRepository(), receiveCommand);
             } catch (IOException e) {
-                receivePack.sendError("IOException");
-                receiveCommand.setResult(Result.REJECTED_OTHER_REASON, "I/O Exception");
-            } catch (FailedConnectionException e) {
-                receivePack.sendError("failed connection");
-                receiveCommand.setResult(Result.REJECTED_OTHER_REASON, "failed connection");
+                receivePack.sendError(e.getMessage());
+                receiveCommand.setResult(Result.REJECTED_OTHER_REASON, e.getMessage());
             } catch (OutOfDateException e) {
                 receiveCommand.setResult(Result.REJECTED_NONFASTFORWARD);
             } catch (SnapshotPostException e) {
-                String message = e.getMessage();
-                receivePack.sendError(message);
-                for (String line : e.getDescriptionLines()) {
-                    receivePack.sendMessage("hint: " + line);
-                }
-                receiveCommand.setResult(Result.REJECTED_OTHER_REASON, message);
+                handleSnapshotPostException(receivePack, receiveCommand, e);
             } catch (Throwable t) {
                 t.printStackTrace();
+                handleSnapshotPostException(receivePack, receiveCommand, new InternalErrorException());
             }
         }
     }
 
+    private void handleSnapshotPostException(ReceivePack receivePack, ReceiveCommand receiveCommand, SnapshotPostException e) {
+        String message = e.getMessage();
+        receivePack.sendError(message);
+        for (String line : e.getDescriptionLines()) {
+            receivePack.sendMessage("hint: " + line);
+        }
+        receiveCommand.setResult(Result.REJECTED_OTHER_REASON, message);
+    }
+
     private void handleReceiveCommand(Repository repository, ReceiveCommand receiveCommand) throws IOException, SnapshotPostException, FailedConnectionException {
         checkBranch(receiveCommand);
         checkForcedPush(receiveCommand);

+ 17 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/Main.java

@@ -0,0 +1,17 @@
+package uk.ac.ic.wlgitbridge.test;
+
+import uk.ac.ic.wlgitbridge.test.server.MockSnapshotServer;
+import uk.ac.ic.wlgitbridge.test.state.SnapshotAPIState;
+
+/**
+ * Created by Winston on 10/01/15.
+ */
+public class Main {
+
+    public static void main(String[] args) {
+        MockSnapshotServer server = new MockSnapshotServer();
+        server.setState(new SnapshotAPIState());
+        server.start();
+    }
+
+}

+ 0 - 46
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/SnapshotDummyServer.java

@@ -1,46 +0,0 @@
-package uk.ac.ic.wlgitbridge.test;
-
-import org.eclipse.jetty.server.NetworkConnector;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.AbstractHandler;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
-
-/**
- * Created by Winston on 09/01/15.
- */
-public class SnapshotDummyServer {
-
-    private final Server server;
-    private int port;
-
-    public SnapshotDummyServer() {
-        server = new Server(0);
-        server.setHandler(new AbstractHandler() {
-            @Override
-            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
-                response.getWriter().println(target);
-                baseRequest.setHandled(true);
-            }
-        });
-    }
-
-    public void start() {
-        try {
-            server.start();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        port = ((NetworkConnector) server.getConnectors()[0]).getLocalPort();
-        System.out.println(port);
-    }
-
-    public static void main(String[] args) {
-        new SnapshotDummyServer().start();
-    }
-
-}

+ 12 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/exception/InvalidAPICallException.java

@@ -0,0 +1,12 @@
+package uk.ac.ic.wlgitbridge.test.exception;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class InvalidAPICallException extends Exception {
+
+    public InvalidAPICallException(String target) {
+        super(target);
+    }
+
+}

+ 14 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/SnapshotResponse.java

@@ -0,0 +1,14 @@
+package uk.ac.ic.wlgitbridge.test.response;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public abstract class SnapshotResponse {
+
+    public abstract String respond();
+
+    public String postback() {
+        return null;
+    }
+
+}

+ 57 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/SnapshotResponseBuilder.java

@@ -0,0 +1,57 @@
+package uk.ac.ic.wlgitbridge.test.response;
+
+import uk.ac.ic.wlgitbridge.test.exception.InvalidAPICallException;
+import uk.ac.ic.wlgitbridge.test.response.getdoc.SnapshotGetDocResponse;
+import uk.ac.ic.wlgitbridge.test.response.getforver.SnapshotGetForVerResponse;
+import uk.ac.ic.wlgitbridge.test.response.getsavedver.SnapshotGetSavedVersResponse;
+import uk.ac.ic.wlgitbridge.test.response.push.SnapshotPushResponse;
+import uk.ac.ic.wlgitbridge.test.state.SnapshotAPIState;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotResponseBuilder {
+
+    private SnapshotAPIState state;
+
+    public SnapshotResponse buildWithTarget(String target, String method) throws InvalidAPICallException {
+        checkPrefix(target);
+        return parseTarget(target, target.split("/"), method);
+    }
+
+    private void checkPrefix(String target) throws InvalidAPICallException {
+        if (!target.startsWith("/api/v0/docs/")) {
+            throw new InvalidAPICallException(target);
+        }
+    }
+
+    private SnapshotResponse parseTarget(String target, String[] parts, String method) throws InvalidAPICallException {
+        String projectName = parts[4];
+        if (parts.length == 5) {
+            if (method.equals("GET")) {
+                return new SnapshotGetDocResponse(state.getStateForGetDoc(projectName));
+            }
+        } else if (parts.length == 6) {
+            String type = parts[5];
+            if (type.equals("snapshots") && method.equals("POST")) {
+                return new SnapshotPushResponse(state.getStateForPush(projectName), state.getStateForPostback(projectName));
+            } else if (type.equals("saved_vers") && method.equals("GET")) {
+                return new SnapshotGetSavedVersResponse(state.getStateForGetSavedVers(projectName));
+            }
+        } else if (parts.length == 7) {
+            if (parts[5].equals("snapshots") && method.equals("GET")) {
+                try {
+                    return new SnapshotGetForVerResponse(state.getStateForGetForVers(projectName, Integer.parseInt(parts[6])));
+                } catch (NumberFormatException e) {
+
+                }
+            }
+        }
+        throw new InvalidAPICallException(target);
+    }
+
+    public void setState(SnapshotAPIState state) {
+        this.state = state;
+    }
+
+}

+ 22 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/getdoc/SnapshotGetDocResponse.java

@@ -0,0 +1,22 @@
+package uk.ac.ic.wlgitbridge.test.response.getdoc;
+
+import uk.ac.ic.wlgitbridge.test.response.SnapshotResponse;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.SnapshotGetDocResult;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotGetDocResponse extends SnapshotResponse {
+
+    private final SnapshotGetDocResult state;
+
+    public SnapshotGetDocResponse(SnapshotGetDocResult state) {
+        this.state = state;
+    }
+
+    @Override
+    public String respond() {
+        return state.toJson().toString();
+    }
+
+}

+ 22 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/getforver/SnapshotGetForVerResponse.java

@@ -0,0 +1,22 @@
+package uk.ac.ic.wlgitbridge.test.response.getforver;
+
+import uk.ac.ic.wlgitbridge.test.response.SnapshotResponse;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion.SnapshotGetForVersionResult;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotGetForVerResponse extends SnapshotResponse {
+
+    private final SnapshotGetForVersionResult state;
+
+    public SnapshotGetForVerResponse(SnapshotGetForVersionResult state) {
+        this.state = state;
+    }
+
+    @Override
+    public String respond() {
+        return state.toJson().toString();
+    }
+
+}

+ 22 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/getsavedver/SnapshotGetSavedVersResponse.java

@@ -0,0 +1,22 @@
+package uk.ac.ic.wlgitbridge.test.response.getsavedver;
+
+import uk.ac.ic.wlgitbridge.test.response.SnapshotResponse;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers.SnapshotGetSavedVersResult;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotGetSavedVersResponse extends SnapshotResponse {
+
+    private final SnapshotGetSavedVersResult state;
+
+    public SnapshotGetSavedVersResponse(SnapshotGetSavedVersResult state) {
+        this.state = state;
+    }
+
+    @Override
+    public String respond() {
+        return state.toJson().toString();
+    }
+
+}

+ 34 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/SnapshotPushResponse.java

@@ -0,0 +1,34 @@
+package uk.ac.ic.wlgitbridge.test.response.push;
+
+import uk.ac.ic.wlgitbridge.test.response.SnapshotResponse;
+import uk.ac.ic.wlgitbridge.test.response.push.postback.SnapshotPostbackRequest;
+import uk.ac.ic.wlgitbridge.test.response.push.data.SnapshotPushResult;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotPushResponse extends SnapshotResponse {
+
+    private final SnapshotPushResult stateForPush;
+    private final SnapshotPostbackRequest stateForPostback;
+
+    public SnapshotPushResponse(SnapshotPushResult stateForPush, SnapshotPostbackRequest stateForPostback) {
+        this.stateForPush = stateForPush;
+        this.stateForPostback = stateForPostback;
+    }
+
+    @Override
+    public String respond() {
+        return stateForPush.toJson().toString();
+    }
+
+    @Override
+    public String postback() {
+        if (stateForPush.hasPostback()) {
+            return stateForPostback.toJson().toString();
+        } else {
+            return null;
+        }
+    }
+
+}

+ 31 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/data/SnapshotPushResult.java

@@ -0,0 +1,31 @@
+package uk.ac.ic.wlgitbridge.test.response.push.data;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public abstract class SnapshotPushResult {
+
+    private final int status;
+    private final String code;
+    private final String message;
+
+    public SnapshotPushResult(int status, String code, String message) {
+        this.status = status;
+        this.code = code;
+        this.message = message;
+    }
+
+    public JsonElement toJson() {
+        JsonObject jsonThis = new JsonObject();
+        jsonThis.addProperty("status", status);
+        jsonThis.addProperty("code", code);
+        jsonThis.addProperty("message", message);
+        return jsonThis;
+    }
+
+    public abstract boolean hasPostback();
+
+}

+ 17 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/data/SnapshotPushResultOutOfDate.java

@@ -0,0 +1,17 @@
+package uk.ac.ic.wlgitbridge.test.response.push.data;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotPushResultOutOfDate extends SnapshotPushResult {
+
+    public SnapshotPushResultOutOfDate() {
+        super(409, "outOfDate", "Out of Date");
+   }
+
+    @Override
+    public boolean hasPostback() {
+        return false;
+    }
+
+}

+ 17 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/data/SnapshotPushResultSuccess.java

@@ -0,0 +1,17 @@
+package uk.ac.ic.wlgitbridge.test.response.push.data;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotPushResultSuccess extends SnapshotPushResult {
+
+    public SnapshotPushResultSuccess() {
+        super(402, "accepted", "Accepted");
+    }
+
+    @Override
+    public boolean hasPostback() {
+        return true;
+    }
+
+}

+ 22 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequest.java

@@ -0,0 +1,22 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback;
+
+import com.google.gson.JsonObject;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public abstract class SnapshotPostbackRequest {
+
+    private final String code;
+
+    public SnapshotPostbackRequest(String code) {
+        this.code = code;
+    }
+
+    public JsonObject toJson() {
+        JsonObject jsonThis = new JsonObject();
+        jsonThis.addProperty("code", code);
+        return jsonThis;
+    }
+
+}

+ 21 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestError.java

@@ -0,0 +1,21 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback;
+
+import com.google.gson.JsonObject;
+
+/**
+ * Created by Winston on 10/01/15.
+ */
+public class SnapshotPostbackRequestError extends SnapshotPostbackRequest {
+
+    public SnapshotPostbackRequestError() {
+        super("error");
+    }
+
+    @Override
+    public JsonObject toJson() {
+        JsonObject jsonThis = super.toJson();
+        jsonThis.addProperty("message", "Unexpected Error");
+        return jsonThis;
+    }
+
+}

+ 32 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestInvalidFiles.java

@@ -0,0 +1,32 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import uk.ac.ic.wlgitbridge.test.response.push.postback.invalidfile.InvalidFileError;
+
+import java.util.List;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotPostbackRequestInvalidFiles extends SnapshotPostbackRequest {
+
+    private final List<InvalidFileError> errors;
+
+    public SnapshotPostbackRequestInvalidFiles(List<InvalidFileError> errors) {
+        super("invalidFiles");
+        this.errors = errors;
+    }
+
+    @Override
+    public JsonObject toJson() {
+        JsonObject jsonThis = super.toJson();
+        JsonArray jsonErrors = new JsonArray();
+        for (InvalidFileError error : errors) {
+            jsonErrors.add(error.toJson());
+        }
+        jsonThis.add("errors", jsonErrors);
+        return jsonThis;
+    }
+
+}

+ 33 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestInvalidProject.java

@@ -0,0 +1,33 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonPrimitive;
+
+import java.util.List;
+
+/**
+ * Created by Winston on 10/01/15.
+ */
+public class SnapshotPostbackRequestInvalidProject extends SnapshotPostbackRequest {
+
+    private final List<String> errors;
+
+    public SnapshotPostbackRequestInvalidProject(List<String> errors) {
+        super("invalidProject");
+        this.errors = errors;
+    }
+
+    @Override
+    public JsonObject toJson() {
+        JsonObject jsonThis = super.toJson();
+        jsonThis.addProperty("message", "short string message for debugging");
+        JsonArray jsonErrors = new JsonArray();
+        for (String error : errors) {
+            jsonErrors.add(new JsonPrimitive(error));
+        }
+        jsonThis.add("errors", jsonErrors);
+        return jsonThis;
+    }
+
+}

+ 21 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestOutOfDate.java

@@ -0,0 +1,21 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback;
+
+import com.google.gson.JsonObject;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotPostbackRequestOutOfDate extends SnapshotPostbackRequest {
+
+    public SnapshotPostbackRequestOutOfDate() {
+        super("outOfDate");
+    }
+
+    @Override
+    public JsonObject toJson() {
+        JsonObject jsonThis = super.toJson();
+        jsonThis.addProperty("message", "Out of Date");
+        return jsonThis;
+    }
+
+}

+ 24 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/SnapshotPostbackRequestSuccess.java

@@ -0,0 +1,24 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback;
+
+import com.google.gson.JsonObject;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class SnapshotPostbackRequestSuccess extends SnapshotPostbackRequest {
+
+    private final int latestVerId;
+
+    public SnapshotPostbackRequestSuccess(int latestVerId) {
+        super("upToDate");
+        this.latestVerId = latestVerId;
+    }
+
+    @Override
+    public JsonObject toJson() {
+        JsonObject jsonThis = super.toJson();
+        jsonThis.addProperty("latestVerId", latestVerId);
+        return jsonThis;
+    }
+
+}

+ 25 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/invalidfile/InvalidFileError.java

@@ -0,0 +1,25 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback.invalidfile;
+
+import com.google.gson.JsonObject;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public abstract class InvalidFileError {
+
+    private final String file;
+
+    public InvalidFileError(String file) {
+        this.file = file;
+    }
+
+    public JsonObject toJson() {
+        JsonObject jsonThis = new JsonObject();
+        jsonThis.addProperty("file", file);
+        jsonThis.addProperty("state", getState());
+        return jsonThis;
+    }
+
+    protected abstract String getState();
+
+}

+ 17 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/invalidfile/InvalidFileErrorDefault.java

@@ -0,0 +1,17 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback.invalidfile;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class InvalidFileErrorDefault extends InvalidFileError {
+
+    public InvalidFileErrorDefault(String file) {
+        super(file);
+    }
+
+    @Override
+    protected String getState() {
+        return "error";
+    }
+
+}

+ 17 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/invalidfile/InvalidFileErrorDisallowed.java

@@ -0,0 +1,17 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback.invalidfile;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class InvalidFileErrorDisallowed extends InvalidFileError {
+
+    public InvalidFileErrorDisallowed(String file) {
+        super(file);
+    }
+
+    @Override
+    protected String getState() {
+        return "disallowed";
+    }
+
+}

+ 29 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/response/push/postback/invalidfile/InvalidFileErrorUnclean.java

@@ -0,0 +1,29 @@
+package uk.ac.ic.wlgitbridge.test.response.push.postback.invalidfile;
+
+import com.google.gson.JsonObject;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class InvalidFileErrorUnclean extends InvalidFileError {
+
+    private final String cleanFile;
+
+    public InvalidFileErrorUnclean(String file, String cleanFile) {
+        super(file);
+        this.cleanFile = cleanFile;
+    }
+
+    @Override
+    public JsonObject toJson() {
+        JsonObject jsonThis = super.toJson();
+        jsonThis.addProperty("cleanFile", cleanFile);
+        return jsonThis;
+    }
+
+    @Override
+    protected String getState() {
+        return "unclean_name";
+    }
+
+}

+ 40 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/server/MockSnapshotRequestHandler.java

@@ -0,0 +1,40 @@
+package uk.ac.ic.wlgitbridge.test.server;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import uk.ac.ic.wlgitbridge.test.exception.InvalidAPICallException;
+import uk.ac.ic.wlgitbridge.test.response.SnapshotResponse;
+import uk.ac.ic.wlgitbridge.test.response.SnapshotResponseBuilder;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class MockSnapshotRequestHandler extends AbstractHandler {
+
+    private final SnapshotResponseBuilder responseBuilder;
+
+    public MockSnapshotRequestHandler(SnapshotResponseBuilder responseBuilder) {
+        this.responseBuilder = responseBuilder;
+    }
+
+    @Override
+    public void handle(String target, final Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+
+        try {
+            final SnapshotResponse snapshotResponse = responseBuilder.buildWithTarget(target, baseRequest.getMethod());
+            response.getWriter().println(snapshotResponse.respond());
+            new PostbackThread(baseRequest.getReader(), snapshotResponse.postback()).startIfNotNull();
+        } catch (InvalidAPICallException e) {
+            e.printStackTrace();
+        } catch (RuntimeException e) {
+            e.printStackTrace();
+        }
+        baseRequest.setHandled(true);
+    }
+
+}

+ 37 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/server/MockSnapshotServer.java

@@ -0,0 +1,37 @@
+package uk.ac.ic.wlgitbridge.test.server;
+
+import org.eclipse.jetty.server.NetworkConnector;
+import org.eclipse.jetty.server.Server;
+import uk.ac.ic.wlgitbridge.test.response.SnapshotResponseBuilder;
+import uk.ac.ic.wlgitbridge.test.state.SnapshotAPIState;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class MockSnapshotServer {
+
+    private final Server server;
+    private final SnapshotResponseBuilder responseBuilder;
+    private int port;
+
+    public MockSnapshotServer() {
+        server = new Server(60000);
+        responseBuilder = new SnapshotResponseBuilder();
+        server.setHandler(new MockSnapshotRequestHandler(responseBuilder));
+    }
+
+    public void start() {
+        try {
+            server.start();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        port = ((NetworkConnector) server.getConnectors()[0]).getLocalPort();
+        System.out.println(port);
+    }
+
+    public void setState(SnapshotAPIState state) {
+        responseBuilder.setState(state);
+    }
+
+}

+ 45 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/server/PostbackThread.java

@@ -0,0 +1,45 @@
+package uk.ac.ic.wlgitbridge.test.server;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.ning.http.client.AsyncHttpClient;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Created by Winston on 10/01/15.
+ */
+public class PostbackThread extends Thread {
+
+    private String url;
+    private String postback;
+
+    public PostbackThread(Reader reader, String postback) {
+        if (postback != null) {
+            url = new Gson().fromJson(reader, JsonObject.class).get("postbackUrl").getAsString();
+            this.postback = postback;
+        }
+    }
+
+    @Override
+    public void run() {
+        try {
+            new AsyncHttpClient().preparePost(url).setBody(postback).execute().get().getResponseBody();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void startIfNotNull() {
+        if (url != null && postback != null) {
+            start();
+        }
+    }
+
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 44 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/test/state/SnapshotAPIState.java


+ 6 - 13
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/SnapshotRepositoryBuilder.java

@@ -3,11 +3,11 @@ package uk.ac.ic.wlgitbridge.writelatex;
 import org.eclipse.jgit.errors.RepositoryNotFoundException;
 import org.eclipse.jgit.lib.Repository;
 import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
-import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
+import org.eclipse.jgit.transport.ServiceMayNotContinueException;
 import uk.ac.ic.wlgitbridge.bridge.RepositorySource;
 import uk.ac.ic.wlgitbridge.bridge.WLBridgedProject;
 import uk.ac.ic.wlgitbridge.bridge.WriteLatexDataSource;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.InternalErrorException;
 
 import java.io.File;
 import java.io.IOException;
@@ -24,13 +24,9 @@ public class SnapshotRepositoryBuilder implements RepositorySource {
     }
 
     @Override
-    public Repository getRepositoryWithNameAtRootDirectory(String name, File rootDirectory) throws RepositoryNotFoundException, ServiceNotEnabledException {
-        try {
-            if (!writeLatexDataSource.repositoryExists(name)) {
-                throw new RepositoryNotFoundException(name);
-            }
-        } catch (FailedConnectionException e) {
-            throw new ServiceNotEnabledException();
+    public Repository getRepositoryWithNameAtRootDirectory(String name, File rootDirectory) throws RepositoryNotFoundException, ServiceMayNotContinueException {
+        if (!writeLatexDataSource.repositoryExists(name)) {
+            throw new RepositoryNotFoundException(name);
         }
         File repositoryDirectory = new File(rootDirectory, name);
 
@@ -38,11 +34,8 @@ public class SnapshotRepositoryBuilder implements RepositorySource {
         try {
             repository = new FileRepositoryBuilder().setWorkTree(repositoryDirectory).build();
             new WLBridgedProject(repository, name, writeLatexDataSource).buildRepository();
-        } catch (FailedConnectionException e) {
-            e.printStackTrace();
-            throw new ServiceNotEnabledException();
         } catch (IOException e) {
-            throw new ServiceNotEnabledException();
+            throw new ServiceMayNotContinueException(new InternalErrorException().getDescriptionLines().get(0));
         }
         return repository;
     }

+ 1 - 3
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/WriteLatexAPI.java

@@ -69,7 +69,7 @@ public class WriteLatexAPI implements WriteLatexDataSource {
     }
 
     @Override
-    public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException, FailedConnectionException {
+    public void putDirectoryContentsToProjectWithName(String projectName, RawDirectoryContents directoryContents, String hostname) throws SnapshotPostException, IOException {
         mainProjectLock.lockForProject(projectName);
         try {
             System.out.println("Pushing project: " + projectName);
@@ -87,8 +87,6 @@ public class WriteLatexAPI implements WriteLatexDataSource {
             throw e;
         } catch (IOException e) {
             throw e;
-        } catch (FailedConnectionException e) {
-            throw e;
         } finally {
             mainProjectLock.unlockForProject(projectName);
         }

+ 9 - 1
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/base/Result.java

@@ -8,7 +8,7 @@ import com.google.gson.JsonElement;
 public abstract class Result implements JSONSource {
 
     private JsonElement json;
-    private final Request request;
+    private Request request;
 
     public Result(Request request, JsonElement json) {
         this.request = request;
@@ -16,12 +16,20 @@ public abstract class Result implements JSONSource {
         fromJSON(json);
     }
 
+    protected Result() {
+    }
+
     public Request getRequest() {
         return request;
     }
 
+    public abstract JsonElement toJson();
+
     @Override
     public String toString() {
+        if (json == null) {
+            return "result";
+        }
         return json.toString();
     }
 

+ 1 - 1
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/base/SnapshotAPIRequest.java

@@ -32,7 +32,7 @@ public abstract class SnapshotAPIRequest<T extends Result> extends Request<T> {
 
     /* baseURL ends with / */
     public static void setBaseURL(String baseURL) {
-        BASE_URL = baseURL + "/docs/";
+        BASE_URL = baseURL + "docs/";
     }
 
 }

+ 9 - 1
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/exception/FailedConnectionException.java

@@ -1,7 +1,15 @@
 package uk.ac.ic.wlgitbridge.writelatex.api.request.exception;
 
+import org.eclipse.jgit.transport.ServiceMayNotContinueException;
+import uk.ac.ic.wlgitbridge.util.Util;
+
 /**
  * Created by Winston on 08/11/14.
  */
-public class FailedConnectionException extends Exception {
+public class FailedConnectionException extends ServiceMayNotContinueException {
+
+    public FailedConnectionException() {
+        super(Util.getServiceName() + " server not available. Please try again later.");
+    }
+
 }

+ 19 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getdoc/SnapshotGetDocResult.java

@@ -23,6 +23,25 @@ public class SnapshotGetDocResult extends Result {
         super(request, json);
     }
 
+    public SnapshotGetDocResult(int versionID, String createdAt, String email, String name) {
+        this.versionID = versionID;
+        this.createdAt = createdAt;
+        this.name = name;
+        this.email = email;
+    }
+
+    @Override
+    public JsonElement toJson() {
+        JsonObject jsonThis = new JsonObject();
+        jsonThis.addProperty("latestVerId", versionID);
+        jsonThis.addProperty("latestVerAt", createdAt);
+        JsonObject latestVerBy = new JsonObject();
+        latestVerBy.addProperty("email", email);
+        latestVerBy.addProperty("name", name);
+        jsonThis.add("latestVerBy", latestVerBy);
+        return jsonThis;
+    }
+
     @Override
     public void fromJSON(JsonElement json) {
         JsonObject jsonObject = json.getAsJsonObject();

+ 13 - 3
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getdoc/exception/InvalidProjectException.java

@@ -1,9 +1,11 @@
 package uk.ac.ic.wlgitbridge.writelatex.api.request.getdoc.exception;
 
+import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
 
+import java.util.LinkedList;
 import java.util.List;
 
 /**
@@ -11,26 +13,34 @@ import java.util.List;
  */
 public class InvalidProjectException extends SnapshotPostException {
 
+    private List<String> errors;
+
     public InvalidProjectException(JsonObject json) {
         super(json);
     }
 
     public InvalidProjectException() {
         super();
+        errors = new LinkedList<String>();
     }
 
     @Override
     public String getMessage() {
-        return null;
+        return "invalid project";
     }
 
     @Override
     public List<String> getDescriptionLines() {
-        return null;
+        return errors;
     }
 
     @Override
     public void fromJSON(JsonElement json) {
-
+        errors = new LinkedList<String>();
+        JsonArray errors = json.getAsJsonObject().get("errors").getAsJsonArray();
+        System.out.println(errors);
+        for (JsonElement error : errors) {
+            this.errors.add(error.getAsString());
+        }
     }
 }

+ 14 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotAttachment.java

@@ -2,6 +2,7 @@ package uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion;
 
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
 
 /**
  * Created by Winston on 06/11/14.
@@ -14,6 +15,19 @@ public class SnapshotAttachment extends SnapshotFile {
         super(json);
     }
 
+    public SnapshotAttachment(String url, String path) {
+        super(null, path);
+        this.url = url;
+    }
+
+    @Override
+    public JsonElement toJson() {
+        JsonArray jsonThis = new JsonArray();
+        jsonThis.add(new JsonPrimitive(url));
+        jsonThis.add(new JsonPrimitive(getPath()));
+        return jsonThis;
+    }
+
     @Override
     public byte[] getContents() {
         return null;

+ 21 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotData.java

@@ -2,6 +2,7 @@ package uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion;
 
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.base.JSONSource;
 
 import java.util.LinkedList;
@@ -24,6 +25,26 @@ public class SnapshotData implements JSONSource {
         fromJSON(json);
     }
 
+    public SnapshotData(List<SnapshotFile> srcs, List<SnapshotAttachment> atts) {
+        this.srcs = srcs;
+        this.atts = atts;
+    }
+
+    public JsonElement toJson() {
+        JsonObject jsonThis = new JsonObject();
+        JsonArray jsonSrcs = new JsonArray();
+        for (SnapshotFile src : srcs) {
+            jsonSrcs.add(src.toJson());
+        }
+        jsonThis.add("srcs", jsonSrcs);
+        JsonArray jsonAtts = new JsonArray();
+        for (SnapshotAttachment att : atts) {
+            jsonAtts.add(att.toJson());
+        }
+        jsonThis.add("atts", jsonAtts);
+        return jsonThis;
+    }
+
     @Override
     public void fromJSON(JsonElement json) {
         populateSrcs(json.getAsJsonObject().get(JSON_KEY_SRCS).getAsJsonArray());

+ 15 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotFile.java

@@ -2,6 +2,7 @@ package uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion;
 
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
+import com.google.gson.JsonPrimitive;
 import uk.ac.ic.wlgitbridge.bridge.RawFile;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.base.JSONSource;
 
@@ -17,6 +18,20 @@ public class SnapshotFile implements JSONSource, RawFile {
         fromJSON(json);
     }
 
+    public SnapshotFile(String contents, String path) {
+        this.path = path;
+        if (contents != null) {
+            this.contents = contents.getBytes();
+        }
+    }
+
+    public JsonElement toJson() {
+        JsonArray jsonThis = new JsonArray();
+        jsonThis.add(new JsonPrimitive(new String(contents)));
+        jsonThis.add(new JsonPrimitive(path));
+        return jsonThis;
+    }
+
     @Override
     public String getPath() {
         return path;

+ 9 - 1
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getforversion/SnapshotGetForVersionResult.java

@@ -3,7 +3,6 @@ package uk.ac.ic.wlgitbridge.writelatex.api.request.getforversion;
 import com.google.gson.JsonElement;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.base.Request;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.base.Result;
-import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
 
 /**
  * Created by Winston on 06/11/14.
@@ -16,6 +15,15 @@ public class SnapshotGetForVersionResult extends Result {
         super(request, json);
     }
 
+    public SnapshotGetForVersionResult(SnapshotData snapshotData) {
+        this.snapshotData = snapshotData;
+    }
+
+    @Override
+    public JsonElement toJson() {
+        return snapshotData.toJson();
+    }
+
     @Override
     public void fromJSON(JsonElement json) {
         snapshotData = new SnapshotData(json);

+ 24 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getsavedvers/SnapshotGetSavedVersResult.java

@@ -1,7 +1,9 @@
 package uk.ac.ic.wlgitbridge.writelatex.api.request.getsavedvers;
 
 import com.google.gson.Gson;
+import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.base.Request;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.base.Result;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.exception.FailedConnectionException;
@@ -20,6 +22,28 @@ public class SnapshotGetSavedVersResult extends Result {
         super(request, json);
     }
 
+    public SnapshotGetSavedVersResult(List<SnapshotInfo> savedVers) {
+        this.savedVers = savedVers;
+    }
+
+    @Override
+    public JsonElement toJson() {
+        JsonArray jsonThis = new JsonArray();
+        for (SnapshotInfo savedVer : savedVers) {
+            JsonObject jsonSavedVer = new JsonObject();
+            jsonSavedVer.addProperty("versionId", savedVer.getVersionId());
+            jsonSavedVer.addProperty("comment", savedVer.getComment());
+            WLUser user = savedVer.getUser();
+            JsonObject jsonUser = new JsonObject();
+            jsonUser.addProperty("email", user.getEmail());
+            jsonUser.addProperty("name", user.getName());
+            jsonSavedVer.add("user", jsonUser);
+            jsonSavedVer.addProperty("createdAt", savedVer.getCreatedAt());
+            jsonThis.add(jsonSavedVer);
+        }
+        return jsonThis;
+    }
+
     @Override
     public void fromJSON(JsonElement json) {
         savedVers = new LinkedList<SnapshotInfo>();

+ 6 - 2
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/getsavedvers/SnapshotInfo.java

@@ -13,8 +13,12 @@ public class SnapshotInfo {
     private String createdAt;
 
     public SnapshotInfo(int versionID, String createdAt, String name, String email) {
-        this.versionId = versionID;
-        comment = "Update on " + Util.getServiceName() + ".";
+        this(versionID, "Update on " + Util.getServiceName() + ".", name, email, createdAt);
+    }
+
+    public SnapshotInfo(int versionID, String comment, String email, String name, String createdAt) {
+        versionId = versionID;
+        this.comment = comment;
         user = new WLUser(name, email);
         this.createdAt = createdAt;
     }

+ 48 - 20
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/PostbackContents.java

@@ -1,14 +1,22 @@
 package uk.ac.ic.wlgitbridge.writelatex.api.request.push;
 
+import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.InternalErrorException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.InvalidPostbackKeyException;
+import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.PostbackTimeoutException;
 import uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception.SnapshotPostException;
 
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
 /**
  * Created by Winston on 17/11/14.
  */
 public class PostbackContents {
 
     private final String postbackKey;
+    private final ReentrantLock lock;
+    private final Condition cond;
 
     private boolean received;
     private int versionID;
@@ -16,37 +24,57 @@ public class PostbackContents {
 
     public PostbackContents(String postbackKey) {
         this.postbackKey = postbackKey;
+        lock = new ReentrantLock();
+        cond = lock.newCondition();
         received = false;
         exception = null;
     }
 
-    public synchronized int waitForPostback() throws SnapshotPostException {
-        while (!received) {
-            try {
-                wait();
-            } catch (InterruptedException e) {
-                e.printStackTrace();
+    public int waitForPostback() throws SnapshotPostException {
+        lock.lock();
+        try {
+            while (!received) {
+                try {
+                    if (!cond.await(30, TimeUnit.SECONDS)) {
+                        throw new PostbackTimeoutException();
+                    }
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                    throw new InternalErrorException();
+                }
             }
+            if (exception != null) {
+                throw exception;
+            }
+            return versionID;
+        } finally {
+            lock.unlock();
         }
-        if (exception != null) {
-            throw exception;
-        }
-        return versionID;
     }
 
-    public synchronized void receivedVersionID(int versionID, String postbackKey) {
-        if (postbackKey.equals(this.postbackKey)) {
-            this.versionID = versionID;
-            received = true;
-            notifyAll();
+    public void receivedVersionID(int versionID, String postbackKey) {
+        lock.lock();
+        try {
+            if (postbackKey.equals(this.postbackKey)) {
+                this.versionID = versionID;
+                received = true;
+                cond.signalAll();
+            }
+        } finally {
+            lock.unlock();
         }
     }
 
-    public synchronized void receivedException(SnapshotPostException exception, String postbackKey) {
-        if (postbackKey.equals(this.postbackKey)) {
-            this.exception = exception;
-            received = true;
-            notifyAll();
+    public void receivedException(SnapshotPostException exception, String postbackKey) {
+        lock.lock();
+        try {
+            if (postbackKey.equals(this.postbackKey)) {
+                this.exception = exception;
+                received = true;
+                cond.signalAll();
+            }
+        } finally {
+            lock.unlock();
         }
     }
 

+ 7 - 3
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/PostbackManager.java

@@ -23,9 +23,13 @@ public class PostbackManager {
     }
 
     public int getVersionID(String projectName) throws SnapshotPostException {
-        int versionID = postbackContentsTable.get(projectName).waitForPostback();
-        postbackContentsTable.remove(projectName);
-        return versionID;
+        try {
+            return postbackContentsTable.get(projectName).waitForPostback();
+        } catch (SnapshotPostException e) {
+            throw e;
+        } finally {
+            postbackContentsTable.remove(projectName);
+        }
     }
 
     public void postVersionIDForProject(String projectName, int versionID, String postbackKey) throws UnexpectedPostbackException {

+ 5 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/SnapshotPushRequestResult.java

@@ -17,6 +17,11 @@ public class SnapshotPushRequestResult extends Result {
         super(request, json);
     }
 
+    @Override
+    public JsonElement toJson() {
+        return null;
+    }
+
     public boolean wasSuccessful() {
         return success;
     }

+ 30 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/exception/InternalErrorException.java

@@ -0,0 +1,30 @@
+package uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception;
+
+import com.google.gson.JsonElement;
+import uk.ac.ic.wlgitbridge.util.Util;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class InternalErrorException extends SnapshotPostException {
+
+    @Override
+    public String getMessage() {
+        return "internal error";
+    }
+
+    @Override
+    public List<String> getDescriptionLines() {
+        return Arrays.asList("There as an internal error with the Git server.",
+                             "Please contact " + Util.getServiceName() + ".");
+    }
+
+    @Override
+    public void fromJSON(JsonElement json) {
+
+    }
+
+}

+ 29 - 0
services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/writelatex/api/request/push/exception/PostbackTimeoutException.java

@@ -0,0 +1,29 @@
+package uk.ac.ic.wlgitbridge.writelatex.api.request.push.exception;
+
+import com.google.gson.JsonElement;
+import uk.ac.ic.wlgitbridge.util.Util;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Created by Winston on 09/01/15.
+ */
+public class PostbackTimeoutException extends SnapshotPostException {
+
+    @Override
+    public String getMessage() {
+        return "timeout";
+    }
+
+    @Override
+    public List<String> getDescriptionLines() {
+        return Arrays.asList("The " + Util.getServiceName() + " server is currently unavailable.", "Please try again later.");
+    }
+
+    @Override
+    public void fromJSON(JsonElement json) {
+
+    }
+
+}

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio