Simplify connection error handling to show only one message for now
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -28,11 +28,10 @@ public class CFTargetCache {
|
||||
private final CloudFoundryClientFactory clientFactory;
|
||||
private final ClientTimeouts timeouts;
|
||||
private final LoadingCache<ClientParamsCacheKey, CFTarget> 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<ClientParamsCacheKey, CFTarget> loader = new CacheLoader<ClientParamsCacheKey, CFTarget>() {
|
||||
|
||||
@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<CFTarget> getOrCreate() throws NoTargetsException, Exception {
|
||||
return callableContext.checkConnection(() -> doGetOrCreate());
|
||||
return cacheCallableContext.checkConnection(() -> doGetOrCreate());
|
||||
}
|
||||
|
||||
|
||||
protected synchronized List<CFTarget> doGetOrCreate() throws NoTargetsException, Exception {
|
||||
|
||||
List<CFClientParams> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<? extends Throwable> expected, String expectedMessage)
|
||||
throws Exception {
|
||||
Throwable error = null;
|
||||
|
||||
@@ -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<Collection<YVa
|
||||
*/
|
||||
protected Throwable getErrorNoAppending(Throwable e) {
|
||||
return ExceptionUtil.findThrowable(e,
|
||||
ImmutableList.of(NoTargetsException.class, ConnectionException.class, UnauthorizedException.class));
|
||||
ImmutableList.of(NoTargetsException.class, ConnectionException.class));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user