diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFCallableContext.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFCallableContext.java index a6d565fea..969ac867e 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFCallableContext.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFCallableContext.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget; +import java.net.SocketException; import java.net.UnknownHostException; import java.util.concurrent.Callable; @@ -20,10 +21,8 @@ import reactor.ipc.netty.channel.AbortedException; public class CFCallableContext { - public static final String UNAUTHORIZED_ERROR = "unauthorized"; - private final CFParamsProviderMessages paramsProviderMessages; - private Throwable lastConnectionError; + private Exception lastConnectionError; public CFCallableContext(CFParamsProviderMessages paramsProviderMessages) { this.paramsProviderMessages = paramsProviderMessages; @@ -38,29 +37,26 @@ public class CFCallableContext { } } - private Exception convertToCfVscodeError(Exception e) { - Throwable deepestCause = ExceptionUtil.getDeepestCause(e); - if (deepestCause instanceof UaaException) { - String error = ((UaaException) deepestCause).getError(); - if (error != null && error.contains(UNAUTHORIZED_ERROR)) { - this.lastConnectionError = deepestCause; - return new UnauthorizedException(this.paramsProviderMessages.unauthorised()); - } - } else if (deepestCause instanceof AbortedException) { - // This one is odd. It is thrown when a wrong token is specified, but - // instead of getting an expected UaaException, this AbortedException is thrown instead by reactor netty. - this.lastConnectionError = deepestCause; - return new UnauthorizedException(this.paramsProviderMessages.unauthorised()); - } else if (deepestCause instanceof UnknownHostException) { - this.lastConnectionError = deepestCause; - String message = ExceptionUtil.getMessage(deepestCause); - return new ConnectionException(this.paramsProviderMessages.noNetworkConnection() + " " + message); - } + protected Exception convertToCfVscodeError(Exception e) { + this.lastConnectionError = getConnectionError(e); + // return the "converted" error if it is available + if (this.lastConnectionError != null) { + return this.lastConnectionError; + } return e; } + protected Exception getConnectionError(Exception e) { + Throwable deepestCause = ExceptionUtil.getDeepestCause(e); + + if (deepestCause instanceof UaaException || deepestCause instanceof AbortedException + || deepestCause instanceof SocketException || deepestCause instanceof UnknownHostException) { + return new ConnectionException(this.paramsProviderMessages.noNetworkConnection()); + } + return null; + } + public boolean hasConnectionError() { return this.lastConnectionError != null; } - -} +} \ No newline at end of file diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTargetCache.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTargetCache.java index 5225dff64..65db645d9 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTargetCache.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CFTargetCache.java @@ -28,11 +28,10 @@ public class CFTargetCache { private final CloudFoundryClientFactory clientFactory; private final ClientTimeouts timeouts; private final LoadingCache cache; - private final CFCallableContext callableContext; + private final CFCallableContext cacheCallableContext; public static final long SERVICES_EXPIRATION = 10; public static final long TARGET_EXPIRATION = 1; - public CFTargetCache(ClientParamsProvider paramsProvider, CloudFoundryClientFactory clientFactory, ClientTimeouts timeouts) { @@ -41,7 +40,7 @@ public class CFTargetCache { this.paramsProvider = paramsProvider; this.clientFactory = clientFactory; this.timeouts = timeouts; - this.callableContext = new CFCallableContext(paramsProvider.getMessages()); + this.cacheCallableContext = new CFCallableContext(paramsProvider.getMessages()); CacheLoader loader = new CacheLoader() { @Override @@ -50,7 +49,8 @@ public class CFTargetCache { } }; - cache = CacheBuilder.newBuilder().maximumSize(1).expireAfterAccess(TARGET_EXPIRATION, TimeUnit.HOURS).build(loader); + cache = CacheBuilder.newBuilder().maximumSize(1).expireAfterAccess(TARGET_EXPIRATION, TimeUnit.HOURS) + .build(loader); } /** @@ -61,9 +61,9 @@ public class CFTargetCache { * for any other error encountered */ public synchronized List getOrCreate() throws NoTargetsException, Exception { - return callableContext.checkConnection(() -> doGetOrCreate()); + return cacheCallableContext.checkConnection(() -> doGetOrCreate()); } - + protected synchronized List doGetOrCreate() throws NoTargetsException, Exception { List allParams = paramsProvider.getParams(); @@ -87,7 +87,8 @@ public class CFTargetCache { } protected CFTarget create(CFClientParams params) throws Exception { - return new CFTarget(getTargetName(params), params, clientFactory.getClient(params, timeouts), callableContext); + return new CFTarget(getTargetName(params), params, clientFactory.getClient(params, timeouts), + new CFCallableContext(paramsProvider.getMessages())); } protected static String getTargetName(CFClientParams params) { @@ -103,6 +104,4 @@ public class CFTargetCache { return cfApiUrl; } } - - } diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfCliProviderMessages.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfCliProviderMessages.java index a27da45d3..644eea102 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfCliProviderMessages.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/CfCliProviderMessages.java @@ -19,8 +19,7 @@ public final class CfCliProviderMessages implements CFParamsProviderMessages { * longer */ public static final String NO_CLI_TARGETS_FOUND_MESSAGE = "No Cloud Foundry targets found: Use cf CLI to login"; - public static final String UNAUTHORISED_MESSAGE = "Unauthorized access: Use cf CLI to login"; - public static final String NO_NETWORK_CONNECTION = "Unable to connect to network: Verify network connection"; + public static final String NO_NETWORK_CONNECTION = "No connection to Cloud Foundry: Use cf CLI to login or verify network connection"; @Override public String noTargetsFound() { @@ -29,7 +28,7 @@ public final class CfCliProviderMessages implements CFParamsProviderMessages { @Override public String unauthorised() { - return UNAUTHORISED_MESSAGE; + return NO_NETWORK_CONNECTION; } @Override diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/UnauthorizedException.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/UnauthorizedException.java deleted file mode 100644 index 7488edebb..000000000 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/cftarget/UnauthorizedException.java +++ /dev/null @@ -1,23 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2017 Pivotal, Inc. - * 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: - * Pivotal, Inc. - initial API and implementation - *******************************************************************************/ -package org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget; - -public class UnauthorizedException extends Exception { - - /** - * - */ - private static final long serialVersionUID = 1L; - - public UnauthorizedException(String message) { - super(message); - } -} diff --git a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/CloudFoundryClientCache.java b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/CloudFoundryClientCache.java index e39c25607..5cbfdd472 100644 --- a/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/CloudFoundryClientCache.java +++ b/vscode-extensions/commons/commons-cf/src/main/java/org/springframework/ide/vscode/commons/cloudfoundry/client/v2/CloudFoundryClientCache.java @@ -66,7 +66,9 @@ public class CloudFoundryClientCache { } public synchronized CFClientProvider getOrCreate(CFClientParams params) throws Exception { - return cache.get(ClientParamsCacheKey.from(params)); + return create(params); + // Disable cache as corrupted clients may be kept due to connection or auth errors +// return cache.get(ClientParamsCacheKey.from(params)); } protected CFClientProvider create(CFClientParams params) { diff --git a/vscode-extensions/commons/commons-cf/src/test/java/org/springframework/ide/vscode/commons/cloudfoundry/client/CFClientTest.java b/vscode-extensions/commons/commons-cf/src/test/java/org/springframework/ide/vscode/commons/cloudfoundry/client/CFClientTest.java index 9dad69f27..32d6a8a65 100644 --- a/vscode-extensions/commons/commons-cf/src/test/java/org/springframework/ide/vscode/commons/cloudfoundry/client/CFClientTest.java +++ b/vscode-extensions/commons/commons-cf/src/test/java/org/springframework/ide/vscode/commons/cloudfoundry/client/CFClientTest.java @@ -18,7 +18,6 @@ import static org.mockito.Mockito.when; import java.net.UnknownHostException; import java.util.concurrent.Callable; -import org.cloudfoundry.uaa.UaaException; import org.junit.Before; import org.junit.Test; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFParamsProviderMessages; @@ -27,11 +26,8 @@ import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTar import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CfCliProviderMessages; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.ConnectionException; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.NoTargetsException; -import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.UnauthorizedException; import org.springframework.ide.vscode.commons.util.ExceptionUtil; -import reactor.ipc.netty.channel.AbortedException; - public class CFClientTest { MockCfCli cloudfoundry = new MockCfCli(); @@ -75,38 +71,6 @@ public class CFClientTest { assertError(() -> target.getBuildpacks(), ConnectionException.class, expectedMessages.noNetworkConnection()); } - @Test - public void testAbortedExceptionServices() throws Exception { - ClientRequests client = cloudfoundry.client; - when(client.getServices()).thenThrow(new AbortedException("connection aborted")); - CFTarget target = targetCache.getOrCreate().get(0); - assertError(() -> target.getServices(), UnauthorizedException.class, expectedMessages.unauthorised()); - } - - @Test - public void testAbortedExceptionBuildpacks() throws Exception { - ClientRequests client = cloudfoundry.client; - when(client.getBuildpacks()).thenThrow(new AbortedException("connection aborted")); - CFTarget target = targetCache.getOrCreate().get(0); - assertError(() -> target.getBuildpacks(), UnauthorizedException.class, expectedMessages.unauthorised()); - } - - @Test - public void testUaaExceptionServices() throws Exception { - ClientRequests client = cloudfoundry.client; - when(client.getServices()).thenThrow(new UaaException(401, "unauthorized", "Bad credentials")); - CFTarget target = targetCache.getOrCreate().get(0); - assertError(() -> target.getServices(), UnauthorizedException.class, expectedMessages.unauthorised()); - } - - @Test - public void testUaaExceptionBuildpacks() throws Exception { - ClientRequests client = cloudfoundry.client; - when(client.getBuildpacks()).thenThrow(new UaaException(401, "unauthorized", "Bad credentials")); - CFTarget target = targetCache.getOrCreate().get(0); - assertError(() -> target.getBuildpacks(), UnauthorizedException.class, expectedMessages.unauthorised()); - } - protected void assertError(Callable callable, Class expected, String expectedMessage) throws Exception { Throwable error = null; diff --git a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/AbstractCFHintsProvider.java b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/AbstractCFHintsProvider.java index b26ca6c88..82f3a9a64 100644 --- a/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/AbstractCFHintsProvider.java +++ b/vscode-extensions/vscode-manifest-yaml/src/main/java/org/springframework/ide/vscode/manifest/yaml/AbstractCFHintsProvider.java @@ -18,9 +18,8 @@ import java.util.logging.Logger; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTarget; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.CFTargetCache; -import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.NoTargetsException; -import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.UnauthorizedException; import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.ConnectionException; +import org.springframework.ide.vscode.commons.cloudfoundry.client.cftarget.NoTargetsException; import org.springframework.ide.vscode.commons.util.Assert; import org.springframework.ide.vscode.commons.util.ExceptionUtil; import org.springframework.ide.vscode.commons.util.ValueParseException; @@ -86,7 +85,7 @@ public abstract class AbstractCFHintsProvider implements Callable