diff options
author | Frank Becker | 2014-01-25 20:43:56 +0000 |
---|---|---|
committer | Frank Becker | 2014-10-30 20:41:03 +0000 |
commit | dcdbb2290e00179f91eb07c941631fd8a3bf9d0a (patch) | |
tree | 858df5d6da333b967b1e2ec5d3f6f8a7c75b76b1 | |
parent | abfaa73eca9a4744aff89cdac82057c49719f7cb (diff) | |
download | org.eclipse.mylyn.tasks-dcdbb2290e00179f91eb07c941631fd8a3bf9d0a.tar.gz org.eclipse.mylyn.tasks-dcdbb2290e00179f91eb07c941631fd8a3bf9d0a.tar.xz org.eclipse.mylyn.tasks-dcdbb2290e00179f91eb07c941631fd8a3bf9d0a.zip |
426644: add dummy RepositoryConfiguration to the REST Client
Change-Id: Ib34339764ab981e786aa941a141143b390874d21
Task-Url: https://bugs.eclipse.org/bugs/show_bug.cgi?id=426644
16 files changed, 706 insertions, 18 deletions
diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/META-INF/MANIFEST.MF b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/META-INF/MANIFEST.MF index caf04bc01..45032365d 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/META-INF/MANIFEST.MF +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/META-INF/MANIFEST.MF @@ -6,5 +6,6 @@ Bundle-Version: 1.0.0.qualifier Bundle-Vendor: Eclipse Mylyn Fragment-Host: org.eclipse.mylyn.bugzilla.rest.core Bundle-RequiredExecutionEnvironment: JavaSE-1.6 -Require-Bundle: org.junit;bundle-version="4.8.2" +Require-Bundle: org.junit;bundle-version="4.8.2", + org.eclipse.mylyn.commons.sdk.util Export-Package: org.eclipse.mylyn.internal.bugzilla.rest.core;x-internal:=true diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java new file mode 100644 index 000000000..6432728e3 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestClientTest.java @@ -0,0 +1,154 @@ +/******************************************************************************* + * Copyright (c) 2014 Frank Becker 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: + * Frank Becker - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.bugzilla.rest.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.eclipse.mylyn.commons.net.AuthenticationCredentials; +import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation; +import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType; +import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials; +import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil; +import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil.PrivilegeLevel; +import org.eclipse.mylyn.commons.sdk.util.Junit4TestFixtureRunner; +import org.eclipse.mylyn.commons.sdk.util.Junit4TestFixtureRunner.FixtureDefinition; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestClient; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestConnector; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestException; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestVersion; +import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.BugzillaRestLoginToken; +import org.eclipse.mylyn.internal.bugzilla.rest.test.support.BugzillaRestTestFixture; +import org.eclipse.mylyn.internal.commons.core.operations.NullOperationMonitor; +import org.eclipse.mylyn.internal.commons.repositories.core.InMemoryCredentialsStore; +import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; + +@SuppressWarnings("restriction") +@RunWith(Junit4TestFixtureRunner.class) +@FixtureDefinition(fixtureClass = BugzillaRestTestFixture.class, fixtureType = "bugzillaREST") +// use this if you only want to run the test class if the property exists with +// the value in the fixture. +// Note: When there is no fixture with this property no tests get executed +//@RunOnlyWhenProperty(property = "default", value = "1") +public class BugzillaRestClientTest { + private final BugzillaRestTestFixture actualFixture; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private static TaskRepositoryManager manager; + + private BugzillaRestConnector connector; + + public BugzillaRestClientTest(BugzillaRestTestFixture fixture) { + this.actualFixture = fixture; + } + + @BeforeClass + public static void setUpClass() { + manager = new TaskRepositoryManager(); + } + + @Before + public void setUp() { + manager.addRepository(actualFixture.repository()); + connector = new BugzillaRestConnector(); + } + + @After + public void tearDown() throws Exception { + manager.clearRepositories(); + } + + @Test + public void testConnectorClientCache() throws Exception { + BugzillaRestClient client1 = connector.getClient(actualFixture.repository()); + assertNotNull(client1); + } + + @Test + public void testConnectorClientCacheRepositoryNotInManagerFailwithID() throws Exception { + TaskRepository repository = new TaskRepository(actualFixture.getConnectorKind(), + actualFixture.getRepositoryUrl()); + UserCredentials credentials = CommonTestUtil.getCredentials(PrivilegeLevel.USER); + repository.setCredentials(org.eclipse.mylyn.commons.net.AuthenticationType.REPOSITORY, + new AuthenticationCredentials(credentials.getUserName(), credentials.getPassword()), true); + BugzillaRestClient client1 = connector.getClient(repository); + assertNotNull(client1); + } + + @Test + public void testGetVersion() throws Exception { + BugzillaRestClient client = new BugzillaRestClient(actualFixture.location()); + assertNotNull(client.getClient()); + assertNull(client.getClient().getLoginToken()); + BugzillaRestVersion version = client.getVersion(new NullOperationMonitor()); + assertEquals("expeccted: " + actualFixture.getVersion() + " actual: " + version.toString(), + actualFixture.getVersion(), version.toString()); + } + + @Test + public void testValidate() throws Exception { + BugzillaRestClient client = new BugzillaRestClient(actualFixture.location()); + assertNotNull(client.getClient()); + assertNull(client.getClient().getLoginToken()); + assertTrue(client.validate(new NullOperationMonitor())); + assertNotNull(client.getClient()); + BugzillaRestLoginToken token = client.getClient().getLoginToken(); + assertNotNull(token); + assertEquals("2", token.getId()); + assertNotNull(token.getToken()); + assertTrue(token.getToken().length() > 0); + } + + @Test + public void testInvalideUserValidate() throws BugzillaRestException { + RepositoryLocation location = new RepositoryLocation(); + location.setUrl(actualFixture.getRepositoryUrl()); + location.setProxy(null); + location.setCredentialsStore(new InMemoryCredentialsStore()); + location.setCredentials(AuthenticationType.REPOSITORY, new UserCredentials("wrong", "wrong")); + thrown.expect(BugzillaRestException.class); + thrown.expectMessage("Authentication failed"); + BugzillaRestClient client; + client = new BugzillaRestClient(location); + assertNotNull(client.getClient()); + assertNull(client.getClient().getLoginToken()); + client.validate(new NullOperationMonitor()); + } + + @Test + public void testNoUserValidate() throws BugzillaRestException { + RepositoryLocation location = new RepositoryLocation(); + location.setUrl(actualFixture.getRepositoryUrl()); + location.setProxy(null); + location.setCredentialsStore(new InMemoryCredentialsStore()); + location.setCredentials(AuthenticationType.REPOSITORY, null); + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Authentication requested without valid credentials"); + BugzillaRestClient client; + client = new BugzillaRestClient(location); + assertNotNull(client.getClient()); + assertNull(client.getClient().getLoginToken()); + client.validate(new NullOperationMonitor()); + } +}
\ No newline at end of file diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestConfigurationTest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestConfigurationTest.java new file mode 100644 index 000000000..2ff339046 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestConfigurationTest.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2014 Frank Becker 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: + * Frank Becker - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.bugzilla.rest.core.tests; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.mylyn.commons.sdk.util.Junit4TestFixtureRunner; +import org.eclipse.mylyn.commons.sdk.util.Junit4TestFixtureRunner.FixtureDefinition; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestConnector; +import org.eclipse.mylyn.internal.bugzilla.rest.core.RepositoryKey; +import org.eclipse.mylyn.internal.bugzilla.rest.test.support.BugzillaRestTestFixture; +import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +@SuppressWarnings("restriction") +@RunWith(Junit4TestFixtureRunner.class) +@FixtureDefinition(fixtureClass = BugzillaRestTestFixture.class, fixtureType = "bugzillaREST") +//@RunOnlyWhenProperty(property = "default", value = "1") +public class BugzillaRestConfigurationTest { + private final BugzillaRestTestFixture actualFixture; + + private static TaskRepositoryManager manager; + + public BugzillaRestConfigurationTest(BugzillaRestTestFixture fixture) { + this.actualFixture = fixture; + } + + @BeforeClass + public static void setUpClass() { + manager = new TaskRepositoryManager(); + } + + @Test + public void testRepositoryKey() throws CoreException { + RepositoryKey rep1 = new RepositoryKey(new TaskRepository("xx", "url")); + RepositoryKey rep2 = new RepositoryKey(new TaskRepository("xx1", "url1")); + RepositoryKey rep3 = new RepositoryKey(new TaskRepository("xx", "url")); + assertTrue(rep1.equals(rep1)); + assertTrue(rep1.equals(rep3)); + assertFalse(rep1.equals(rep2)); + } + + @Test + public void testConfigurationFromConnector() throws CoreException { + BugzillaRestConnector connector = new BugzillaRestConnector(); + assertNotNull(connector); + assertNull(connector.getRepositoryConfiguration(actualFixture.repository())); + } + +} diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestConnectorTest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestConnectorTest.java new file mode 100644 index 000000000..083c879c5 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/core/tests/BugzillaRestConnectorTest.java @@ -0,0 +1,46 @@ +package org.eclipse.mylyn.internal.bugzilla.rest.core.tests; + +import static org.junit.Assert.assertNull; + +import org.eclipse.mylyn.commons.net.AuthenticationCredentials; +import org.eclipse.mylyn.commons.net.AuthenticationType; +import org.eclipse.mylyn.commons.sdk.util.Junit4TestFixtureRunner; +import org.eclipse.mylyn.commons.sdk.util.Junit4TestFixtureRunner.FixtureDefinition; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestConfiguration; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestConnector; +import org.eclipse.mylyn.internal.bugzilla.rest.test.support.BugzillaRestTestFixture; +import org.eclipse.mylyn.internal.tasks.core.TaskRepositoryManager; +import org.eclipse.mylyn.tasks.core.TaskRepository; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(Junit4TestFixtureRunner.class) +@FixtureDefinition(fixtureClass = BugzillaRestTestFixture.class, fixtureType = "bugzillaREST") +public class BugzillaRestConnectorTest { + private final BugzillaRestTestFixture actualFixture; + + private static TaskRepositoryManager manager; + + private BugzillaRestConnector connector; + + public BugzillaRestConnectorTest(BugzillaRestTestFixture fixture) { + this.actualFixture = fixture; + } + + @Before + public void setUp() { + connector = new BugzillaRestConnector(); + } + + @Test + public void testLoadCacheWrongRepository() throws Exception { + TaskRepository taskRepository = new TaskRepository(connector.getConnectorKind(), + "http://mylyn.org/bugzilla-rest-trunk-wrong/"); + AuthenticationCredentials credentials = new AuthenticationCredentials("username", "password"); + taskRepository.setCredentials(AuthenticationType.REPOSITORY, credentials, false); + BugzillaRestConfiguration configuration = connector.getRepositoryConfiguration(taskRepository); + assertNull(configuration); + } + +} diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/test/support/BugzillaRestTestFixture.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/test/support/BugzillaRestTestFixture.java new file mode 100644 index 000000000..defde2aa1 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core.tests/src/org/eclipse/mylyn/internal/bugzilla/rest/test/support/BugzillaRestTestFixture.java @@ -0,0 +1,56 @@ +/******************************************************************************* + * Copyright (c) 2014 Frank Becker 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: + * Frank Becker - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.bugzilla.rest.test.support; + +import org.eclipse.mylyn.commons.net.AuthenticationCredentials; +import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials; +import org.eclipse.mylyn.commons.sdk.util.AbstractTestFixture; +import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil; +import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil.PrivilegeLevel; +import org.eclipse.mylyn.commons.sdk.util.FixtureConfiguration; +import org.eclipse.mylyn.commons.sdk.util.TestConfiguration; +import org.eclipse.mylyn.internal.bugzilla.rest.core.BugzillaRestCore; +import org.eclipse.mylyn.tasks.core.TaskRepository; + +public class BugzillaRestTestFixture extends AbstractTestFixture { + + public final String version; + + protected TaskRepository repository; + + @Override + protected AbstractTestFixture getDefault() { + return TestConfiguration.getDefault().discoverDefault(BugzillaRestTestFixture.class, "bugzillaREST"); + } + + public BugzillaRestTestFixture(FixtureConfiguration config) { + super(BugzillaRestCore.CONNECTOR_KIND, config); + version = config.getVersion(); + setInfo("Bugzilla", config.getVersion(), config.getInfo()); + } + + public String getVersion() { + return version; + } + + public TaskRepository repository() { + if (repository != null) { + return repository; + } + repository = new TaskRepository(getConnectorKind(), getRepositoryUrl()); + UserCredentials credentials = CommonTestUtil.getCredentials(PrivilegeLevel.USER); + repository.setCredentials(org.eclipse.mylyn.commons.net.AuthenticationType.REPOSITORY, + new AuthenticationCredentials(credentials.getUserName(), credentials.getPassword()), true); + return repository; + } + +} diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/META-INF/MANIFEST.MF b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/META-INF/MANIFEST.MF index 0a13f401a..e0e05be47 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/META-INF/MANIFEST.MF +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/META-INF/MANIFEST.MF @@ -12,7 +12,8 @@ Require-Bundle: org.eclipse.core.runtime, org.apache.httpcomponents.httpcore, com.google.gson;bundle-version="2.1.0", org.eclipse.mylyn.commons.net, - org.eclipse.equinox.security + org.eclipse.equinox.security, + com.google.guava Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.mylyn.internal.bugzilla.rest.core, diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/build.properties b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/build.properties index 9cbab3c13..ace3b98a1 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/build.properties +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/build.properties @@ -4,3 +4,5 @@ bin.includes = META-INF/,\ .,\ about.html src.includes = about.html +additional.bundles = org.eclipse.jdt.annotation +jars.extra.classpath = platform:/plugin/org.eclipse.jdt.annotation diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedGetRequest.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedGetRequest.java index 77b8fac90..e8c46b2d8 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedGetRequest.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestAuthenticatedGetRequest.java @@ -72,7 +72,16 @@ public abstract class BugzillaRestAuthenticatedGetRequest<T> extends BugzillaRes @Override protected HttpRequestBase createHttpRequestBase() { - HttpRequestBase request = new HttpGet(baseUrl() + getUrlSuffix()); + String bugUrl = getUrlSuffix(); + BugzillaRestLoginToken token = ((BugzillaRestHttpClient) getClient()).getLoginToken(); + if ((!(this instanceof BugzillaRestValidateRequest) && !(this instanceof BugzillaRestUnauthenticatedGetRequest)) + && token != null && bugUrl.length() > 0) { + if (!bugUrl.endsWith("?")) { + bugUrl += "&"; + } + bugUrl += "token=" + token.getToken(); + } + HttpRequestBase request = new HttpGet(baseUrl() + bugUrl); request.setHeader(CONTENT_TYPE, TEXT_XML_CHARSET_UTF_8); request.setHeader(ACCEPT, APPLICATION_JSON); return request; @@ -80,6 +89,9 @@ public abstract class BugzillaRestAuthenticatedGetRequest<T> extends BugzillaRes @Override protected T execute(IOperationMonitor monitor) throws IOException, BugzillaRestException { + if (needsAuthentication()) { + authenticate(monitor); + } HttpRequestBase request = createHttpRequestBase(); CommonHttpResponse response = execute(request, monitor); return processAndRelease(response, monitor); diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java index 6b0c70c8c..c52e3f5c7 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestClient.java @@ -11,10 +11,10 @@ package org.eclipse.mylyn.internal.bugzilla.rest.core; -import org.eclipse.core.runtime.IStatus; import org.eclipse.mylyn.commons.core.operations.IOperationMonitor; import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation; import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.BugzillaRestErrorResponse; +import org.eclipse.mylyn.tasks.core.TaskRepository; public class BugzillaRestClient { @@ -37,4 +37,8 @@ public class BugzillaRestClient { return validateResponse.isError() && validateResponse.getCode() == 32614; } + public BugzillaRestConfiguration getConfiguration(TaskRepository repository, IOperationMonitor monitor) { + return null; + } + } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConfiguration.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConfiguration.java new file mode 100644 index 000000000..f765edfba --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConfiguration.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2013 Frank Becker 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: + * Frank Becker - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.bugzilla.rest.core; + +import java.io.Serializable; + +public class BugzillaRestConfiguration implements Serializable { + + private static final long serialVersionUID = 3433667217913466746L; + + private final String url; + + public BugzillaRestConfiguration(String url) { + this.url = url; + } + + public String getUrl() { + return url; + } + +} diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java index 9578daa1c..0e1c62700 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestConnector.java @@ -11,15 +11,22 @@ package org.eclipse.mylyn.internal.bugzilla.rest.core; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; +import org.eclipse.mylyn.commons.core.operations.IOperationMonitor; import org.eclipse.mylyn.commons.core.operations.OperationUtil; import org.eclipse.mylyn.commons.net.AuthenticationCredentials; import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation; import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType; import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials; +import org.eclipse.mylyn.internal.commons.core.operations.NullOperationMonitor; import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector; import org.eclipse.mylyn.tasks.core.IRepositoryQuery; import org.eclipse.mylyn.tasks.core.ITask; @@ -31,16 +38,85 @@ import org.eclipse.mylyn.tasks.core.data.TaskData; import org.eclipse.mylyn.tasks.core.data.TaskDataCollector; import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession; +import com.google.common.base.Optional; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.UncheckedExecutionException; + public class BugzillaRestConnector extends AbstractRepositoryConnector { - private static BugzillaRestConnector INSTANCE; - public static BugzillaRestConnector getDefault() { - return INSTANCE; - } + public static final Duration CLIENT_CACHE_DURATION = new Duration(24, TimeUnit.HOURS); + + public static final Duration CONFIGURATION_CACHE_EXPIRE_DURATION = new Duration(7, TimeUnit.DAYS); + + public static final Duration CONFIGURATION_CACHE_REFRESH_AFTER_WRITE_DURATION = new Duration(1, TimeUnit.DAYS); + + private final ExecutorService executor = Executors.newFixedThreadPool(3); + + private static final ThreadLocal<IOperationMonitor> context = new ThreadLocal<IOperationMonitor>(); + + private final LoadingCache<RepositoryKey, BugzillaRestClient> clientCache = CacheBuilder.newBuilder() + .expireAfterAccess(CLIENT_CACHE_DURATION.getValue(), CLIENT_CACHE_DURATION.getUnit()) + .build(new CacheLoader<RepositoryKey, BugzillaRestClient>() { + + @Override + public BugzillaRestClient load(RepositoryKey key) throws Exception { + TaskRepository repository = key.getRepository(); + return createClient(repository); + } + }); + + private final LoadingCache<RepositoryKey, Optional<BugzillaRestConfiguration>> configurationCache; public BugzillaRestConnector() { + this(CONFIGURATION_CACHE_REFRESH_AFTER_WRITE_DURATION); + } + + public BugzillaRestConnector(Duration refreshAfterWriteDuration) { super(); - INSTANCE = this; + configurationCache = createCacheBuilder(CONFIGURATION_CACHE_EXPIRE_DURATION, refreshAfterWriteDuration).build( + new CacheLoader<RepositoryKey, Optional<BugzillaRestConfiguration>>() { + + @Override + public Optional<BugzillaRestConfiguration> load(RepositoryKey key) throws Exception { + BugzillaRestClient client = clientCache.get(key); + return Optional.fromNullable(client.getConfiguration(key.getRepository(), context.get())); + } + + @Override + public ListenableFuture<Optional<BugzillaRestConfiguration>> reload(final RepositoryKey key, + Optional<BugzillaRestConfiguration> oldValue) throws Exception { + // asynchronous! + ListenableFutureJob<Optional<BugzillaRestConfiguration>> job = new ListenableFutureJob("") { + + @Override + protected IStatus run(IProgressMonitor monitor) { + BugzillaRestClient client; + try { + client = clientCache.get(key); + set(Optional.fromNullable(client.getConfiguration(key.getRepository(), + context.get()))); + } catch (ExecutionException e) { + e.printStackTrace(); + return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, + "BugzillaRestConnector reload Configuration", e); + } + return Status.OK_STATUS; + } + }; + job.schedule(); + return job; + } + }); + } + + protected CacheBuilder<Object, Object> createCacheBuilder(Duration expireAfterWriteDuration, + Duration refreshAfterWriteDuration) { + return CacheBuilder.newBuilder() + .expireAfterWrite(expireAfterWriteDuration.getValue(), expireAfterWriteDuration.getUnit()) + .refreshAfterWrite(refreshAfterWriteDuration.getValue(), refreshAfterWriteDuration.getUnit()); } @Override @@ -105,8 +181,9 @@ public class BugzillaRestConnector extends AbstractRepositoryConnector { @Override public void updateRepositoryConfiguration(TaskRepository taskRepository, IProgressMonitor monitor) throws CoreException { - // ignore - + context.set(monitor != null ? OperationUtil.convert(monitor) : new NullOperationMonitor()); + configurationCache.refresh(new RepositoryKey(taskRepository)); + context.remove(); } @Override @@ -117,10 +194,10 @@ public class BugzillaRestConnector extends AbstractRepositoryConnector { @Override public AbstractTaskDataHandler getTaskDataHandler() { - return new BugzillaRestTaskDataHandler(); + return new BugzillaRestTaskDataHandler(this); } - public BugzillaRestClient createClient(TaskRepository repository) { + private BugzillaRestClient createClient(TaskRepository repository) { RepositoryLocation location = new RepositoryLocation(repository.getProperties()); AuthenticationCredentials credentials1 = repository.getCredentials(org.eclipse.mylyn.commons.net.AuthenticationType.REPOSITORY); UserCredentials credentials = new UserCredentials(credentials1.getUserName(), credentials1.getPassword(), null, @@ -131,6 +208,23 @@ public class BugzillaRestConnector extends AbstractRepositoryConnector { return client; } + /** + * Returns the Client for the {@link TaskRepository}. + * + * @param repository + * the {@link TaskRepository} object + * @return the client Object + * @throws CoreException + */ + public BugzillaRestClient getClient(TaskRepository repository) throws CoreException { + try { + return clientCache.get(new RepositoryKey(repository)); + } catch (ExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, + "TaskRepositoryManager is null")); + } + } + @Override public RepositoryInfo validateRepository(TaskRepository repository, IProgressMonitor monitor) throws CoreException { try { @@ -145,4 +239,38 @@ public class BugzillaRestConnector extends AbstractRepositoryConnector { } } + public BugzillaRestConfiguration getRepositoryConfiguration(TaskRepository repository) throws CoreException { + if (clientCache.getIfPresent(new RepositoryKey(repository)) == null) { + getClient(repository); + } + try { + Optional<BugzillaRestConfiguration> configurationOptional = configurationCache.get(new RepositoryKey( + repository)); + return configurationOptional.isPresent() ? configurationOptional.get() : null; + } catch (UncheckedExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e)); + } catch (ExecutionException e) { + throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e)); + } + } + + public void clearClientCache() { + clientCache.invalidateAll(); + } + + public void clearConfigurationCache() { + configurationCache.invalidateAll(); + } + + public void clearAllCaches() { + clearClientCache(); + clearConfigurationCache(); + } + + @Override + public boolean isRepositoryConfigurationStale(TaskRepository repository, IProgressMonitor monitor) + throws CoreException { + return false; + } + } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java index 276ce4779..d99ec950e 100644 --- a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/BugzillaRestTaskDataHandler.java @@ -24,9 +24,10 @@ import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; import org.eclipse.mylyn.tasks.core.data.TaskData; public class BugzillaRestTaskDataHandler extends AbstractTaskDataHandler { + protected final BugzillaRestConnector connector; - public BugzillaRestTaskDataHandler() { - // ignore + public BugzillaRestTaskDataHandler(BugzillaRestConnector connector) { + this.connector = connector; } @Override @@ -46,7 +47,7 @@ public class BugzillaRestTaskDataHandler extends AbstractTaskDataHandler { data.setVersion("0"); //$NON-NLS-1$ BugzillaRestTaskSchema.getDefault().initialize(data); if (initializationData != null) { - BugzillaRestConnector.getDefault().getTaskMapping(data).merge(initializationData); + connector.getTaskMapping(data).merge(initializationData); } return true; } diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/Duration.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/Duration.java new file mode 100644 index 000000000..4e0ce7b31 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/Duration.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2014 Frank Becker 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: + * Frank Becker - initial API and implementation + *******************************************************************************/ +package org.eclipse.mylyn.internal.bugzilla.rest.core; + +import java.util.concurrent.TimeUnit; + +public class Duration { + final TimeUnit unit; + + final long value; + + public Duration(long value, TimeUnit unit) { + this.unit = unit; + this.value = value; + } + + public TimeUnit getUnit() { + return unit; + } + + public long getValue() { + return value; + } + +} diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/ListenableFutureJob.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/ListenableFutureJob.java new file mode 100644 index 000000000..5770e0264 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/ListenableFutureJob.java @@ -0,0 +1,111 @@ +/******************************************************************************* + * Copyright (c) 2014 Sam Davis 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: + * Sam Davis - initial API and implementation + *******************************************************************************/ + +package org.eclipse.mylyn.internal.bugzilla.rest.core; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; + +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.ListenableFuture; + +public abstract class ListenableFutureJob<V> extends Job implements ListenableFuture<V> { + + private class Listener { + + Runnable runnable; + + Executor executor; + + public Listener(Runnable runnable, Executor executor) { + this.runnable = runnable; + this.executor = executor; + } + + public void run() { + executor.execute(runnable); + } + } + + List<Listener> listeners = Collections.synchronizedList(Lists.<Listener> newArrayList()); + + private volatile boolean done; + + private V resultObject; + + public ListenableFutureJob(String name) { + super(name); + resultObject = null; + this.addJobChangeListener(new JobChangeAdapter() { + + @Override + public void done(IJobChangeEvent event) { + done = true; + synchronized (listeners) { + for (Listener listener : listeners) { + listener.run(); + } + } + } + }); + } + + @Override + public boolean cancel(boolean mayInterruptIfRunning) { + return this.cancel(); + } + + @Override + public V get() throws InterruptedException, ExecutionException { + this.join(); + return resultObject; + } + + @Override + public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { + long start = System.currentTimeMillis(); + while (!done && System.currentTimeMillis() - start < unit.toMillis(timeout)) { + Thread.sleep(250); + } + if (!done) { + throw new TimeoutException("ListenableFutureJob.get() could not get the result!"); + } + return resultObject; + } + + protected void set(V future) { + this.resultObject = future; + } + + @Override + public boolean isCancelled() { + return this.getResult().getSeverity() == IStatus.CANCEL; + } + + @Override + public boolean isDone() { + return done; + } + + @Override + public void addListener(Runnable listener, Executor executor) { + listeners.add(new Listener(listener, executor)); + } +}
\ No newline at end of file diff --git a/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/RepositoryKey.java b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/RepositoryKey.java new file mode 100644 index 000000000..726eb9130 --- /dev/null +++ b/connector-bugzilla-rest/org.eclipse.mylyn.bugzilla.rest.core/src/org/eclipse/mylyn/internal/bugzilla/rest/core/RepositoryKey.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2014 Frank Becker 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: + * Frank Becker - initial API and implementation + *******************************************************************************/ +package org.eclipse.mylyn.internal.bugzilla.rest.core; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.mylyn.tasks.core.TaskRepository; + +public class RepositoryKey { + private final TaskRepository repository; + + public RepositoryKey(@NonNull TaskRepository repository) { + super(); + this.repository = repository; + } + + public TaskRepository getRepository() { + return repository; + } + + @Override + public int hashCode() { + return repository.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + return this.repository.equals(((RepositoryKey) obj).getRepository()); + } +} diff --git a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java index 9b52c4558..253084e1e 100644 --- a/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java +++ b/org.eclipse.mylyn.tasks.core/src/org/eclipse/mylyn/tasks/core/TaskRepository.java @@ -584,7 +584,7 @@ public final class TaskRepository extends PlatformObject { public void setCharacterEncoding(String characterEncoding) { properties.put(IRepositoryConstants.PROPERTY_ENCODING, characterEncoding == null ? DEFAULT_CHARACTER_ENCODING - : characterEncoding); + : characterEncoding); } /** @@ -709,7 +709,7 @@ public final class TaskRepository extends PlatformObject { public void setTimeZoneId(String timeZoneId) { setProperty(IRepositoryConstants.PROPERTY_TIMEZONE, timeZoneId == null ? TimeZone.getDefault().getID() - : timeZoneId); + : timeZoneId); } /** |