aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPiotr Janik2011-06-29 07:19:06 (EDT)
committerSzymon Brandys2011-06-29 07:19:06 (EDT)
commita1cccf0254e0fec09366f5805ea89b25f382b939 (patch)
tree0006375adb4a3a446bff07bee096a682791b3561
parent9b53b80cd424cb6d4de3206fef0501f71e856f20 (diff)
downloadorg.eclipse.orion.server-a1cccf0254e0fec09366f5805ea89b25f382b939.zip
org.eclipse.orion.server-a1cccf0254e0fec09366f5805ea89b25f382b939.tar.gz
org.eclipse.orion.server-a1cccf0254e0fec09366f5805ea89b25f382b939.tar.bz2
bug 349952 - [git][server] Git Init should be a task
https://bugs.eclipse.org/bugs/show_bug.cgi?id=349952
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java33
-rw-r--r--bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/InitJob.java127
-rw-r--r--tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java71
-rw-r--r--tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitInitTest.java1
-rw-r--r--tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitTest.java7
5 files changed, 212 insertions, 27 deletions
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java
index 9c3c242..eebbd1e 100644
--- a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/GitCloneHandlerV1.java
@@ -167,27 +167,21 @@ public class GitCloneHandlerV1 extends ServletResourceHandler<String> {
clone.setContentLocation(webProject.getProjectStore().toURI());
}
clone.setName(cloneName);
+ JSONObject cloneObject = WebClone.toJSON(clone, getURI(request));
+ String cloneLocation = cloneObject.getString(ProtocolConstants.KEY_LOCATION);
if (initOnly) {
// git init
- // call Init using JGit porcelain API
- InitCommand command = new InitCommand();
- File directory = new File(clone.getContentLocation());
- command.setDirectory(directory);
- Repository repository = command.call().getRepository();
- Git git = new Git(repository);
-
- // configure the repo
- doConfigureClone(git, request.getRemoteUser());
-
- // we need to perform an initial commit to workaround JGit bug 339610
- git.commit().setMessage("Initial commit").call();
-
- JSONObject result = WebClone.toJSON(clone, getURI(request));
- String cloneLocation = result.getString(ProtocolConstants.KEY_LOCATION);
+ InitJob job = new InitJob(clone, request.getRemoteUser(), cloneLocation);
+ job.schedule();
+ TaskInfo task = job.getTask();
+ JSONObject result = task.toJSON();
+ // Not nice that the git service knows the location of the task servlet, but task service doesn't know this either
+ String taskLocation = getURI(request).resolve("../../task/id/" + task.getTaskId()).toString(); //$NON-NLS-1$
+ result.put(ProtocolConstants.KEY_LOCATION, taskLocation);
+ response.setHeader(ProtocolConstants.HEADER_LOCATION, taskLocation);
OrionServlet.writeJSONResponse(request, response, result);
- response.setHeader(ProtocolConstants.HEADER_LOCATION, cloneLocation);
- response.setStatus(HttpServletResponse.SC_CREATED);
+ response.setStatus(HttpServletResponse.SC_ACCEPTED);
return true;
} else {
// git clone
@@ -204,15 +198,12 @@ public class GitCloneHandlerV1 extends ServletResourceHandler<String> {
cp.setPublicKey(publicKey);
cp.setPassphrase(passphrase);
- JSONObject cloneObject = WebClone.toJSON(clone, getURI(request));
- String cloneLocation = cloneObject.getString(ProtocolConstants.KEY_LOCATION);
-
// if all went well, clone
CloneJob job = new CloneJob(clone, cp, request.getRemoteUser(), cloneLocation, webProjectExists ? null : webProject /* used for cleaning up, so null when not needed */);
job.schedule();
TaskInfo task = job.getTask();
JSONObject result = task.toJSON();
- //Not nice that the git service knows the location of the task servlet, but task service doesn't know this either
+ // Not nice that the git service knows the location of the task servlet, but task service doesn't know this either
String taskLocation = getURI(request).resolve("../../task/id/" + task.getTaskId()).toString(); //$NON-NLS-1$
result.put(ProtocolConstants.KEY_LOCATION, taskLocation);
response.setHeader(ProtocolConstants.HEADER_LOCATION, taskLocation);
diff --git a/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/InitJob.java b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/InitJob.java
new file mode 100644
index 0000000..668c309
--- /dev/null
+++ b/bundles/org.eclipse.orion.server.git/src/org/eclipse/orion/server/git/servlets/InitJob.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.orion.server.git.servlets;
+
+import java.io.File;
+import org.eclipse.core.runtime.*;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.InitCommand;
+import org.eclipse.jgit.api.errors.JGitInternalException;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.orion.server.core.tasks.ITaskService;
+import org.eclipse.orion.server.core.tasks.TaskInfo;
+import org.eclipse.orion.server.git.GitActivator;
+import org.eclipse.osgi.util.NLS;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * A job to perform an init operation in the background
+ */
+public class InitJob extends GitJob {
+
+ private final WebClone clone;
+ private final TaskInfo task;
+ private ITaskService taskService;
+ private ServiceReference<ITaskService> taskServiceRef;
+ private final String user;
+ private final String cloneLocation;
+
+ public InitJob(WebClone clone, String user, String cloneLocation) {
+ super("Init"); //$NON-NLS-1$
+ this.clone = clone;
+ this.user = user;
+ this.cloneLocation = cloneLocation;
+ this.task = createTask();
+ }
+
+ private TaskInfo createTask() {
+ TaskInfo info = getTaskService().createTask();
+ info.setMessage(NLS.bind("Initializing repository {0}...", clone.getName()));
+ getTaskService().updateTask(info);
+ return info;
+ }
+
+ private IStatus doInit() {
+ try {
+ InitCommand command = new InitCommand();
+ File directory = new File(clone.getContentLocation());
+ command.setDirectory(directory);
+ Repository repository = command.call().getRepository();
+ Git git = new Git(repository);
+
+ // configure the repo
+ GitCloneHandlerV1.doConfigureClone(git, user);
+
+ // we need to perform an initial commit to workaround JGit bug 339610
+ git.commit().setMessage("Initial commit").call();
+ } catch (CoreException e) {
+ return e.getStatus();
+ } catch (JGitInternalException e) {
+ return getJGitInternalExceptionStatus(e, "An internal git error initializing git repository.");
+ } catch (Exception e) {
+ return new Status(IStatus.ERROR, GitActivator.PI_GIT, "Error initializing git repository", e);
+ }
+ return Status.OK_STATUS;
+ }
+
+ public TaskInfo getTask() {
+ return task;
+ }
+
+ private ITaskService getTaskService() {
+ if (taskService == null) {
+ BundleContext context = GitActivator.getDefault().getBundleContext();
+ if (taskServiceRef == null) {
+ taskServiceRef = context.getServiceReference(ITaskService.class);
+ if (taskServiceRef == null)
+ throw new IllegalStateException("Task service not available");
+ }
+ taskService = context.getService(taskServiceRef);
+ if (taskService == null)
+ throw new IllegalStateException("Task service not available");
+ }
+ return taskService;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ IStatus result = doInit();
+ if (result.isOK()) {
+ // save the clone metadata
+ task.setResultLocation(cloneLocation);
+ String message = "Init complete.";
+ task.setMessage(message);
+ result = new Status(IStatus.OK, GitActivator.PI_GIT, message);
+ }
+ task.done(result);
+ updateTask();
+ //return the actual result so errors are logged
+ return result;
+ } finally {
+ cleanUp();
+ }
+ }
+
+ private void cleanUp() {
+ taskService = null;
+ if (taskServiceRef != null) {
+ GitActivator.getDefault().getBundleContext().ungetService(taskServiceRef);
+ taskServiceRef = null;
+ }
+ }
+
+ private void updateTask() {
+ getTaskService().updateTask(task);
+ }
+
+}
diff --git a/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java b/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java
index bb6740e..95bd3a0 100644
--- a/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java
+++ b/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitConfigTest.java
@@ -50,8 +50,7 @@ public class GitConfigTest extends GitTest {
private static final String GIT_COMMIT_MESSAGE = "message";
@Test
- public void testConfigUsingUserProfile() throws Exception {
-
+ public void testClonedRepoConfigUsingUserProfile() throws Exception {
// set Git name and mail in the user profile
WebRequest request = getPutUserRequest();
WebResponse response = webConversation.getResponse(request);
@@ -61,6 +60,7 @@ public class GitConfigTest extends GitTest {
URI workspaceLocation = createWorkspace(getMethodName());
JSONObject project = createProjectOrLink(workspaceLocation, getMethodName(), null);
IPath clonePath = new Path("file").append(project.getString(ProtocolConstants.KEY_ID)).makeAbsolute();
+
String contentLocation = clone(clonePath).getString(ProtocolConstants.KEY_CONTENT_LOCATION);
// check the repository configuration using JGit API
@@ -117,6 +117,73 @@ public class GitConfigTest extends GitTest {
}
@Test
+ public void testInitializedRepoConfigUsingUserProfile() throws Exception {
+ // set Git name and mail in the user profile
+ WebRequest request = getPutUserRequest();
+ WebResponse response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+
+ // init a repo
+ URI workspaceLocation = createWorkspace(getMethodName());
+ JSONObject project = createProjectOrLink(workspaceLocation, getMethodName(), null);
+ IPath initPath = new Path("file").append(project.getString(ProtocolConstants.KEY_ID)).makeAbsolute();
+
+ String contentLocation = init(null, initPath, null).getString(ProtocolConstants.KEY_CONTENT_LOCATION);
+
+ // check the repository configuration using JGit API
+ Git git = new Git(getRepositoryForContentLocation(contentLocation));
+ StoredConfig config = git.getRepository().getConfig();
+ assertEquals(GIT_NAME, config.getString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_NAME));
+ assertEquals(GIT_MAIL, config.getString(ConfigConstants.CONFIG_USER_SECTION, null, ConfigConstants.CONFIG_KEY_EMAIL));
+
+ // now check if commits have the right committer set
+
+ request = getGetFilesRequest(project.getString(ProtocolConstants.KEY_CONTENT_LOCATION));
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+ project = new JSONObject(response.getText());
+ String childrenLocation = project.getString(ProtocolConstants.KEY_CHILDREN_LOCATION);
+ assertNotNull(childrenLocation);
+
+ // check if Git locations are in place
+ JSONObject gitSection = project.optJSONObject(GitConstants.KEY_GIT);
+ assertNotNull(gitSection);
+ String gitIndexUri = gitSection.getString(GitConstants.KEY_INDEX);
+ String gitHeadUri = gitSection.getString(GitConstants.KEY_HEAD);
+
+ // modify
+ String projectLocation = project.getString(ProtocolConstants.KEY_LOCATION);
+ request = getPutFileRequest(projectLocation + "/test.txt", "change to commit");
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+
+ // add
+ request = GitAddTest.getPutGitIndexRequest(gitIndexUri + "test.txt");
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+
+ // commit all
+ request = GitCommitTest.getPostGitCommitRequest(gitHeadUri /* all */, GIT_COMMIT_MESSAGE, false);
+ response = webConversation.getResponse(request);
+ assertEquals(HttpURLConnection.HTTP_OK, response.getResponseCode());
+
+ // log
+ // TODO: replace with RESTful API for git log when available
+ Iterable<RevCommit> commits = git.log().call();
+ PersonIdent testIdent = new PersonIdent(GIT_NAME, GIT_MAIL);
+ PersonIdent[] expectedIdents = new PersonIdent[] {testIdent};
+ int c = 0;
+ for (RevCommit commit : commits) {
+ if (commit.getFullMessage().equals(GIT_COMMIT_MESSAGE)) {
+ assertEquals(expectedIdents[expectedIdents.length - 1 - c].getName(), commit.getCommitterIdent().getName());
+ assertEquals(expectedIdents[expectedIdents.length - 1 - c].getEmailAddress(), commit.getCommitterIdent().getEmailAddress());
+ }
+ c++;
+ }
+ assertEquals(2, c);
+ }
+
+ @Test
public void testGetListOfConfigEntries() throws Exception {
URI workspaceLocation = createWorkspace(getMethodName());
JSONObject projectTop = createProjectOrLink(workspaceLocation, getMethodName() + "-top", null);
diff --git a/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitInitTest.java b/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitInitTest.java
index b1e6310..63f66ba 100644
--- a/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitInitTest.java
+++ b/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitInitTest.java
@@ -84,7 +84,6 @@ public class GitInitTest extends GitTest {
@Test
public void testInitWithoutNameAndFilePath() throws Exception {
URI workspaceLocation = createWorkspace(getMethodName());
- JSONObject project = createProjectOrLink(workspaceLocation, getMethodName(), null);
IPath initPath = new Path("workspace").append(getWorkspaceId(workspaceLocation)).makeAbsolute();
WebRequest request = getPostGitInitRequest(initPath, null, null);
diff --git a/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitTest.java b/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitTest.java
index 8bcaa08..1b7d1c5 100644
--- a/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitTest.java
+++ b/tests/org.eclipse.orion.server.tests/src/org/eclipse/orion/server/tests/servlets/git/GitTest.java
@@ -346,9 +346,10 @@ public abstract class GitTest extends FileSystemTest {
// no Git URL for init
WebRequest request = getPostGitCloneRequest(null, workspacePath, filePath, name, null, null);
WebResponse response = webConversation.getResponse(request);
- assertEquals(HttpURLConnection.HTTP_CREATED, response.getResponseCode());
- String cloneLocation = response.getHeaderField(ProtocolConstants.HEADER_LOCATION);
- assertNotNull(cloneLocation);
+ assertEquals(HttpURLConnection.HTTP_ACCEPTED, response.getResponseCode());
+ String taskLocation = response.getHeaderField(ProtocolConstants.HEADER_LOCATION);
+ assertNotNull(taskLocation);
+ String cloneLocation = waitForTaskCompletion(taskLocation);
// validate the clone metadata
response = webConversation.getResponse(getGetRequest(cloneLocation));