From 5d8495a1da969e0f46012b8eee3535be3fd6d7dc Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Tue, 14 Jun 2016 08:48:14 -0400 Subject: [PATCH 001/258] [OSJC-261] Impl OkHttpClient. [OSJC-212] Refactor authorization context Fix all integration tests --- README.md | 62 +- pom.xml | 51 +- .../internal/restclient/ApiTypeMapper.java | 41 +- .../internal/restclient/DefaultClient.java | 398 ++++-------- .../internal/restclient/ResourceFactory.java | 4 +- .../internal/restclient/URLBuilder.java | 18 +- .../internal/restclient/WatchClient.java | 284 --------- .../authorization/AuthorizationClient.java | 247 ------- .../authorization/AuthorizationContext.java | 70 +- .../authorization/AuthorizationDetails.java | 22 +- ...penShiftAuthorizationRedirectStrategy.java | 95 --- .../OpenShiftCredentialsProvider.java | 77 --- .../AbstractOpenShiftBinaryCapability.java | 24 +- ...erRegistryImageStreamImportCapability.java | 180 +++--- .../ImageStreamImportCapability.java | 6 +- .../resources/OpenShiftBinaryRSync.java | 4 +- .../resources/ProjectTemplateProcessing.java | 2 +- .../resources/UpdateableCapability.java | 10 + .../server/ServerTemplateProcessing.java | 100 +-- .../restclient/http/BadRequestException.java | 27 - .../restclient/http/CallbackTrustManager.java | 62 -- .../restclient/http/EncodingException.java | 24 - .../http/FormUrlEncodedMediaType.java | 120 ---- .../restclient/http/HttpClientException.java | 42 -- .../internal/restclient/http/HttpMethod.java | 35 - .../internal/restclient/http/IMediaType.java | 31 - .../http/InternalServerErrorException.java | 27 - .../restclient/http/JsonMediaType.java | 100 --- .../restclient/http/NotFoundException.java | 27 - .../internal/restclient/http/Parameter.java | 75 --- .../restclient/http/ParameterValue.java | 60 -- .../restclient/http/ParameterValueArray.java | 50 -- .../restclient/http/ParameterValueMap.java | 95 --- .../restclient/http/StringParameter.java | 31 - .../internal/restclient/http/StringValue.java | 29 - .../http/UnauthorizedException.java | 28 - .../http/UrlConnectionHttpClient.java | 601 ------------------ .../http/UrlConnectionHttpClientBuilder.java | 88 --- .../internal/restclient/model/Config.java | 27 - .../internal/restclient/model/List.java | 8 +- .../internal/restclient/model/Status.java | 6 +- .../model/build/BuildConfigBuilder.java | 9 + .../restclient/model/template/Template.java | 5 +- .../okhttp/BasicChallangeHandler.java | 49 ++ .../restclient/okhttp/IChallangeHandler.java | 40 ++ .../okhttp/OpenShiftAuthenticator.java | 142 +++++ .../okhttp/ResponseCodeInterceptor.java | 132 ++++ .../restclient/okhttp/WatchClient.java | 189 ++++++ .../com/openshift/internal/util/URIUtils.java | 25 +- .../restclient/BadRequestException.java | 34 + .../openshift/restclient/ClientBuilder.java | 168 ++++- .../openshift/restclient/ClientFactory.java | 36 -- .../openshift/restclient/IApiTypeMapper.java | 2 + .../com/openshift/restclient/IClient.java | 46 +- .../restclient/ISSLCertificateCallback.java | 7 +- .../restclient/OpenShiftException.java | 19 +- .../AbstractAuthorizationStrategy.java | 54 -- .../AuthorizationClientFactory.java | 60 -- .../BasicAuthorizationStrategy.java | 55 -- .../authorization/IAuthorizationClient.java | 40 -- .../authorization/IAuthorizationContext.java | 47 +- .../authorization/IAuthorizationStrategy.java | 40 -- .../IAuthorizationStrategyVisitor.java | 19 - .../restclient/authorization/IRequest.java | 27 - .../TokenAuthorizationStrategy.java | 46 -- .../authorization/URLConnectionRequest.java | 29 - .../authorization/UnauthorizedException.java | 18 +- .../resources/IBuildCancelable.java | 19 + .../server/ITemplateProcessing.java | 3 +- .../restclient/http/IHttpClient.java | 62 -- .../restclient/http/IHttpConstants.java | 8 +- .../model/build/IBuildConfigBuilder.java | 9 +- .../restclient/model/template/ITemplate.java | 2 +- ...ftBinaryRSyncRetrievalIntegrationTest.java | 74 --- .../restclient/ApiTypeMapperTest.java | 9 +- .../DefaultClientIntegrationTest.java | 74 ++- .../restclient/DefaultClientTest.java | 122 +--- .../restclient/IntegrationTestHelper.java | 156 ++++- .../PodStatusRunningConditional.java | 31 + .../restclient/TypeMapperFixture.java | 79 ++- .../AuthorizationClientIntegrationTest.java | 103 --- .../AuthorizationDetailsTest.java | 44 +- .../BuildCapabilitiesIntegrationTest.java | 119 ++++ .../BuildTriggerIntegrationTest.java | 61 -- .../DockerManifestComparatorTest.java | 45 ++ ...StreamImportCapabilityIntegrationTest.java | 14 +- .../ImageStreamImportCapabilityTest.java | 1 + ...tBinaryPodLogRetrievalIntegrationTest.java | 23 +- ...ftBinaryPortForwardingIntegrationTest.java | 38 +- ...ftBinaryRSyncRetrievalIntegrationTest.java | 78 ++- ...rverTemplateProcessingIntegrationTest.java | 40 +- .../server/ServerTemplateProcessingTest.java | 50 +- .../restclient/http/HttpClientTest.java | 516 --------------- .../restclient/http/HttpMethodTest.java | 30 - .../http/UrlConnectionHttpClientTest.java | 61 -- .../restclient/model/v1/ListTest.java | 6 +- .../restclient/model/v1/TemplateTest.java | 2 +- .../okhttp/BasicChallangeHandlerTest.java | 68 ++ .../BasicAuthorizationStrategyTest.java | 88 --- .../TokenAuthorizationStrategyTest.java | 93 --- ...URLConnectionAuthorizationRequestTest.java | 34 - .../openshift/restclient/utils/Samples.java | 4 +- .../openshiftv3IntegrationTest.properties | 5 +- .../dockerregistry/v1_image_manifest.json | 38 ++ .../samples/openshift3/v1_template.json | 38 +- 105 files changed, 2113 insertions(+), 4760 deletions(-) delete mode 100644 src/main/java/com/openshift/internal/restclient/WatchClient.java delete mode 100644 src/main/java/com/openshift/internal/restclient/authorization/AuthorizationClient.java delete mode 100644 src/main/java/com/openshift/internal/restclient/authorization/OpenShiftAuthorizationRedirectStrategy.java delete mode 100644 src/main/java/com/openshift/internal/restclient/authorization/OpenShiftCredentialsProvider.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/BadRequestException.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/CallbackTrustManager.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/EncodingException.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/FormUrlEncodedMediaType.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/HttpClientException.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/HttpMethod.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/IMediaType.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/InternalServerErrorException.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/JsonMediaType.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/NotFoundException.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/Parameter.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/ParameterValue.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/ParameterValueArray.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/ParameterValueMap.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/StringParameter.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/StringValue.java delete mode 100644 src/main/java/com/openshift/internal/restclient/http/UnauthorizedException.java delete mode 100755 src/main/java/com/openshift/internal/restclient/http/UrlConnectionHttpClient.java delete mode 100755 src/main/java/com/openshift/internal/restclient/http/UrlConnectionHttpClientBuilder.java delete mode 100644 src/main/java/com/openshift/internal/restclient/model/Config.java create mode 100644 src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java create mode 100644 src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java create mode 100644 src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java create mode 100644 src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java create mode 100644 src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java create mode 100644 src/main/java/com/openshift/restclient/BadRequestException.java delete mode 100644 src/main/java/com/openshift/restclient/ClientFactory.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/AbstractAuthorizationStrategy.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/AuthorizationClientFactory.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/BasicAuthorizationStrategy.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/IAuthorizationClient.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/IAuthorizationStrategy.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/IAuthorizationStrategyVisitor.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/IRequest.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/TokenAuthorizationStrategy.java delete mode 100644 src/main/java/com/openshift/restclient/authorization/URLConnectionRequest.java delete mode 100755 src/main/java/com/openshift/restclient/http/IHttpClient.java delete mode 100644 src/test/java/OpenshiftBinaryRSyncRetrievalIntegrationTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/PodStatusRunningConditional.java delete mode 100644 src/test/java/com/openshift/internal/restclient/authorization/AuthorizationClientIntegrationTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java delete mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/BuildTriggerIntegrationTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/DockerManifestComparatorTest.java delete mode 100755 src/test/java/com/openshift/internal/restclient/http/HttpClientTest.java delete mode 100644 src/test/java/com/openshift/internal/restclient/http/HttpMethodTest.java delete mode 100644 src/test/java/com/openshift/internal/restclient/http/UrlConnectionHttpClientTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java delete mode 100644 src/test/java/com/openshift/restclient/authorization/BasicAuthorizationStrategyTest.java delete mode 100644 src/test/java/com/openshift/restclient/authorization/TokenAuthorizationStrategyTest.java delete mode 100644 src/test/java/com/openshift/restclient/authorization/URLConnectionAuthorizationRequestTest.java create mode 100644 src/test/resources/samples/dockerregistry/v1_image_manifest.json diff --git a/README.md b/README.md index 3009c320..06bb0089 100755 --- a/README.md +++ b/README.md @@ -4,15 +4,63 @@ OpenShift Java REST Client [![Travis](https://travis-ci.org/openshift/openshift-restclient-java.svg?branch=master)](https://travis-ci.org/openshift/openshift-restclient-java) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.openshift/openshift-restclient-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.openshift/openshift-restclient-java) This is the Java REST client for the version 3 architecture of [OpenShift](https://github.com/openshift/origin) based on Kubernetes. The implementation is -a work in progress to provide functionality and features of the command-line interface and is used by JBoss Tools for OpenShift. For compatibility with +a work in progress to provide similiar functionality and features of the command-line interface and is used by JBoss Tools for OpenShift. For compatibility with OpenShift 2.x see https://github.com/openshift/openshift-java-client/. +Download +-------- +You may either build from source using maven (mvn clean package) which, using the master branch, will generate a snapshot build of the lastest updates. You may also retrieve final released jars from [Maven Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.openshift%22%20AND%20a%3A%22openshift-restclient-java%22). + + Usage ----- - IClient client = new ClientFactory().create(url, sslCertCallback); - client.setAuthorizationStrategy(new TokenAuthorizationStrategy("ADSASEAWRA-AFAEWAAA"); - List projects = client.list(ResourceKind.PROJECTS, "test-project"); -Download --------- -You may either build from source using maven (mvn clean package) or get the prebuilt artifact from the maven central. +Creating a client: + + IClient client = new ClientBuilder("https://api.preview.openshift.com") + .withUserName("openshiftdev") + .withPassword("wouldntUlik3T0kn0w") + .build(); + +This will authorize the client if the cluster is configured for basic authorization. The alternative is to retrieve your OAUTH token and provide it to the client. The token can be set with the builder or later by accessing the authorization context: + + client.getAuthorizationContext().setToken("asfdsfd8a70a3qrfafdsadsf786324"); + +Create a project to associate with your application by submitting a project request: + + IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, "myfirstproject"); + IProject project = (IProject)client.create(request); + +Resources can be created by stubbing which will instantiate and instance of the resource but not create it on the server: + + IService service = client.getResourceFactory().stub(ResourceKind.SERVICE, "myfirstservice", project.getName()); + service.setSelector(labelSelectors); + service = client.create(service); + + +The client as well as resources supported by OpenShift may have certain capabilities that are instantiated when the resource is initialized. The [capabilities](https://github.com/openshift/openshift-restclient-java/tree/master/src/main/java/com/openshift/restclient/capability) are implemented using an adapter pattern and used like the following to create a BuildConfig: + + IBuildConfig buildConfig = client.accept(new CapabilityVisitor() { + + @Override + public IBuildConfig visit(IBuildConfigBuilder builder) { + return builder + .named("mybuildconfig") + .inNamespace(project.getName()) + .fromGitSource() + .fromGitUrl("https://github.com/openshift/rails-example") + .usingGitReference("master") + .end() + .usingSourceStrategy() + .fromImageStreamTag("ruby:latest") + .inNamespace("openshift") + .withEnvVars(envVars) + .end() + .buildOnSourceChange(true) + .buildOnConfigChange(true) + .buildOnImageChange(true) + .toImageStreamTag("mybuildconfig:latest") + .build(); + } + }, null); + diff --git a/pom.xml b/pom.xml index 0cc5ba5d..f716accb 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 4.1.0-SNAPSHOT + 5.0.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com @@ -128,6 +128,16 @@ + + com.squareup.okhttp3 + okhttp + 3.3.1 + + + com.squareup.okhttp3 + okhttp-ws + 3.3.1 + org.yaml snakeyaml @@ -191,26 +201,6 @@ log4j 1.2.16 - - org.eclipse.jetty.websocket - websocket-client - 9.2.13.v20150730 - - - org.eclipse.jetty - jetty-client - 9.2.13.v20150730 - - - org.apache.httpcomponents - httpclient - 4.3.6 - - - org.apache.httpcomponents - httpcore - 4.3.3 - commons-codec commons-codec @@ -309,21 +299,16 @@ 2.12 - ${libra_server} - ${default_rhlogin} - ${rhpassword} - ${proxyHost} - ${proxyPort} - ${proxyHost} - ${proxyPort} - ${proxyHost} - ${proxyPort} + ${libra_server} + ${default_rhlogin} + ${rhpassword} + ${openshift.binary.location} - **/OpenShiftSuite.java + none - **/OpenShiftIntegrationTestSuite.java + **/*IntegrationTest.java none @@ -340,7 +325,7 @@ none - **/integration/*Test.java + **/*IntegrationTest.java diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index 18019df9..76530157 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -10,8 +10,7 @@ ******************************************************************************/ package com.openshift.internal.restclient; -import java.net.MalformedURLException; -import java.net.SocketTimeoutException; +import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -29,17 +28,17 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.openshift.internal.restclient.http.HttpClientException; -import com.openshift.internal.restclient.http.NotFoundException; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.internal.util.JBossDmrExtentions; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.http.IHttpClient; -import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IResource; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + /** * Typemapper to determine the endpoints for * various openshift resources @@ -54,18 +53,23 @@ public class ApiTypeMapper implements IApiTypeMapper, ResourcePropertyKeys{ private static final String API_GROUPS_API = "apis"; private static final Logger LOGGER = LoggerFactory.getLogger(ApiTypeMapper.class); private final String baseUrl; - private final IHttpClient client; + private final OkHttpClient client; private List resourceEndpoints; private Map preferedVersion = new HashMap<>(2); private AtomicBoolean initialized = new AtomicBoolean(false); - public ApiTypeMapper(String baseUrl, IHttpClient client) { + public ApiTypeMapper(String baseUrl, OkHttpClient client) { this.baseUrl = baseUrl; this.client = client; preferedVersion.put(KUBE_API, KubernetesAPIVersion.v1.toString()); preferedVersion.put(OS_API, OpenShiftAPIVersion.v1.toString()); } + @Override + public String getPreferedVersionFor(String endpoint) { + return preferedVersion.get(endpoint); + } + @Override public boolean isSupported(IResource resource) { return isSupported(resource.getApiVersion(), resource.getKind()); @@ -191,19 +195,14 @@ private String readEndpoint(final String endpoint) { try { final URL url = new URL(new URL(this.baseUrl), endpoint); LOGGER.debug(url.toString()); - String response = client.get(url, IHttpConstants.DEFAULT_READ_TIMEOUT); - LOGGER.debug(response); - return response; - } catch (MalformedURLException | SocketTimeoutException e) { - throw new OpenShiftException(e,""); - //HACK - This gets us around a server issue - } catch (HttpClientException e) { - if(e instanceof NotFoundException) { - throw new com.openshift.restclient.NotFoundException(e); - } - LOGGER.error("Unauthorized exception. Can system:anonymous get the API endpoint", e); - throw e; - } + Request request = new Request.Builder() + .url(url) + .build(); + Response response = client.newCall(request).execute(); + return response.body().string(); + } catch (IOException e) { + throw new OpenShiftException(e,"Unable to read endpoint %s/%s", this.baseUrl, endpoint); + } } static class ApiGroup implements IApiGroup{ diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index a269b430..d9c66527 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -10,10 +10,8 @@ import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeClientCapabilities; -import java.net.MalformedURLException; -import java.net.SocketTimeoutException; +import java.io.IOException; import java.net.URL; -import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -23,38 +21,31 @@ import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; -import org.jboss.dmr.ModelNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.openshift.internal.restclient.http.HttpClientException; -import com.openshift.internal.restclient.http.NotFoundException; -import com.openshift.internal.restclient.http.UnauthorizedException; -import com.openshift.internal.restclient.http.UrlConnectionHttpClientBuilder; -import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; +import com.openshift.internal.restclient.authorization.AuthorizationContext; +import com.openshift.internal.restclient.okhttp.WatchClient; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; import com.openshift.restclient.IOpenShiftWatchListener; import com.openshift.restclient.IResourceFactory; -import com.openshift.restclient.ISSLCertificateCallback; import com.openshift.restclient.IWatcher; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.UnsupportedOperationException; -import com.openshift.restclient.authorization.AuthorizationClientFactory; -import com.openshift.restclient.authorization.IAuthorizationClient; import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.IAuthorizationDetails; -import com.openshift.restclient.authorization.IAuthorizationStrategy; -import com.openshift.restclient.authorization.ResourceForbiddenException; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.ICapability; -import com.openshift.restclient.http.IHttpClient; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IList; import com.openshift.restclient.model.IResource; -import com.openshift.restclient.model.IStatus; -import com.openshift.restclient.model.user.IUser; + +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; /** * @author Jeff Cantrill @@ -66,56 +57,41 @@ public class DefaultClient implements IClient, IHttpConstants{ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); private URL baseUrl; - private IHttpClient client; + private OkHttpClient client; private IResourceFactory factory; private Map, ICapability> capabilities = new HashMap, ICapability>(); private boolean capabilitiesInitialized = false; - private static final String API_ENDPOINT = "api"; - private static final String OS_API_LEGACY_ENDPOINT = "osapi"; private static final String OS_API_ENDPOINT = "oapi"; private String openShiftVersion; private String kubernetesVersion; - private IAuthorizationStrategy strategy; - private IAuthorizationClient authClient; + private AuthorizationContext authContext; private IApiTypeMapper typeMapper; - public DefaultClient(URL baseUrl, IHttpClient httpClient, ISSLCertificateCallback sslCertCallback, IResourceFactory factory){ - this(baseUrl, httpClient, sslCertCallback, factory, null, null, null, IHttpClient.NO_TIMEOUT); - } - public DefaultClient(URL baseUrl, IHttpClient httpClient, ISSLCertificateCallback sslCertCallback, IResourceFactory factory, String alias, X509Certificate cert, int configTimeoutMillies) { - this(baseUrl, httpClient, sslCertCallback, factory, alias, cert, null, configTimeoutMillies); - } - public DefaultClient(URL baseUrl, IHttpClient httpClient, ISSLCertificateCallback sslCertCallback, IResourceFactory factory, String alias, X509Certificate cert, IApiTypeMapper typeMapper, int configTimeoutMillies){ + public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, IApiTypeMapper typeMapper, AuthorizationContext authContext){ this.baseUrl = baseUrl; - client = httpClient != null ? httpClient : newIHttpClient(sslCertCallback, alias, cert, configTimeoutMillies); + this.client = client; this.factory = factory; if(this.factory != null) { this.factory.setClient(this); } openShiftVersion = System.getProperty(SYSTEM_PROP_OPENSHIFT_API_VERSION, null); kubernetesVersion = System.getProperty(SYSTEM_PROP_K8E_API_VERSION, null); - authClient = new AuthorizationClientFactory.AuthorizationClientBuilder() - .withClient(this) - .withConnectTimeout(configTimeoutMillies) - .build(); - authClient.setSSLCertificateCallback(sslCertCallback); this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client); + this.authContext = authContext; } - /* - * Factory method for testing - */ - private IHttpClient newIHttpClient(ISSLCertificateCallback sslCertCallback, String alias, X509Certificate cert, int configTimeoutMillies){ - return new UrlConnectionHttpClientBuilder() - .setAcceptMediaType("application/json") - .setCertificate(alias, cert) - .setSSLCertificateCallback(sslCertCallback) - .setConfigTimeout(configTimeoutMillies) - .client(); - } + @Override + public IClient clone() { + AuthorizationContext context = authContext.clone(); + DefaultClient clone = new DefaultClient(baseUrl, client, factory, typeMapper, context); + context.setClient(clone); + return clone; + } + + @Override public IResourceFactory getResourceFactory() { return factory; @@ -123,8 +99,8 @@ public IResourceFactory getResourceFactory() { @Override public IWatcher watch(String namespace, IOpenShiftWatchListener listener, String...kinds) { - WatchClient watcher = new WatchClient(getBaseURL(), typeMapper, this); - return watcher.watch(Arrays.asList(kinds), namespace, listener); + WatchClient watcher = new WatchClient(this, this.typeMapper, this.client); + return watcher.watch(Arrays.asList(kinds), namespace, listener); } @Override @@ -145,23 +121,9 @@ public List list(String kind, String namespace) { @SuppressWarnings("unchecked") @Override public List list(String kind, String namespace, Map labels) { - try { - if(!typeMapper.isSupported(kind)) - // TODO: replace with specific runtime exception - throw new RuntimeException("No OpenShift resource endpoint for type: " + kind); - URLBuilder builder = new URLBuilder(this.baseUrl, typeMapper) - .kind(kind) - .namespace(namespace); - final URL endpoint = builder.build(); - String response = client.get(endpoint, IHttpClient.DEFAULT_READ_TIMEOUT); - LOGGER.debug(String.format("List Response: %s:", response)); - List items = (List) factory.createList(response, kind); - return filterItems(items, labels); //client filter until we can figure out how to restrict with a server call - } catch (HttpClientException e){ - throw createOpenShiftException(String.format("Could not list %s resources in namespace %s: %s", kind, namespace, e.getMessage()), e); - } catch (SocketTimeoutException e) { - throw new OpenShiftException(e, "Socket timeout listing resources"); - } + IList list = get(kind, namespace); + ArrayList items = new ArrayList((Collection)list.getItems()); + return filterItems(items, labels); //client filter until we can figure out how to restrict with a server call } private List filterItems(List items, Map labels){ @@ -180,7 +142,7 @@ public Collection create(IList list, String namespace){ List results = new ArrayList(list.getItems().size()); for (IResource resource : list.getItems()) { try{ - results.add(createVersion(resource, namespace, resource.getApiVersion())); + results.add(create(resource, namespace)); }catch(OpenShiftException e){ if(e.getStatus() != null){ results.add(e.getStatus()); @@ -200,122 +162,104 @@ public T create(T resource) { @Override public T create(T resource, String namespace) { - return createVersion(resource, namespace, null); + return execute(HttpMethod.POST, resource.getKind(), namespace, null, null, resource); + } + + @Override + public T create(String kind, String namespace, String name, String subresource, IResource payload) { + return execute(HttpMethod.POST, kind, namespace, name, subresource, payload); } - private T createVersion(T resource, String namespace, String version) { - if(ResourceKind.LIST.equals(resource.getKind())) throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); - try { - namespace = ResourceKind.PROJECT.equals(resource.getKind()) ? "" : namespace; - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) - .kind(resource.getKind()) + enum HttpMethod{ + GET, + PUT, + POST, + DELETE + } + + private T execute(HttpMethod method, String kind, String namespace, String name, String subresource, IResource payload) { + return execute(method.toString(), kind, namespace, name, subresource, payload); + } + + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload) { + if(ResourceKind.LIST.equals(kind)) + throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); + final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) + .kind(kind) + .name(name) .namespace(namespace) + .subresource(subresource) .build(); - String response = client.post(endpoint, IHttpClient.DEFAULT_READ_TIMEOUT, resource); - LOGGER.debug(response); - return factory.create(response); - } catch (HttpClientException e){ - throw createOpenShiftException(String.format("Could not create resource %s in namespace '%s': %s", resource.getName(), namespace, e.getMessage()), e); - } catch (SocketTimeoutException e) { - throw new OpenShiftException(e, "Socket timeout creating resource %s", resource.getName()); + + try { + Request.Builder builder = newRequestBuilderTo(endpoint.toString()); + if(!HttpMethod.GET.toString().equals(method)) { + String json = payload == null ? "" : payload.toJson(true); + builder.method(method.toString(), + RequestBody.create(MediaType.parse(MEDIATYPE_APPLICATION_JSON), json)); + LOGGER.debug("About to send payload: {}", json); + } + Request request = builder.build(); + LOGGER.debug("About to make {} request: {}", request.method(), request); + try(Response result = client.newCall(request).execute()){ + String response = result.body().string(); + LOGGER.debug("Response: {}", response); + return (T) factory.create(response); + } + } catch (IOException e){ + throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); } } - + + @Override - public T create(String kind, String namespace, String name, String subresource, IResource payload) { - if(ResourceKind.LIST.equals(kind)) throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); + public String getServerReadyStatus() { try { - namespace = ResourceKind.PROJECT.equals(kind) ? null : namespace; - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) - .kind(kind) - .name(name) - .namespace(namespace) - .subresource(subresource) + Request request = new Request.Builder() + .url(new URL(this.baseUrl, "healthz/ready")) + .header(PROPERTY_ACCEPT, "*/*") .build(); - String response = client.post(endpoint, IHttpClient.DEFAULT_READ_TIMEOUT, payload); - LOGGER.debug(response); - return factory.create(response); - } catch (HttpClientException e){ - throw createOpenShiftException(String.format("Could not create %s resource %s in namespace %s for subresource %s: %s", kind, name, namespace, subresource, e.getMessage()), e); - } catch (SocketTimeoutException e) { - throw new OpenShiftException(e, "Socket timeout creating resource %s", name); + try(Response response = client.newCall(request).execute()){ + return response.body().string(); + } + } catch (IOException e) { + throw new OpenShiftException(e, "Exception while trying to determine the health/ready response of the server"); } } + + public Request.Builder newRequestBuilderTo(String endpoint){ + Request.Builder builder = new Request.Builder() + .url(endpoint.toString()) + .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON); + + String token = null; + if(this.authContext != null && StringUtils.isNotBlank(this.authContext.getToken())){ + token = this.authContext.getToken(); + } + builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)); + return builder; + } @Override public T update(T resource) { - if(ResourceKind.LIST.equals(resource.getKind())) throw new UnsupportedOperationException("Update operation not supported for resource type 'List'"); - try { - final URL endpoint = new URLBuilder(getBaseURL(), typeMapper) - .resource(resource) - .namespace(resource.getNamespace()) - .build(); - String response = client.put(endpoint, IHttpClient.DEFAULT_READ_TIMEOUT, resource); - LOGGER.debug(response); - return factory.create(response); - } catch (HttpClientException e){ - throw createOpenShiftException(String.format("Could not update resource %s: %s", resource.getName(), e.getMessage()), e); - } catch (SocketTimeoutException e) { - throw new OpenShiftException(e, "Socket timeout updating resource %s", resource.getName()); - } + return execute(HttpMethod.PUT, resource.getKind(), resource.getNamespace(), resource.getName(), null, resource); } @Override public void delete(T resource) { - if(ResourceKind.LIST.equals(resource.getKind())) throw new UnsupportedOperationException("Delete operation not supported for resource type 'List'"); - try { - String namespace = ResourceKind.PROJECT.equals(resource.getKind()) ? "" : resource.getNamespace(); - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) - .resource(resource) - .namespace(namespace) - .build(); - LOGGER.debug(String.format("Deleting resource %s", endpoint)); - String response = client.delete(endpoint, IHttpClient.DEFAULT_READ_TIMEOUT); - LOGGER.debug(response); - //TODO return response object here - } catch (HttpClientException e){ - throw createOpenShiftException(String.format("Could not delete resource %s: %s", resource.getName(), e.getMessage()), e); - } catch (SocketTimeoutException e) { - throw new OpenShiftException(e, "SocketTimeout deleting resource %s", resource.getName()); - } + execute(HttpMethod.DELETE, resource.getKind(), resource.getNamespace(), resource.getName(), null, resource); } @Override public IList get(String kind, String namespace) { - try { - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) - .kind(kind) - .namespace(namespace) - .build(); - String response = client.get(endpoint, IHttpClient.DEFAULT_READ_TIMEOUT); - LOGGER.debug(response); - return factory.create(response); - } catch (HttpClientException e){ - throw createOpenShiftException(String.format("Could not list resource kind %s in namespace '%s': %s", kind, namespace, e.getMessage()), e); - } catch (SocketTimeoutException e) { - throw new OpenShiftException(e, "SocketTimeout getting listing resource kind '%s' in namespace '%s'", kind, namespace); - } - + return execute(HttpMethod.GET, kind, namespace, null, null, null); } @Override public T get(String kind, String name, String namespace) { - try { - namespace = ResourceKind.PROJECT.equals(kind) ? "" : namespace; - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) - .kind(kind) - .name(name) - .namespace(namespace) - .build(); - String response = client.get(endpoint, IHttpClient.DEFAULT_READ_TIMEOUT); - LOGGER.debug(response); - return factory.create(response); - } catch (HttpClientException e){ - throw createOpenShiftException(String.format("Could not get resource %s in namespace %s: %s", name, namespace, e.getMessage()), e); - } catch (SocketTimeoutException e) { - throw new OpenShiftException(e, "SocketTimeout getting resource %s", name); - } + return execute(HttpMethod.GET, kind, namespace, name, null, null); } public synchronized void initializeCapabilities(){ @@ -349,129 +293,29 @@ public R accept(CapabilityVisitor visitor, R un return unsupportedCapabililityValue; } - public List getKubernetesVersions() { - return getVersion(KubernetesAPIVersion.class, API_ENDPOINT); - } - - public List getOpenShiftVersions() { - List versions = getVersion(OpenShiftAPIVersion.class, OS_API_ENDPOINT); - versions.addAll(getVersion(OpenShiftAPIVersion.class, OS_API_LEGACY_ENDPOINT)); - return versions; - } - - public String getKubernetesVersion() { - if(kubernetesVersion == null){ - List versions = getKubernetesVersions(); - kubernetesVersion = ResourcePropertiesRegistry.getInstance().getMaxSupportedKubernetesVersion(versions).toString(); - } - return kubernetesVersion; - } - @Override public String getOpenShiftAPIVersion() { - if(openShiftVersion == null){ - List versions = getOpenShiftVersions(); - openShiftVersion = ResourcePropertiesRegistry.getInstance().getMaxSupportedOpenShiftVersion(versions).toString(); - } - return openShiftVersion; + return typeMapper.getPreferedVersionFor(OS_API_ENDPOINT); } - private > List getVersion(Class klass, String endpoint) { - try { - final URL url = new URL(this.baseUrl, endpoint); - LOGGER.debug(url.toString()); - String response = client.get(url, IHttpClient.DEFAULT_READ_TIMEOUT); - LOGGER.debug(response); - ModelNode json = ModelNode.fromJSONString(response); - List versionNodes = json.get("versions").asList(); - List versions = new ArrayList(versionNodes.size()); - for (ModelNode node : versionNodes) { - try{ - versions.add(Enum.valueOf(klass, node.asString())); - }catch(IllegalArgumentException e){ - LOGGER.warn(String.format("Unsupported server version '%s' for '%s'", node.asString(), klass.getSimpleName())); - } - } - return versions; - } catch (MalformedURLException e) { - LOGGER.error("Exception", e); - throw new OpenShiftException(e,""); - } catch (SocketTimeoutException e) { - LOGGER.error("Exception", e); - throw new OpenShiftException(e,""); - //HACK - This gets us around a server issue - } catch (HttpClientException e) { - if(e instanceof NotFoundException) { - throw new com.openshift.restclient.NotFoundException(e); - } - if(e.getResponseCode() != 403) { - throw e; - } - LOGGER.error("Unauthorized exception. Can system:anonymous get the API endpoint", e); - return new ArrayList(); - } - } - @Override public URL getBaseURL() { return this.baseUrl; } - @SuppressWarnings("deprecation") @Override - public void setAuthorizationStrategy(IAuthorizationStrategy strategy) { - this.strategy = strategy; - this.client.setAuthorizationStrategy(strategy); + public IAuthorizationContext getAuthorizationContext() { + return this.authContext; } - @Override - public IAuthorizationStrategy getAuthorizationStrategy() { - return this.strategy; + public void setToken(String token) { + this.authContext.setToken(token); } - - private OpenShiftException createOpenShiftException(String message, HttpClientException e) { - LOGGER.debug(message, e); - final String token = strategy != null ? strategy.getToken() : ""; - if (e.getMessage() != null - && e.getMessage().startsWith("{")) { - IStatus status = factory.create(e.getMessage()); - if(status.getCode() == STATUS_FORBIDDEN) { - if(StringUtils.isNotBlank(token)) { //truly forbidden - return new ResourceForbiddenException(status.getMessage(), status, e); - }else { - return new com.openshift.restclient.authorization.UnauthorizedException(authClient.getAuthorizationDetails(this.baseUrl.toString())); - } - } - return new OpenShiftException(e, status, message); - } else { - if(e instanceof UnauthorizedException) { - return new com.openshift.restclient.authorization.UnauthorizedException(authClient.getAuthorizationDetails(this.baseUrl.toString())); - } - return new OpenShiftException(e, message); - } - } - - @Override - public IUser getCurrentUser() { - return get(ResourceKind.USER, "~", ""); - } - - @Override - public IAuthorizationContext getContext(String baseURL) { - return this.authClient.getContext(baseURL); - } - - @Override - public IAuthorizationDetails getAuthorizationDetails(String baseURL) { - return this.authClient.getAuthorizationDetails(baseURL); + + public String getToken() { + return getAuthorizationContext().getToken(); } - @Override - public void setSSLCertificateCallback(ISSLCertificateCallback callback) { - this.authClient.setSSLCertificateCallback(callback); - this.client.setSSLCertificateCallback(callback); - } - @Override public int hashCode() { final int prime = 31; @@ -479,7 +323,7 @@ public int hashCode() { result = prime * result + ((baseUrl == null) ? 0 : baseUrl.hashCode()); result = prime * result + ((kubernetesVersion == null) ? 0 : kubernetesVersion.hashCode()); result = prime * result + ((openShiftVersion == null) ? 0 : openShiftVersion.hashCode()); - result = prime * result + ((strategy == null || strategy.getToken() == null) ? 0 : strategy.getToken().hashCode()); + result = prime * result + ((authContext == null || authContext.getToken() == null) ? 0 : authContext.getToken().hashCode()); return result; } @@ -508,15 +352,31 @@ public boolean equals(Object obj) { } else if (!openShiftVersion.equals(other.openShiftVersion)) { return false; } - if (strategy == null) { - return other.strategy == null; + if (authContext == null) { + return other.authContext == null; } else { - if (other.strategy == null) { + if (other.authContext == null) { return false; } - return ObjectUtils.equals(strategy.getUsername(), other.strategy.getUsername()); + return ObjectUtils.equals(authContext.getUserName(), other.authContext.getUserName()); } } + + @SuppressWarnings("unchecked") + @Override + public T adapt(Class klass) { + if(OkHttpClient.class.equals(klass)) { + return (T) this.client; + } + if(IApiTypeMapper.class.equals(klass)) { + return (T)this.typeMapper; + } + if(ICapability.class.isAssignableFrom(klass) && this.supports((Class) klass)) { + return (T) getCapability((Class)klass); + } + return null; + } + } diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 7cc7709b..158c240c 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -24,7 +24,6 @@ import com.openshift.internal.restclient.model.Build; import com.openshift.internal.restclient.model.BuildConfig; -import com.openshift.internal.restclient.model.Config; import com.openshift.internal.restclient.model.DeploymentConfig; import com.openshift.internal.restclient.model.ImageStream; import com.openshift.internal.restclient.model.KubernetesEvent; @@ -71,13 +70,12 @@ public class ResourceFactory implements IResourceFactory{ private static final String KIND = "kind"; private static final String APIVERSION = "apiVersion"; - private static final Map> IMPL_MAP = new HashMap>(); + private static final Map> IMPL_MAP = new HashMap<>(); static { //OpenShift kinds IMPL_MAP.put(ResourceKind.BUILD, Build.class); IMPL_MAP.put(ResourceKind.BUILD_CONFIG, BuildConfig.class); IMPL_MAP.put(ResourceKind.BUILD_REQUEST, BuildRequest.class); - IMPL_MAP.put(ResourceKind.CONFIG, Config.class); IMPL_MAP.put(ResourceKind.DEPLOYMENT_CONFIG, DeploymentConfig.class); IMPL_MAP.put(ResourceKind.IMAGE_STREAM, ImageStream.class); IMPL_MAP.put(ResourceKind.IMAGE_STREAM_IMPORT, ImageStreamImport.class); diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index 04f4aaa2..57ddf2fa 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -66,28 +66,28 @@ public class URLBuilder { * @param baseUrl * @param typeMappings the map of kinds to endpoint */ - URLBuilder(URL baseUrl, IApiTypeMapper typeMappings) { + public URLBuilder(URL baseUrl, IApiTypeMapper typeMappings) { this.baseUrl = baseUrl.toString().replaceAll("/*$", ""); this.typeMappings = typeMappings; } - URLBuilder apiVersion(String apiVersion){ + public URLBuilder apiVersion(String apiVersion){ this.apiVersion = apiVersion; return this; } - URLBuilder namespace(String namespace){ + public URLBuilder namespace(String namespace){ if(StringUtils.isBlank(namespace)) return this; this.namespace = namespace; return this; } - URLBuilder name(String name) { + public URLBuilder name(String name) { this.name = name; return this; } - URLBuilder kind(String kind) { + public URLBuilder kind(String kind) { if(!ResourceKind.values().contains(kind)) { LOG.warn(String.format("There kind '%s' is not recognized by this client; this operation may fail.", kind)); } @@ -95,7 +95,7 @@ URLBuilder kind(String kind) { return this; } - URLBuilder resource(IResource resource) { + public URLBuilder resource(IResource resource) { if (resource == null) return this; this.name = resource.getName(); kind(resource.getKind()); @@ -103,13 +103,13 @@ URLBuilder resource(IResource resource) { return this; } - URLBuilder addParmeter(String key, String value) { + public URLBuilder addParmeter(String key, String value) { params.put(key, value); return this; } - URLBuilder subresource(String value) { + public URLBuilder subresource(String value) { this.subResource = value; return this; } @@ -119,7 +119,7 @@ URLBuilder subresource(String value) { * a resource kind must be provided * @return */ - URL build() { + public URL build() { StringBuilder url = new StringBuilder(baseUrl); if (kind == null) throw new RuntimeException( diff --git a/src/main/java/com/openshift/internal/restclient/WatchClient.java b/src/main/java/com/openshift/internal/restclient/WatchClient.java deleted file mode 100644 index f9d0e598..00000000 --- a/src/main/java/com/openshift/internal/restclient/WatchClient.java +++ /dev/null @@ -1,284 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient; - -import java.net.URI; -import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import org.apache.commons.lang.StringUtils; -import org.eclipse.jetty.util.component.LifeCycle; -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.websocket.api.Session; -import org.eclipse.jetty.websocket.api.UpgradeException; -import org.eclipse.jetty.websocket.api.WebSocketAdapter; -import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; -import org.eclipse.jetty.websocket.client.WebSocketClient; -import org.jboss.dmr.ModelNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.openshift.internal.restclient.model.KubernetesResource; -import com.openshift.restclient.IApiTypeMapper; -import com.openshift.restclient.IClient; -import com.openshift.restclient.IOpenShiftWatchListener; -import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; -import com.openshift.restclient.IResourceFactory; -import com.openshift.restclient.IWatcher; -import com.openshift.restclient.OpenShiftException; -import com.openshift.restclient.authorization.ResourceForbiddenException; -import com.openshift.restclient.http.IHttpConstants; -import com.openshift.restclient.model.IList; -import com.openshift.restclient.model.IResource; - -/** - * Encapsulation of the logic to handle watching resources. - * @author Jeff Cantrill - * - */ -public class WatchClient implements IHttpConstants, IWatcher{ - private static final Logger LOGGER = LoggerFactory.getLogger(WatchClient.class); - private static final long DEFAULT_LOCK_TIMEOUT = 30 * 1000; - - private URL baseUrl; - private IApiTypeMapper typeMappings; - private IResourceFactory factory; - private IClient client; - private static WebSocketClient wsClient; - private static AtomicReference status = new AtomicReference<>(Status.Stopped); - private static Lock lock = new ReentrantLock(); - private static Condition isStarted = lock.newCondition(); - private static long lockTimeout; - - private enum Status { - Started, - Starting, - Stopped, - Stopping - } - - static { - lockTimeout = getLockTimeout(); - // TODO: move this to lazy creation - wsClient = createWebSocketClient(); - } - - private static WebSocketClient createWebSocketClient() { - WebSocketClient wsClient = newWebSocketClient(); - wsClient.addLifeCycleListener(new LifeCycle.Listener() { - - @Override - public void lifeCycleStopping(LifeCycle event) { - status.set(Status.Stopping); - } - - @Override - public void lifeCycleStopped(LifeCycle event) { - status.set(Status.Stopped); - } - - @Override - public void lifeCycleStarting(LifeCycle event) { - status.set(Status.Starting); - } - - @Override - public void lifeCycleStarted(LifeCycle event) { - status.set(Status.Started); - try { - if (lock.tryLock(lockTimeout, TimeUnit.MILLISECONDS)) { - isStarted.signalAll(); - } - } catch (InterruptedException e) { - LOGGER.debug("Exception while trying to get lock", e); - } finally { - lock.unlock(); - } - } - - @Override - public void lifeCycleFailure(LifeCycle event, Throwable cause) { - LOGGER.error("The watchclient failed:", cause); - status.set(Status.Stopped); - } - }); - return wsClient; - } - - private static long getLockTimeout() { - try { - return Long.parseLong(System.getProperty("com.openshift.restclient.watchlocktimeoutms", String.valueOf(DEFAULT_LOCK_TIMEOUT))); - } catch (NumberFormatException e) { - return DEFAULT_LOCK_TIMEOUT; - } - } - - public WatchClient(URL baseUrl, IApiTypeMapper typeMappings, IClient client) { - this.baseUrl = baseUrl; - this.typeMappings = typeMappings; - this.factory = client.getResourceFactory(); - this.client = client; - } - - private class WatchEndpoint extends WebSocketAdapter{ - private IOpenShiftWatchListener listener; - private List resources; - private final String kind; - - public WatchEndpoint(IOpenShiftWatchListener listener, String kind) { - this.listener = listener; - this.kind = kind; - } - - public void setResources(List resources) { - this.resources = resources; - } - - @Override - public void onWebSocketClose(int statusCode, String reason) { - LOGGER.debug("WatchSocket closed for kind {}", kind); - getSession().close(statusCode, reason); - super.onWebSocketClose(statusCode, reason); - listener.disconnected(); - } - - @Override - public void onWebSocketConnect(Session session) { - LOGGER.debug("WatchSocket connected {}", kind); - super.onWebSocketConnect(session); - listener.connected(resources); - - } - - @Override - public void onWebSocketError(Throwable err) { - LOGGER.debug("WatchSocket Error for kind " + kind, err); - listener.error(createOpenShiftException("WatchSocket Error", err)); - } - - @Override - public void onWebSocketText(String message) { - LOGGER.debug(message); - KubernetesResource payload = factory.create(message); - ModelNode node = payload.getNode(); - IOpenShiftWatchListener.ChangeType event = new ChangeType(node.get("type").asString()); - IResource resource = factory.create(node.get("object").toJSONString(true)); - if(StringUtils.isEmpty(resource.getKind())) { - LOGGER.error("Unable to determine resource kind from: " + node.get("object").toJSONString(false)); - } - listener.received(resource, event); - } - } - - public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatchListener listener) { - try { - ClientUpgradeRequest request = newRequest(this.client.getAuthorizationStrategy().getToken()); - for (String kind : kinds) { - WatchEndpoint socket = new WatchEndpoint(listener, kind); - final String resourceVersion = getResourceVersion(kind, namespace, socket); - - final String endpoint = new URLBuilder(baseUrl, typeMappings) - .kind(kind) - .namespace(namespace) - .watch() - .addParmeter("resourceVersion", resourceVersion) - .websocket(); - connect(socket, endpoint, request); - } - } catch (Exception e) { - throw createOpenShiftException(String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), e); - } - return this; - } - - private void connect(WatchEndpoint socket, String endpoint, ClientUpgradeRequest request) throws Exception { - start(); - if(status.get() == Status.Starting) { - isStarted.await(lockTimeout, TimeUnit.MILLISECONDS); - } - wsClient.connect(socket, new URI(endpoint), request); - } - - public void start() { - if(status.get() == Status.Started - || status.get() == Status.Starting) { - return; - } - try { - wsClient.start(); - } catch (Exception e) { - throw createOpenShiftException(String.format("Could not start watchClient"),e); - } - } - - @Override - public void stop(){ - if(status.get() == Status.Stopping - || status.get() == Status.Stopped) { - return; - } - try { - wsClient.stop(); - } catch (Exception e) { - LOGGER.debug("Unable to stop the watch client",e); - } - } - - - - private ClientUpgradeRequest newRequest(final String token) { - ClientUpgradeRequest request = new ClientUpgradeRequest(); - request.setHeader("Origin", baseUrl.toString()); - request.setHeader("User-Agent", "openshift-restclient-java"); - request.setHeader("Authorization", "Bearer " + token); - return request; - } - - private static WebSocketClient newWebSocketClient() { - SslContextFactory factory = new SslContextFactory(); - factory.setTrustAll(true); - WebSocketClient client = new WebSocketClient(factory); - return client; - } - - private String getResourceVersion(String kind, String namespace, WatchEndpoint endpoint) throws Exception{ - IList list = client.get(kind, namespace); - Collection items = list.getItems(); - List resources = new ArrayList<>(items.size()); - resources.addAll(items); - endpoint.setResources(resources); - return list.getMetadata().get("resourceVersion"); - } - - private OpenShiftException createOpenShiftException(String message, Throwable e) { - LOGGER.debug(message, e); - int responseCode = 0; - if(e instanceof UpgradeException) { - UpgradeException ex = (UpgradeException)e; - responseCode = ex.getResponseStatusCode(); - } - switch(responseCode) { - case STATUS_FORBIDDEN: - return new ResourceForbiddenException("Resource Forbidden", e); - case STATUS_UNAUTHORIZED: - return new com.openshift.restclient.authorization.UnauthorizedException(client.getAuthorizationDetails(this.baseUrl.toString())); - default: - return new OpenShiftException(e, message); - } - } -} diff --git a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationClient.java b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationClient.java deleted file mode 100644 index 2b9a7baf..00000000 --- a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationClient.java +++ /dev/null @@ -1,247 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.internal.restclient.authorization; - -import java.io.Closeable; -import java.io.IOException; -import java.net.ProxySelector; -import java.net.URISyntaxException; -import java.security.GeneralSecurityException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.conn.ssl.AllowAllHostnameVerifier; -import org.apache.http.conn.ssl.X509HostnameVerifier; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.impl.conn.SystemDefaultRoutePlanner; -import org.apache.http.params.HttpParams; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.openshift.restclient.IClient; -import com.openshift.restclient.ISSLCertificateCallback; -import com.openshift.restclient.NoopSSLCertificateCallback; -import com.openshift.restclient.OpenShiftException; -import com.openshift.restclient.authorization.IAuthorizationClient; -import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.IAuthorizationDetails; -import com.openshift.restclient.authorization.IAuthorizationStrategy; -import com.openshift.restclient.authorization.ResourceForbiddenException; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; -import com.openshift.restclient.authorization.UnauthorizedException; -import com.openshift.restclient.http.IHttpClient; - -/** - * @author Jeff Cantrill - */ -public class AuthorizationClient implements IAuthorizationClient { - private static final Logger LOG = LoggerFactory.getLogger(IAuthorizationClient.class); - - private static final int TIMEOUT = 10 * 1000; //10 seconds - - private SSLContext sslContext; - private X509HostnameVerifier hostnameVerifier = new AllowAllHostnameVerifier(); - private IClient openshiftClient; - private int connectTimeoutMillis; - - - public AuthorizationClient(IClient client) { - this(client, TIMEOUT); - connectTimeoutMillis = TIMEOUT; - } - - - public AuthorizationClient(IClient client, int connectTimeoutMillis) { - this.openshiftClient = client; - this.connectTimeoutMillis = connectTimeoutMillis; - setSSLCertificateCallback(new NoopSSLCertificateCallback()); - } - - - @Override - public IAuthorizationDetails getAuthorizationDetails(final String baseURL) { - try { - getContextUsingCredentials(baseURL, null); - return new AuthorizationDetails(String.format("%s/oauth/token/request", baseURL)); - }catch(UnauthorizedException e) { - return e.getAuthorizationDetails(); - } - } - - @Override - public IAuthorizationContext getContext(final String baseURL) { - OpenShiftCredentialsProvider credentialsProvider = new OpenShiftCredentialsProvider(); - openshiftClient.getAuthorizationStrategy().accept(credentialsProvider); - final IAuthorizationStrategy configuredAuthStrategy = openshiftClient.getAuthorizationStrategy(); - try { - final String token = credentialsProvider.getToken(); - openshiftClient.setAuthorizationStrategy(new TokenAuthorizationStrategy(token)); - return new AuthorizationContext(token, null, openshiftClient.getCurrentUser(), credentialsProvider.getScheme()); - }catch(ResourceForbiddenException e) { - //the response if token is invalid because we tried to - //get the current user - }catch(UnauthorizedException | com.openshift.internal.restclient.http.UnauthorizedException e) { - openshiftClient.setAuthorizationStrategy(configuredAuthStrategy); - return getContextUsingCredentials(baseURL, credentialsProvider); - }finally{ - openshiftClient.setAuthorizationStrategy(configuredAuthStrategy); - } - return getContextUsingCredentials(baseURL, credentialsProvider); - - } - - private IAuthorizationContext getContextUsingCredentials(final String baseURL, CredentialsProvider credentialsProvider) { - - CloseableHttpResponse response = null; - CloseableHttpClient client = null; - try { - OpenShiftAuthorizationRedirectStrategy redirectStrategy = new OpenShiftAuthorizationRedirectStrategy(openshiftClient); - RequestConfig defaultRequestConfig = RequestConfig.custom() - .setSocketTimeout(connectTimeoutMillis) - .setConnectTimeout(connectTimeoutMillis) - .setConnectionRequestTimeout(connectTimeoutMillis) - .setStaleConnectionCheckEnabled(true) - .build(); - client = HttpClients.custom() - .setRedirectStrategy(redirectStrategy) - .setRoutePlanner(new SystemDefaultRoutePlanner(ProxySelector.getDefault())) - .setHostnameVerifier(hostnameVerifier) - .setDefaultCredentialsProvider(credentialsProvider) - .setSslcontext(sslContext) - .setDefaultRequestConfig(defaultRequestConfig) - .build(); - HttpGet request = - new HttpGet( - new URIBuilder(String.format("%s/oauth/authorize", baseURL)) - .addParameter("response_type", "token") - .addParameter("client_id", "openshift-challenging-client") - .build()); - request.addHeader("X-CSRF-Token", "1"); - response = client.execute(request); - return redirectStrategy.getAuthorizationContext(); - } catch (URISyntaxException e) { - throw new OpenShiftException(e, String.format("Unvalid URI while trying to get an authorization context for server %s", baseURL)); - } catch (ClientProtocolException e) { - throw new OpenShiftException(e, String.format("Client protocol exception while trying to get authorization context for server %s", baseURL)); - } catch (IOException e) { - throw new OpenShiftException(e, String.format("%s while trying to get an authorization context for server %s", e.getClass().getName(), baseURL)); - } finally { - close(response); - close(client); - } - - } - - private void close(Closeable closer) { - if (closer == null) - return; - try { - closer.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - @Override - public void setSSLCertificateCallback(ISSLCertificateCallback callback) { - X509TrustManager trustManager = null; - if (callback != null) { - trustManager = createCallbackTrustManager(callback); - } - try { - this.sslContext = SSLContext.getInstance("TLS"); - this.sslContext.init(null, new TrustManager[] { trustManager }, null); - } catch (NoSuchAlgorithmException e) { - LOG.warn("Could not install trust manager callback", e); - this.sslContext = null; - } catch (KeyManagementException e) { - LOG.warn("Could not install trust manager callback", e); - this.sslContext = null; - } - } - - // TODO REPLACE me with osjc impl - private X509TrustManager createCallbackTrustManager(ISSLCertificateCallback sslAuthorizationCallback) { - X509TrustManager trustManager = null; - try { - trustManager = getCurrentTrustManager(); - if (trustManager == null) { - LOG.warn("Could not install trust manager callback, no trustmanager was found."); - } else { - trustManager = new CallbackTrustManager(trustManager, sslAuthorizationCallback); - } - } catch (GeneralSecurityException e) { - LOG.warn("Could not install trust manager callback.", e); - } - return trustManager; - } - - // TODO replace me with OSJC implementation - private X509TrustManager getCurrentTrustManager() throws NoSuchAlgorithmException, KeyStoreException { - TrustManagerFactory trustManagerFactory = - TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init((KeyStore) null); - - X509TrustManager x509TrustManager = null; - for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { - if (trustManager instanceof X509TrustManager) { - x509TrustManager = (X509TrustManager) trustManager; - break; - } - } - return x509TrustManager; - } - - // TODO - Replace me with instance in OSJC - private static class CallbackTrustManager implements X509TrustManager { - - private X509TrustManager trustManager; - private ISSLCertificateCallback callback; - - private CallbackTrustManager(X509TrustManager currentTrustManager, ISSLCertificateCallback callback) - throws NoSuchAlgorithmException, KeyStoreException { - this.trustManager = currentTrustManager; - this.callback = callback; - } - - public X509Certificate[] getAcceptedIssuers() { - return trustManager.getAcceptedIssuers(); - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - try { - trustManager.checkServerTrusted(chain, authType); - } catch (CertificateException e) { - if (!callback.allowCertificate(chain)) { - throw e; - } - } - } - - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - trustManager.checkServerTrusted(chain, authType); - } - } -} diff --git a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java index 4f72bbac..2bbc0775 100644 --- a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java +++ b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java @@ -10,7 +10,10 @@ import org.apache.commons.lang.StringUtils; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; import com.openshift.restclient.authorization.IAuthorizationContext; +import com.openshift.restclient.authorization.IAuthorizationDetails; import com.openshift.restclient.model.user.IUser; /** @@ -22,11 +25,19 @@ public class AuthorizationContext implements IAuthorizationContext { private String expires; private String scheme; private IUser user; - + private String userName; + private String password; + private IClient client; + public AuthorizationContext(String scope){ this.scheme = scope; } + public AuthorizationContext(String token, String userName, String password){ + this.token = token; + this.userName = userName; + this.password = password; + } public AuthorizationContext(String token, String expires, IUser user, String scheme){ this.token = token; @@ -35,11 +46,33 @@ public AuthorizationContext(String token, String expires, IUser user, String sch this.scheme = scheme; } + public AuthorizationContext clone() { + AuthorizationContext context = new AuthorizationContext(this.token, this.expires, this.user, this.scheme); + context.setUserName(this.userName); + context.setPassword(this.password); + context.setClient(this.client); + return context; + } + + public void setClient(IClient client){ + this.client = client; + } + @Override public boolean isAuthorized() { + if(user == null) { + synchronized (this) { + user = client.get(ResourceKind.USER, "~", ""); + } + } return StringUtils.isNotEmpty(token); } + @Override + public IAuthorizationDetails getAuthorizationDetails() { + return new AuthorizationDetails(String.format("%s/oauth/token/request", client.getBaseURL())); + } + @Override public String getToken(){ return this.token; @@ -60,4 +93,39 @@ public IUser getUser() { return user; } + public void setUser(IUser user) { + this.user = user; + } + + + @Override + public void setToken(String token) { + this.token = token; + } + + + @Override + public void setUserName(String userName) { + this.userName = userName; + } + + + @Override + public String getUserName() { + return this.userName; + } + + + @Override + public void setPassword(String password) { + this.password = password; + } + + + @Override + public String getPassword() { + return this.password; + } + + } diff --git a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationDetails.java b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationDetails.java index eff2781b..30935def 100644 --- a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationDetails.java +++ b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationDetails.java @@ -13,10 +13,10 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import org.apache.http.Header; - import com.openshift.restclient.authorization.IAuthorizationDetails; +import okhttp3.Headers; + /** * @author Jeff Cantrill */ @@ -47,21 +47,20 @@ public AuthorizationDetails(String error, String errorDetails) { } } - public AuthorizationDetails(Header[] headers) { - for (Header header : headers) { - final String name = header.getName(); + public AuthorizationDetails(Headers headers) { + for (String name : headers.names()) { if(LINK.equalsIgnoreCase(name)) { - Matcher matcher = LINK_RE.matcher(header.getValue()); + Matcher matcher = LINK_RE.matcher(headers.get(name)); if(matcher.find()) { link = matcher.group(1); } }else if(WARNING.equalsIgnoreCase(name)) { - Matcher matcher = WARNING_RE.matcher(header.getValue()); + Matcher matcher = WARNING_RE.matcher(headers.get(name)); if(matcher.find()) { message = matcher.group(1); } }else if(WWW_AUTHENTICATE.equalsIgnoreCase(name)) { - scheme = header.getValue(); + scheme = headers.get(name); if(scheme.contains("realm")) { scheme = scheme.split(" ")[0]; } @@ -70,6 +69,13 @@ public AuthorizationDetails(Header[] headers) { } + public AuthorizationDetails(Headers headers, String link) { + this(headers); + if(link != null) { + this.link = link; + } + } + @Override public String getScheme() { return scheme ; diff --git a/src/main/java/com/openshift/internal/restclient/authorization/OpenShiftAuthorizationRedirectStrategy.java b/src/main/java/com/openshift/internal/restclient/authorization/OpenShiftAuthorizationRedirectStrategy.java deleted file mode 100644 index 24731374..00000000 --- a/src/main/java/com/openshift/internal/restclient/authorization/OpenShiftAuthorizationRedirectStrategy.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.internal.restclient.authorization; - -import java.net.URI; -import java.util.Map; - -import org.apache.http.Header; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.HttpStatus; -import org.apache.http.ProtocolException; -import org.apache.http.impl.client.DefaultRedirectStrategy; -import org.apache.http.protocol.HttpContext; - -import com.openshift.internal.util.Assert; -import com.openshift.internal.util.URIUtils; -import com.openshift.restclient.IClient; -import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.IAuthorizationDetails; -import com.openshift.restclient.authorization.IAuthorizationStrategy; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; -import com.openshift.restclient.authorization.UnauthorizedException; - -/** - * OpenShift authorization redirect strategy to disable - * redirects once an access token is granted - * - * @author Jeff Cantrill - */ -public class OpenShiftAuthorizationRedirectStrategy extends DefaultRedirectStrategy{ - // access_token and expires_in fragment params are an OAuth token response - private static final String ACCESS_TOKEN = "access_token"; - private static final String EXPIRES = "expires_in"; - - // error and error_details query params are an OAuth error response - private static final String ERROR = "error"; - private static final String ERROR_DETAILS = "error_details"; - - private IAuthorizationContext authcontext; - private IClient client; - - public OpenShiftAuthorizationRedirectStrategy(IClient client) { - Assert.notNull(this.client = client); - } - - public IAuthorizationContext getAuthorizationContext() { - return authcontext; - } - - @Override - public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) throws ProtocolException { - // 401 response - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) { - IAuthorizationDetails details = new AuthorizationDetails(response.getAllHeaders()); - throw new UnauthorizedException(details); - } - - // 302 response - if (response.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) { - Header locationHeader = response.getFirstHeader("Location"); - if (locationHeader == null) { - return false; - } - URI locationURI = createLocationURI(locationHeader.getValue()); - - // check access_token fragment param - Map pairs = URIUtils.splitFragment(locationURI); - if (pairs.containsKey(ACCESS_TOKEN)) { - final String token = pairs.get(ACCESS_TOKEN); - IAuthorizationStrategy strategy = client.getAuthorizationStrategy(); - client.setAuthorizationStrategy(new TokenAuthorizationStrategy(token)); - this.authcontext = new AuthorizationContext(token, pairs.get(EXPIRES), client.getCurrentUser(), IAuthorizationContext.AUTHSCHEME_BASIC); - client.setAuthorizationStrategy(strategy); - return false; - } - - // check error query param - Map queryParams = URIUtils.splitQuery(locationURI.getQuery()); - if (queryParams.containsKey(ERROR)) { - IAuthorizationDetails details = new AuthorizationDetails(queryParams.get(ERROR), queryParams.get(ERROR_DETAILS)); - throw new UnauthorizedException(details); - } - } - - return super.isRedirected(request, response, context); - } - -} \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/authorization/OpenShiftCredentialsProvider.java b/src/main/java/com/openshift/internal/restclient/authorization/OpenShiftCredentialsProvider.java deleted file mode 100644 index a279981d..00000000 --- a/src/main/java/com/openshift/internal/restclient/authorization/OpenShiftCredentialsProvider.java +++ /dev/null @@ -1,77 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.authorization; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.Credentials; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.impl.client.SystemDefaultCredentialsProvider; - -import com.openshift.restclient.authorization.BasicAuthorizationStrategy; -import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.IAuthorizationStrategyVisitor; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; - -public class OpenShiftCredentialsProvider implements CredentialsProvider, IAuthorizationStrategyVisitor{ - - private CredentialsProvider provider = new SystemDefaultCredentialsProvider(); - private Map creds = new HashMap(2); - private String token; - private String scheme; - - /** - * Get the token if known; - * @return - */ - public String getToken() { - return token; - } - - public String getScheme() { - return scheme; - } - - @Override - public void visit(BasicAuthorizationStrategy strategy) { - creds.put(IAuthorizationContext.AUTHSCHEME_BASIC.toLowerCase(), new UsernamePasswordCredentials(strategy.getUsername(), strategy.getPassword())); - scheme = IAuthorizationContext.AUTHSCHEME_BASIC; - token = strategy.getToken(); - } - - - @Override - public void visit(TokenAuthorizationStrategy strategy) { - this.scheme = IAuthorizationContext.AUTHSCHEME_OAUTH; - this.token = strategy.getToken(); - } - - @Override - public void setCredentials(AuthScope authscope, Credentials credentials) { - provider.setCredentials(authscope, credentials); - } - - @Override - public Credentials getCredentials(AuthScope authscope) { - final String scheme = authscope.getScheme().toLowerCase(); - if(creds.containsKey(scheme)){ - return creds.get(scheme); - } - return provider.getCredentials(authscope); - } - - @Override - public void clear() { - provider.clear(); - } - -} \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index b383b985..b5f82a8d 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -22,9 +22,6 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.OpenShiftContext; import com.openshift.restclient.OpenShiftException; -import com.openshift.restclient.authorization.BasicAuthorizationStrategy; -import com.openshift.restclient.authorization.IAuthorizationStrategyVisitor; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.capability.resources.LocationNotFoundException; @@ -87,7 +84,7 @@ public void run() { protected String getUserFlag() { final StringBuilder argBuilder = new StringBuilder(); - argBuilder.append("--user=").append(client.getCurrentUser().getName()).append(" "); + argBuilder.append("--user=").append(client.getAuthorizationContext().getUserName()).append(" "); return argBuilder.toString(); } @@ -105,22 +102,9 @@ protected String getServerFlag() { * @return the command-line argument to use the current token */ protected String getTokenFlag() { - final StringBuilder argBuilder = new StringBuilder(); - argBuilder.append("--token="); - client.getAuthorizationStrategy().accept(new IAuthorizationStrategyVisitor() { - - @Override - public void visit(TokenAuthorizationStrategy strategy) { - argBuilder.append(strategy.getToken()); - } - - @Override - public void visit(BasicAuthorizationStrategy strategy) { - argBuilder.append(strategy.getToken()); - } - }); - argBuilder.append(" "); - return argBuilder.toString(); + return new StringBuilder("--token=") + .append(client.getAuthorizationContext().getToken()) + .append(" ").toString(); } /** diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java index cc291f19..0e1b4d59 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java @@ -18,11 +18,6 @@ import java.util.stream.Collectors; import org.apache.commons.lang.StringUtils; -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.http.HttpHeader; -import org.eclipse.jetty.util.ssl.SslContextFactory; import org.jboss.dmr.ModelNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,7 +25,9 @@ import com.openshift.internal.restclient.model.ModelNodeBuilder; import com.openshift.internal.restclient.model.image.ImageStreamImport; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; +import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; import com.openshift.internal.util.JBossDmrExtentions; +import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; @@ -39,6 +36,11 @@ import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.image.IImageStreamImport; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + /** * Retrieve metadata directly from docker. * @author jeff.cantrill @@ -48,7 +50,6 @@ public class DockerRegistryImageStreamImportCapability implements IImageStreamIm private static final String TOKEN = "token"; private static final String STATUS_STATUS = "status.status"; - private static final int TIMEOUT = 10 * 1000; //10 seconds private static final String ID = "id"; private static final String PARENT = "parent"; private static final String REALM = "realm"; @@ -56,10 +57,17 @@ public class DockerRegistryImageStreamImportCapability implements IImageStreamIm private static final String DEFAULT_DOCKER_REGISTRY = "https://registry-1.docker.io/v2"; private IResourceFactory factory; private IProject project; + private OkHttpClient okClient; - public DockerRegistryImageStreamImportCapability(IProject project, IResourceFactory factory) { + public DockerRegistryImageStreamImportCapability(IProject project, IResourceFactory factory, IClient client) { this.factory = factory; this.project = project; + this.okClient = client.adapt(OkHttpClient.class); + if(okClient != null) { + okClient = okClient.newBuilder() + .followRedirects(true) + .build(); + } } @Override @@ -72,24 +80,28 @@ public String getName() { return DockerRegistryImageStreamImportCapability.class.getSimpleName(); } - private boolean registryExists(HttpClient client) throws Exception{ - ContentResponse response = client.newRequest(DEFAULT_DOCKER_REGISTRY).send(); + private boolean registryExists(OkHttpClient client) throws Exception{ + Request req = new Request.Builder() + .url(DEFAULT_DOCKER_REGISTRY) + .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true") + .build(); + Response response = client.newCall(req).execute(); if(response == null) return false; - return (response.getStatus() == STATUS_UNAUTHORIZED || response.getStatus() == STATUS_OK); + return (response.code() == STATUS_UNAUTHORIZED || response.code() == STATUS_OK); } /** * @return the token required to pull docker metadata */ - private String retrieveAuthToken(HttpClient client, String details) throws Exception { + private String retrieveAuthToken(OkHttpClient client, String details) throws Exception { if(StringUtils.isNotBlank(details)) { Map auth = parseAuthDetails(details); if(auth.containsKey(REALM)) { - Request request = createAuthRequest(client, auth); - ContentResponse response = request.send(); + Request request = createAuthRequest(auth); + Response response = client.newCall(request).execute(); LOG.debug("Auth response: " + response.toString()); - if(response.getStatus() == STATUS_OK && response.getHeaders().contains(PROPERTY_CONTENT_TYPE, MEDIATYPE_APPLICATION_JSON)) { - ModelNode tokenNode = ModelNode.fromJSONString(response.getContentAsString()); + if(response.code() == STATUS_OK && MEDIATYPE_APPLICATION_JSON.equals(response.headers().get(PROPERTY_CONTENT_TYPE))) { + ModelNode tokenNode = ModelNode.fromJSONString(response.body().string()); if(tokenNode.hasDefined(TOKEN)) { return tokenNode.get(TOKEN).asString(); }else { @@ -105,14 +117,19 @@ private String retrieveAuthToken(HttpClient client, String details) throws Excep return null; } - private Request createAuthRequest(HttpClient client, Map authParams) { - Request request = client.newRequest(StringUtils.strip(authParams.get(REALM),"\"")); + private Request createAuthRequest(Map authParams) { + HttpUrl.Builder builder = HttpUrl.parse(StringUtils.strip(authParams.get(REALM),"\"")) + .newBuilder(); for (Entry e: authParams.entrySet()) { if(!REALM.equals(e.getKey())) { - request.param(StringUtils.strip(e.getKey(),"\""), StringUtils.strip(e.getValue(),"\"")); + builder.addQueryParameter(StringUtils.strip(e.getKey(),"\""), StringUtils.strip(e.getValue(),"\"")); } } - LOG.debug("Auth request uri: " + request.getURI()); + Request request = new Request.Builder() + .url(builder.build()) + .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true") + .build(); + LOG.debug("Auth request uri: " + request.url()); return request; } @@ -132,25 +149,27 @@ private Map parseAuthDetails(String auth){ return map; } - private DockerResponse retrieveMetaData(HttpClient client, String token, DockerImageURI uri) throws Exception { + private DockerResponse retrieveMetaData(OkHttpClient client, String token, DockerImageURI uri) throws Exception { String regUri = String.format("%s/%s/%s/manifests/%s", DEFAULT_DOCKER_REGISTRY, StringUtils.defaultIfBlank(uri.getUserName(),"library"), uri.getName(), uri.getTag()); - Request request = client.newRequest(regUri); + Request.Builder builder = new Request.Builder() + .url(regUri) + .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true"); if(token != null) { - request.header(PROPERTY_AUTHORIZATION, String.format("%s %s", AUTHORIZATION_BEARER, token)); + builder.header(PROPERTY_AUTHORIZATION, String.format("%s %s", AUTHORIZATION_BEARER, token)); } LOG.debug("retrieveMetaData uri: " + regUri); - ContentResponse response = request.send(); + Response response = client.newCall(builder.build()).execute(); LOG.debug("retrieveMetaData response: " + response.toString()); - switch(response.getStatus()) { + switch(response.code()) { case STATUS_OK: - return new DockerResponse(DockerResponse.DATA, response.getContentAsString()); + return new DockerResponse(DockerResponse.DATA, response.body().string()); case STATUS_UNAUTHORIZED: - return new DockerResponse(DockerResponse.AUTH, response.getHeaders().get(HttpHeader.WWW_AUTHENTICATE)); + return new DockerResponse(DockerResponse.AUTH, response.headers().get(IHttpConstants.PROPERTY_WWW_AUTHENTICATE)); } LOG.info("Unable to retrieve docker meta data: " + response.toString()); return null; @@ -175,39 +194,27 @@ public String getData() { @Override public IImageStreamImport importImageMetadata(DockerImageURI uri) { - - HttpClient client = null; - try { - SslContextFactory sslFactory = new SslContextFactory(true); - client = new HttpClient(sslFactory); - client.setConnectTimeout(TIMEOUT); - client.start(); - if(registryExists(client)) { - String token = null; - DockerResponse response = retrieveMetaData(client, token, uri); - if(DockerResponse.AUTH.equals(response.getResponseType())){ - LOG.debug("Unauthorized. Trying to retrieve token..."); - token = retrieveAuthToken(client, response.getData()); - response = retrieveMetaData(client, token, uri); - } - if(DockerResponse.DATA.equals(response.getResponseType())) { - String meta = response.getData(); - LOG.debug("Raw Docker image metadata: " + meta); - return buildResponse(meta, uri); - }else { - LOG.info("Unable to retrieve image metadata from docker registry"); - return buildErrorResponse(uri); - } - } - } catch (Exception e) { - LOG.error("Exception while trying to retrieve image metadata from docker", e); - }finally { + if(okClient != null) { try { - if(client != null) { - client.stop(); + if(registryExists(okClient)) { + String token = null; + DockerResponse response = retrieveMetaData(okClient, token, uri); + if(DockerResponse.AUTH.equals(response.getResponseType())){ + LOG.debug("Unauthorized. Trying to retrieve token..."); + token = retrieveAuthToken(okClient, response.getData()); + response = retrieveMetaData(okClient, token, uri); + } + if(DockerResponse.DATA.equals(response.getResponseType())) { + String meta = response.getData(); + LOG.debug("Raw Docker image metadata: " + meta); + return buildResponse(meta, uri); + }else { + LOG.info("Unable to retrieve image metadata from docker registry"); + return buildErrorResponse(uri); + } } } catch (Exception e) { - LOG.warn("Exception while trying to stop http client", e); + LOG.error("Exception while trying to retrieve image metadata from docker", e); } } return buildErrorResponse(uri); @@ -234,7 +241,8 @@ private IImageStreamImport buildResponse(String meta, DockerImageURI uri) { .set("tag", uri.getTag()) .set("image.metadata.name", uri.getName()) .set(ImageStreamImport.IMAGE_DOCKER_IMAGE_REFERENCE,uri.getUriUserNameAndName()) - .set("image.dockerImageMetadata", last); + .set("image.dockerImageMetadata", last) + .set("status.code", IHttpConstants.STATUS_OK); return buildImageStreamImport(uri, builder.build()); } @@ -251,35 +259,43 @@ private ImageStreamImport buildImageStreamImport(DockerImageURI uri, ModelNode n private ModelNode findNewestHistoryEntry(ModelNode root) { ModelNode history = root.get("history"); List entries = history.asList().stream().map(n->ModelNode.fromJSONString(n.get("v1Compatibility").asString())).collect(Collectors.toList()); - entries.sort(new Comparator() { + entries.sort(new ManifestComparator()); - @Override - public int compare(ModelNode one, ModelNode two) { - String parent1 = one.has(PARENT ) ? one.get(PARENT).asString() : null; - String parent2 = two.has(PARENT ) ? one.get(PARENT).asString() : null; - if(parent1 == null && parent2 != null) { - return -1; - }else if(parent1 != null && parent2 == null) { - return 1; - }else if(parent1 == null && parent2 == null) { - return 0; //we should never get here - } - String id1 = one.get(ID).asString(); - String id2 = two.get(ID).asString(); - - if(parent2.equals(id1)) { - return -1; - }else if(parent1.equals(id2)) { - return 1; - } - - return 0; //we should never get here - } - }); - ModelNode last = entries.get(0); + ModelNode last = entries.get(entries.size() - 1); LOG.debug("newest history: " + last.toJSONString(false)); return last; } + /** + * Sorts history entries ordering from oldest to newest + * by comparing the entry id to its referenced parent + * @author jeff.cantrill + * + */ + static class ManifestComparator implements Comparator { + + @Override + public int compare(ModelNode one, ModelNode two) { + String parent1 = one.has(PARENT) ? one.get(PARENT).asString() : null; + String parent2 = two.has(PARENT) ? one.get(PARENT).asString() : null; + if(parent1 == null && parent2 != null) { + return -1; + }else if(parent1 != null && parent2 == null) { + return 1; + }else if(parent1 == null && parent2 == null) { + return 0; //we should never get here + } + String id1 = one.get(ID).asString(); + String id2 = two.get(ID).asString(); + + if(parent2.equals(id1)) { + return -1; + }else if(parent1.equals(id2)) { + return 1; + } + + return 0; //we should never get here + } + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java index fb09d86d..c16a963a 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java @@ -14,11 +14,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.openshift.internal.restclient.model.Status; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.UnsupportedEndpointException; import com.openshift.restclient.authorization.ResourceForbiddenException; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; +import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IStatus; @@ -50,7 +52,7 @@ public IImageStreamImport importImageMetadata(DockerImageURI uri) { try { IImageStreamImport result = client.create(streamImport); for (IStatus status : result.getImageStatus()) { - if("Success".equalsIgnoreCase(status.getStatus())) { + if(IStatus.SUCCESS.equalsIgnoreCase(status.getStatus())) { return result; } } @@ -58,7 +60,7 @@ public IImageStreamImport importImageMetadata(DockerImageURI uri) { LOG.info("Unsuccessful in trying OpenShift server. ImageStreamImport is not supported."); } LOG.debug("Unsuccessful in trying OpenShift server. Trying dockerhub v2 registry..."); - DockerRegistryImageStreamImportCapability reg = new DockerRegistryImageStreamImportCapability(this.project, client.getResourceFactory()); + DockerRegistryImageStreamImportCapability reg = new DockerRegistryImageStreamImportCapability(this.project, client.getResourceFactory(), client); return reg.importImageMetadata(uri); } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java index 72a16956..bf8cd25c 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java @@ -18,7 +18,7 @@ import java.util.concurrent.TimeUnit; import org.apache.commons.io.IOUtils; -import org.eclipse.jetty.util.StringUtil; +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -93,7 +93,7 @@ public void await() throws InterruptedException { if (getProcess().exitValue() != 0) { String errorMessage = getErrorMessage(getProcess().getErrorStream()); throw new OpenShiftException("Syncing %s to %s failed" - + (StringUtil.isBlank(errorMessage) ? "" : ": %s"), + + (StringUtils.isBlank(errorMessage) ? "" : ": %s"), source, destination, errorMessage); } } catch (InterruptedException e) { diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java index 2df39cc3..db3fdcdb 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java @@ -55,7 +55,7 @@ public ITemplate process(ITemplate template) { @Override public Collection apply(ITemplate template) { IList resources = client.getResourceFactory().create(template.getApiVersion(), ResourceKind.LIST); - resources.addAll(template.getItems()); + resources.addAll(template.getObjects()); return client.create(resources, this.namespace); } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/UpdateableCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/UpdateableCapability.java index 3baab3e6..567ed0e6 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/UpdateableCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/UpdateableCapability.java @@ -1,3 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; import com.openshift.internal.restclient.model.KubernetesResource; diff --git a/src/main/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessing.java b/src/main/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessing.java index 4d583965..acab0c3d 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessing.java +++ b/src/main/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessing.java @@ -8,19 +8,10 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.server; -import java.util.Collection; -import java.util.Map; - -import org.apache.commons.lang.StringUtils; -import org.jboss.dmr.ModelNode; - -import com.openshift.internal.restclient.OpenShiftAPIVersion; -import com.openshift.internal.restclient.model.KubernetesResource; +import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.server.ITemplateProcessing; -import com.openshift.restclient.model.IResource; -import com.openshift.restclient.model.template.IParameter; import com.openshift.restclient.model.template.ITemplate; /** @@ -36,7 +27,11 @@ public ServerTemplateProcessing(IClient client){ @Override public boolean isSupported() { - return true; + IApiTypeMapper mapper = client.adapt(IApiTypeMapper.class); + if(mapper != null) { + return mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES); + } + return false; } @Override @@ -44,89 +39,10 @@ public String getName() { return this.getClass().getSimpleName(); } - @SuppressWarnings("unchecked") @Override public ITemplate process(ITemplate template, String namespace) { - return client.create(new TemplateConfigAdapter(template, namespace)); - } - - protected static class TemplateConfigAdapter extends KubernetesResource implements ITemplate { - - private ITemplate template; - private String namespace; - - public TemplateConfigAdapter(ITemplate template, String namespace){ - super(new ModelNode(), null, null); - this.template = template; - this.namespace = namespace; - } - - @Override - public String getName() { - return template.getName(); - } - - @Override - public String getNamespace(){ - return namespace; - } - - @Override - public String getKind() { - return ResourceKind.PROCESSED_TEMPLATES; - } - - @Override - public String toString() { - return template.toString(); - } + return client.execute("POST", ResourceKind.PROCESSED_TEMPLATES, namespace, null, null, template); - @Override - public Collection getItems() { - return template.getItems(); - } - - @Override - public Map getParameters() { - return template.getParameters(); - } - - @Override - public void updateParameterValues(Collection parameters) { - template.updateParameterValues(parameters); - } - - - - @Override - public void updateParameter(String key, String value) { - template.updateParameter(key, value); - } - - @Override - public Map getObjectLabels() { - return template.getObjectLabels(); - } - - @Override - public void addObjectLabel(String key, String value) { - template.addObjectLabel(key, value); - } - - @Override - public boolean isMatching(String text) { - if (StringUtils.isEmpty(text)) { - return true; - } - if (text.equals(getNamespace())) { - return true; - } - if (template == null) { - return false; - } - - return template.isMatching(text); - } - } + } diff --git a/src/main/java/com/openshift/internal/restclient/http/BadRequestException.java b/src/main/java/com/openshift/internal/restclient/http/BadRequestException.java deleted file mode 100644 index baca5ca9..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/BadRequestException.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * @author André Dietisheim - */ -public class BadRequestException extends HttpClientException { - - private static final long serialVersionUID = 1L; - - public BadRequestException(String message, Throwable cause) { - super(message, cause); - } - - public BadRequestException(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/com/openshift/internal/restclient/http/CallbackTrustManager.java b/src/main/java/com/openshift/internal/restclient/http/CallbackTrustManager.java deleted file mode 100644 index 638dcd8f..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/CallbackTrustManager.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.X509TrustManager; - -import com.openshift.internal.util.Assert; - -/** - * A trust manager that calls a callback if the wrapped trustmanager fails to - * validate a given certificate. - * - * @author Andre Dietisheim - * - * @see TrustManagerCallback - */ -public class CallbackTrustManager implements X509TrustManager { - - private X509TrustManager trustManager; - private TrustManagerCallback callback; - - private CallbackTrustManager(X509TrustManager trustManager, TrustManagerCallback callback) { - Assert.isTrue(trustManager != null); - this.trustManager = trustManager; - this.callback = callback; - } - - public X509Certificate[] getAcceptedIssuers() { - return trustManager.getAcceptedIssuers(); - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - try { - trustManager.checkServerTrusted(chain, authType); - } catch (CertificateException e) { - if (callback.allow(chain)) { - throw e; - } - } - } - - public void checkClientTrusted(X509Certificate[] chain, - String authType) throws CertificateException { - trustManager.checkServerTrusted(chain, authType); - } - - public interface TrustManagerCallback { - - public boolean allow(X509Certificate[] chain); - } -} \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/http/EncodingException.java b/src/main/java/com/openshift/internal/restclient/http/EncodingException.java deleted file mode 100644 index bfc4fb32..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/EncodingException.java +++ /dev/null @@ -1,24 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - - -/** - * @author Ioannis Canellos - */ -public class EncodingException extends HttpClientException { - - private static final long serialVersionUID = 1L; - - public EncodingException(String message, Throwable t) { - super(message, t); - } -} diff --git a/src/main/java/com/openshift/internal/restclient/http/FormUrlEncodedMediaType.java b/src/main/java/com/openshift/internal/restclient/http/FormUrlEncodedMediaType.java deleted file mode 100644 index 541e4573..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/FormUrlEncodedMediaType.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.text.MessageFormat; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.openshift.internal.util.URLUtils; -import com.openshift.restclient.http.IHttpConstants; - -/** - * A class that encodes request parameters to formurl-encoded format so that they may get sent to - * the server. There are 4 types that are recognized and correctly encoded: - *
    - *
  • Parameter (key-/value-pair, keys are always strings, values may be - * StringValue, ParameterValueArray, ParameterValueMap))
  • - *
  • StringValue (string value: paramname="value")/li> - *
  • ParameterValueArray (array of values: paramname[]="value"¶mname[]="value")
  • - *
  • ParameterValueMap (map of values: paramname[key]="value"¶mname[key]="value)"
  • - *
- * - * @author Andre Dietisheim - * - * @see IHttpClient#post(java.net.URL, IMediaType, int, - * com.openshift.internal.restclient.http.client.httpclient.request.Parameter...) - * @see IHttpClient#put(java.net.URL, IMediaType, int, - * com.openshift.internal.restclient.http.client.httpclient.request.Parameter...) - * @see IHttpClient#delete(java.net.URL, IMediaType, int, - * com.openshift.internal.restclient.http.client.httpclient.request.Parameter...) - */ -public class FormUrlEncodedMediaType implements IMediaType { - - private static final Logger LOGGER = LoggerFactory.getLogger(FormUrlEncodedMediaType.class); - - private static final String UTF8 = "UTF-8"; - private boolean firstParameter = true; - - @Override - public String getType() { - return IHttpConstants.MEDIATYPE_APPLICATION_FORMURLENCODED; - } - - public void writeTo(ParameterValueMap parameterMap, OutputStream out) throws EncodingException { - // reset for eventual 2nd write - try { - this.firstParameter = true; - for (Parameter parameter : parameterMap.getValue().values()) { - writeTo(parameter.getName(), parameter.getValue(), out); - } - } catch (IOException e) { - throw new EncodingException( - MessageFormat.format("Could not encode parameters {0}", parameterMap.toString()), e); - } - } - - private void writeTo(String name, ParameterValueMap parameterMap, OutputStream out) throws IOException { - for (Parameter parameter : parameterMap.getValue().values()) { - String childName = new StringBuilder() - .append(name) - .append('[').append(parameter.getName()).append(']') - .toString(); - writeTo(childName, parameter.getValue(), out); - } - } - - private void writeTo(String name, ParameterValue value, OutputStream out) throws IOException { - if (StringValue.class.isAssignableFrom(value.getClass())) { - writeTo(name, (StringValue) value, out); - } else if (ParameterValueArray.class.isAssignableFrom(value.getClass())) { - writeTo(name, (ParameterValueArray) value, out); - } else if (ParameterValueMap.class.isAssignableFrom(value.getClass())) { - writeTo(name, (ParameterValueMap) value, out); - } - } - - private void writeTo(String name, ParameterValueArray array, OutputStream out) throws IOException { - String childName = name + "[]"; - for (ParameterValue value : array.getValue()) { - writeTo(childName, value, out); - } - } - - private void writeTo(String name, StringValue stringValue, OutputStream out) throws IOException { - StringBuilder builder = new StringBuilder(); - if (!firstParameter) { - builder.append(IHttpConstants.AMPERSAND); - } else { - firstParameter = false; - } - String value = encode(stringValue.getValue()); - String parameterString = builder - .append(name) - .append(IHttpConstants.EQUALS).append(value) - .toString(); - out.write(parameterString.getBytes()); - LOGGER.trace(out.toString()); - } - - private String encode(String value) throws UnsupportedEncodingException { - if (URLUtils.isUrl(value)) { - // dont encode url payload - return value; - } - return URLEncoder.encode(value, UTF8); - } -} diff --git a/src/main/java/com/openshift/internal/restclient/http/HttpClientException.java b/src/main/java/com/openshift/internal/restclient/http/HttpClientException.java deleted file mode 100644 index b7064b66..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/HttpClientException.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * @author André Dietisheim - */ -public class HttpClientException extends RuntimeException { - - private static final long serialVersionUID = 1L; - private int code = -1; - - public HttpClientException(String message, Throwable cause) { - super(message, cause); - } - - public HttpClientException(String message, Throwable cause, int code) { - super(message, cause); - this.code = code; - } - - public HttpClientException(String message) { - super(message); - } - - public HttpClientException(Throwable cause) { - super(cause); - } - - public int getResponseCode() { - return code; - } - -} diff --git a/src/main/java/com/openshift/internal/restclient/http/HttpMethod.java b/src/main/java/com/openshift/internal/restclient/http/HttpMethod.java deleted file mode 100644 index 686a8774..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/HttpMethod.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * @author Andre Dietisheim - */ -public enum HttpMethod { - GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS; - - /** - * hasValue determines if enum can safely convert string to enum value - * - * @param value the value to inspect - * @return true if the value can be safely converted to the enum; false otherwise - */ - public static boolean hasValue(String value) { - HttpMethod[] enumConstants = HttpMethod.class.getEnumConstants(); - for (int i = 0; i < enumConstants.length; i++) { - HttpMethod httpMethod = enumConstants[i]; - if(httpMethod.name().equalsIgnoreCase(value)){ - return true; - } - } - return false; - } -} diff --git a/src/main/java/com/openshift/internal/restclient/http/IMediaType.java b/src/main/java/com/openshift/internal/restclient/http/IMediaType.java deleted file mode 100644 index 04436d42..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/IMediaType.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import java.io.OutputStream; - -/** - * - * A media type that encodes and writes request parameters before they get sent by the client. - * - * @author Andre Dietisheim - * - * @see IHttpClient#post(java.net.URL, IMediaType, int, com.openshift.internal.restclient.client.httpclient.request.Parameter...) - * @see IHttpClient#put(java.net.URL, IMediaType, int, com.openshift.internal.restclient.client.httpclient.request.Parameter...) - * @see IHttpClient#delete(java.net.URL, IMediaType, int, com.openshift.internal.restclient.client.httpclient.request.Parameter...) - */ -public interface IMediaType { - - public String getType(); - - public void writeTo(ParameterValueMap parameterMap, OutputStream out) throws EncodingException; - -} diff --git a/src/main/java/com/openshift/internal/restclient/http/InternalServerErrorException.java b/src/main/java/com/openshift/internal/restclient/http/InternalServerErrorException.java deleted file mode 100644 index d17b6e78..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/InternalServerErrorException.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * @author André Dietisheim - */ -public class InternalServerErrorException extends HttpClientException { - - private static final long serialVersionUID = 1L; - - public InternalServerErrorException(String message, Throwable cause) { - super(message, cause); - } - - public InternalServerErrorException(String message) { - super(message); - } -} diff --git a/src/main/java/com/openshift/internal/restclient/http/JsonMediaType.java b/src/main/java/com/openshift/internal/restclient/http/JsonMediaType.java deleted file mode 100644 index e192182e..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/JsonMediaType.java +++ /dev/null @@ -1,100 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import java.io.OutputStream; -import java.io.PrintWriter; - -import org.jboss.dmr.ModelNode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.openshift.restclient.http.IHttpConstants; - -/** - * A class that encodes request parameters to json so that they may get sent to - * the server. There are 4 types that are recognized and correctly encoded: - *
    - *
  • Parameter (key-/value-pair, keys are always strings, values may be - * StringValue, ParameterValueArray, ParameterValueMap))
  • - *
  • StringValue (string value, in json: string)/li> - *
  • ParameterValueArray (array of values, in json: array
  • - *
  • ParameterValueMap (map of values, in json: object
  • - *
- * - * @author Andre Dietisheim - * - * @see IHttpClient#post(java.net.URL, IMediaType, int, com.openshift.internal.restclient.http.client.httpclient.request.Parameter...) - * @see IHttpClient#put(java.net.URL, IMediaType, int, com.openshift.internal.restclient.http.client.httpclient.request.Parameter...) - * @see IHttpClient#delete(java.net.URL, IMediaType, int, com.openshift.internal.restclient.http.client.httpclient.request.Parameter...) - */ -public class JsonMediaType implements IMediaType { - - private static final Logger LOGGER = LoggerFactory.getLogger(JsonMediaType.class); - - @Override - public String getType() { - return IHttpConstants.MEDIATYPE_APPLICATION_JSON; - } - - public void writeTo(ParameterValueMap parameterMap, OutputStream out) throws EncodingException { - ModelNode root = new ModelNode(); - for (Parameter parameter : parameterMap.getValue().values()) { - ModelNode property = root.get(parameter.getName()); - create(parameter.getValue(), property); - } - - writeTo(out, root); - log(root); - } - - private void create(ParameterValueMap parameterMap, ModelNode node) { - for (Parameter parameter : parameterMap.getValue().values()) { - ModelNode property = node.get(parameter.getName()); - create(parameter.getValue(), property); - } - } - - private void create(ParameterValue value, ModelNode node) { - if (StringValue.class.isAssignableFrom(value.getClass())) { - create((StringValue) value, node); - } else if (ParameterValueArray.class.isAssignableFrom(value.getClass())) { - create((ParameterValueArray) value, node); - } else if (ParameterValueMap.class.isAssignableFrom(value.getClass())) { - create((ParameterValueMap) value, node); - } - } - - private void create(ParameterValueArray array, ModelNode node) { - for (ParameterValue value : array.getValue()) { - ModelNode member = new ModelNode(); - create(value, member); - node.add(member); - } - } - - private void create(StringValue stringValue, ModelNode node) { - node.set(stringValue.getValue()); - } - - private void writeTo(OutputStream out, ModelNode node) { - PrintWriter writer = new PrintWriter(out); - node.writeJSONString(writer, true); - writer.flush(); - } - - private void log(ModelNode node) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(node.toJSONString(true)); - } - } - -} diff --git a/src/main/java/com/openshift/internal/restclient/http/NotFoundException.java b/src/main/java/com/openshift/internal/restclient/http/NotFoundException.java deleted file mode 100644 index 89b8c4c3..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/NotFoundException.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * @author André Dietisheim - */ -public class NotFoundException extends HttpClientException { - - private static final long serialVersionUID = 1L; - - public NotFoundException(String message, Throwable cause) { - super(message, cause); - } - - public NotFoundException(String message) { - super(message); - } -} diff --git a/src/main/java/com/openshift/internal/restclient/http/Parameter.java b/src/main/java/com/openshift/internal/restclient/http/Parameter.java deleted file mode 100644 index a23e2c92..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/Parameter.java +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * A parameter wrapper to pass param key/values to the service when executing a - * remote operation from a link. - * - * @author Andre Dietisheim - * - */ -public class Parameter extends ParameterValue> { - - private final String name; - - public Parameter(final String name, final String value) { - this(name, new StringValue(value)); - } - - public Parameter(final String name, final ParameterValue value) { - super(value); - this.name = name; - } - - public String getName() { - return name; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((getValue() == null) ? 0 : getValue().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Parameter other = (Parameter) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (getValue() == null) { - if (other.getValue() != null) - return false; - } else if (!getValue().equals(other.getValue())) - return false; - return true; - } - - @Override - public String toString() { - return "Parameter [" - + "name=" + name - + ", value=" + String.valueOf(getValue()) - + "]"; - } -} diff --git a/src/main/java/com/openshift/internal/restclient/http/ParameterValue.java b/src/main/java/com/openshift/internal/restclient/http/ParameterValue.java deleted file mode 100644 index 380afeec..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/ParameterValue.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ - -package com.openshift.internal.restclient.http; - -/** - * @author Andre Dietisheim - */ -public abstract class ParameterValue { - - private V value; - - public ParameterValue(V value) { - this.value = value; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - @SuppressWarnings("rawtypes") - ParameterValue other = (ParameterValue) obj; - if (value == null) { - if (other.value != null) - return false; - } else if (!value.equals(other.value)) - return false; - return true; - } - - public V getValue() { - return value; - } - - @Override - public String toString() { - return "ParameterValue [value=" + value + "]"; - } -} - diff --git a/src/main/java/com/openshift/internal/restclient/http/ParameterValueArray.java b/src/main/java/com/openshift/internal/restclient/http/ParameterValueArray.java deleted file mode 100644 index 9c5a4947..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/ParameterValueArray.java +++ /dev/null @@ -1,50 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -/** - * @author Andre Dietisheim - */ -public class ParameterValueArray extends ParameterValue>> { - - public ParameterValueArray() { - this(new ArrayList>()); - } - - public ParameterValueArray(List> values) { - super(values); - } - - public ParameterValueArray add(String name, String value) { - return add(new StringParameter(name, value)); - } - - public ParameterValueArray add(ParameterValue value) { - getValue().add(value); - return this; - } - - public ParameterValueArray addAll(List> values) { - getValue().addAll(values); - return this; - } - - @Override - public String toString() { - return "ParameterValueArray [" - + "values=" + Arrays.toString(getValue().toArray()) + "]"; - } - -} diff --git a/src/main/java/com/openshift/internal/restclient/http/ParameterValueMap.java b/src/main/java/com/openshift/internal/restclient/http/ParameterValueMap.java deleted file mode 100644 index 036b3eef..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/ParameterValueMap.java +++ /dev/null @@ -1,95 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.openshift.restclient.OpenShiftException; - - -/** - * @author Andre Dietisheim - */ -public class ParameterValueMap extends ParameterValue> { - - public ParameterValueMap(List parameters) { - this(); - addAll(parameters); - } - - public ParameterValueMap(Parameter... parameters) { - this(); - addAll(Arrays.asList(parameters)); - } - - public ParameterValueMap() { - super(new LinkedHashMap()); - } - - public ParameterValueMap addAll(List parameters) { - for (Parameter parameter : parameters) { - add(parameter); - } - return this; - } - - public ParameterValueMap add(String name, String value) { - add(new StringParameter(name, value)); - return this; - } - - public ParameterValueMap add(Parameter parameter) { - if (getValue().put(parameter.getName(), parameter) != null) { - throw new OpenShiftException( - "Duplicate parameter found. There's already a parameter named {0}", parameter.getName()); - } - return this; - } - - public Parameter getParamater(String name) { - return getValue().get(name); - } - - public boolean isEmpty() { - Map values = getValue(); - return values == null - || values.isEmpty(); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - @SuppressWarnings("rawtypes") - ParameterValue other = (ParameterValue) obj; - if (getValue() == null) { - if (other.getValue() != null) - return false; - } else if (!getValue().equals(other.getValue())) - return false; - return true; - } - - @Override - public String toString() { - return "ParameterValueMap [" - + "values=" + getValue() + "]"; - } - - -} diff --git a/src/main/java/com/openshift/internal/restclient/http/StringParameter.java b/src/main/java/com/openshift/internal/restclient/http/StringParameter.java deleted file mode 100644 index e0fa6361..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/StringParameter.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * @author Andre Dietisheim - */ -public class StringParameter extends Parameter { - - public StringParameter(final String name, final String value) { - super(name, new StringValue(value)); - } - - @Override - public String toString() { - return "StringParameter [" - + "name=" + getName() - + ", value=" + getValue() - + "]"; - } - - -} diff --git a/src/main/java/com/openshift/internal/restclient/http/StringValue.java b/src/main/java/com/openshift/internal/restclient/http/StringValue.java deleted file mode 100644 index 7cc6bc7b..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/StringValue.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * @author Andre Dietisheim - */ -public class StringValue extends ParameterValue { - - public StringValue(String value) { - super(value); - } - - @Override - public String toString() { - return "StringValue [" - + "value=" + getValue() - + "]"; - } -} - diff --git a/src/main/java/com/openshift/internal/restclient/http/UnauthorizedException.java b/src/main/java/com/openshift/internal/restclient/http/UnauthorizedException.java deleted file mode 100644 index 43d9e09c..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/UnauthorizedException.java +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -/** - * @author André Dietisheim - */ -public class UnauthorizedException extends HttpClientException { - - private static final long serialVersionUID = 1L; - - public UnauthorizedException(String message, Throwable cause) { - super(message, cause); - } - - public UnauthorizedException(Throwable cause) { - super(cause); - } - -} diff --git a/src/main/java/com/openshift/internal/restclient/http/UrlConnectionHttpClient.java b/src/main/java/com/openshift/internal/restclient/http/UrlConnectionHttpClient.java deleted file mode 100755 index b3dee93b..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/UrlConnectionHttpClient.java +++ /dev/null @@ -1,601 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013-2014 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import java.io.IOException; -import java.io.PrintWriter; -import java.net.HttpURLConnection; -import java.net.InetAddress; -import java.net.ProtocolException; -import java.net.Socket; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.net.URLConnection; -import java.net.UnknownHostException; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.text.MessageFormat; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.openshift.restclient.ISSLCertificateCallback; -import com.openshift.restclient.authorization.IAuthorizationStrategy; -import com.openshift.restclient.authorization.URLConnectionRequest; -import com.openshift.restclient.http.IHttpClient; -import com.openshift.restclient.http.IHttpConstants; -import com.openshift.restclient.model.IResource; -import com.openshift.restclient.utils.SSLUtils; - -/** - * @author Andre Dietisheim - * @author Nicolas Spano - * @author Corey Daley - * @author Sean Kavanagh - */ -public class UrlConnectionHttpClient implements IHttpClient { - - private static final Logger LOGGER = LoggerFactory.getLogger(UrlConnectionHttpClient.class); - - protected String userAgent; - protected String acceptedMediaType; - protected String acceptedVersion; - protected ISSLCertificateCallback sslAuthorizationCallback; - protected Integer configTimeout; - private String excludedSSLCipherRegex; - private IAuthorizationStrategy authStrategy; - - private TrustManagerFactory trustManagerFactory; - private NoSuchAlgorithmException trustManagerFactoryException; - - public UrlConnectionHttpClient(String userAgent, String acceptedMediaType, String version){ - this(userAgent, acceptedMediaType, version, null, null, null); - } - - public UrlConnectionHttpClient(String userAgent, String acceptedMediaType, - String version, ISSLCertificateCallback callback, Integer configTimeout, String excludedSSLCipherRegex) { - this(userAgent, acceptedMediaType, version, callback, configTimeout, excludedSSLCipherRegex, null, null); - } - - public UrlConnectionHttpClient(String userAgent, String acceptedMediaType, - String version, ISSLCertificateCallback callback, Integer configTimeout, String excludedSSLCipherRegex, - String alias, X509Certificate cert) { - this.userAgent = userAgent; - this.acceptedMediaType = acceptedMediaType; - this.acceptedVersion = version; - this.sslAuthorizationCallback = callback; - this.configTimeout = configTimeout; - this.excludedSSLCipherRegex = excludedSSLCipherRegex; - this.initTrustManagerFactory(alias, cert); - } - - private void initTrustManagerFactory(String alias, X509Certificate cert) { - try { - trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - if (alias != null && cert != null) { - KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - // need this load to initialize the key store, and allow for the subsequent set certificate entry - ks.load(null, null); - cert.checkValidity(); - ks.setCertificateEntry(alias, cert); - // testing has proven that you can only call init() once for a TrustManagerFactory wrt loading certs - // from the KeyStore ... subsequent KeyStore.setCertificateEntry / TrustManagerFactory.init calls are - // ignored. - // So if a specific cert is required to validate this connection's communication with the server, add it up front - // in the ctor. - trustManagerFactory.init(ks); - } else { - trustManagerFactory.init((KeyStore)null); - } - - } catch (NoSuchAlgorithmException e) { - LOGGER.warn("Could not get trust manager factory.", e); - trustManagerFactoryException = e; - } catch (KeyStoreException e) { - LOGGER.warn("Count not get key store.", e); - } catch (CertificateException e) { - LOGGER.warn("An invalid certificate was provided to this connection.", e); - } catch (IOException e) { - LOGGER.warn("An IO exception occurred while setting up a cert with the trust store.", e); - } - } - - // not part of IHttpClient currently, only put in place for test verification - public X509Certificate[] getTrustedCertificates() throws KeyStoreException, NoSuchAlgorithmException { - return getCurrentTrustManager().getAcceptedIssuers(); - } - - @Override - public void setSSLCertificateCallback(ISSLCertificateCallback callback) { - this.sslAuthorizationCallback = callback; - } - - @Override - public ISSLCertificateCallback getSSLCertificateCallback() { - return sslAuthorizationCallback; - } - - @Override - public void setAuthorizationStrategy(IAuthorizationStrategy strategy) { - this.authStrategy = strategy; - } - - @Override - public String get(URL url, int timeout) throws HttpClientException, SocketTimeoutException { - return request(HttpMethod.GET, url, null, timeout); - } - - @Override - public String head(URL url, int timeout) throws HttpClientException, SocketTimeoutException { - return request(HttpMethod.HEAD, url, null, timeout); - } - - public String put(URL url, IMediaType mediaType, int timeout, Parameter... parameters) - throws HttpClientException, SocketTimeoutException, EncodingException { - return request(HttpMethod.PUT, url, mediaType, timeout, parameters); - } - - @Override - public String put(URL url, int timeout, IResource resource) - throws HttpClientException, SocketTimeoutException, EncodingException { - return request(HttpMethod.PUT, url, timeout, resource); - } - - @Override - public String post(URL url, int timeout, IResource resource) throws HttpClientException, SocketTimeoutException, EncodingException { - return request(HttpMethod.POST, url, timeout, resource); - } - - public String delete(URL url, IMediaType mediaType, int timeout, Parameter... parameters) - throws HttpClientException, SocketTimeoutException, EncodingException { - return request(HttpMethod.DELETE, url, mediaType, timeout, parameters); - } - - @Override - public String delete(URL url, int timeout) - throws HttpClientException, SocketTimeoutException, EncodingException { - return delete(url, null, timeout); - } - - protected String request(HttpMethod httpMethod, URL url, IMediaType requestMediaType, int timeout, - Parameter... parameters) - throws SocketTimeoutException, HttpClientException { - return request(httpMethod, url, requestMediaType, timeout, new ParameterValueMap(parameters)); - } - - protected String request(HttpMethod httpMethod, URL url, IMediaType requestMediaType, int timeout, - ParameterValueMap parameters) - throws SocketTimeoutException, HttpClientException { - HttpURLConnection connection = null; - try { - connection = createConnection( - url, userAgent, acceptedVersion, acceptedMediaType, sslAuthorizationCallback, timeout); - if (httpMethod == HttpMethod.POST || httpMethod == HttpMethod.PUT) { - setContentTypeHeader(acceptedVersion, acceptedMediaType, connection); - } - // PATCH not yet supported by JVM - setRequestMethod(httpMethod, connection); - if (!parameters.isEmpty()) { - connection.setDoOutput(true); - setRequestMediaType(requestMediaType, connection); - requestMediaType.writeTo(parameters, connection.getOutputStream()); - } - return IOUtils.toString(connection.getInputStream(), "UTF-8"); - } catch (SocketTimeoutException e) { - throw e; - } catch (IOException e) { - throw createException(e, connection); - } finally { - disconnect(connection); - } - } - - protected String request(HttpMethod httpMethod, URL url, int timeout, IResource resource) - throws SocketTimeoutException, HttpClientException { - HttpURLConnection connection = null; - try { - connection = createConnection( - url, userAgent, acceptedVersion, acceptedMediaType, sslAuthorizationCallback, timeout); - if (httpMethod == HttpMethod.POST || httpMethod == HttpMethod.PUT) { - setContentTypeHeader(acceptedVersion, acceptedMediaType, connection); - } - // PATCH not yet supported by JVM - setRequestMethod(httpMethod, connection); - if(LOGGER.isDebugEnabled()) { - LOGGER.debug(String.format("Request Properties: %s", connection.getRequestProperties())); - LOGGER.debug(String.format("Request Method: %s", connection.getRequestMethod())); - } - if(resource != null){ - if(LOGGER.isDebugEnabled()) LOGGER.debug(resource.toJson(false)); - connection.setDoOutput(true); - PrintWriter writer = new PrintWriter(connection.getOutputStream()); - writer.write(resource.toString()); - writer.flush(); - } - return IOUtils.toString(connection.getInputStream(), "UTF-8"); - } catch (SocketTimeoutException e) { - throw e; - } catch (IOException e) { - throw createException(e, connection); - } finally { - disconnect(connection); - } - } - - private void setRequestMethod(HttpMethod httpMethod, HttpURLConnection connection) throws ProtocolException { - if (httpMethod == HttpMethod.PATCH) { - httpMethod = HttpMethod.POST; - connection.setRequestProperty("X-Http-Method-Override", "PATCH"); - } - connection.setRequestMethod(httpMethod.toString()); - } - - private void disconnect(HttpURLConnection connection) { - if (connection != null) { - connection.disconnect(); - } - } - - private HttpClientException createException(IOException ioe, HttpURLConnection connection) - throws SocketTimeoutException { - try { - int responseCode = connection.getResponseCode(); - String errorMessage = createErrorMessage(ioe, connection); - switch (responseCode) { - case IHttpConstants.STATUS_INTERNAL_SERVER_ERROR: - return new InternalServerErrorException(errorMessage, ioe); - case IHttpConstants.STATUS_BAD_REQUEST: - return new BadRequestException(errorMessage, ioe); - case IHttpConstants.STATUS_UNAUTHORIZED: - return new UnauthorizedException(errorMessage, ioe); - case IHttpConstants.STATUS_NOT_FOUND: - return new NotFoundException(errorMessage, ioe); - default: - return new HttpClientException(errorMessage, ioe, responseCode); - } - } catch (SocketTimeoutException e) { - throw e; - } catch (IOException e) { - return new HttpClientException(e); - } - } - - protected String createErrorMessage(IOException ioe, HttpURLConnection connection) throws IOException { - String errorMessage = IOUtils.toString(connection.getErrorStream()); - if (!StringUtils.isEmpty(errorMessage)) { - return errorMessage; - } - StringBuilder builder = new StringBuilder("Connection to ") - .append(connection.getURL()); - String reason = connection.getResponseMessage(); - if (!StringUtils.isEmpty(reason)) { - builder.append(": ").append(reason); - } - return builder.toString(); - } - - private boolean isHttps(URL url) { - return "https".equals(url.getProtocol()); - } - - protected HttpURLConnection createConnection(URL url, String userAgent, String acceptedVersion, String acceptedMediaType, - ISSLCertificateCallback callback, int timeout) - throws IOException { - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - if (isHttps(url)) { - HttpsURLConnection httpsConnection = (HttpsURLConnection) connection; - SSLContext sslContext = setSSLCallback(sslAuthorizationCallback, url, httpsConnection); - setFilteredCiphers(excludedSSLCipherRegex, sslContext, httpsConnection); - } - setAuthorization(connection); - connection.setUseCaches(false); - connection.setDoInput(true); - connection.setAllowUserInteraction(false); - setConnectTimeout(NO_TIMEOUT, connection); - setReadTimeout(timeout, connection); - // wont work when switching http->https - // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4620571 - connection.setInstanceFollowRedirects(true); - setUserAgent(userAgent, connection); - setAcceptHeader(acceptedVersion, acceptedMediaType, connection); - - return connection; - } - - private void setUserAgent(String userAgent, HttpURLConnection connection) { - if (!StringUtils.isEmpty(userAgent)) { - connection.setRequestProperty(IHttpConstants.PROPERTY_USER_AGENT, userAgent); - } - } - - private void setAcceptHeader(String acceptedVersion, String acceptedMediaType, HttpURLConnection connection) { - if (StringUtils.isEmpty(acceptedMediaType)) { - throw new HttpClientException(MessageFormat.format( - "Accepted media type (ex. {0}) is not defined", IHttpConstants.MEDIATYPE_APPLICATION_JSON)); - } - - StringBuilder builder = new StringBuilder(acceptedMediaType); - if (acceptedVersion != null) { - builder.append(IHttpConstants.SEMICOLON).append(IHttpConstants.SPACE) - .append(IHttpConstants.VERSION).append(IHttpConstants.EQUALS).append(acceptedVersion); - } - - connection.setRequestProperty(IHttpConstants.PROPERTY_ACCEPT, builder.toString()); - } - - private void setContentTypeHeader(String version, String mediaType, HttpURLConnection connection) { - if (StringUtils.isEmpty(mediaType)) { - throw new HttpClientException(MessageFormat.format( - "Accepted media type (ex. {0}) is not defined", IHttpConstants.MEDIATYPE_APPLICATION_JSON)); - } - - StringBuilder builder = new StringBuilder(mediaType); - if (acceptedVersion != null) { - builder.append(IHttpConstants.SEMICOLON).append(IHttpConstants.SPACE) - .append(IHttpConstants.VERSION).append(IHttpConstants.EQUALS).append(version); - } - - connection.setRequestProperty(IHttpConstants.PROPERTY_CONTENT_TYPE, builder.toString()); - } - - protected final void setAuthorization(HttpURLConnection connection) { - if(authStrategy != null){ - authStrategy.authorize(new URLConnectionRequest(connection)); - return; - } - } - - private SSLContext setSSLCallback(ISSLCertificateCallback sslAuthorizationCallback, URL url, HttpsURLConnection connection) { - X509TrustManager trustManager = null; - if (sslAuthorizationCallback != null) { - connection.setHostnameVerifier(new CallbackHostnameVerifier()); - trustManager = createCallbackTrustManager(sslAuthorizationCallback, connection); - } - - try { - SSLContext sslContext = SSLUtils.getSSLContext(trustManager); - connection.setSSLSocketFactory(sslContext.getSocketFactory()); - return sslContext; - } catch (GeneralSecurityException e) { - LOGGER.warn("Could not install trust manager callback", e);; - return null; - } - } - - /** - * Returns the callback trustmanager or null if it could not be created. - * - * @see ISSLCertificateCallback - */ - private X509TrustManager createCallbackTrustManager(ISSLCertificateCallback sslAuthorizationCallback,HttpsURLConnection connection) { - X509TrustManager trustManager = null; - try { - trustManager = getCurrentTrustManager(); - if (trustManager == null) { - LOGGER.warn("Could not install trust manager callback, no trustmanager was found.", trustManager); - } else { - trustManager = new CallbackTrustManager(trustManager, sslAuthorizationCallback); - } - } catch (GeneralSecurityException e) { - LOGGER.warn("Could not install trust manager callback.", e);; - } - return trustManager; - } - - /** - * Sets a ssl socket factory that sets a filtered list of ciphers based on - * the #excludedSSLCipherRegex to the given connection. - * - * @param sslContext - * - * @param sslContext - * the ssl context that shall be used - * @param url - * the url we are connecting to - * @param connection - * the connection that the cipher filter shall be applied to - */ - protected SSLContext setFilteredCiphers(String excludedSSLCipherRegex, SSLContext sslContext, HttpsURLConnection connection) { - if (excludedSSLCipherRegex != null) { - connection.setSSLSocketFactory( - new EnabledCiphersSSLSocketFactory( - SSLUtils.filterCiphers( - excludedSSLCipherRegex, getSupportedCiphers(sslContext)), sslContext - .getSocketFactory())); - } - return sslContext; - } - - protected String[] getSupportedCiphers(SSLContext sslContext) { - return sslContext.getSupportedSSLParameters().getCipherSuites(); - } - - private void setConnectTimeout(int timeout, URLConnection connection) { - if (getTimeout(timeout) != NO_TIMEOUT) { - connection.setConnectTimeout(getTimeout(timeout)); - } - } - - private void setReadTimeout(int timeout, URLConnection connection) { - if (getTimeout(timeout) != NO_TIMEOUT) { - connection.setReadTimeout(getTimeout(timeout)); - } - } - - private int getTimeout(int timeout) { - if (timeout == NO_TIMEOUT) { - if (configTimeout != null) { - timeout = this.configTimeout; - } - } - return timeout; - } - - private void setRequestMediaType(IMediaType mediaType, HttpURLConnection connection) { - if (mediaType == null - || StringUtils.isEmpty(mediaType.getType())) { - throw new HttpClientException( - MessageFormat.format("Request media type (ex. {0}) is not defined", - IHttpConstants.MEDIATYPE_APPLICATION_FORMURLENCODED)); - } - connection.setRequestProperty(IHttpConstants.PROPERTY_CONTENT_TYPE, mediaType.getType()); - } - - private X509TrustManager getCurrentTrustManager() throws NoSuchAlgorithmException, KeyStoreException { - if (trustManagerFactoryException != null) - throw trustManagerFactoryException; - - X509TrustManager x509TrustManager = null; - for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { - if (trustManager instanceof X509TrustManager) { - x509TrustManager = (X509TrustManager) trustManager; - break; - } - } - return x509TrustManager; - - } - - @Override - public void setUserAgent(String userAgent) { - this.userAgent = userAgent; - } - - @Override - public void setAcceptVersion(String version) { - this.acceptedVersion = version; - } - - @Override - public void setAcceptedMediaType(String acceptedMediaType) { - this.acceptedMediaType = acceptedMediaType; - } - - public class CallbackTrustManager implements X509TrustManager { - - private X509TrustManager trustManager; - private ISSLCertificateCallback callback; - - private CallbackTrustManager(X509TrustManager currentTrustManager, ISSLCertificateCallback callback) - throws NoSuchAlgorithmException, KeyStoreException { - this.trustManager = currentTrustManager; - this.callback = callback; - } - - public X509Certificate[] getAcceptedIssuers() { - return trustManager.getAcceptedIssuers(); - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - try { - trustManager.checkServerTrusted(chain, authType); - } catch (CertificateException e) { - if (!callback.allowCertificate(chain)) { - throw e; - } - } - } - - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - trustManager.checkServerTrusted(chain, authType); - } - } - - private class CallbackHostnameVerifier implements HostnameVerifier { - - @Override - public boolean verify(String hostname, SSLSession session) { - return sslAuthorizationCallback.allowHostname(hostname, session); - } - } - - /** - * SSL socket factory that wraps a given socket factory and sets given ciphers - * to the socket that the wrapped factory creates. - * - * @see http://stackoverflow.com/questions/6851461/java-why-does-ssl-handshake-give-could-not-generate-dh-keypair-exception/16686994#16686994 - */ - private static class EnabledCiphersSSLSocketFactory extends SSLSocketFactory { - - private String[] enabledCiphers; - private SSLSocketFactory socketFactory; - - EnabledCiphersSSLSocketFactory(String[] enabledCiphers, SSLSocketFactory socketFactory) { - this.enabledCiphers = enabledCiphers; - this.socketFactory = socketFactory; - } - - @Override - public Socket createSocket(InetAddress host, int port, InetAddress localHost, int localPort) throws IOException { - return setEnabledCiphers((SSLSocket) socketFactory.createSocket(host, port, localHost, localPort)); - } - - @Override - public Socket createSocket(String host, int port, InetAddress localHost, int localPort) - throws IOException, UnknownHostException { - return setEnabledCiphers((SSLSocket) socketFactory.createSocket(host, port, localHost, localPort)); - } - - @Override - public Socket createSocket(InetAddress host, int port) throws IOException { - return setEnabledCiphers((SSLSocket) socketFactory.createSocket(host, port)); - } - - @Override - public Socket createSocket(String host, int port) throws IOException, UnknownHostException { - return setEnabledCiphers((SSLSocket) socketFactory.createSocket(host, port)); - } - - @Override - public String[] getSupportedCipherSuites() { - if (enabledCiphers == null) { - return socketFactory.getSupportedCipherSuites(); - } else { - return enabledCiphers; - } - } - - @Override - public String[] getDefaultCipherSuites() { - return socketFactory.getDefaultCipherSuites(); - } - - @Override - public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { - return setEnabledCiphers((SSLSocket) socketFactory.createSocket(socket, host, port, autoClose)); - } - - private SSLSocket setEnabledCiphers(SSLSocket socket) { - if (enabledCiphers == null) { - return socket; - } - socket.setEnabledCipherSuites(enabledCiphers); - return socket; - } - } - -} diff --git a/src/main/java/com/openshift/internal/restclient/http/UrlConnectionHttpClientBuilder.java b/src/main/java/com/openshift/internal/restclient/http/UrlConnectionHttpClientBuilder.java deleted file mode 100755 index 24aeca31..00000000 --- a/src/main/java/com/openshift/internal/restclient/http/UrlConnectionHttpClientBuilder.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2014 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import java.security.cert.X509Certificate; - -import com.openshift.restclient.ISSLCertificateCallback; -import com.openshift.restclient.authorization.BasicAuthorizationStrategy; -import com.openshift.restclient.authorization.IAuthorizationStrategy; -import com.openshift.restclient.http.IHttpClient; - -/** - * @author André Dietisheim - * @author Corey Daley - * @author Sean Kavanagh - */ -public class UrlConnectionHttpClientBuilder { - - private String userAgent; - private String acceptedMediaType; - private String version; - private Integer configTimeout; - private ISSLCertificateCallback callback; - private String certificateAlias; - private X509Certificate certificate; - private String excludeSSLCipherRegex; - private IAuthorizationStrategy authStrategy; - - public UrlConnectionHttpClientBuilder setUserAgent(String userAgent) { - this.userAgent = userAgent; - return this; - } - - public UrlConnectionHttpClientBuilder setAuthorizationStrategy(IAuthorizationStrategy strategy){ - this.authStrategy = strategy; - return this; - } - - public UrlConnectionHttpClientBuilder setCredentials(String username, String password, String token) { - return setAuthorizationStrategy(new BasicAuthorizationStrategy(username, password, token)); - } - - public UrlConnectionHttpClientBuilder setCertificate(String alias, X509Certificate cert) { - this.certificateAlias = alias; - this.certificate = cert; - return this; - } - - public UrlConnectionHttpClientBuilder setConfigTimeout (Integer configTimeout) { - this.configTimeout = configTimeout; - return this; - } - - public UrlConnectionHttpClientBuilder setAcceptMediaType(String mediaType) { - this.acceptedMediaType = mediaType; - return this; - } - - public UrlConnectionHttpClientBuilder setSSLCertificateCallback(ISSLCertificateCallback callback) { - this.callback = callback; - return this; - } - - public UrlConnectionHttpClientBuilder setVersion(String version) { - this.version = version; - return this; - } - - public UrlConnectionHttpClientBuilder excludeSSLCipher(String excludeSSLCipherRegex) { - this.excludeSSLCipherRegex = excludeSSLCipherRegex; - return this; - } - - public IHttpClient client() { - UrlConnectionHttpClient urlClient = new UrlConnectionHttpClient( - userAgent, acceptedMediaType, version, callback, configTimeout, excludeSSLCipherRegex, certificateAlias, certificate); - urlClient.setAuthorizationStrategy(authStrategy); - return urlClient; - } -} diff --git a/src/main/java/com/openshift/internal/restclient/model/Config.java b/src/main/java/com/openshift/internal/restclient/model/Config.java deleted file mode 100644 index 17f30025..00000000 --- a/src/main/java/com/openshift/internal/restclient/model/Config.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.internal.restclient.model; - -import java.util.Map; - -import org.jboss.dmr.ModelNode; - -import com.openshift.restclient.IClient; -import com.openshift.restclient.model.IConfig; - -/** - * @author Jeff Cantrill - */ -@Deprecated -public class Config extends List implements IConfig{ - - public Config(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } -} diff --git a/src/main/java/com/openshift/internal/restclient/model/List.java b/src/main/java/com/openshift/internal/restclient/model/List.java index 4c050961..421cc308 100644 --- a/src/main/java/com/openshift/internal/restclient/model/List.java +++ b/src/main/java/com/openshift/internal/restclient/model/List.java @@ -26,6 +26,8 @@ */ public class List extends KubernetesResource implements IList{ + private static final String ITEMS = "items"; + private String kind; private Collection items; public List(ModelNode node, IClient client, Map propertyKeys) { @@ -34,13 +36,12 @@ public List(ModelNode node, IClient client, Map propertyKeys) if(StringUtils.isNotBlank(listKind)) { kind = listKind.substring(0, listKind.length() - "List".length()); } - } @Override public Collection getItems(){ if(items == null) { - String key = getNode().has(OBJECTS) ? OBJECTS : "items"; + String key = getNode().has(OBJECTS) ? OBJECTS : ITEMS; ModelNode listNode = get(key); if (listNode.isDefined()) { Collection nodes = get(key).asList(); @@ -51,6 +52,9 @@ public Collection getItems(){ if (kind != null && !node.get(KIND).isDefined()) { set(node, KIND, kind); } + if(!node.get(APIVERSION).isDefined()) { + set(node, APIVERSION, getApiVersion()); + } IResource resource = factory.create(node.toJSONString(true)); items.add(resource); } diff --git a/src/main/java/com/openshift/internal/restclient/model/Status.java b/src/main/java/com/openshift/internal/restclient/model/Status.java index 7bad4d9b..1dac6b37 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Status.java +++ b/src/main/java/com/openshift/internal/restclient/model/Status.java @@ -8,6 +8,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.model; +import java.util.HashMap; import java.util.Map; import org.jboss.dmr.ModelNode; @@ -24,6 +25,9 @@ public class Status extends KubernetesResource implements IStatus{ private static final String STATUS_CODE = "code"; private static final String STATUS_STATUS = "status"; + public Status(String json) { + this(ModelNode.fromJSONString(json), null, new HashMap<>()); + } public Status(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); @@ -37,7 +41,7 @@ public String getMessage(){ public int getCode() { return asInt(STATUS_CODE); } - + @Override public String getStatus() { return asString(STATUS_STATUS); diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java index 200de401..006a00b3 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java @@ -220,6 +220,15 @@ public ISourceStrategyBuilder withEnvVars(List envVars) { return this; } + @Override + public ISourceStrategyBuilder fromDockerImage(String tag) { + this.tag = tag; + this.fromKind = "DockerImage"; + return this; + } + + + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/template/Template.java b/src/main/java/com/openshift/internal/restclient/model/template/Template.java index 4ad5ec31..a1eaae8e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/template/Template.java +++ b/src/main/java/com/openshift/internal/restclient/model/template/Template.java @@ -66,7 +66,10 @@ public Map getParameters() { } @Override - public Collection getItems() { + public Collection getObjects() { + if(!getNode().has(OBJECTS)) { + return Collections.emptyList(); + } Collection nodes = get(OBJECTS).asList(); List resources = new ArrayList(nodes.size()); IResourceFactory factory = getClient().getResourceFactory(); diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java new file mode 100644 index 00000000..eda87054 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.okhttp; + +import org.apache.commons.lang.StringUtils; + +import com.openshift.restclient.authorization.IAuthorizationContext; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.utils.Base64Coder; + +import okhttp3.Headers; +import okhttp3.Request.Builder; + +/** + * + * @author jeff.cantrill + * + */ +public class BasicChallangeHandler implements IChallangeHandler{ + + private IAuthorizationContext context; + + public BasicChallangeHandler(IAuthorizationContext context) { + this.context = context; + } + + @Override + public boolean canHandle(Headers headers) { + return OpenShiftAuthenticator.AUTHORIZATION_BASIC.equalsIgnoreCase(headers.get(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE)); + } + + @Override + public Builder handleChallange(Builder builder) { + StringBuilder value = new StringBuilder(context.getUserName()).append(":"); + if(StringUtils.isNotBlank(context.getPassword())) { + value.append(context.getPassword()); + } + return builder.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION, IHttpConstants.AUTHORIZATION_BASIC + " " + Base64Coder.encode(value.toString())); + } + +} \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java new file mode 100644 index 00000000..eed411dd --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.okhttp; + +import okhttp3.Headers; +import okhttp3.Request; +import okhttp3.Request.Builder; + +/** + * A challange handler that can retrieve a token + * @author jeff.cantrill + * + */ +interface IChallangeHandler{ + + /** + * Is able to handle a challange given the auth mechanism + * provided in the header + * + * @param headers + * @return true if can handle, false otherwise + */ + boolean canHandle(Headers headers); + + /** + * Handle the challange + * + * @param builder + * @return + */ + Request.Builder handleChallange(Builder builder); +} \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java new file mode 100644 index 00000000..f00e4554 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java @@ -0,0 +1,142 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.okhttp; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.authorization.AuthorizationDetails; +import com.openshift.internal.util.URIUtils; +import com.openshift.restclient.IClient; +import com.openshift.restclient.authorization.IAuthorizationContext; +import com.openshift.restclient.authorization.IAuthorizationDetails; +import com.openshift.restclient.authorization.UnauthorizedException; +import com.openshift.restclient.http.IHttpConstants; + +import okhttp3.Authenticator; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Request.Builder; +import okhttp3.Response; +import okhttp3.Route; + +/** + * OkHttp Authenticator implementations for OpenShift 3 + * @author jeff.cantrill + * + */ +public class OpenShiftAuthenticator implements Authenticator, IHttpConstants{ + + public static final String ACCESS_TOKEN = "access_token"; + private static final String AUTH_ATTEMPTS = "X-OPENSHIFT-AUTH-ATTEMPTS"; + private static final String CSRF_TOKEN = "X-CSRF-Token"; + private static final String ERROR = "error"; + private static final String ERROR_DETAILS = "error_details"; + + private Collection challangeHandlers = new ArrayList<>(); + private OkHttpClient okClient; + private IClient client; + + @Override + public Request authenticate(Route route, Response response) throws IOException { + if(unauthorizedForCluster(response)){ + String requestUrl = response.request().url().toString(); + Request authRequest = new Request.Builder() + .addHeader(CSRF_TOKEN, "1") + .url(route.address().url().toString() + "oauth/authorize?response_type=token&client_id=openshift-challenging-client") + .build(); + try ( + Response authResponse = tryAuth(authRequest)){ + if(authResponse.isSuccessful()) { + String token = extractAndSetAuthContextToken(authResponse); + return response.request().newBuilder() + .header(IHttpConstants.PROPERTY_AUTHORIZATION, String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)) + .build(); + } + } + throw new UnauthorizedException(captureAuthDetails(requestUrl), ResponseCodeInterceptor.getStatus(response.body().string())); + } + + return null; + } + + private boolean unauthorizedForCluster(Response response) { + String requestHost = response.request().url().host(); + return response.code() == IHttpConstants.STATUS_UNAUTHORIZED && client.getBaseURL().getHost().equals(requestHost); + } + + private Response tryAuth(Request authRequest) throws IOException { + return okClient + .newBuilder() + .authenticator(new Authenticator() { + + @Override + public Request authenticate(Route route, Response response) throws IOException { + if(StringUtils.isNotBlank(response.request().header(AUTH_ATTEMPTS))) { + return null; + } + if(StringUtils.isNotBlank(response.header(IHttpConstants.PROPERTY_WWW_AUTHENTICATE))) { + for (IChallangeHandler challangeHandler : challangeHandlers) { + if(!challangeHandler.canHandle(response.headers())) { + Builder requestBuilder = response.request().newBuilder() + .header(AUTH_ATTEMPTS, "1"); + return challangeHandler.handleChallange(requestBuilder).build(); + } + } + } + return null; + } + }) + .followRedirects(false) + .followRedirects(false) + .build() + .newCall(authRequest).execute(); + } + + private IAuthorizationDetails captureAuthDetails(String url) { + IAuthorizationDetails details = null; + Map pairs = URIUtils.splitFragment(url); + if (pairs.containsKey(ERROR)) { + details = new AuthorizationDetails(pairs.get(ERROR), pairs.get(ERROR_DETAILS)); + } + return details; + } + + private String extractAndSetAuthContextToken(Response response) { + String token = null; + Map pairs = URIUtils.splitFragment(response.header(PROPERTY_LOCATION)); + if (pairs.containsKey(ACCESS_TOKEN)) { + token = pairs.get(ACCESS_TOKEN); + IAuthorizationContext authContext = client.getAuthorizationContext(); + if(authContext != null) { + authContext.setToken(token); + } + } + return token; + } + + + public void setOkClient(OkHttpClient okClient) { + this.okClient = okClient; + } + + public void setClient(DefaultClient client) { + this.client = client; + challangeHandlers.clear(); + challangeHandlers.add(new BasicChallangeHandler(client.getAuthorizationContext())); + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java new file mode 100644 index 00000000..435c53a6 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.okhttp; + +import java.io.IOException; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.authorization.AuthorizationDetails; +import com.openshift.internal.restclient.model.Status; +import com.openshift.internal.util.URIUtils; +import com.openshift.restclient.BadRequestException; +import com.openshift.restclient.IClient; +import com.openshift.restclient.NotFoundException; +import com.openshift.restclient.OpenShiftException; +import com.openshift.restclient.authorization.ResourceForbiddenException; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.model.IStatus; + +import okhttp3.Interceptor; +import okhttp3.Response; + +/** + * Interpret response codes and handle accordingly + * + * @author jeff.cantrill + * + */ +public class ResponseCodeInterceptor implements Interceptor, IHttpConstants { + + public static final String X_OPENSHIFT_IGNORE_RCI = "X-OPENSHIFT-IGNORE-RCI"; + + private static final Logger LOGGER = Logger.getLogger(ResponseCodeInterceptor.class); + + private IClient client; + + @Override + public Response intercept(Chain chain) throws IOException { + Response response = chain.proceed(chain.request()); + if(!response.isSuccessful() && StringUtils.isBlank(response.request().header(X_OPENSHIFT_IGNORE_RCI))) { + switch(response.code()) { + case STATUS_UPGRADE_PROTOCOL: + case STATUS_MOVED_PERMANENTLY: + break; + case STATUS_MOVED_TEMPORARILY: + response = makeSuccessIfAuthorized(response); + break; + default: + throw createOpenShiftException(client, response, null); + } + } + return response; + } + + private Response makeSuccessIfAuthorized(Response response) { + String location = response.header(PROPERTY_LOCATION); + if(StringUtils.isNotBlank(location) && URIUtils.splitFragment(location).containsKey(OpenShiftAuthenticator.ACCESS_TOKEN)) { + response = response.newBuilder() + .request(response.request()) + .code(STATUS_OK) + .headers(response.headers()) + .build(); + } + return response; + } + + public void setClient(DefaultClient client) { + this.client = client; + } + + public static IStatus getStatus(String response) { + if(response.startsWith("{")) { + return new Status(response); + } + return null; + } + + public static OpenShiftException createOpenShiftException(IClient client, Response response, Throwable e) throws IOException{ + LOGGER.debug(response, e); + IStatus status = getStatus(response.body().string()); + int responseCode = response.code(); + if(status != null && status.getCode() != 0) { + responseCode = status.getCode(); + } + switch(responseCode) { + case STATUS_BAD_REQUEST: + return new BadRequestException(e, status, response.request().url().toString()); + case STATUS_FORBIDDEN: + return new ResourceForbiddenException(status != null ? status.getMessage() : "Resource Forbidden", status, e); + case STATUS_UNAUTHORIZED: + String link = String.format("%s/oauth/token/request", client.getBaseURL()); + AuthorizationDetails details = new AuthorizationDetails(response.headers(), link); + return new com.openshift.restclient.authorization.UnauthorizedException(details, status); + case IHttpConstants.STATUS_NOT_FOUND: + return new NotFoundException(status == null ? "Not Found" : status.getMessage()); + default: + return new OpenShiftException(e, status, "Exception trying to %s %s response code: %s", response.request().method(), response.request().url().toString(), responseCode); + } + } + + public static OpenShiftException createOpenShiftException(IClient client, int responseCode, String message, String response, Throwable e) throws IOException{ + LOGGER.debug(response, e); + IStatus status = getStatus(response); + if(status != null && status.getCode() != 0) { + responseCode = status.getCode(); + } + switch(responseCode) { + case STATUS_BAD_REQUEST: + return new BadRequestException(e, status, response); + case STATUS_FORBIDDEN: + return new ResourceForbiddenException(status != null ? status.getMessage() : "Resource Forbidden", status, e); + case STATUS_UNAUTHORIZED: + return new com.openshift.restclient.authorization.UnauthorizedException(client.getAuthorizationContext().getAuthorizationDetails(), status); + case IHttpConstants.STATUS_NOT_FOUND: + return new NotFoundException(status == null ? "Not Found" : status.getMessage()); + default: + return new OpenShiftException(e, status, "Exception trying to fetch %s response code: %s", response, responseCode); + } + } + + +} diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java new file mode 100644 index 00000000..642000cd --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.okhttp; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + +import org.apache.commons.lang.StringUtils; +import org.jboss.dmr.ModelNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.URLBuilder; +import com.openshift.internal.restclient.model.KubernetesResource; +import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IOpenShiftWatchListener; +import com.openshift.restclient.IWatcher; +import com.openshift.restclient.OpenShiftException; +import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.model.IList; +import com.openshift.restclient.model.IResource; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.ws.WebSocket; +import okhttp3.ws.WebSocketCall; +import okhttp3.ws.WebSocketListener; +import okio.Buffer; + +public class WatchClient implements IWatcher, IHttpConstants { + + private static final Logger LOGGER = LoggerFactory.getLogger(WatchClient.class); + private DefaultClient client; + private OkHttpClient okClient; + private static AtomicReference status = new AtomicReference<>(Status.Stopped); + private WebSocket wsClient; + private IApiTypeMapper typeMappings; + + private enum Status { + Started, + Starting, + Stopped, + Stopping + } + + public WatchClient(DefaultClient client, IApiTypeMapper typeMapper, OkHttpClient okClient) { + this.client = client; + this.typeMappings = typeMapper; + this.okClient = okClient; + } + + @Override + public void stop() { + if(status.get() == Status.Stopping + || status.get() == Status.Stopped) { + return; + } + try { + if(wsClient != null) { + wsClient.close(1000, "Client was asked to stop."); + wsClient = null; + status.set(Status.Stopped); + } + } catch (Exception e) { + LOGGER.debug("Unable to stop the watch client",e); + } + } + + public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatchListener listener) { + + try { + for (String kind : kinds) { + WatchEndpoint socket = new WatchEndpoint(listener, kind); + final String resourceVersion = getResourceVersion(kind, namespace, socket); + + final String endpoint = new URLBuilder(client.getBaseURL(), this.typeMappings) + .kind(kind) + .namespace(namespace) + .watch() + .addParmeter(ResourcePropertyKeys.RESOURCE_VERSION, resourceVersion) + .websocket(); + Request request = client.newRequestBuilderTo(endpoint) + .header(PROPERTY_ORIGIN, client.getBaseURL().toString()) + .header(PROPERTY_USER_AGENT, "openshift-restclient-java") + .build(); + WebSocketCall call = WebSocketCall.create(okClient, request); + call.enqueue(socket); + } + } catch (Exception e) { + try { + throw ResponseCodeInterceptor.createOpenShiftException(client, 500, String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), null, e); + } catch (IOException e1) { + throw new OpenShiftException(e1, "IOException trying to create an OpenShift specific exception"); + } + } + return this; + } + + private String getResourceVersion(String kind, String namespace, WatchEndpoint endpoint) throws Exception{ + IList list = client.get(kind, namespace); + Collection items = list.getItems(); + List resources = new ArrayList<>(items.size()); + resources.addAll(items); + endpoint.setResources(resources); + return list.getResourceVersion(); + } + + private class WatchEndpoint implements WebSocketListener{ + + private IOpenShiftWatchListener listener; + private List resources; + private final String kind; + + public WatchEndpoint(IOpenShiftWatchListener listener, String kind) { + this.listener = listener; + this.kind = kind; + } + + public void setResources(List resources) { + this.resources = resources; + } + + @Override + public void onClose(int statusCode, String reason) { + LOGGER.debug("WatchSocket closed for kind: {}, code: {}, reason: {}", new Object[]{kind, statusCode, reason}); + listener.disconnected(); + status.set(Status.Stopped); + } + + @Override + public void onFailure(IOException err, Response response) { + LOGGER.debug("WatchSocket Error for kind " + kind, err); + try { + if(response == null) { + listener.error(ResponseCodeInterceptor.createOpenShiftException(client, 0, "", "", err)); + }else { + listener.error(ResponseCodeInterceptor.createOpenShiftException(client, response.code(), response.body().string(), response.request().url().toString(), err)); + } + } catch (IOException e) { + LOGGER.error("IOException trying to notify listener of specific OpenShiftException", err); + listener.error(err); + } + } + + @Override + public void onMessage(ResponseBody body) throws IOException { + String message = body.string(); + LOGGER.debug(message); + KubernetesResource payload = client.getResourceFactory().create(message); + ModelNode node = payload.getNode(); + IOpenShiftWatchListener.ChangeType event = new ChangeType(node.get("type").asString()); + IResource resource = client.getResourceFactory().create(node.get("object").toJSONString(true)); + if(StringUtils.isEmpty(resource.getKind())) { + LOGGER.error("Unable to determine resource kind from: " + node.get("object").toJSONString(false)); + } + listener.received(resource, event); + } + + @Override + public void onOpen(WebSocket socket, Response response) { + LOGGER.debug("WatchSocket connected for {}", kind); + status.set(Status.Started); + wsClient = socket; + listener.connected(resources); + } + + @Override + public void onPong(Buffer buffer) { + } + + } + +} diff --git a/src/main/java/com/openshift/internal/util/URIUtils.java b/src/main/java/com/openshift/internal/util/URIUtils.java index 60539769..5d91eb1d 100644 --- a/src/main/java/com/openshift/internal/util/URIUtils.java +++ b/src/main/java/com/openshift/internal/util/URIUtils.java @@ -8,14 +8,18 @@ ******************************************************************************/ package com.openshift.internal.util; +import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; +import java.net.URLDecoder; import java.nio.charset.StandardCharsets; +import java.util.Collections; import java.util.HashMap; import java.util.Map; -import org.apache.http.NameValuePair; -import org.apache.http.client.utils.URLEncodedUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + /** * Helper methods for manipulating URIs @@ -23,11 +27,15 @@ * @author Jeff Cantrill */ public class URIUtils { + private static final Logger LOG = Logger.getLogger(URIUtils.class); private URIUtils(){ } public static Map splitFragment(String location){ + if(StringUtils.isEmpty(location)) { + return Collections.emptyMap(); + } URI uri = null; try { uri = new URI(location); @@ -44,8 +52,17 @@ public static Map splitFragment(URI uri){ public static Map splitQuery(String q) { HashMap params = new HashMap(); if (q != null) { - for (NameValuePair pair : URLEncodedUtils.parse(q, StandardCharsets.UTF_8)) { - params.put(pair.getName(), pair.getValue()); + try { + String decoded = URLDecoder.decode(q, StandardCharsets.UTF_8.toString()); + String[] split = decoded.split("&"); + for (String pair : split) { + String[] keyValue = pair.split("="); + if(keyValue.length >= 2) { + params.put(keyValue[0], keyValue[1]); + } + } + } catch (UnsupportedEncodingException e) { + LOG.error("Unable to decode " + q, e); } } return params; diff --git a/src/main/java/com/openshift/restclient/BadRequestException.java b/src/main/java/com/openshift/restclient/BadRequestException.java new file mode 100644 index 00000000..6556e65f --- /dev/null +++ b/src/main/java/com/openshift/restclient/BadRequestException.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient; + +import com.openshift.restclient.model.IStatus; + +/** + * The exception thrown when the client is trying to submit a request + * to with parameters that are not accepted by the server + * + * @author jeff.cantrill + * + */ +public class BadRequestException extends OpenShiftException { + + + /** + * + */ + private static final long serialVersionUID = -333562634088784896L; + + public BadRequestException(Throwable e, IStatus status, String endpoint) { + super(e, status, "%s", endpoint); + } + +} diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 5571f611..2db125c8 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -10,13 +10,30 @@ ******************************************************************************/ package com.openshift.restclient; -import java.net.MalformedURLException; +import java.io.IOException; import java.net.URL; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.ResourceFactory; -import com.openshift.restclient.authorization.IAuthorizationStrategy; +import com.openshift.internal.restclient.authorization.AuthorizationContext; +import com.openshift.internal.restclient.okhttp.OpenShiftAuthenticator; +import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.utils.SSLUtils; + +import okhttp3.OkHttpClient; /** * Builder to create IClient instances. @@ -26,14 +43,20 @@ public class ClientBuilder { private String baseUrl; - private ISSLCertificateCallback sslCertificateCallback; + private ISSLCertificateCallback sslCertificateCallback = new NoopSSLCertificateCallback(); private X509Certificate certificate; private String certificateAlias; private IResourceFactory resourceFactory; - private IAuthorizationStrategy authStrategy; - private String withUserName; - private Object token; - private int connectTimeoutMillies; + private String userName; + private String token; + private String password; + + private int readTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; + private TimeUnit readTimeoutUnit = TimeUnit.MILLISECONDS; + private int connectTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; + private TimeUnit connectTimeoutUnit = TimeUnit.MILLISECONDS; + private int writeTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; + private TimeUnit writeTimeoutUnit = TimeUnit.MILLISECONDS; public ClientBuilder() { this(null); @@ -44,7 +67,7 @@ public ClientBuilder(String baseUrl) { } public ClientBuilder sslCertificateCallback(ISSLCertificateCallback callback) { - this.sslCertificateCallback = callback; + this.sslCertificateCallback = callback == null ? new NoopSSLCertificateCallback() : callback; return this; } @@ -59,29 +82,39 @@ public ClientBuilder resourceFactory(IResourceFactory factory) { return this; } - @Deprecated - public ClientBuilder resourceFactory(IAuthorizationStrategy authStrategy) { - this.authStrategy = authStrategy; + public ClientBuilder toCluster(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + public ClientBuilder withUserName(String userName) { + this.userName = userName; return this; } - public ClientBuilder authorizationStrategy(IAuthorizationStrategy authStrategy) { - this.authStrategy = authStrategy; + public ClientBuilder withPassword(String password) { + this.password = password; return this; } - public ClientBuilder toCluster(String baseUrl) { - this.baseUrl = baseUrl; + public ClientBuilder usingToken(String token) { + this.token = token; return this; } - public ClientBuilder withUserName(String userName) { - this.withUserName = userName; + public ClientBuilder withConnectTimeout(int timeout, TimeUnit unit) { + this.connectTimeout = timeout; + this.connectTimeoutUnit = unit; return this; } - - public ClientBuilder usingToken(String userName) { - this.token = token; + public ClientBuilder withReadTimeout(int timeout, TimeUnit unit) { + this.readTimeout = timeout; + this.readTimeoutUnit = unit; + return this; + } + public ClientBuilder withWriteTimeout(int timeout, TimeUnit unit) { + this.writeTimeout = timeout; + this.writeTimeoutUnit = unit; return this; } @@ -92,7 +125,7 @@ public ClientBuilder usingToken(String userName) { * @return */ public ClientBuilder withConnectTimeout(int connectInMillis) { - this.connectTimeoutMillies = connectInMillis; + this.connectTimeout = connectInMillis; return this; } @@ -107,18 +140,39 @@ public ClientBuilder withConnectTimeout(int connectInMillis) { * 3. currentContext of config file located at ~/.kube/config * * @return + * @throws KeyManagementException */ public IClient build() { try { - ISSLCertificateCallback sslCallback = defaultIfNull(this.sslCertificateCallback, new NoopSSLCertificateCallback()); + TrustManagerFactory trustManagerFactory = initTrustManagerFactory(certificateAlias, certificate); + X509TrustManager trustManager = getCurrentTrustManager(trustManagerFactory); + SSLContext sslContext = SSLUtils.getSSLContext(trustManager); + + ResponseCodeInterceptor responseCodeInterceptor = new ResponseCodeInterceptor(); + OpenShiftAuthenticator authenticator = new OpenShiftAuthenticator(); + + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .addInterceptor(responseCodeInterceptor) + .authenticator(authenticator) + .readTimeout(readTimeout, readTimeoutUnit) + .writeTimeout(writeTimeout, writeTimeoutUnit) + .connectTimeout(connectTimeout, connectTimeoutUnit) + .hostnameVerifier(this.sslCertificateCallback) + .sslSocketFactory(sslContext.getSocketFactory(), trustManager); + OkHttpClient okClient = builder.build(); + IResourceFactory factory = defaultIfNull(resourceFactory, new ResourceFactory(null)); - DefaultClient client = new DefaultClient(new URL(this.baseUrl), null, sslCallback, factory, certificateAlias, certificate, connectTimeoutMillies); + AuthorizationContext authContext = new AuthorizationContext(token, userName, password); + DefaultClient client = new DefaultClient(new URL(this.baseUrl), okClient, factory, null, authContext); - client.setAuthorizationStrategy(authStrategy); + authContext.setClient(client); + responseCodeInterceptor.setClient(client); + authenticator.setClient(client); + authenticator.setOkClient(okClient); return client; - } catch (MalformedURLException e) { - throw new OpenShiftException(e, ""); + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) { + throw new OpenShiftException(e, "Unable to initialize client"); } } @@ -127,4 +181,66 @@ private T defaultIfNull(T value, T aDefault) { return value; return aDefault; } + + private X509TrustManager getCurrentTrustManager(TrustManagerFactory trustManagerFactory) throws NoSuchAlgorithmException, KeyStoreException { + for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { + if (trustManager instanceof X509TrustManager) { + X509TrustManager x509TrustManager = (X509TrustManager) trustManager; + return new CallbackTrustManager(x509TrustManager, this.sslCertificateCallback); + } + } + return null; + + } + + private TrustManagerFactory initTrustManagerFactory(String alias, X509Certificate cert) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + if (alias != null && cert != null) { + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + // need this load to initialize the key store, and allow for the subsequent set certificate entry + ks.load(null, null); + cert.checkValidity(); + ks.setCertificateEntry(alias, cert); + // testing has proven that you can only call init() once for a TrustManagerFactory wrt loading certs + // from the KeyStore ... subsequent KeyStore.setCertificateEntry / TrustManagerFactory.init calls are + // ignored. + // So if a specific cert is required to validate this connection's communication with the server, add it up front + // in the ctor. + trustManagerFactory.init(ks); + } else { + trustManagerFactory.init((KeyStore)null); + } + return trustManagerFactory; + } + + private static class CallbackTrustManager implements X509TrustManager { + + private X509TrustManager trustManager; + private ISSLCertificateCallback callback; + + private CallbackTrustManager(X509TrustManager currentTrustManager, ISSLCertificateCallback callback) + throws NoSuchAlgorithmException, KeyStoreException { + this.trustManager = currentTrustManager; + this.callback = callback; + } + + public X509Certificate[] getAcceptedIssuers() { + return trustManager.getAcceptedIssuers(); + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + try { + trustManager.checkServerTrusted(chain, authType); + } catch (CertificateException e) { + if (!callback.allowCertificate(chain)) { + throw e; + } + } + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + trustManager.checkServerTrusted(chain, authType); + } + } + } diff --git a/src/main/java/com/openshift/restclient/ClientFactory.java b/src/main/java/com/openshift/restclient/ClientFactory.java deleted file mode 100644 index 60868d9b..00000000 --- a/src/main/java/com/openshift/restclient/ClientFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient; - - -/** - * Factory class for creating clients to an OpenShift server - * - * @author Jeff Cantrill - */ -@Deprecated -public final class ClientFactory { - - /** - * Creates a client for the given base url and ssl certificate callback. - * - * @param baseUrl - * The OpenShift server URL - * @param sslCertCallback - * The callback handler for SSL Cert challanges - * @return an implementation of IClient - * @throws OpenShiftException - * if the baseURL is malformed - */ - public final IClient create(String baseUrl, ISSLCertificateCallback sslCertCallback){ - return new ClientBuilder(baseUrl) - .sslCertificateCallback(sslCertCallback) - .build(); - } -} diff --git a/src/main/java/com/openshift/restclient/IApiTypeMapper.java b/src/main/java/com/openshift/restclient/IApiTypeMapper.java index 5b1976b0..fb1e06f8 100644 --- a/src/main/java/com/openshift/restclient/IApiTypeMapper.java +++ b/src/main/java/com/openshift/restclient/IApiTypeMapper.java @@ -22,6 +22,8 @@ */ public interface IApiTypeMapper { + String getPreferedVersionFor(String endpoint); + /** * return the versioned endpoint for the given kind * @param version the apiVersion, null or empty is best guess diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index 013ba76e..d2fe1267 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -13,12 +13,10 @@ import java.util.List; import java.util.Map; -import com.openshift.restclient.authorization.IAuthorizationClient; -import com.openshift.restclient.authorization.IAuthorizationStrategy; +import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.capability.ICapable; import com.openshift.restclient.model.IList; import com.openshift.restclient.model.IResource; -import com.openshift.restclient.model.user.IUser; /** * Client is the the simplest interface for interacting with the OpenShift @@ -27,7 +25,7 @@ * @author Jeff Cantrill * */ -public interface IClient extends ICapable, IAuthorizationClient{ +public interface IClient extends ICapable, Cloneable { IWatcher watch(String namespace, IOpenShiftWatchListener listener, String...kinds); @@ -126,6 +124,19 @@ public interface IClient extends ICapable, IAuthorizationClient{ * @throws UnsupportedOperationException if the resource is a list */ void delete(T resource); + + + /** + * Raw execution of a request + * @param httpMethod HttpMethod (e.g. POST) + * @param kind + * @param namespace + * @param name + * @param subresource subresource or capability + * @param payload the payload to sumit. only valid on non-get operations + * @return + */ + T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload); /** * @@ -149,13 +160,10 @@ public interface IClient extends ICapable, IAuthorizationClient{ String getOpenShiftAPIVersion() throws UnsupportedVersionException; /** - * Sets the authorization strategy for the client when - * making requests to the server - * @param strategy + * The authorization context for this client. + * @return The context which will never be null */ - void setAuthorizationStrategy(IAuthorizationStrategy strategy); - - IAuthorizationStrategy getAuthorizationStrategy(); + IAuthorizationContext getAuthorizationContext(); /** * Returns the resource factory used to create resources based on the @@ -165,9 +173,21 @@ public interface IClient extends ICapable, IAuthorizationClient{ IResourceFactory getResourceFactory(); /** - * @return the user associated with the current session + * Adapt this class to the given type + * @param klass + * @return an instance of the class or null if it can not */ - IUser getCurrentUser(); - + default T adapt(Class klass) { + return null; + }; + + /** + * Query the server to determine if it + * is ready + * @return + * @throws OpenShiftException + */ + String getServerReadyStatus(); + IClient clone(); } diff --git a/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java b/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java index 9ed1d7b7..f5000349 100644 --- a/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java +++ b/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java @@ -10,14 +10,19 @@ import java.security.cert.X509Certificate; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; /** * @author Andre Dietisheim */ -public interface ISSLCertificateCallback { +public interface ISSLCertificateCallback extends HostnameVerifier { boolean allowCertificate(X509Certificate[] chain); boolean allowHostname(String hostname, SSLSession session); + + default boolean verify(String hostname, SSLSession session) { + return allowHostname(hostname, session); + } } diff --git a/src/main/java/com/openshift/restclient/OpenShiftException.java b/src/main/java/com/openshift/restclient/OpenShiftException.java index 07be8820..2553de82 100644 --- a/src/main/java/com/openshift/restclient/OpenShiftException.java +++ b/src/main/java/com/openshift/restclient/OpenShiftException.java @@ -8,6 +8,8 @@ ******************************************************************************/ package com.openshift.restclient; +import org.apache.commons.lang.StringUtils; + import com.openshift.restclient.model.IStatus; /** @@ -27,11 +29,26 @@ public OpenShiftException(String message, Object... arguments) { } public OpenShiftException(Throwable cause, IStatus status, String message, Object... arguments ) { - super(String.format(message, arguments), cause); + super(String.format(StringUtils.defaultIfBlank(message, ""), arguments), cause); this.status = status; } public IStatus getStatus(){ return this.status; } + + public boolean hasStatus() { + return this.status != null; + } + + @Override + public String getMessage() { + if(hasStatus()) { + return super.getMessage() + " " + status.getMessage(); + } + return super.getMessage(); + } + + + } diff --git a/src/main/java/com/openshift/restclient/authorization/AbstractAuthorizationStrategy.java b/src/main/java/com/openshift/restclient/authorization/AbstractAuthorizationStrategy.java deleted file mode 100644 index 70042385..00000000 --- a/src/main/java/com/openshift/restclient/authorization/AbstractAuthorizationStrategy.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -/** - * Base Authorization stategy - * - * @author Andre Dietisheim - */ -public abstract class AbstractAuthorizationStrategy implements IAuthorizationStrategy { - - private final String username; - - public AbstractAuthorizationStrategy(String username) { - this.username = username; - } - - @Override - public String getUsername() { - return username; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((username == null) ? 0 : username.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AbstractAuthorizationStrategy other = (AbstractAuthorizationStrategy) obj; - if (username == null) { - if (other.username != null) - return false; - } else if (!username.equals(other.username)) - return false; - return true; - } - -} diff --git a/src/main/java/com/openshift/restclient/authorization/AuthorizationClientFactory.java b/src/main/java/com/openshift/restclient/authorization/AuthorizationClientFactory.java deleted file mode 100644 index 85963056..00000000 --- a/src/main/java/com/openshift/restclient/authorization/AuthorizationClientFactory.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -import com.openshift.internal.restclient.authorization.AuthorizationClient; -import com.openshift.restclient.IClient; - -/** - * @author Jeff Cantrill - */ -@Deprecated -public class AuthorizationClientFactory { - - /** - * Create an authorization client - * @param client the OpenShift client to use when retrieving a user - * @return - */ - public IAuthorizationClient create(IClient client){ - return new AuthorizationClient(client); - } - - /** - * Leaving here until we find a usecase to make it 'public' outside of - * the internal packages. - * - * @author jeff.cantrill - * - */ - public static class AuthorizationClientBuilder{ - - private int connectTimeoutMillis; - private IClient client; - - public AuthorizationClientBuilder withClient(IClient client) { - this.client = client; - return this; - } - - /** - * The connect timeout in millis - * @param connectTimeoutMillis - * @return - */ - public AuthorizationClientBuilder withConnectTimeout(int connectTimeoutMillis) { - this.connectTimeoutMillis = connectTimeoutMillis; - return this; - } - - public IAuthorizationClient build() { - return new AuthorizationClient(this.client, connectTimeoutMillis); - } - } -} diff --git a/src/main/java/com/openshift/restclient/authorization/BasicAuthorizationStrategy.java b/src/main/java/com/openshift/restclient/authorization/BasicAuthorizationStrategy.java deleted file mode 100644 index a1c52d07..00000000 --- a/src/main/java/com/openshift/restclient/authorization/BasicAuthorizationStrategy.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -import com.openshift.restclient.http.IHttpConstants; -import com.openshift.restclient.utils.Base64Coder; - -/** - * Authorization strategy for basic authorization - * - * @author Jeff Cantrill - */ -public class BasicAuthorizationStrategy extends AbstractAuthorizationStrategy { - - private final String password; - private final String token; - - /** - * - * @param username - * @param password - * @param token optionally a token to use before trying to auth with username/password - */ - public BasicAuthorizationStrategy(String username, String password, String token) { - super(username); - this.password = password; - this.token = token; - } - - public String getPassword() { - return password; - } - - @Override - public String getToken() { - return token; - } - - @Override - public void authorize(IRequest request) { - String value = IHttpConstants.AUTHORIZATION_BASIC + " " + Base64Coder.encode(String.format("%s:%s", getUsername(), password)); - request.setProperty(IHttpConstants.PROPERTY_AUTHORIZATION, value); - } - - @Override - public void accept(IAuthorizationStrategyVisitor visitor) { - visitor.visit(this); - } -} diff --git a/src/main/java/com/openshift/restclient/authorization/IAuthorizationClient.java b/src/main/java/com/openshift/restclient/authorization/IAuthorizationClient.java deleted file mode 100644 index 1df636eb..00000000 --- a/src/main/java/com/openshift/restclient/authorization/IAuthorizationClient.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -import com.openshift.restclient.ISSLCertificateCallback; - -/** - * @author Jeff Cantrill - */ -public interface IAuthorizationClient { - - /** - * Retrieve a token for OpenShift. - * - * @param baseURL - * @return - * @throws UnauthorizedException - */ - IAuthorizationContext getContext(final String baseURL); - - /** - * Retrieve the authorization details for a server - * - * @param baseURL - * @return - */ - IAuthorizationDetails getAuthorizationDetails(String baseURL); - - /** - * Set the callback handler to use for certificate trust issues. - * @param callback - */ - void setSSLCertificateCallback(ISSLCertificateCallback callback); -} diff --git a/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java b/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java index ee79263e..0154fbc3 100644 --- a/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java +++ b/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java @@ -25,8 +25,10 @@ public interface IAuthorizationContext { IUser getUser(); /** - * - * @return true if the token is non-null; false otherwise + * This can trigger a remote call if a user + * has not attempted to authorize previously + * + * @return true if authorized; false otherwise */ boolean isAuthorized(); @@ -43,11 +45,50 @@ public interface IAuthorizationContext { */ String getToken(); + /** + * The token to try and use for communication + * to the apiserver + * @param token + */ + void setToken(String token); + + /** + * A username to use for authenticating + * @param userName + */ + void setUserName(String userName); + + /** + * A username to use for authenticating + * @return userName + */ + String getUserName(); + + /** + * Password to use to authenticate to retrieve a + * token + * @param password + */ + void setPassword(String password); + + /** + * Password to use to authenticate to retrieve a + * token + * @return password + */ + String getPassword(); /** * Time in ?? when the token expires. Will return * non-null value if authorized * @return */ String getExpiresIn(); - + + /** + * Retrieve the authorization details for a server + * + * @param baseURL + * @return + */ + IAuthorizationDetails getAuthorizationDetails(); } diff --git a/src/main/java/com/openshift/restclient/authorization/IAuthorizationStrategy.java b/src/main/java/com/openshift/restclient/authorization/IAuthorizationStrategy.java deleted file mode 100644 index 23e2a1bf..00000000 --- a/src/main/java/com/openshift/restclient/authorization/IAuthorizationStrategy.java +++ /dev/null @@ -1,40 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -/** - * Authorization interface to provide various authorization mechanisms - * to an OpenShift server - * - * @author Jeff Cantrill - * - */ -public interface IAuthorizationStrategy{ - - /** - * Authorizes the given request - * @param request - */ - void authorize(IRequest request); - - - void accept(IAuthorizationStrategyVisitor visitor); - - /** - * Return the token that is used for authentication - * @return - */ - String getToken(); - - /** - * Returns the username for this strategy. - * @return - */ - String getUsername(); -} diff --git a/src/main/java/com/openshift/restclient/authorization/IAuthorizationStrategyVisitor.java b/src/main/java/com/openshift/restclient/authorization/IAuthorizationStrategyVisitor.java deleted file mode 100644 index 0242d346..00000000 --- a/src/main/java/com/openshift/restclient/authorization/IAuthorizationStrategyVisitor.java +++ /dev/null @@ -1,19 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.restclient.authorization; - -/** - * @author Jeff Cantrill - */ -public interface IAuthorizationStrategyVisitor { - - void visit(BasicAuthorizationStrategy strategy); - - void visit(TokenAuthorizationStrategy tokenAuthorizationStrategy); -} diff --git a/src/main/java/com/openshift/restclient/authorization/IRequest.java b/src/main/java/com/openshift/restclient/authorization/IRequest.java deleted file mode 100644 index 84bdfbab..00000000 --- a/src/main/java/com/openshift/restclient/authorization/IRequest.java +++ /dev/null @@ -1,27 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -/** - * A type to decouple an IAuthorizationStrategy from - * the underlying connection stream - * - * @author Jeff Cantrill - */ -public interface IRequest { - - /** - * Add the property with the given name and - * value to the underlying request - * - * @param name - * @param value - */ - void setProperty(String name, String value); -} diff --git a/src/main/java/com/openshift/restclient/authorization/TokenAuthorizationStrategy.java b/src/main/java/com/openshift/restclient/authorization/TokenAuthorizationStrategy.java deleted file mode 100644 index 48544bdf..00000000 --- a/src/main/java/com/openshift/restclient/authorization/TokenAuthorizationStrategy.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -import com.openshift.restclient.http.IHttpConstants; - -/** - * Authorization stategy to add a Bearer Token to a request - * - * @author Jeff Cantrill - * @author Andre Dietisheim - */ -public class TokenAuthorizationStrategy extends AbstractAuthorizationStrategy { - - private final String token; - - public TokenAuthorizationStrategy(String token) { - this(token, null); - } - - public TokenAuthorizationStrategy(String token, String username) { - super(username); - this.token = token; - } - - @Override - public void authorize(IRequest request) { - request.setProperty(IHttpConstants.PROPERTY_AUTHORIZATION, String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)); - } - - @Override - public String getToken(){ - return this.token; - } - - @Override - public void accept(IAuthorizationStrategyVisitor visitor) { - visitor.visit(this); - } -} diff --git a/src/main/java/com/openshift/restclient/authorization/URLConnectionRequest.java b/src/main/java/com/openshift/restclient/authorization/URLConnectionRequest.java deleted file mode 100644 index ca084353..00000000 --- a/src/main/java/com/openshift/restclient/authorization/URLConnectionRequest.java +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -import java.net.URLConnection; - -/** - * @author Jeff Cantrill - */ -public class URLConnectionRequest implements IRequest { - - private final URLConnection connection; - - public URLConnectionRequest(URLConnection connection) { - this.connection = connection; - } - - @Override - public void setProperty(String name, String value) { - connection.setRequestProperty(name, value); - } - -} diff --git a/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java b/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java index c22e40d1..1deff811 100644 --- a/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java +++ b/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java @@ -20,8 +20,9 @@ public class UnauthorizedException extends OpenShiftException { private static final long serialVersionUID = -3999801367045252906L; private static final String MSG_BASE = "Unauthorized to access resource."; - private IAuthorizationDetails details; + private String message; private IStatus status; + private IAuthorizationDetails details; public UnauthorizedException(IAuthorizationDetails details) { this(details, null); @@ -29,8 +30,15 @@ public UnauthorizedException(IAuthorizationDetails details) { public UnauthorizedException(IAuthorizationDetails details, IStatus status) { super(String.format("%s See the authorization details for additional information or contact your system administrator.", MSG_BASE)); - this.details = details; this.status = status; + this.details = details; + if(details != null) { + if(StringUtils.isNotBlank(details.getScheme())){ + message = String.format("%s You can access the server using %s authentication.", MSG_BASE, details.getScheme()); + }else + message = details.getMessage(); + }else + message = super.getMessage(); } public IAuthorizationDetails getAuthorizationDetails() { @@ -39,11 +47,7 @@ public IAuthorizationDetails getAuthorizationDetails() { @Override public String getMessage() { - String scheme = details.getScheme(); - if(StringUtils.isNotBlank(scheme)){ - return String.format("%s You can access the server using %s authentication.", MSG_BASE, scheme); - } - return StringUtils.defaultIfEmpty(details.getMessage(), super.getMessage()); + return message; } @Override diff --git a/src/main/java/com/openshift/restclient/capability/resources/IBuildCancelable.java b/src/main/java/com/openshift/restclient/capability/resources/IBuildCancelable.java index b70832bb..ea1349e1 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IBuildCancelable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IBuildCancelable.java @@ -1,10 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.model.IBuild; +/** + * Capability to cancel a build that is running + * @author jeff.cantrill + * + */ public interface IBuildCancelable extends ICapability { + /** + * Cancel the build + * @return + */ IBuild cancel(); } diff --git a/src/main/java/com/openshift/restclient/capability/server/ITemplateProcessing.java b/src/main/java/com/openshift/restclient/capability/server/ITemplateProcessing.java index 13c461dd..a7f00417 100644 --- a/src/main/java/com/openshift/restclient/capability/server/ITemplateProcessing.java +++ b/src/main/java/com/openshift/restclient/capability/server/ITemplateProcessing.java @@ -9,7 +9,6 @@ package com.openshift.restclient.capability.server; import com.openshift.restclient.capability.ICapability; -import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.template.ITemplate; /** @@ -27,5 +26,5 @@ public interface ITemplateProcessing extends ICapability { * @param namespace The namespace to use when processing the template * @return ITemplate */ - T process(ITemplate template, String namespace); + ITemplate process(ITemplate template, String namespace); } diff --git a/src/main/java/com/openshift/restclient/http/IHttpClient.java b/src/main/java/com/openshift/restclient/http/IHttpClient.java deleted file mode 100755 index b2a35f19..00000000 --- a/src/main/java/com/openshift/restclient/http/IHttpClient.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2011-2014 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.restclient.http; - -import java.net.SocketTimeoutException; -import java.net.URL; - -import com.openshift.internal.restclient.http.EncodingException; -import com.openshift.internal.restclient.http.HttpClientException; -import com.openshift.restclient.ISSLCertificateCallback; -import com.openshift.restclient.authorization.IAuthorizationStrategy; -import com.openshift.restclient.model.IResource; - -/** - * @author André Dietisheim - * @author Nicolas Spano - * @author Corey Daley - * @author Sean Kavanagh - * @deprecated This interface and its supporting classes to be deprecated in the near future. - */ -@Deprecated -public interface IHttpClient { - - public static final String SYSPROP_OPENSHIFT_CONNECT_TIMEOUT = "com.openshift.httpclient.connect.timeout"; - public static final String SYSPROP_OPENSHIFT_READ_TIMEOUT = "com.openshift.httpclient.read.timeout"; - public static final String SYSPROP_DEFAULT_CONNECT_TIMEOUT = "sun.net.client.defaultConnectTimeout"; - public static final String SYSPROP_DEFAULT_READ_TIMEOUT = "sun.net.client.defaultReadTimeout"; - - public static final int DEFAULT_READ_TIMEOUT = 2 * 60 * 1000; - public static final int NO_TIMEOUT = -1; - - public String get(URL url, int timeout) throws HttpClientException, SocketTimeoutException; - - public String head(URL url, int timeout) throws HttpClientException, SocketTimeoutException; - - public String post(URL url, int timeout, IResource resource) throws HttpClientException, SocketTimeoutException, EncodingException; - - public String put(URL url, int timeout, IResource resource) throws HttpClientException, SocketTimeoutException, EncodingException; - - public String delete(URL url, int timeout) throws HttpClientException, SocketTimeoutException, EncodingException; - - public void setUserAgent(String userAgent); - - public void setAcceptVersion(String version); - - public void setAcceptedMediaType(String acceptedMediaType); - - public void setAuthorizationStrategy(IAuthorizationStrategy strategy); - - public void setSSLCertificateCallback(ISSLCertificateCallback callback); - - public ISSLCertificateCallback getSSLCertificateCallback(); - -} diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index 8874bef1..2bf06663 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -15,9 +15,12 @@ * @author Andre Dietisheim * */ -public interface IHttpConstants { +public interface IHttpConstants { + public static final int STATUS_UPGRADE_PROTOCOL = 101; public static final int STATUS_OK = 200; + public static final int STATUS_MOVED_PERMANENTLY = 301; + public static final int STATUS_MOVED_TEMPORARILY = 302; public static final int STATUS_INTERNAL_SERVER_ERROR = 500; public static final int STATUS_BAD_REQUEST = 400; public static final int STATUS_UNAUTHORIZED = 401; @@ -27,12 +30,15 @@ public interface IHttpConstants { public static final String PROPERTY_CONTENT_TYPE = "Content-Type"; public static final String PROPERTY_AUTHORIZATION = "Authorization"; public static final String PROPERTY_ACCEPT = "Accept"; + public static final String PROPERTY_ORIGIN = "Origin"; + public static final String PROPERTY_LOCATION = "Location"; public static final String PROPERTY_USER_AGENT = "User-Agent"; public static final String PROPERTY_WWW_AUTHENTICATE = "Www-Authenticate"; public static final String PROPERTY_AUTHKEY = "broker_auth_key"; public static final String PROPERTY_AUTHIV = "broker_auth_iv"; + public static final String MEDIATYPE_ANY = "*/*"; public static final String MEDIATYPE_APPLICATION_JSON = "application/json"; public static final String MEDIATYPE_APPLICATION_XML = "application/xml"; public static final String MEDIATYPE_APPLICATION_FORMURLENCODED = "application/x-www-form-urlencoded"; diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java index dfd22bc0..392b4c4c 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java @@ -16,6 +16,7 @@ import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IEnvironmentVariable; import com.openshift.restclient.model.IResourceBuilder; +import com.openshift.restclient.model.build.IBuildConfigBuilder.IGitSourceBuilder; public interface IBuildConfigBuilder extends IResourceBuilder, ICapability { @@ -42,7 +43,7 @@ interface ISourceStrategyBuilder extends Endable{ /** * The imagestream tag in form of 'name:tag" - * @param tag + * @param tag 'name:tag' * @return */ ISourceStrategyBuilder fromImageStreamTag(String tag); @@ -50,6 +51,12 @@ interface ISourceStrategyBuilder extends Endable{ ISourceStrategyBuilder inNamespace(String namespace); ISourceStrategyBuilder withEnvVars(List envVars); + + /** + * @param tag docker pullspec + * @return + */ + ISourceStrategyBuilder fromDockerImage(String tag); } diff --git a/src/main/java/com/openshift/restclient/model/template/ITemplate.java b/src/main/java/com/openshift/restclient/model/template/ITemplate.java index 1fbfeee8..9fcb472b 100644 --- a/src/main/java/com/openshift/restclient/model/template/ITemplate.java +++ b/src/main/java/com/openshift/restclient/model/template/ITemplate.java @@ -25,7 +25,7 @@ public interface ITemplate extends IResource { * creates * @return */ - Collection getItems(); + Collection getObjects(); /** * Returns a map of parameter names to parameters. diff --git a/src/test/java/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/OpenshiftBinaryRSyncRetrievalIntegrationTest.java deleted file mode 100644 index 1e394ca0..00000000 --- a/src/test/java/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ - - - -import java.io.BufferedInputStream; - -import org.junit.Before; -import org.junit.Test; - -import com.openshift.internal.restclient.IntegrationTestHelper; -import com.openshift.internal.restclient.authorization.AuthorizationClient; -import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.authorization.BasicAuthorizationStrategy; -import com.openshift.restclient.authorization.IAuthorizationClient; -import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; -import com.openshift.restclient.capability.CapabilityVisitor; -import com.openshift.restclient.capability.IBinaryCapability; -import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; -import com.openshift.restclient.capability.resources.IPodLogRetrieval; -import com.openshift.restclient.model.IPod; - -/** - * - * @author Jeff Cantrill - * - */ -public class OpenshiftBinaryRSyncRetrievalIntegrationTest { - - private IntegrationTestHelper helper = new IntegrationTestHelper(); - @Before - public void setUp() throws Exception { - } - - @Test - public void testLogRetrieval() { - System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - IClient client = helper.createClient(); - client.setAuthorizationStrategy(new BasicAuthorizationStrategy("admin", "admin", "")); - IAuthorizationClient authClient = new AuthorizationClient(client); - IAuthorizationContext context = authClient.getContext(client.getBaseURL().toString()); - client.setAuthorizationStrategy(new TokenAuthorizationStrategy(context.getToken())); - client.get(ResourceKind.POD, "hello-openshift", "openshift-dev"); - IPod pod = client.get(ResourceKind.POD, "hello-openshift", "openshift-dev"); - - pod.accept(new CapabilityVisitor() { - - @Override - public Object visit(IPodLogRetrieval cap) { - try { - BufferedInputStream os = new BufferedInputStream(cap.getLogs(true, OpenShiftBinaryOption.SKIP_TLS_VERIFY)); - int c; - while((c = os.read()) != -1) { - System.out.print((char)c); - } - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - }, new Object()); - } -} diff --git a/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java b/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java index 1e017e84..e758d279 100644 --- a/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java +++ b/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java @@ -11,19 +11,14 @@ package com.openshift.internal.restclient; import static org.junit.Assert.*; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; -import java.net.URL; - import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.http.IHttpClient; import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.IService; @@ -39,10 +34,10 @@ public class ApiTypeMapperTest extends TypeMapperFixture { public void testKubernetesResourceIsSupportedAfterInitiallyErrorIsThrown() throws Exception { IService resource = factory.stub(ResourceKind.SERVICE); try { - when(getHttpClient().get(eq(new URL(super.base + "/api")), anyInt())).thenThrow(new RuntimeException()); + getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api").thenThrow(new RuntimeException()); assertTrue("Exp. Kube support", mapper.isSupported(resource)); }catch(RuntimeException e) { - when(getHttpClient().get(eq(new URL(base + "/api")), anyInt())).thenReturn(super.VERSIONS); + getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api").thenReturn(responseOf(TypeMapperFixture.VERSIONS)); assertTrue("Exp. Kube support", mapper.isSupported(resource)); } } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index 6074e1ae..9233ec5e 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -9,6 +9,8 @@ package com.openshift.internal.restclient; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static com.openshift.internal.restclient.IntegrationTestHelper.*; import java.net.MalformedURLException; import java.util.List; @@ -20,14 +22,16 @@ import com.openshift.internal.restclient.model.Project; import com.openshift.internal.restclient.model.Service; +import com.openshift.internal.restclient.model.project.OpenshiftProjectRequest; import com.openshift.internal.restclient.model.template.Template; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; +import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.authorization.UnauthorizedException; import com.openshift.restclient.model.IProject; -import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.project.IProjectRequest; import com.openshift.restclient.model.template.ITemplate; -import com.openshift.restclient.utils.Samples; /** * @author Jeff Cantrill @@ -49,20 +53,40 @@ public void setup () { factory = new ResourceFactory(client); } + @Test + public void testAuthContextIsAuthorizedWithValidUserNameAndPassword() { + client = helper.createClient(); + client.getAuthorizationContext().setUserName(helper.getDefaultClusterAdminUser()); + client.getAuthorizationContext().setPassword(helper.getDefaultClusterAdminPassword()); + client.getAuthorizationContext().isAuthorized(); + } + @Test(expected=UnauthorizedException.class) + public void testAuthContextIsAuthorizedWithoutPasswordThrows() { + client = helper.createClient(); + client.getAuthorizationContext().setUserName(helper.getDefaultClusterAdminUser()); + client.getAuthorizationContext().isAuthorized(); + } + + @Test + public void testReady() { + client.getServerReadyStatus(); + } + @Test public void testListTemplates(){ Template template = null; - Project project = null; + IProject project = null; try { - project = factory.create(VERSION, ResourceKind.PROJECT); - project.setName(helper.generateNamespace()); - template = factory.create(Samples.V1_TEMPLATE.getContentAsString()); - template.setNamespace(project.getName()); + OpenshiftProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); + projectRequest.setName(helper.generateNamespace()); + template = factory.stub(ResourceKind.TEMPLATE, "mytemplate"); - project = client.create(project); + project = (IProject) client.create(projectRequest); template = client.create(template, project.getNamespace()); + assertNotNull("Exp. the template to be found but was not", waitForResource(client, ResourceKind.TEMPLATE, project.getName(), template.getName(), 5 * MILLISECONDS_PER_SECOND)); + List list = client.list(ResourceKind.TEMPLATE, project.getName()); assertEquals(1, list.size()); for (ITemplate t : list) { @@ -78,16 +102,16 @@ public void testListTemplates(){ public void testResourceLifeCycle() throws MalformedURLException { - IProject project = factory.create(VERSION, ResourceKind.PROJECT); - ((Project) project).setName(helper.generateNamespace()); - LOG.debug(String.format("Stubbing project: %s", project)); + IProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); + ((OpenshiftProjectRequest) projectRequest).setName(helper.generateNamespace()); + LOG.debug(String.format("Stubbing project request: %s", projectRequest)); - IProject other = factory.create(VERSION, ResourceKind.PROJECT); - ((Project) other).setName(helper.generateNamespace()); - LOG.debug(String.format("Stubbing project: %s", project)); + IProjectRequest otherProjectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); + ((OpenshiftProjectRequest) otherProjectRequest).setName(helper.generateNamespace()); + LOG.debug(String.format("Stubbing project request: %s", otherProjectRequest)); Service service = factory.create(VERSION, ResourceKind.SERVICE); - service.setNamespace(project.getName()); //this will be the project's namespace + service.setNamespace(projectRequest.getName()); //this will be the project's namespace service.setName("some-service"); service.setTargetPort(6767); service.setPort(6767); @@ -95,7 +119,7 @@ public void testResourceLifeCycle() throws MalformedURLException { LOG.debug(String.format("Stubbing service: %s", service)); Service otherService = factory.create(VERSION, ResourceKind.SERVICE); - otherService.setNamespace(other.getName()); //this will be the project's namespace + otherService.setNamespace(otherProjectRequest.getName()); //this will be the project's namespace otherService.setName("some-other-service"); otherService.setTargetPort(8787); otherService.setPort(8787); @@ -103,11 +127,13 @@ public void testResourceLifeCycle() throws MalformedURLException { LOG.debug(String.format("Stubbing service: %s", otherService)); + IProject project = null; + IProject other = null; try{ - project = client.create(project); + project = (IProject) client.create(projectRequest); LOG.debug(String.format("Created project: %s", project)); - other = client.create(other); + other = (IProject) client.create(otherProjectRequest); LOG.debug(String.format("Created project: %s", project)); LOG.debug(String.format("Creating service: %s", service)); @@ -132,6 +158,8 @@ public void testResourceLifeCycle() throws MalformedURLException { assertEquals("Expected there to be only one service returned", 1, services.size()); assertEquals("Expected to get the service with the correct name", service.getName(), services.get(0).getName()); + }catch(OpenShiftException e) { + e.printStackTrace(); }finally{ cleanUpResource(client, project); cleanUpResource(client, other); @@ -141,14 +169,4 @@ public void testResourceLifeCycle() throws MalformedURLException { } - private void cleanUpResource(IClient client, IResource resource){ - try{ - Thread.sleep(1000); - LOG.debug(String.format("Deleting resource: %s", resource)); -// client.delete(resource); - }catch(Exception e){ - LOG.error("Exception deleting", e); - } - } - } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index bb550f66..23fcaabd 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -12,12 +12,9 @@ import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.*; -import static org.mockito.Mockito.*; import java.net.MalformedURLException; import java.net.URL; -import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -28,13 +25,10 @@ import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; +import com.openshift.internal.restclient.authorization.AuthorizationContext; import com.openshift.internal.restclient.model.Pod; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.authorization.BasicAuthorizationStrategy; -import com.openshift.restclient.authorization.IAuthorizationStrategy; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; -import com.openshift.restclient.http.IHttpClient; import com.openshift.restclient.model.IPod; /** @@ -47,7 +41,6 @@ public class DefaultClientTest extends TypeMapperFixture{ private static final String VERSION = "v1"; private DefaultClient client; -// private IHttpClient httpClient; private ModelNode response; private Pod podFrontEnd; private Pod podBackEnd; @@ -61,13 +54,12 @@ public void setUp() throws Exception{ this.baseUrl = new URL("http://myopenshift"); givenAClient(); givenAPodList(); - when(getHttpClient().get(eq(new URL("http://myopenshift/api/v1/namespaces/aNamespace/pods")), anyInt())) - .thenReturn(response.toJSONString(false)); + getHttpClient().whenRequestTo("http://myopenshift/api/v1/namespaces/aNamespace/pods").thenReturn(responseOf(response.toJSONString(false))); } private void givenAClient() throws MalformedURLException{ factory = new ResourceFactory(null); - client = new DefaultClient(baseUrl, getHttpClient(), null, factory, null, null, getApiTypeMapper(), IHttpClient.NO_TIMEOUT); + client = new DefaultClient(baseUrl, getHttpClient(), factory, getApiTypeMapper(), new AuthorizationContext(null)); } private void givenAPodList(){ @@ -97,6 +89,12 @@ private void givenAPodList(){ items.add(podBackEnd.getNode()); } + + private DefaultClient givenClient(URL baseUrl, String token, String user) { + DefaultClient client = new DefaultClient(baseUrl, null, null, null, new AuthorizationContext(token,user,null)); + return client; + } + @SuppressWarnings("serial") @Test public void testListResourceFilteringWithExactMatch() throws Exception { @@ -109,14 +107,6 @@ public void testListResourceFilteringWithExactMatch() throws Exception { assertEquals("Expected the frontend pod", podBackEnd, pods.get(0)); } - @Test - public void testSetAuthStrategySetsIHttpClientAuthStrategy(){ - IAuthorizationStrategy strategy = mock(IAuthorizationStrategy.class); - client.setAuthorizationStrategy(strategy ); - - verify(getHttpClient()).setAuthorizationStrategy(eq(strategy)); - } - @Test public void testListResourceFilteringNoMatch() throws Exception { Map labels = new HashMap(); @@ -148,106 +138,32 @@ public void testListResourceFilteringSingleLabel() throws Exception { @Test public void clientShouldEqualClientWithSameUrl() throws Exception { - assertThat(new DefaultClient(baseUrl, null, null, null)) - .isEqualTo(new DefaultClient(baseUrl, null, null, null)); + assertThat(givenClient(baseUrl,null,null)) + .isEqualTo(givenClient(baseUrl,null,null)); } @Test public void clientShouldNotEqualClientWithDifferentUrl() throws Exception { - assertThat(new DefaultClient(baseUrl, null, null, null)) - .isNotEqualTo(new DefaultClient(new URL("http://localhost:8443"), null, null, null)); + assertThat(givenClient(baseUrl,null,null)) + .isNotEqualTo(givenClient(new URL("http://localhost:8443"),null,null)); } - public void client_should_equal_client_with_same_TokenAuthStrategy_with_different_token() throws Exception { - DefaultClient tokenClientOne = new DefaultClient(baseUrl, null, null, null); - tokenClientOne.setAuthorizationStrategy(new TokenAuthorizationStrategy("tokenOne", "aUser")); + public void client_should_equal_client_with_same_user_with_different_token() throws Exception { + DefaultClient tokenClientOne = givenClient(baseUrl, "tokenOne", "aUser"); - DefaultClient tokenClientTwo = new DefaultClient(baseUrl, null, null, null); - tokenClientTwo.setAuthorizationStrategy(new TokenAuthorizationStrategy("tokenTwo", "aUser")); + DefaultClient tokenClientTwo = givenClient(baseUrl,"tokenTwo", "aUser"); assertThat(tokenClientOne).isEqualTo(tokenClientTwo); } - @Test - public void client_should_not_equal_client_with_same_TokenAuthStrategy_with_different_username() throws Exception { - DefaultClient tokenClientOne = new DefaultClient(baseUrl, null, null, null); - tokenClientOne.setAuthorizationStrategy(new TokenAuthorizationStrategy("aToken", "aUser")); - - DefaultClient tokenClientTwo = new DefaultClient(baseUrl, null, null, null); - tokenClientTwo.setAuthorizationStrategy(new TokenAuthorizationStrategy("aToken", "differentUser")); - - assertThat(tokenClientOne).isNotEqualTo(tokenClientTwo); - } @Test - public void client_should_not_equal_client_with_same_BasicAuthStrategy_with_different_username() throws Exception { - DefaultClient tokenClientOne = new DefaultClient(baseUrl, null, null, null); - tokenClientOne.setAuthorizationStrategy(new BasicAuthorizationStrategy("aUser", "aPassword", "aToken")); + public void client_should_not_equal_client_with_different_username() throws Exception { + DefaultClient tokenClientOne = givenClient(baseUrl,"aToken", "aUser"); - DefaultClient tokenClientTwo = new DefaultClient(baseUrl, null, null, null); - tokenClientTwo.setAuthorizationStrategy(new BasicAuthorizationStrategy("differentUser", "aPassword", "aToken")); + DefaultClient tokenClientTwo = givenClient(baseUrl, "aToken", "differentUser"); assertThat(tokenClientOne).isNotEqualTo(tokenClientTwo); } - @Test - public void client_should_equal_client_with_same_BasicAuthStrategy_with_different_password_and_different_token() throws Exception { - DefaultClient tokenClientOne = new DefaultClient(baseUrl, null, null, null); - tokenClientOne.setAuthorizationStrategy(new BasicAuthorizationStrategy("aUser", "aPassword", "aToken")); - - DefaultClient tokenClientTwo = new DefaultClient(baseUrl, null, null, null); - tokenClientTwo.setAuthorizationStrategy(new BasicAuthorizationStrategy("aUser", "differentPassword", "differentToken")); - - assertThat(tokenClientOne).isEqualTo(tokenClientTwo); - } - - @Test - public void tokenAuthClient_should_equal_basicAuthclient_with_same_username() throws Exception { - DefaultClient tokenClient = new DefaultClient(baseUrl, null, null, null); - tokenClient.setAuthorizationStrategy(new TokenAuthorizationStrategy("aToken", "aUser")); - - DefaultClient basicAuthClient = new DefaultClient(baseUrl, null, null, null); - basicAuthClient.setAuthorizationStrategy(new BasicAuthorizationStrategy("aUser", "aPassword", "differentToken")); - - assertThat(tokenClient).isEqualTo(basicAuthClient); - } - - @Test - public void tokenAuthClient_should_not_equal_basicAuthclient_with_different_username() throws Exception { - DefaultClient tokenClient = new DefaultClient(baseUrl, null, null, null); - tokenClient.setAuthorizationStrategy(new TokenAuthorizationStrategy("aToken", "aUser")); - - DefaultClient basicAuthClient = new DefaultClient(baseUrl, null, null, null); - basicAuthClient.setAuthorizationStrategy(new BasicAuthorizationStrategy("differentUser", "aPassword", "aToken")); - - assertThat(tokenClient).isNotEqualTo(basicAuthClient); - } - - @Test - public void basicAuthClient_should_equal_tokenClient_with_same_username() throws Exception { - DefaultClient basicAuthClient = new DefaultClient(baseUrl, null, null, null); - basicAuthClient.setAuthorizationStrategy(new BasicAuthorizationStrategy("aUser", "aPassword", "differentToken")); - - DefaultClient tokenClient = new DefaultClient(baseUrl, null, null, null); - tokenClient.setAuthorizationStrategy(new TokenAuthorizationStrategy("aToken", "aUser")); - - assertThat(basicAuthClient).isEqualTo(tokenClient); - } - - @Test - public void clientShouldEqualClientWithDifferentCert() throws Exception { - X509Certificate certOne = mock(X509Certificate.class); - when(certOne.getSigAlgName()).thenReturn("sig1"); - DefaultClient certClientOne = new DefaultClient(baseUrl, null, null, null, "cert1", certOne, IHttpClient.NO_TIMEOUT); - - X509Certificate certTwo = mock(X509Certificate.class); - when(certTwo.getSigAlgName()).thenReturn("sig2"); - DefaultClient certClientTwo = new DefaultClient(baseUrl, null, null, null, "cert2", certTwo, IHttpClient.NO_TIMEOUT); - - assertThat(certClientTwo).isEqualTo(certClientOne); - } - - - - } diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index a59bdfef..a45295d2 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -8,25 +8,24 @@ ******************************************************************************/ package com.openshift.internal.restclient; -import java.io.FileNotFoundException; import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; +import java.util.HashMap; import java.util.Properties; import java.util.Random; +import org.jboss.dmr.ModelNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.openshift.internal.restclient.model.ModelNodeBuilder; +import com.openshift.internal.restclient.model.Pod; +import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.ClientBuilder; import com.openshift.restclient.IClient; -import com.openshift.restclient.NoopSSLCertificateCallback; -import com.openshift.restclient.authorization.AuthorizationClientFactory; -import com.openshift.restclient.authorization.BasicAuthorizationStrategy; -import com.openshift.restclient.authorization.IAuthorizationClient; -import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.IAuthorizationDetails; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; +import com.openshift.restclient.NotFoundException; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IResource; import static org.junit.Assert.fail; @@ -36,6 +35,9 @@ */ public class IntegrationTestHelper { + public static final long MILLISECONDS_PER_SECOND = 1000; + public static final long MILLISECONDS_PER_MIN = MILLISECONDS_PER_SECOND * 60; + private static final String KEY_DEFAULT_PROJECT = "default.project"; private static final String KEY_SERVER_URL = "serverURL"; private static final String KEY_PASSWORD = "default.clusteradmin.password"; @@ -57,13 +59,10 @@ public IClient createClient(){ } public IClient createClientForBasicAuth() { - IClient client = createClient(); - final String user = getDefaultClusterAdminUser(); - final String password = getDefaultClusterAdminPassword(); - client.setAuthorizationStrategy(new BasicAuthorizationStrategy(user, password, "")); - IAuthorizationClient authClient = new AuthorizationClientFactory().create(client); - IAuthorizationContext context = authClient.getContext(client.getBaseURL().toString()); - client.setAuthorizationStrategy(new TokenAuthorizationStrategy(context.getToken())); + IClient client = new ClientBuilder(prop.getProperty(KEY_SERVER_URL)) + .withUserName(getDefaultClusterAdminUser()) + .withPassword(getDefaultClusterAdminPassword()) + .build(); return client; } @@ -74,6 +73,36 @@ public String getDefaultNamespace(){ public String generateNamespace() { return String.format("%s-%s",getDefaultNamespace(), new Random().nextInt(9999)); } + + public IProject generateProject(IClient client) { + IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, generateNamespace()); + return (IProject) client.create(request); + } + + /** + * Stub a pod definition to the openshift/hello-openshift + * image for purposes of testing. + * @param client + * @param project + * @return a pod definition that needs to be further created using the client + */ + public static IPod stubPod(IClient client, IProject project) { + //cluster shouldnt allow us to create pods directly + ModelNode builder = new ModelNodeBuilder() + .set(ResourcePropertyKeys.KIND, ResourceKind.POD) + .set(ResourcePropertyKeys.METADATA_NAME, "hello-openshift") + .set(ResourcePropertyKeys.METADATA_NAMESPACE, project.getName()) + .add("spec.containers", new ModelNodeBuilder() + .set(ResourcePropertyKeys.NAME, "hello-openshift") + .set("image", "openshift/hello-openshift") + .add("ports", new ModelNodeBuilder() + .set("containerPort", 8080) + .set("protocol", "TCP") + ) + ) + .build(); + return new Pod(builder, client, new HashMap<>()); + } /** * Loads the properties from the given {@code propertyFileName}, then @@ -107,16 +136,6 @@ private static void overrideIfExists(final Properties properties, final String p properties.setProperty(propertyName, propertyValue); } } - - public static void cleanUpResource(IClient client, IResource resource) { - try { - Thread.sleep(1000); - LOG.debug(String.format("Deleting resource: %s", resource)); - client.delete(resource); - } catch (Exception e) { - LOG.error("Exception deleting", e); - } - } public String getOpenShiftLocation() { return prop.getProperty(KEY_OPENSHIFT_LOCATION); @@ -134,4 +153,87 @@ public String getServerUrl() { return prop.getProperty(KEY_SERVER_URL); } + public static void cleanUpResource(IClient client, IResource resource) { + if(client == null || resource == null) { + LOG.debug("Skipping cleanup as client %s or resource %s is null", client, resource); + } + try { + Thread.sleep(1000); + LOG.debug(String.format("Deleting resource: %s", resource)); + client.delete(resource); + } catch (Exception e) { + LOG.error("Exception deleting", e); + } + } + + /** + * Wait for the resource to exist for cases where the test is faster + * then the server in reconciling its existence; + * @param client + * @param kind + * @param namespace + * @param name + * @param maxWaitMillis + * @return The resource or null if the maxWaitMillis was exceeded or the resource doesnt exist + */ + public static IResource waitForResource(IClient client, String kind, String namespace, String name, long maxWaitMillis) { + return waitForResource(client, kind, namespace, name, maxWaitMillis, new ReadyConditional() { + @Override + public boolean isReady(IResource resource) { + return resource != null; + } + + }); + } + /** + * Wait for the resource to exist for cases where the test is faster + * then the server in reconciling its existence; + * + * @param client + * @param kind + * @param namespace + * @param name + * @param maxWaitMillis + * @param conditional + * @return + */ + public static IResource waitForResource(IClient client, String kind, String namespace, String name, long maxWaitMillis, ReadyConditional conditional) { + IResource resource = null; + final long timeout = System.currentTimeMillis() + maxWaitMillis; + do { + try { + resource = client.get(kind, name, namespace); + if(resource != null && conditional != null) { + if(conditional.isReady(resource)) { + return resource; + } + resource = null; + } + }catch(NotFoundException e) { + try { + Thread.sleep(1000); + } catch (InterruptedException e1) { + throw new RuntimeException(e1); + } + } + }while(resource == null && System.currentTimeMillis() <= timeout); + return resource; + } + + /** + * Interface that can evaluate a resource to determine if its ready + * @author jeff.cantrill + * + */ + public static interface ReadyConditional { + + /** + * + * @param resource + * @return true if the resource is 'ready' + */ + boolean isReady(IResource resource); + } + + } diff --git a/src/test/java/com/openshift/internal/restclient/PodStatusRunningConditional.java b/src/test/java/com/openshift/internal/restclient/PodStatusRunningConditional.java new file mode 100644 index 00000000..2358fdc1 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/PodStatusRunningConditional.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient; + +import com.openshift.internal.restclient.IntegrationTestHelper.ReadyConditional; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IResource; + +/** + * Conditional to determin if a pod has acheived Running Status + * @author jeff.cantrill + * + */ +public class PodStatusRunningConditional implements ReadyConditional { + + @Override + public boolean isReady(IResource resource) { + if(resource == null) return false; + if(!(resource instanceof IPod)) return false; + IPod pod = (IPod) resource; + return "Running".equals(pod.getStatus()); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 02f2bbd8..2351e1db 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -10,44 +10,93 @@ ******************************************************************************/ package com.openshift.internal.restclient; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.*; -import java.net.URL; +import java.io.IOException; import org.junit.Before; -import org.mockito.Mock; +import org.mockito.ArgumentMatcher; +import org.mockito.stubbing.OngoingStubbing; import com.openshift.restclient.IApiTypeMapper; -import com.openshift.restclient.http.IHttpClient; +import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.utils.Samples; +import okhttp3.Call; +import okhttp3.OkHttpClient; +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; + public class TypeMapperFixture { protected static final String VERSIONS = "{ \"versions\": [\"v1\"]}"; protected static final String base = "https://localhost:8443"; + private static final String ANY = "--any--"; + private TestOkHttpClient client = spy(new TestOkHttpClient()); - @Mock - private IHttpClient client; protected IApiTypeMapper mapper; protected IApiTypeMapper getApiTypeMapper() { return mapper; } - protected IHttpClient getHttpClient() { + protected TestOkHttpClient getHttpClient() { return client; } @Before public void setUp() throws Exception { - when(client.get(eq(new URL(base + "/api")), anyInt())).thenReturn(VERSIONS); - when(client.get(eq(new URL(base + "/oapi")), anyInt())).thenReturn(VERSIONS); - when(client.get(eq(new URL(base + "/apis")), anyInt())).thenReturn(Samples.GROUP_ENDPONT_APIS.getContentAsString()); - when(client.get(eq(new URL(base + "/api/v1")), anyInt())).thenReturn(Samples.GROUP_ENDPONT_API_V1.getContentAsString()); - when(client.get(eq(new URL(base + "/oapi/v1")), anyInt())).thenReturn(Samples.GROUP_ENDPONT_OAPI_V1.getContentAsString()); - when(client.get(eq(new URL(base + "/apis/extensions/v1beta1")), anyInt())).thenReturn(Samples.GROUP_ENDPONT_APIS_EXTENSIONS.getContentAsString()); + client.whenRequestTo(ANY).thenReturn(responseOf("")); + client.whenRequestTo(base + "/api").thenReturn(responseOf(VERSIONS)); + client.whenRequestTo(base + "/oapi").thenReturn(responseOf(VERSIONS)); + client.whenRequestTo(base + "/apis").thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS.getContentAsString())); + client.whenRequestTo(base + "/api/v1").thenReturn(responseOf(Samples.GROUP_ENDPONT_API_V1.getContentAsString())); + client.whenRequestTo(base + "/oapi/v1").thenReturn(responseOf(Samples.GROUP_ENDPONT_OAPI_V1.getContentAsString())); + client.whenRequestTo(base + "/apis/extensions/v1beta1").thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS_EXTENSIONS.getContentAsString())); mapper = new ApiTypeMapper(base, client); } + + static class TestOkHttpClient extends OkHttpClient{ + + OngoingStubbing whenRequestTo(String url) throws IOException{ + Call call = mock(Call.class); + doReturn(call).when(this).newCall(requestTo(url)); + return when(call.execute()); + } + + } + + static Request requestTo(String url) { + return argThat(new RequestMatcher(url)); + } + + protected static Response responseOf(String response) { + return new Response.Builder() + .request(new Request.Builder().url("https://someurlfortesting").build()) + .protocol(Protocol.HTTP_1_1) + .code(IHttpConstants.STATUS_OK) + .body(ResponseBody.create(null, response)) + .build(); + } + + static class RequestMatcher extends ArgumentMatcher{ + + private final String url; + + public RequestMatcher(String url) { + this.url = url; + } + + @Override + public boolean matches(Object argument) { + if(ANY.equals(this.url)) return true; + if(argument == null || !(argument instanceof Request)) + return false; + return ((Request)argument).url().toString().equals(url); + } + + } } diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationClientIntegrationTest.java deleted file mode 100644 index a2a8b0ec..00000000 --- a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationClientIntegrationTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.authorization; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; -import static org.junit.Assert.fail; - -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.openshift.internal.restclient.DefaultClientIntegrationTest; -import com.openshift.internal.restclient.IntegrationTestHelper; -import com.openshift.restclient.IClient; -import com.openshift.restclient.authorization.BasicAuthorizationStrategy; -import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.UnauthorizedException; - -/** - * @author Jeff Cantrill - */ -public class AuthorizationClientIntegrationTest { - - - private static final Logger LOG = LoggerFactory.getLogger(DefaultClientIntegrationTest.class); - - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private IClient client; - - @Before - public void setup () { - client = helper.createClient(); - } - - /*---------- These are tests that should pass when server is configured for oauth auth. No expectations regarding others */ - - /* - * Assume Basic Auth, invalid token - */ - @Test - //@Environment(auth=oauth) //lets build this - public void getAuthorizationContextWhenOauthConfigurationAndInvalidToken() { - try { - client = helper.createClientForBasicAuth(); - client.getContext(client.getBaseURL().toString()); - fail("Expected to fail with authorization details"); - }catch(UnauthorizedException e) { - assertNotNull(e.getAuthorizationDetails()); - LOG.info(e.toString()); - } - } - - /* - * Assume Basic Auth, valid token - */ - @Test - //@Environment(auth=oauth) //lets build this - public void getAuthorizationContextWhenOauthConfigurationAndValidToken() { - final String token = "Mzk2MDliYWYtOTA4OC00NzJlLTk2YmQtOGM3ZTAwYTM3ZDU4"; - client = helper.createClient(); - client.setAuthorizationStrategy(new BasicAuthorizationStrategy(helper.getDefaultClusterAdminUser(), helper.getDefaultClusterAdminPassword(), token)); - IAuthorizationContext context = client.getContext(client.getBaseURL().toString()); - assertEquals(token, context.getToken()); - } - - /*---------- These are tests that should pass when server is configured for basic auth. No expectations regarding others */ - - /* - * Assume Basic Auth, valid token - */ - @Test - //@Environment(auth=basic) //lets build this - public void getAuthorizationContextWhenBasicAuthConfiguredAndValidToken() { - final String token = "Mzk2MDliYWYtOTA4OC00NzJlLTk2YmQtOGM3ZTAwYTM3ZDU4"; - client = helper.createClient(); - client.setAuthorizationStrategy(new BasicAuthorizationStrategy(helper.getDefaultClusterAdminUser(), helper.getDefaultClusterAdminPassword(), token)); - IAuthorizationContext context = client.getContext(client.getBaseURL().toString()); - assertEquals(token, context.getToken()); - } - - /* - * Assume Basic Auth, invalid token - */ - @Test - //@Environment(auth=basic) //lets build this - public void getAuthorizationContextWhenBasicAuthConfiguredAndInValidToken() { - final String token = "asdfasd"; - client = helper.createClient(); - client.setAuthorizationStrategy(new BasicAuthorizationStrategy(helper.getDefaultClusterAdminUser(), helper.getDefaultClusterAdminPassword(), token)); - IAuthorizationContext context = client.getContext(client.getBaseURL().toString()); - assertNotSame("Exp. to get a new token using the username and password", token, context.getToken()); - } - -} diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationDetailsTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationDetailsTest.java index 180ce56d..49f0f77d 100644 --- a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationDetailsTest.java +++ b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationDetailsTest.java @@ -12,14 +12,11 @@ import static org.junit.Assert.*; -import java.util.ArrayList; -import java.util.List; - -import org.apache.http.Header; -import org.apache.http.HeaderElement; -import org.apache.http.ParseException; +import org.junit.Before; import org.junit.Test; +import okhttp3.Headers; + /** * @author Jeff Cantrill */ @@ -31,8 +28,13 @@ public class AuthorizationDetailsTest { * Warning: 199 OpenShift "You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request" * code 401 */ - private List
headers = new ArrayList
(); + private Headers.Builder builder = new Headers.Builder(); + @Before + public void setUp() { + + } + @Test public void testMessageDetailsWithoutAuthorizationHeader() { givenHeader("Link", "; rel=\"related\""); @@ -51,35 +53,11 @@ public void testMessageDetailsWithAuthorizationHeader() { } private AuthorizationDetails whenCreatingAnAuthorizationScheme() { - return new AuthorizationDetails(headers.toArray(new Header[] {})); + return new AuthorizationDetails(builder.build()); } private void givenHeader(String name, String value) { - headers.add(new FakeHeader(name, value)); + builder.add(name, value); } - private static class FakeHeader implements Header{ - private String name; - private String value; - - FakeHeader(String name, String value){ - this.name = name; - this.value = value; - } - @Override - public String getName() { - return name; - } - - @Override - public String getValue() { - return value; - } - - @Override - public HeaderElement[] getElements() throws ParseException { - throw new UnsupportedOperationException("Method not supported in test impl"); - } - - } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java new file mode 100644 index 00000000..3bb7c724 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java @@ -0,0 +1,119 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.CapabilityVisitor; +import com.openshift.restclient.capability.resources.IBuildCancelable; +import com.openshift.restclient.capability.resources.IBuildTriggerable; +import com.openshift.restclient.model.IBuild; +import com.openshift.restclient.model.IBuildConfig; +import com.openshift.restclient.model.IImageStream; +import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.build.IBuildConfigBuilder; + +/** + * + * @author Jeff Cantrill + * + */ +public class BuildCapabilitiesIntegrationTest { + + private static final Logger LOG = LoggerFactory.getLogger(BuildCapabilitiesIntegrationTest.class); + private IBuildConfig config; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IProject project; + private IClient client; + + @Before + public void setUp() throws Exception { + client = helper.createClientForBasicAuth(); + project = helper.generateProject(client); + + //an output imagestream + IImageStream is = client.getResourceFactory().stub(ResourceKind.IMAGE_STREAM, "ruby-hello-world", project.getName()); + LOG.debug("Creating imagestream {}", is); + is = client.create(is); + LOG.debug("Generated imagestream {}", is); + + //a buildconfig + IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); + assertNotNull("Exp. the client to be able to use a buildconfigbuilder", builder); + config = builder.named("hello-openshift") + .inNamespace(project.getName()) + .fromGitSource() + .fromGitUrl("https://github.com/openshift/ruby-hello-world.git") + .end() + .usingSourceStrategy() + .fromDockerImage("centos/ruby-22-centos7:latest") + .end() + .toImageStreamTag("ruby-hello-world:latest") + .build(); + LOG.debug("Creating BuildConfig {}", config); + config = client.create(config); + LOG.debug("Created BuildConfig {}", config); + assertNotNull(config); + } + + @Test + public void testBuildActions() { + + //trigger the build + LOG.debug("Triggering build from the buildconfig..."); + IBuild build = config.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBuildTriggerable capability) { + return capability.trigger(); + } + }, null); + assertNotNull("Exp. to be able to trigger a build from a buildconfig", build); + LOG.debug("Triggered build {}", build); + + LOG.debug("Canceling the build..."); + //cancel the build + build = build.accept(new CapabilityVisitor() { + + @Override + public IBuild visit(IBuildCancelable cap) { + return cap.cancel(); + } + }, null); + assertNotNull("Exp. to be able to cancel a build", build); + LOG.debug("Canceled build {}", build); + + //trigger the build from a build + LOG.debug("Triggering build from a build..."); + build = build.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBuildTriggerable capability) { + return capability.trigger(); + } + }, null); + assertNotNull("Exp. to be able to trigger a build from a build", build); + LOG.debug("Triggered build {}", build); + } + + @After + public void tearDown() { + IntegrationTestHelper.cleanUpResource(client, project); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildTriggerIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildTriggerIntegrationTest.java deleted file mode 100644 index 1cff1e5d..00000000 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildTriggerIntegrationTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.capability.resources; - -import static org.junit.Assert.*; - -import org.junit.Before; -import org.junit.Test; - -import com.openshift.internal.restclient.IntegrationTestHelper; -import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; -import com.openshift.restclient.capability.CapabilityVisitor; -import com.openshift.restclient.capability.resources.IBuildTriggerable; -import com.openshift.restclient.model.IBuild; -import com.openshift.restclient.model.IBuildConfig; - -/** - * - * @author Jeff Cantrill - * - */ -public class BuildTriggerIntegrationTest { - - IBuildConfig config; - - @Before - public void setUp() throws Exception { - //client - IClient client = new IntegrationTestHelper().createClientForBasicAuth(); - IAuthorizationContext auth = client.getContext(client.getBaseURL().toString()); - client.setAuthorizationStrategy(new TokenAuthorizationStrategy(auth.getToken())); - //create buildconfig or retrieve from already initialized server - config = client.get(ResourceKind.BUILD_CONFIG, "ruby-sample-build", "test"); - assertNotNull(config); - } - - @Test - public void testTriggerABuild() { - IBuild build = config.accept(new CapabilityVisitor() { - - @Override - public IBuild visit(IBuildTriggerable capability) { - return capability.trigger(); - } - }, null); - assertNotNull("Exp. to be able to trigger a build", build); - System.out.println(build.toString()); - } - -} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DockerManifestComparatorTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DockerManifestComparatorTest.java new file mode 100644 index 00000000..3f33f110 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DockerManifestComparatorTest.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import static org.junit.Assert.*; + +import java.util.List; +import java.util.stream.Collectors; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import com.openshift.internal.restclient.capability.resources.DockerRegistryImageStreamImportCapability.ManifestComparator; +import com.openshift.restclient.utils.Samples; + +public class DockerManifestComparatorTest { + + private ModelNode root; + private ManifestComparator comparator = new ManifestComparator(); + + @Before + public void setUp() throws Exception { + root = ModelNode.fromJSONString(Samples.V1_DOCKER_IMAGE_MANIFEST.getContentAsString()); + } + + @Test + public void testCompareWithMultipleHistoryEntries() { + ModelNode history = root.get("history"); + List entries = history.asList().stream().map(n->ModelNode.fromJSONString(n.get("v1Compatibility").asString())).collect(Collectors.toList()); + entries.sort(comparator); + + ModelNode last = entries.get(entries.size()-1); + assertEquals("Exp. to retrieve the 'newest' entry with a non-null parent","5f162644b2633962f753b9a09c7783d342c8aaebccaf6270fde68404d2af7a8c",last.get("id").asString()); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java index 5374c21b..2eaff04d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java @@ -10,6 +10,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; +import static org.junit.Assert.*; import org.junit.After; import org.junit.Before; @@ -17,11 +18,11 @@ import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; +import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IProject; -import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.IStatus; import com.openshift.restclient.model.image.IImageStreamImport; import junit.framework.Assert; @@ -41,8 +42,7 @@ public class ImageStreamImportCapabilityIntegrationTest { @Before public void setUp() throws Exception { client = helper.createClientForBasicAuth(); - IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, helper.generateNamespace()); - project = (IProject) client.create(request); + project = helper.generateProject(client); cap = new ImageStreamImportCapability(project, client); } @@ -55,7 +55,9 @@ public void tearDown() { public void testImportImageForExistingImage() { DockerImageURI image = new DockerImageURI("openshift/hello-openshift"); IImageStreamImport imported = cap.importImageMetadata(image); - Assert.assertNotNull(imported); + assertNotNull(imported); + IStatus status = imported.getImageStatus().iterator().next(); + assertTrue(status.isSuccess()); } @Test @@ -63,6 +65,8 @@ public void testImportImageForUnknownImage() { DockerImageURI image = new DockerImageURI("openshift/hello-openshifts"); IImageStreamImport imported = cap.importImageMetadata(image); Assert.assertNotNull(imported); + IStatus status = imported.getImageStatus().iterator().next(); + assertEquals(IHttpConstants.STATUS_UNAUTHORIZED, status.getCode()); //exp code when image does not exist } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java index e2b2504d..ba8b5fff 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java @@ -24,6 +24,7 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; +import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IStatus; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java index 0a9d4dca..2896ad99 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java @@ -10,10 +10,12 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import java.io.BufferedInputStream; +import java.util.List; -import org.junit.Before; import org.junit.Test; import com.openshift.internal.restclient.IntegrationTestHelper; @@ -23,6 +25,7 @@ import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.capability.resources.IPodLogRetrieval; import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IResource; /** * @@ -31,22 +34,21 @@ */ public class OpenshiftBinaryPodLogRetrievalIntegrationTest { - private static final String HELLO_OPENSHIFT = "docker-registry-1-uuho4"; private IntegrationTestHelper helper = new IntegrationTestHelper(); - @Before - public void setUp() throws Exception { - } + private Exception ex; @Test public void testLogRetrieval() { System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); IClient client = helper.createClientForBasicAuth(); - IPod pod = client.get(ResourceKind.POD, HELLO_OPENSHIFT, "default"); + List pods = client.list(ResourceKind.POD, "default"); + IPod pod = (IPod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); + assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); - pod.accept(new CapabilityVisitor() { + ex = pod.accept(new CapabilityVisitor() { @Override - public Object visit(IPodLogRetrieval cap) { + public Exception visit(IPodLogRetrieval cap) { try { BufferedInputStream os = new BufferedInputStream(cap.getLogs(false, ""));//HELLO_OPENSHIFT)); int c; @@ -54,13 +56,14 @@ public Object visit(IPodLogRetrieval cap) { System.out.print((char)c); } } catch (Exception e) { - e.printStackTrace(); + return e; }finally { cap.stop(); } return null; } - }, new Object()); + }, null); + assertNull("Expected no exception", ex); } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java index 36aaf011..c7455561 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java @@ -10,6 +10,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; +import static org.junit.Assert.assertNotNull; import java.net.HttpURLConnection; import java.net.URL; @@ -17,52 +18,67 @@ import org.apache.commons.io.IOUtils; import org.jboss.dmr.ModelNode; +import org.junit.After; import org.junit.Before; import org.junit.Test; import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.internal.restclient.PodStatusRunningConditional; import com.openshift.internal.restclient.model.Pod; import com.openshift.internal.restclient.model.Port; +import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.IClient; -import com.openshift.restclient.IResourceFactory; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; import com.openshift.restclient.capability.resources.IPortForwardable; import com.openshift.restclient.capability.resources.IPortForwardable.PortPair; +import com.openshift.restclient.model.IProject; /** * * @author Jeff Cantrill * */ -public class OpenshiftBinaryPortForwardingIntegrationTest { +public class OpenshiftBinaryPortForwardingIntegrationTest implements ResourcePropertyKeys{ private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IClient client; + private IProject project; + @Before public void setUp() throws Exception { + System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); + client = helper.createClientForBasicAuth(); + project = helper.generateProject(client); + } + + @After + public void teardown() throws Exception{ + IntegrationTestHelper.cleanUpResource(client, project); } @Test public void testPortForwarding() { - System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - IClient client = helper.createClient(); - IResourceFactory resourceFactory = client.getResourceFactory(); - Pod pod = resourceFactory.create("v1", ResourceKind.POD); + Pod pod = (Pod) IntegrationTestHelper.stubPod(client, project); + pod = (Pod) client.create(pod); + pod = (Pod) IntegrationTestHelper.waitForResource(client, + pod.getKind(), + pod.getNamespace(), + pod.getName(), 5 * IntegrationTestHelper.MILLISECONDS_PER_MIN, new PodStatusRunningConditional()); + + assertNotNull("The test timed out before the pod was in a running state", pod); + final Port port = new Port(new ModelNode()); port.setProtocol("tcp"); port.setContainerPort(8080); - pod.setName("hello-openshift"); - pod.setNamespace("test"); - pod.accept(new CapabilityVisitor() { @Override public Object visit(IPortForwardable capability) { capability.forwardPorts(Arrays.asList(new PortPair(8181, port)), OpenShiftBinaryOption.SKIP_TLS_VERIFY); try { - Thread.sleep(5 * 1000); + Thread.sleep(5 * IntegrationTestHelper.MILLISECONDS_PER_SECOND); curl(); } catch (Exception e) { e.printStackTrace(); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java index b271c29a..9f36d946 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java @@ -16,32 +16,28 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; -import java.util.Queue; import static org.fest.assertions.Assertions.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.IntegrationTestHelper; -import com.openshift.internal.restclient.ResourceFactory; -import com.openshift.internal.restclient.authorization.AuthorizationClient; -import com.openshift.restclient.ClientBuilder; +import com.openshift.internal.restclient.model.Pod; import com.openshift.restclient.IClient; -import com.openshift.restclient.NoopSSLCertificateCallback; import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.authorization.BasicAuthorizationStrategy; -import com.openshift.restclient.authorization.IAuthorizationClient; -import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.authorization.TokenAuthorizationStrategy; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.capability.resources.IRSyncable; import com.openshift.restclient.capability.resources.IRSyncable.LocalPeer; import com.openshift.restclient.capability.resources.IRSyncable.PodPeer; -import com.openshift.restclient.model.IPod; -import com.openshift.restclient.model.IService; +import com.openshift.restclient.model.IResource; /** * @@ -50,59 +46,61 @@ */ public class OpenshiftBinaryRSyncRetrievalIntegrationTest { - /** The usual Logger.*/ - private static final Logger LOGGER = LoggerFactory.getLogger(OpenshiftBinaryRSyncRetrievalIntegrationTest.class); + private static final Logger LOG = LoggerFactory.getLogger(OpenshiftBinaryRSyncRetrievalIntegrationTest.class); private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IClient client; + + private File localTempDir; + + private Pod pod; @Before public void setUp() throws Exception { - } + // given + System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); + client = helper.createClientForBasicAuth(); + List pods = client.list(ResourceKind.POD, "default"); + pod = (Pod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); + assertNotNull("Did not find the registry pod to which to rsync", pod); + + localTempDir = new File(FileUtils.getTempDirectory(), helper.generateNamespace()); + localTempDir.deleteOnExit(); + assertTrue(localTempDir.mkdirs()); + } + @Test public void testRSyncLogRetrieval() throws IOException { - // given - System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - final IClient client = new ClientBuilder(helper.getServerUrl()).resourceFactory(new ResourceFactory(null)) - .sslCertificateCallback(new NoopSSLCertificateCallback()).build(); - client.setAuthorizationStrategy(new BasicAuthorizationStrategy("test-admin", "test-admin", "")); - final IAuthorizationClient authClient = new AuthorizationClient(client); - final IAuthorizationContext context = authClient.getContext(client.getBaseURL().toString()); - client.setAuthorizationStrategy(new TokenAuthorizationStrategy(context.getToken())); - // retrieve the first pod in the 'eap-app' service - final IService service = client.get(ResourceKind.SERVICE, "nodejs-example", "int-test"); - final List pods = service.getPods(); - assertThat(pods).isNotEmpty(); - final IPod pod = pods.get(0); - final String localDir = "/Users/xcoulon/git/nodejs-ex"; + final String targetDir = "/tmp"; // when // create a dummy file to be sure there will be something to rsync - final String fileName = File.createTempFile("test", ".txt", new File(localDir)).getName(); + final String fileName = File.createTempFile("test", ".txt", localTempDir).getName() + ; // run the rsync and collect the logs - final List logs = new ArrayList<>(100); - pod.accept(new CapabilityVisitor() { + List logs = pod.accept(new CapabilityVisitor>() { @Override - public Object visit(IRSyncable cap) { + public List visit(IRSyncable cap) { try { - System.out.println("**** RSync Logs ****"); final BufferedReader reader = new BufferedReader(new InputStreamReader( - cap.sync(new LocalPeer(localDir), new PodPeer(targetDir, pod)))); - String line; - while((line = reader.readLine()) != null) { - System.out.println(line); - logs.add(line); - } + cap.sync(new LocalPeer(localTempDir.getAbsolutePath()), new PodPeer(targetDir, pod)))); + List logs = IOUtils.readLines(reader); // wait until end of 'rsync' cap.await(); + return logs; } catch (Exception e) { e.printStackTrace(); } return null; } - }, new Object()); + }, new ArrayList<>()); + if(LOG.isDebugEnabled()) { + LOG.debug("**** RSync Logs ****"); + logs.forEach(l->LOG.debug(l)); + } // then // verify that the logs contain a message about the dummy file assertThat(logs).isNotEmpty(); diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java index 9f4daabb..72b64d69 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java @@ -8,6 +8,8 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.server; +import static org.junit.Assert.*; + import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; @@ -21,8 +23,10 @@ import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.internal.restclient.model.template.Template; import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.server.ITemplateProcessing; +import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.template.ITemplate; import com.openshift.restclient.utils.Samples; @@ -31,18 +35,20 @@ * @author Jeff Cantrill */ public class ServerTemplateProcessingIntegrationTest { - private static final String VERSION = "v1"; - - private static final String COMMON = "openshift"; private static final Logger LOG = LoggerFactory.getLogger(ServerTemplateProcessingIntegrationTest.class); private IClient client; private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IProject project; + @Before public void setup () throws MalformedURLException{ - client = helper.createClient(); + client = helper.createClientForBasicAuth(); + String namespace = helper.generateNamespace(); + client.create(client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, namespace)); + project = client.get(ResourceKind.PROJECT, namespace, ""); } @Test @@ -50,31 +56,31 @@ public void testProcessAndApplyTemplate() throws Exception{ final Collection results = new ArrayList(); ModelNode node = ModelNode.fromJSONString(Samples.V1_TEMPLATE.getContentAsString()); final Template template = new Template(node, client, null); - template.setNamespace(COMMON); + template.setNamespace(null); try { client.accept(new CapabilityVisitor() { @Override public Object visit(ITemplateProcessing capability) { - LOG.debug("Processing template: " + template.toString()); - ITemplate processedTemplate = capability.process(template, COMMON); + LOG.debug("Processing template: {}", template.toJson()); + assertFalse("Exp. the template to have items for this test be interesting", template.getObjects().isEmpty()); + final int items = template.getObjects().size(); + ITemplate processedTemplate = capability.process(template, project.getName()); - LOG.debug("Applying template: ", processedTemplate.toString()); - LOG.debug("applied template"); - for (IResource resource : processedTemplate.getItems()) { - LOG.debug("creating: ", resource); - results.add(client.create(resource, COMMON)); - LOG.debug("created: ", resource.toString()); + LOG.debug("Applying template: {}", processedTemplate.toJson()); + LOG.debug("Applied template"); + assertEquals("Exp. the pre and post item count to be the same", items, template.getObjects().size()); + for (IResource resource : processedTemplate.getObjects()) { + LOG.debug("creating: {}", resource); + results.add(client.create(resource, project.getName())); + LOG.debug("created: {}", resource.toJson()); } return null; } }, new Object()); } finally { - IntegrationTestHelper.cleanUpResource(client, template); - for (IResource resource : results) { - IntegrationTestHelper.cleanUpResource(client, resource); - } + IntegrationTestHelper.cleanUpResource(client, project); } } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingTest.java index b5abfd67..0ad0524a 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingTest.java @@ -11,33 +11,53 @@ import static org.junit.Assert.*; import static org.mockito.Mockito.*; -import java.util.ArrayList; - +import org.junit.Before; import org.junit.Test; import com.openshift.internal.restclient.capability.server.ServerTemplateProcessing; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.model.IResource; -import com.openshift.restclient.model.template.ITemplate; +import com.openshift.restclient.capability.server.ITemplateProcessing; /** * @author Jeff Cantrill */ public class ServerTemplateProcessingTest { + private IApiTypeMapper mapper; + private IClient client; + private ITemplateProcessing cap; + + @Before + public void setup() { + mapper = mock(IApiTypeMapper.class); + client = mock(IClient.class); + cap = new ServerTemplateProcessing(client); + + } + + @Test + public void testIsSupportedWhenApiEndpointExists() { + when(mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES)).thenReturn(true); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + + assertTrue("Exp. endpoint to be supported when processedtemplates is supported", cap.isSupported()); + } + + @Test + public void testIsSupportedWhenApiEndpointDoesNotExists() { + when(mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES)).thenReturn(false); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + + assertFalse("Exp. endpoint to not be supported when processedtemplates does not exist", cap.isSupported()); + } + @Test - public void testTemplateConfigAdapter() { - ITemplate template = mock(ITemplate.class); - when(template.toString()).thenReturn("theToStringValue"); - final ArrayList items = new ArrayList(); - when(template.getItems()).thenReturn(items); - final String namespace = "test"; - ServerTemplateProcessing.TemplateConfigAdapter adapter = new ServerTemplateProcessing.TemplateConfigAdapter (template, namespace); + public void testIsNotSupportedWhenNotAdaptableToApiTypeMapper() { + when(client.adapt(IApiTypeMapper.class)).thenReturn(null); - assertEquals(namespace, adapter.getNamespace()); - assertEquals(ResourceKind.PROCESSED_TEMPLATES, adapter.getKind()); - assertEquals(template.toString(), adapter.toString()); - assertEquals(items, adapter.getItems()); + assertFalse("Exp. endpoint to not be supported when not adaptable", cap.isSupported()); } } diff --git a/src/test/java/com/openshift/internal/restclient/http/HttpClientTest.java b/src/test/java/com/openshift/internal/restclient/http/HttpClientTest.java deleted file mode 100755 index 540c8506..00000000 --- a/src/test/java/com/openshift/internal/restclient/http/HttpClientTest.java +++ /dev/null @@ -1,516 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012-2014 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import static org.fest.assertions.Assertions.assertThat; -import static org.hamcrest.CoreMatchers.instanceOf; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import java.io.IOException; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.security.KeyStoreException; -import java.security.cert.X509Certificate; -import java.util.Random; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.SSLSession; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import com.openshift.internal.restclient.http.UrlConnectionHttpClient; -import com.openshift.internal.restclient.http.UrlConnectionHttpClientBuilder; -import com.openshift.internal.util.TestTimer; -import com.openshift.restclient.ISSLCertificateCallback; -import com.openshift.restclient.http.IHttpClient; -import com.openshift.restclient.http.IHttpConstants; -import com.openshift.restclient.server.HttpServerFake; -import com.openshift.restclient.server.HttpsServerFake; -import com.openshift.restclient.server.WaitingHttpServerFake; -import com.openshift.restclient.utils.Base64Coder; -import com.openshift.restclient.utils.ExceptionCauseMatcher; - -/** - * @author Andre Dietisheim - * @author Nicolas Spano - * @author Corey Daley - * @author Sean Kavanagh - */ -public class HttpClientTest extends TestTimer { - - private static final String ACCEPT_APPLICATION_JSON = "Accept: application/json"; - private static final Pattern AUTHORIZATION_PATTERN = Pattern.compile("Authorization: Basic ([^\n]*)"); - - private HttpServerFake serverFake; - private IHttpClient httpClient; - private HttpsServerFake httpsServerFake; - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Before - public void setUp() throws Exception { - this.serverFake = startHttpServerFake(null); - this.httpsServerFake = startHttpsServerFake(null); - this.httpClient = new UrlConnectionHttpClientBuilder() - .setAcceptMediaType(ACCEPT_APPLICATION_JSON) - .setUserAgent("com.openshift.client.test") - .setConfigTimeout(new Integer("10000")) - .client(); - } - - @After - public void tearDown() { - serverFake.stop(); - httpsServerFake.stop(); - } - - @Test(expected = HttpClientException.class) - public void shouldThrowIfNoAcceptedMediaType() throws SocketTimeoutException, HttpClientException, - MalformedURLException { - IHttpClient client = new UrlConnectionHttpClient( "useragent", null, "42.0"); - client.get(serverFake.getUrl(), IHttpClient.NO_TIMEOUT); - } - - @Test - public void canGet() throws Throwable { - String response = httpClient.get(serverFake.getUrl(), IHttpClient.NO_TIMEOUT); - assertThat(response).startsWith("GET"); - } - - - @Test - public void canHead() throws Throwable { - String response = httpClient.head(serverFake.getUrl(), IHttpClient.NO_TIMEOUT); - assertThat(response).isEqualTo(""); - } - - @Test - public void canDelete() throws Throwable { - String response = httpClient.delete(serverFake.getUrl(), IHttpClient.NO_TIMEOUT); - assertThat(response).startsWith("DELETE"); - } - - /** - * Assumes that the server is sending a certificate that is not known to the - * client. The test does this by having a custom ssl server with a self-signed certificate. - * - * @see HttpsServerFake - */ - @Test - public void shouldFailHttpsSelfsignedCertificateNoCallback() throws Throwable { - // pre-condition - expectedException.expect(new ExceptionCauseMatcher(instanceOf(SSLHandshakeException.class))); - - // operation - httpClient.get(httpsServerFake.getUrl(), IHttpClient.NO_TIMEOUT); - } - - /** - * Assumes that the server is sending a certificate that is not known to the - * client. The test does this by having a custom ssl server with a self-signed certificate. - * - * @see HttpsServerFake - */ - @Test - public void shouldSucceedHttpsSelfsignedCertificate() throws Throwable { - IHttpClient client = new UrlConnectionHttpClientBuilder() - .setAcceptMediaType(ACCEPT_APPLICATION_JSON) - .setUserAgent("com.openshift.client.test") - .setSSLCertificateCallback(new ISSLCertificateCallback() { - - @Override - public boolean allowHostname(String hostname, SSLSession session) { - return true; - } - - @Override - public boolean allowCertificate(X509Certificate[] chain) { - return true; - } - }) - .client(); - client.get(httpsServerFake.getUrl(), IHttpClient.NO_TIMEOUT); - } - - @Test - public void shouldCertificateBeInTrustStore() throws Throwable { - X509Certificate certOne = mock(X509Certificate.class); - when(certOne.getSigAlgName()).thenReturn("sig1"); - UrlConnectionHttpClient client = (UrlConnectionHttpClient) new UrlConnectionHttpClientBuilder() - .setAcceptMediaType(ACCEPT_APPLICATION_JSON) - .setUserAgent("com.openshift.client.test") - .setCertificate(httpsServerFake.getUrl().toString(), certOne) - .setSSLCertificateCallback(new ISSLCertificateCallback() { - - @Override - public boolean allowHostname(String hostname, SSLSession session) { - return true; - } - - @Override - public boolean allowCertificate(X509Certificate[] chain) { - return true; - } - }) - .client(); - X509Certificate[] certs = client.getTrustedCertificates(); - for (X509Certificate cert : certs) { - if (cert.getSigAlgName().equals("sig1")) { - return; - } - } - throw new Throwable("Did not find our certificate."); - } - - /** - * Assumes that the server is sending a certificate that is not known to the - * client. The test does this by having a custom ssl server with a self-signed certificate. - * - * @see HttpsServerFake - */ - @Test - public void shouldFailHttpsSelfsignedCertificate() throws Throwable { - // pre-condition - expectedException.expect(new ExceptionCauseMatcher(instanceOf(SSLHandshakeException.class))); - - IHttpClient client = new UrlConnectionHttpClientBuilder() - .setAcceptMediaType(ACCEPT_APPLICATION_JSON) - .setUserAgent("com.openshift.client.test") - .setSSLCertificateCallback(new ISSLCertificateCallback() { - - @Override - public boolean allowHostname(String hostname, SSLSession session) { - return true; - } - - @Override - public boolean allowCertificate(X509Certificate[] chain) { - return false; - } - }) - .client(); - - // operation - client.get(httpsServerFake.getUrl(), IHttpClient.NO_TIMEOUT); - } - - @Test - public void canAddAuthorization() throws SocketTimeoutException, HttpClientException, MalformedURLException { - String username = "andre.dietisheim@redhat.com"; - String password = "dummyPassword"; - IHttpClient httpClient = new UrlConnectionHttpClientBuilder() - .setAcceptMediaType(ACCEPT_APPLICATION_JSON) - .setUserAgent("com.openshift.client.test") - .setCredentials(username, password, null) - .client(); - - String response = httpClient.get(serverFake.getUrl(), IHttpClient.NO_TIMEOUT); - assertNotNull(response); - Matcher matcher = AUTHORIZATION_PATTERN.matcher(response); - assertTrue(matcher.find()); - assertEquals(1, matcher.groupCount()); - String credentials = matcher.group(1); - String cleartextCredentials = Base64Coder.decode(credentials); - assertThat(credentials) - .describedAs("credentials were not encoded in httpClient").isNotEqualTo(cleartextCredentials); - assertEquals(username + ":" + password, cleartextCredentials); - } - - @Test - public void shouldAcceptJson() throws SocketTimeoutException, HttpClientException, MalformedURLException { - String response = httpClient.get(serverFake.getUrl(), IHttpClient.NO_TIMEOUT); - assertNotNull(response); - assertTrue(response.indexOf(ACCEPT_APPLICATION_JSON) > 0); - } - - @Test - public void shouldAddServiceVersionToAcceptHeader() throws Exception { - // pre-conditions - String version = "42.0"; - AcceptVersionClientFake clientFake = new AcceptVersionClientFake(version); - // operation - HttpURLConnection connection = clientFake.createConnection(); - // verification - assertThat(clientFake.getAcceptHeader(connection)).endsWith("; version=" + version); - } - - @Test(expected = NotFoundException.class) - public void shouldThrowNotFoundException() throws Exception { - HttpServerFake server = null; - try { - // precondition - this.serverFake.stop(); - server = startHttpServerFake("HTTP/1.0 404 Not Found"); - - // operation - httpClient.get(server.getUrl(), IHttpClient.NO_TIMEOUT); - } finally { - server.stop(); - } - } - - /** - * - * RFC 1945 6.1.1 / Reason Phrase is optional - *

- * 'HTTP/1.1 404 ' is equivalent to HTTP/1.1 404 Not Found' - * https://bugzilla.redhat.com/show_bug.cgi?id=913796 - * - * @throws IOException - */ - @Test(expected = NotFoundException.class) - public void shouldReasonPhraseIsOptional() throws Exception { - HttpServerFake server = null; - try { - // precondition - this.serverFake.stop(); - // RFC 1945 6.1.1 / Reason Phrase is optional - server = startHttpServerFake("HTTP/1.0 404 "); - - // operation - httpClient.get(server.getUrl(), IHttpClient.NO_TIMEOUT); - } finally { - server.stop(); - } - } - - @Test - public void shouldHaveURLInExceptionMessage() throws Exception { - HttpServerFake server = null; - try { - // precondition - this.serverFake.stop(); - // RFC 1945 6.1.1 / Reason Phrase is optional - server = startHttpServerFake("HTTP/1.0 404 Not Found"); - - // operation - httpClient.get(server.getUrl(), IHttpClient.NO_TIMEOUT); - fail("Expected NotFoundException not thrown"); - } catch (NotFoundException e) { - assertTrue(e.getMessage().contains(server.getUrl().toString())); - } finally { - server.stop(); - } - } -//TODO delete me? after moving to apache.httpclient -// @Test -// public void shouldRespectGivenTimeoutPOST() throws Throwable { -// // pre-conditions -// final int timeout = 1000; -// final int serverDelay = timeout * 4; -// assertThat(timeout).isLessThan(IHttpConstants.DEFAULT_READ_TIMEOUT); -// WaitingHttpServerFake serverFake = startWaitingHttpServerFake(serverDelay); -// long startTime = System.currentTimeMillis(); -// // operations -// try { -// httpClient.post(serverFake.getUrl(), new FormUrlEncodedMediaType(), timeout); -// fail("Timeout expected."); -// } catch (SocketTimeoutException e) { -// // assert -// assertThat(System.currentTimeMillis() - startTime).isGreaterThan(timeout) -// .isLessThan(serverDelay) -// .isLessThan(IHttpConstants.DEFAULT_READ_TIMEOUT); -// } finally { -// serverFake.stop(); -// } -// } - - @Test - public void shouldRespectGivenTimeoutDELETE() throws Throwable { - // pre-conditions - final int timeout = 1000; - final int serverDelay = timeout * 4; - assertThat(timeout).isLessThan(IHttpClient.DEFAULT_READ_TIMEOUT); - WaitingHttpServerFake serverFake = startWaitingHttpServerFake(serverDelay); - long startTime = System.currentTimeMillis(); - // operations - try { - httpClient.delete(serverFake.getUrl(), timeout); - fail("Timeout expected."); - } catch (SocketTimeoutException e) { - // assert - assertThat(System.currentTimeMillis() - startTime).isGreaterThan(timeout) - .isLessThan(serverDelay) - .isLessThan(IHttpClient.DEFAULT_READ_TIMEOUT); - } finally { - serverFake.stop(); - } - } - -// @Test -// public void shouldRespectGivenTimeoutPUT() throws Throwable { -// // pre-conditions -// final int timeout = 1000; -// final int serverDelay = timeout * 4; -// assertThat(timeout).isLessThan(IHttpConstants.DEFAULT_READ_TIMEOUT); -// WaitingHttpServerFake serverFake = startWaitingHttpServerFake(serverDelay); -// long startTime = System.currentTimeMillis(); -// // operations -// try { -// httpClient.put(serverFake.getUrl(), new FormUrlEncodedMediaType(), timeout); -// fail("Timeout expected."); -// } catch (SocketTimeoutException e) { -// // assert -// assertThat(System.currentTimeMillis() - startTime).isGreaterThan(timeout) -// .isLessThan(serverDelay) -// .isLessThan(IHttpConstants.DEFAULT_READ_TIMEOUT); -// } finally { -// serverFake.stop(); -// } -// } - - @Test - public void shouldRespectGivenTimeoutGET() throws Throwable { - // pre-conditions - final int timeout = 1000; - final int serverDelay = timeout * 4; - assertThat(timeout).isLessThan(IHttpClient.DEFAULT_READ_TIMEOUT); - WaitingHttpServerFake serverFake = this.startWaitingHttpServerFake(serverDelay); - - long startTime = System.currentTimeMillis(); - // operations - try { - httpClient.get(serverFake.getUrl(), timeout); - fail("Timeout expected."); - } catch (SocketTimeoutException e) { - // assert - assertThat(System.currentTimeMillis() - startTime).isGreaterThan(timeout) - .isLessThan(serverDelay) - .isLessThan(IHttpClient.DEFAULT_READ_TIMEOUT); - } finally { - serverFake.stop(); - } - } - - @Test - public void shouldFallbackToOpenShiftTimeout() throws Throwable { - // pre-conditions - final int timeout = 1000; - final int serverDelay = timeout * 15; - assertThat(timeout).isLessThan(IHttpClient.DEFAULT_READ_TIMEOUT); - System.setProperty(IHttpClient.SYSPROP_OPENSHIFT_READ_TIMEOUT, String.valueOf(timeout)); - WaitingHttpServerFake serverFake = startWaitingHttpServerFake(serverDelay); - long startTime = System.currentTimeMillis(); - // operations - try { - httpClient.get(serverFake.getUrl(), IHttpClient.NO_TIMEOUT); - fail("Timeout expected."); - } catch (SocketTimeoutException e) { - // assert - assertThat(System.currentTimeMillis() - startTime).isGreaterThan(timeout) - .isLessThan(serverDelay) - .isLessThan(IHttpClient.DEFAULT_READ_TIMEOUT); - } finally { - serverFake.stop(); - System.clearProperty(IHttpClient.SYSPROP_OPENSHIFT_READ_TIMEOUT); - } - } - -// @Test -// public void shouldRespectDefaultTimeout() throws Throwable { -// // pre-conditions -// final int timeout = 1000; -// final int serverDelay = timeout * 10000; -// IOpenShiftConfiguration configuration = new OpenShiftConfigurationFake(null,null,null,"5000"); -// IHttpClient httpClient = new UrlConnectionHttpClientBuilder() -// .setAcceptMediaType(ACCEPT_APPLICATION_JSON) -// .setUserAgent("com.openshift.client.test") -// .setConfigTimeout(configuration.getTimeout()) -// .client(); -// WaitingHttpServerFake serverFake = startWaitingHttpServerFake(serverDelay); -// long startTime = System.currentTimeMillis(); -// // operations -// try { -// httpClient.get(serverFake.getUrl(), IHttpConstants.NO_TIMEOUT); -// fail("Timeout expected."); -// } catch (SocketTimeoutException e) { -// // assert -// assertThat(System.currentTimeMillis() - startTime) -// .isGreaterThan(configuration.getTimeout() - 20) -// .isLessThan(configuration.getTimeout() + 20); -// } finally { -// serverFake.stop(); -// } -// } - - - private HttpServerFake startHttpServerFake(String statusLine) throws Exception { - int port = new Random().nextInt(9 * 1024) + 1024; - HttpServerFake serverFake = null; - if (statusLine == null) { - serverFake = new HttpServerFake(port); - } else { - serverFake = new HttpServerFake(port, null, statusLine); - } - serverFake.start(); - return serverFake; - } - - private HttpsServerFake startHttpsServerFake(String statusLine) throws Exception { - int port = new Random().nextInt(9 * 1024) + 1024; - HttpsServerFake serverFake = null; - if (statusLine == null) { - serverFake = new HttpsServerFake(port); - } else { - serverFake = new HttpsServerFake(port, null, statusLine); - } - serverFake.start(); - return serverFake; - } - - private WaitingHttpServerFake startWaitingHttpServerFake(int delay) throws Exception { - WaitingHttpServerFake serverFake = new WaitingHttpServerFake(delay); - serverFake.start(); - return serverFake; - } - - private class AcceptVersionClientFake extends UrlConnectionHttpClientFake { - - public AcceptVersionClientFake(String acceptVersion) { - super(null, acceptVersion); - } - - public String getAcceptHeader(HttpURLConnection connection) { - return connection.getRequestProperty(IHttpConstants.PROPERTY_ACCEPT); - } - } - - private abstract class UrlConnectionHttpClientFake extends UrlConnectionHttpClient { - private UrlConnectionHttpClientFake(String userAgent, String acceptVersion) { - super(userAgent, IHttpConstants.MEDIATYPE_APPLICATION_JSON, acceptVersion, - null, IHttpClient.NO_TIMEOUT, null); - } - - private UrlConnectionHttpClientFake(String userAgent, String acceptVersion, ISSLCertificateCallback callback) { - super(userAgent, IHttpConstants.MEDIATYPE_APPLICATION_JSON, acceptVersion, - callback,IHttpClient.NO_TIMEOUT, null); - } - - public HttpURLConnection createConnection() throws IOException, KeyStoreException { - return super.createConnection(new URL("http://localhost"), userAgent, acceptedVersion, acceptedMediaType, sslAuthorizationCallback, NO_TIMEOUT); - } - }; - -} diff --git a/src/test/java/com/openshift/internal/restclient/http/HttpMethodTest.java b/src/test/java/com/openshift/internal/restclient/http/HttpMethodTest.java deleted file mode 100644 index 3a9094e6..00000000 --- a/src/test/java/com/openshift/internal/restclient/http/HttpMethodTest.java +++ /dev/null @@ -1,30 +0,0 @@ - /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import static org.junit.Assert.*; - -import org.junit.Test; - -/** - * @author Andre Dietisheim - */ -public class HttpMethodTest { - - @Test - public void hasValueForKnownValueShouldReturnTrue() { - assertTrue(HttpMethod.hasValue("POST")); - assertTrue(HttpMethod.hasValue("pOst")); - } - @Test - public void hasValueForUnKnownValueShouldReturnFalse() { - assertFalse(HttpMethod.hasValue("afdadsfads")); - } - -} diff --git a/src/test/java/com/openshift/internal/restclient/http/UrlConnectionHttpClientTest.java b/src/test/java/com/openshift/internal/restclient/http/UrlConnectionHttpClientTest.java deleted file mode 100644 index 9c7acf14..00000000 --- a/src/test/java/com/openshift/internal/restclient/http/UrlConnectionHttpClientTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.internal.restclient.http; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -import java.net.HttpURLConnection; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import com.openshift.internal.restclient.http.UrlConnectionHttpClient; -import com.openshift.restclient.authorization.IAuthorizationStrategy; -import com.openshift.restclient.authorization.IRequest; - -/** - * @author Jeff Cantrill - */ -@RunWith(MockitoJUnitRunner.class) -public class UrlConnectionHttpClientTest { - - @Mock - private IAuthorizationStrategy strategy; - private UrlConnectionHttpClient client; - @Mock - private HttpURLConnection connection; - - @Before - public void setUp(){ - client = new UrlConnectionHttpClient("testagent", "application/json", "1"); - } - - @Test - public void nullAuthStrategyShouldNotThrowNPEWhenSetAuthorization() { - client.setAuthorizationStrategy(null); - client.setAuthorization(connection ); - verify(connection, never()).setRequestProperty(anyString(), anyString()); - } - - @Test - public void setAuthorizationWhenStrategyIsSetShouldUseTheStrategy() { - client.setAuthorizationStrategy(strategy); - - client.setAuthorization(connection); - verify(connection, never()).setRequestProperty(anyString(), anyString()); - verify(strategy).authorize(any(IRequest.class)); - } - -} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ListTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ListTest.java index b20f296e..841e0317 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ListTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ListTest.java @@ -50,11 +50,13 @@ private IList createList(Samples sample) { } @Test - public void testItemKindsAreDefined() { + public void testItemKindAndApiVersionAreDefined() { IList resource = createList(Samples.V1_BUILD_CONFIG_LIST); Collection items = resource.getItems(); assertTrue("Expected to be entries in the list",items.size() >0 ); - assertEquals(ResourceKind.BUILD_CONFIG, items.iterator().next().getKind()); + IResource bc = items.iterator().next(); + assertEquals(ResourceKind.BUILD_CONFIG, bc.getKind()); + assertEquals("v1", bc.getApiVersion()); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/TemplateTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/TemplateTest.java index 6e9581cc..4ff73cf8 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/TemplateTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/TemplateTest.java @@ -48,7 +48,7 @@ public void testGetApiVersion() { @Test public void testGetItems() { - assertEquals("Exp. the number of items to be more than zero", 8, template.getItems().size()); + assertEquals("Exp. the number of items to be more than zero", 8, template.getObjects().size()); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java new file mode 100644 index 00000000..b894bfb5 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.okhttp; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import org.apache.commons.lang.StringUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.openshift.restclient.authorization.IAuthorizationContext; + +import okhttp3.Headers; +import okhttp3.Request; +import okhttp3.Request.Builder; + +@RunWith(MockitoJUnitRunner.class) +public class BasicChallangeHandlerTest { + + @Mock + private IAuthorizationContext context; + private BasicChallangeHandler handler; + + @Before + public void setUp() throws Exception { + this.handler = new BasicChallangeHandler(context); + + when(context.getUserName()).thenReturn("username"); + when(context.getPassword()).thenReturn("password"); + } + + @Test + public void testCanHandle() { + assertTrue(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "basic"))); + assertTrue(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "bAsIC"))); + assertFalse(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "foobar"))); + assertFalse(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, ""))); + assertFalse(handler.canHandle(givenHeader("key","value"))); + } + + @Test + public void testHandleChallange() { + Builder builder = new Request.Builder() + .url("http://foo"); + Request request = handler.handleChallange(builder).build(); + String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); + assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); + assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); + } + + private Headers givenHeader(String name, String value) { + return new Headers.Builder() + .add(name, value) + .build(); + } +} diff --git a/src/test/java/com/openshift/restclient/authorization/BasicAuthorizationStrategyTest.java b/src/test/java/com/openshift/restclient/authorization/BasicAuthorizationStrategyTest.java deleted file mode 100644 index 40ea1e54..00000000 --- a/src/test/java/com/openshift/restclient/authorization/BasicAuthorizationStrategyTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.verify; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import com.openshift.restclient.utils.Base64Coder; - -/** - * @author Jeff Cantrill - */ -@RunWith(MockitoJUnitRunner.class) -public class BasicAuthorizationStrategyTest { - - @Mock - private IRequest request; - private BasicAuthorizationStrategy strategy; - - @Before - public void setup(){ - strategy= new BasicAuthorizationStrategy("aUserName", "aPassword",null); - } - - @Test - public void testAuthorize() { - String usernamePassword = String.format("Basic %s", Base64Coder.encode("aUserName:aPassword")); - strategy.authorize(request); - verify(request).setProperty(eq("Authorization"), eq(usernamePassword)); - } - - @Test - public void BasicStrategyShouldEqualBasicStrategyWithDifferentUsername() { - assertThat(new BasicAuthorizationStrategy("aUsername", "aPassword", null)) - .isNotEqualTo(new BasicAuthorizationStrategy("differentUsername", "aPassword", null)); - } - - @Test - public void BasicStrategyShouldEqualBasicStrategyWithDifferentToken() { - assertThat(new BasicAuthorizationStrategy("aUsername", "aPassword", "123")) - .isEqualTo(new BasicAuthorizationStrategy("aUsername", "aPassword", "234")); - } - - @Test - public void BasicStrategyShouldEqualBasicStrategyWithDifferentPassword() { - assertThat(new BasicAuthorizationStrategy("aUsername", "aPassword", null)) - .isEqualTo(new BasicAuthorizationStrategy("aUsername", "differentPassword", null)); - } - - @Test - public void BasicStrategyShouldNotEqualNonBasicStrategy() { - assertThat(new BasicAuthorizationStrategy("aUsername", "aPassword", null)) - .isNotEqualTo(new IAuthorizationStrategy() { - - - @Override - public String getUsername() { - return null; - } - - @Override - public String getToken() { - return null; - } - - @Override - public void authorize(IRequest request) { - } - - @Override - public void accept(IAuthorizationStrategyVisitor visitor) { - } - }); - } -} diff --git a/src/test/java/com/openshift/restclient/authorization/TokenAuthorizationStrategyTest.java b/src/test/java/com/openshift/restclient/authorization/TokenAuthorizationStrategyTest.java deleted file mode 100644 index a7a424cb..00000000 --- a/src/test/java/com/openshift/restclient/authorization/TokenAuthorizationStrategyTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.verify; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -/** - * @author Jeff Cantrill - */ -@RunWith(MockitoJUnitRunner.class) -public class TokenAuthorizationStrategyTest { - - @Mock - private IRequest request; - private TokenAuthorizationStrategy strategy; - - @Before - public void setup(){ - strategy = new TokenAuthorizationStrategy("123"); - } - - @Test - public void testAuthorize() { - strategy.authorize(request); - - verify(request).setProperty(eq("Authorization"), eq("Bearer 123")); - } - - @Test - public void TokenStrategiesShoulEqualTokenStrategyWithDifferentToken() { - assertThat(new TokenAuthorizationStrategy("123")).isEqualTo(new TokenAuthorizationStrategy("42")); - } - - @Test - public void TokenStrategiesWithSameTokensShouldEqual() { - assertThat(new TokenAuthorizationStrategy("123")).isEqualTo(new TokenAuthorizationStrategy("123")); - } - - @Test - public void TokenStrategiesShoulNotEqualTokenStrategyWithDifferentUsername() { - TokenAuthorizationStrategy tokenStrategy1 = new TokenAuthorizationStrategy("123", "aUsername"); - TokenAuthorizationStrategy tokenStrategy2 = new TokenAuthorizationStrategy("123", "differentUser"); - assertThat(tokenStrategy1).isNotEqualTo(tokenStrategy2); - } - - @Test - public void TokenStrategiesShoulEqualTokenStrategyWithSameUsernameAndSameToken() { - TokenAuthorizationStrategy tokenStrategy1 = new TokenAuthorizationStrategy("123", "aUser"); - TokenAuthorizationStrategy tokenStrategy2 = new TokenAuthorizationStrategy("123", "aUser"); - assertThat(tokenStrategy1).isEqualTo(tokenStrategy2); - } - - @Test - public void TokenStrategyShouldNotEqualNonTokenStrategy() { - assertThat(new TokenAuthorizationStrategy("123")) - .isNotEqualTo(new IAuthorizationStrategy() { - - @Override - public String getToken() { - return null; - } - - - @Override - public String getUsername() { - return null; - } - - @Override - public void authorize(IRequest request) { - } - - @Override - public void accept(IAuthorizationStrategyVisitor visitor) { - } - }); - } - -} diff --git a/src/test/java/com/openshift/restclient/authorization/URLConnectionAuthorizationRequestTest.java b/src/test/java/com/openshift/restclient/authorization/URLConnectionAuthorizationRequestTest.java deleted file mode 100644 index 44996d9f..00000000 --- a/src/test/java/com/openshift/restclient/authorization/URLConnectionAuthorizationRequestTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ -package com.openshift.restclient.authorization; - -import static org.mockito.Mockito.*; - -import java.net.URLConnection; - -import org.junit.Test; - -import com.openshift.restclient.authorization.URLConnectionRequest; - -/** - * @author Jeff Cantrill - */ -public class URLConnectionAuthorizationRequestTest { - - @Test - public void testSetProperty() { - URLConnection conn = mock(URLConnection.class); - - URLConnectionRequest request = new URLConnectionRequest(conn); - request.setProperty("foo", "bar"); - - verify(conn).setRequestProperty(eq("foo"), eq("bar")); - } - -} diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 90fe625a..4736faf0 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -55,7 +55,9 @@ public enum Samples { V1_CONFIG_MAP_LIST_EMPTY("openshift3/v1_config_map_list_empty.json"), V1_EMPTYDIR_VOLUME_SOURCE("openshift3/v1_empty_dir_volume_source.json"), V1_SECRET_VOLUME_SOURCE("openshift3/v1_secret_volume_source.json"), - V1_PVC_VOLUME_SOURCE("openshift3/v1_pvc_volume_source.json"); + V1_PVC_VOLUME_SOURCE("openshift3/v1_pvc_volume_source.json"), + + V1_DOCKER_IMAGE_MANIFEST("dockerregistry/v1_image_manifest.json"); private static final String SAMPLES_FOLDER = "/samples/"; diff --git a/src/test/resources/openshiftv3IntegrationTest.properties b/src/test/resources/openshiftv3IntegrationTest.properties index 272d35c4..bb93f461 100644 --- a/src/test/resources/openshiftv3IntegrationTest.properties +++ b/src/test/resources/openshiftv3IntegrationTest.properties @@ -1,9 +1,10 @@ -#serverURL=https://127.0.0.1:8443 -serverURL=https://10.1.2.2:8443 +serverURL=https://127.0.0.1:8443 + #osadm policy add-cluster-role-to-user cluster-admin $ADMIN_USER --config=openshift.local.config/master/admin.kubeconfig default.clusteradmin.user=admin default.clusteradmin.password=admin + default.project=int-test default.openshift.location=/home/jeff.cantrill/scripts/oc diff --git a/src/test/resources/samples/dockerregistry/v1_image_manifest.json b/src/test/resources/samples/dockerregistry/v1_image_manifest.json new file mode 100644 index 00000000..7265208d --- /dev/null +++ b/src/test/resources/samples/dockerregistry/v1_image_manifest.json @@ -0,0 +1,38 @@ +{ + "schemaVersion": 1, + "name": "openshift/hello-openshift", + "tag": "latest", + "architecture": "amd64", + "fsLayers": [ + { + "blobSum": "sha256:3617f1cc9f1a693e5bd904855aa07d448aa2b1600fa773396ec7042b456adb71" + }, + { + "blobSum": "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4" + } + ], + "history": [ + { + "v1Compatibility": "{\"architecture\":\"amd64\",\"author\":\"Jessica Forrester \\u003cjforrest@redhat.com\\u003e\",\"config\":{\"Hostname\":\"\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"ExposedPorts\":{\"8080/tcp\":{},\"8888/tcp\":{}},\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":null,\"Image\":\"\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":[\"/hello-openshift\"],\"OnBuild\":null,\"Labels\":{}},\"container\":\"3b9f6b446705b66fd50dee69a24bd956e18798ce259f527917fe336302654d76\",\"container_config\":{\"Hostname\":\"3b9f6b446705\",\"Domainname\":\"\",\"User\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":null,\"Cmd\":null,\"Image\":\"scratch-o9u3gdotxmoitn1v9pcyz7qn\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":[\"/bin/sh\",\"-c\",\"# NOP\"],\"OnBuild\":null,\"Labels\":{}},\"created\":\"2016-06-22T20:14:52.468448916Z\",\"docker_version\":\"1.10.3\",\"id\":\"5f162644b2633962f753b9a09c7783d342c8aaebccaf6270fde68404d2af7a8c\",\"os\":\"linux\",\"parent\":\"3690474eb5b4b26fdfbd89c6e159e8cc376ca76ef48032a30fa6aafd56337880\"}" + }, + { + "v1Compatibility": "{\"id\":\"3690474eb5b4b26fdfbd89c6e159e8cc376ca76ef48032a30fa6aafd56337880\",\"comment\":\"Imported from -\",\"created\":\"2016-06-22T20:14:51.59971969Z\",\"container_config\":{\"Cmd\":[\"\"]}}" + } + ], + "signatures": [ + { + "header": { + "jwk": { + "crv": "P-256", + "kid": "CH7Z:EUDI:ZK45:Z644:ZVCW:AXKU:TNHT:G23N:QUDL:PXLW:4RSV:QTF4", + "kty": "EC", + "x": "ldmqX-aMDXSs3_zCy8co89v6v5CJh9nAskmLW7a4vIw", + "y": "OD9FZrrTo5nBzndcvpwlqrzzoZ4PI4BbYcdvfAvHdbA" + }, + "alg": "ES256" + }, + "signature": "l2qVDJfKpBRtD5Lcuj9RJ8wI2SwfjO6jVnd8q9_zN-dz4EJkF-5Aww7_0gdAz7tV-AmuG9_HIL8fdcDtof-Txg", + "protected": "eyJmb3JtYXRMZW5ndGgiOjE5NDEsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNi0wNi0yM1QxNjowNTowNloifQ" + } + ] +} \ No newline at end of file diff --git a/src/test/resources/samples/openshift3/v1_template.json b/src/test/resources/samples/openshift3/v1_template.json index 09fdf1e3..487fc2ab 100644 --- a/src/test/resources/samples/openshift3/v1_template.json +++ b/src/test/resources/samples/openshift3/v1_template.json @@ -3,25 +3,25 @@ "apiVersion": "v1", "metadata": { "name": "ruby-helloworld-sample", - "namespace": "test", - "selfLink": "/osapi/v1beta3/namespaces/test/templates/ruby-helloworld-sample", - "uid": "1affe776-0fab-11e5-9467-080027893417", - "resourceVersion": "366", - "creationTimestamp": "2015-06-10T19:58:47Z", + "namespace": "myproject", + "selfLink": "/oapi/v1/namespaces/myproject/templates/ruby-helloworld-sample", + "uid": "870dab76-38c7-11e6-8e5e-3c970e32f15a", + "resourceVersion": "86618", + "creationTimestamp": "2016-06-22T22:20:29Z", + "labels": { + "abc": "xyz", + "foo": "bar" + }, "annotations": { "description": "This example shows how to create a simple ruby application in openshift origin v3", "iconClass": "icon-ruby", "tags": "instant-app,ruby,mysql" - }, - "labels" : { - "foo" : "bar", - "abc" : "xyz" } }, "objects": [ { "kind": "Service", - "apiVersion": "v1beta3", + "apiVersion": "v1", "metadata": { "name": "frontend", "creationTimestamp": null @@ -49,7 +49,7 @@ }, { "kind": "Route", - "apiVersion": "v1beta3", + "apiVersion": "v1", "metadata": { "name": "route-edge", "creationTimestamp": null @@ -71,7 +71,7 @@ }, { "kind": "ImageStream", - "apiVersion": "v1beta3", + "apiVersion": "v1", "metadata": { "name": "origin-ruby-sample", "creationTimestamp": null @@ -83,7 +83,7 @@ }, { "kind": "ImageStream", - "apiVersion": "v1beta3", + "apiVersion": "v1", "metadata": { "name": "ruby-20-centos7", "creationTimestamp": null @@ -97,7 +97,7 @@ }, { "kind": "BuildConfig", - "apiVersion": "v1beta3", + "apiVersion": "v1", "metadata": { "name": "ruby-sample-build", "creationTimestamp": null, @@ -154,7 +154,7 @@ }, { "kind": "DeploymentConfig", - "apiVersion": "v1beta3", + "apiVersion": "v1", "metadata": { "name": "frontend", "creationTimestamp": null @@ -282,7 +282,7 @@ }, { "kind": "Service", - "apiVersion": "v1beta3", + "apiVersion": "v1", "metadata": { "name": "database", "creationTimestamp": null @@ -310,7 +310,7 @@ }, { "kind": "DeploymentConfig", - "apiVersion": "v1beta3", + "apiVersion": "v1", "metadata": { "name": "database", "creationTimestamp": null @@ -436,7 +436,7 @@ "description": "database password", "generate": "expression", "from": "[a-zA-Z0-9]{8}", - "required" : true + "required": true }, { "name": "MYSQL_DATABASE", @@ -447,4 +447,4 @@ "labels": { "template": "application-template-stibuild" } -} \ No newline at end of file +} From 0229130663b960fac594bbd96849eac835196d47 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Thu, 7 Jul 2016 16:10:16 -0400 Subject: [PATCH 002/258] fix nullpointer in BasicChallangeHandler when the username is null --- .../restclient/okhttp/BasicChallangeHandler.java | 5 ++++- .../restclient/okhttp/BasicChallangeHandlerTest.java | 11 +++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java index eda87054..c59b9ea4 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java @@ -39,7 +39,10 @@ public boolean canHandle(Headers headers) { @Override public Builder handleChallange(Builder builder) { - StringBuilder value = new StringBuilder(context.getUserName()).append(":"); + StringBuilder value = new StringBuilder(); + if(StringUtils.isNotBlank(context.getUserName())) { + value.append(context.getUserName()).append(":"); + } if(StringUtils.isNotBlank(context.getPassword())) { value.append(context.getPassword()); } diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java index b894bfb5..bb3716d5 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java @@ -59,6 +59,17 @@ public void testHandleChallange() { assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); } + + @Test + public void testHandleChallangeWhenUsernameIsNull() { + when(context.getUserName()).thenReturn(null); + Builder builder = new Request.Builder() + .url("http://foo"); + Request request = handler.handleChallange(builder).build(); + String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); + assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); + assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); + } private Headers givenHeader(String name, String value) { return new Headers.Builder() From e1e1077e6888d810fb39f2748d0645e86a0208d2 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Fri, 8 Jul 2016 15:55:34 -0400 Subject: [PATCH 003/258] [OSJC-263] fix unable to delete OpenShift resources --- .../internal/restclient/DefaultClient.java | 23 ++++++++++++------- .../DefaultClientIntegrationTest.java | 22 +++++++++++++++--- .../restclient/IntegrationTestHelper.java | 2 +- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index d9c66527..38e5a49c 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -193,14 +193,9 @@ public T execute(String method, String kind, String namesp .build(); try { - Request.Builder builder = newRequestBuilderTo(endpoint.toString()); - if(!HttpMethod.GET.toString().equals(method)) { - String json = payload == null ? "" : payload.toJson(true); - builder.method(method.toString(), - RequestBody.create(MediaType.parse(MEDIATYPE_APPLICATION_JSON), json)); - LOGGER.debug("About to send payload: {}", json); - } - Request request = builder.build(); + Request request = newRequestBuilderTo(endpoint.toString()) + .method(method, getPayload(method, payload)) + .build(); LOGGER.debug("About to make {} request: {}", request.method(), request); try(Response result = client.newCall(request).execute()){ String response = result.body().string(); @@ -212,6 +207,18 @@ public T execute(String method, String kind, String namesp } } + private RequestBody getPayload(String method, IResource payload) { + switch(method.toUpperCase()){ + case "GET": + case "DELETE": + return null; + default: + String json = payload == null ? "" : payload.toJson(true); + LOGGER.debug("About to send payload: {}", json); + return RequestBody.create(MediaType.parse(MEDIATYPE_APPLICATION_JSON), json); + } + } + @Override public String getServerReadyStatus() { diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index 9233ec5e..c7d49d99 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -29,7 +29,9 @@ import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.authorization.UnauthorizedException; +import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.build.IBuildConfigBuilder; import com.openshift.restclient.model.project.IProjectRequest; import com.openshift.restclient.model.template.ITemplate; @@ -99,7 +101,7 @@ public void testListTemplates(){ } @Test - public void testResourceLifeCycle() throws MalformedURLException { + public void testResourceLifeCycle() { IProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); @@ -158,8 +160,22 @@ public void testResourceLifeCycle() throws MalformedURLException { assertEquals("Expected there to be only one service returned", 1, services.size()); assertEquals("Expected to get the service with the correct name", service.getName(), services.get(0).getName()); - }catch(OpenShiftException e) { - e.printStackTrace(); + + IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); + IBuildConfig bc = builder.named("test") + .fromGitSource() + .fromGitUrl("https://github.com/openshift/origin.git") + .inContextDir("examples/hello-openshift") + .end() + .usingSourceStrategy() + .fromDockerImage("foo/bar") + .end() + .toImageStreamTag("foo/bar:latest") + .build(); + bc = client.create(bc, project.getNamespace()); + LOG.debug(String.format("Created bc: %s", bc.getName())); + LOG.debug(String.format("Trying to delete bc: %s", bc.getName())); + client.delete(bc); }finally{ cleanUpResource(client, project); cleanUpResource(client, other); diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index a45295d2..68a6ebe9 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -162,7 +162,7 @@ public static void cleanUpResource(IClient client, IResource resource) { LOG.debug(String.format("Deleting resource: %s", resource)); client.delete(resource); } catch (Exception e) { - LOG.error("Exception deleting", e); + LOG.warn("Exception deleting", e); } } From 9c9664808041c485d134326474d7aa34703dcfdd Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Tue, 12 Jul 2016 16:18:23 -0400 Subject: [PATCH 004/258] fix watch client queue --- .../restclient/okhttp/WatchClient.java | 98 +++++++++++-------- .../openshift/restclient/ClientBuilder.java | 11 +++ .../{ => okhttp}/WatchClientTest.java | 20 +++- .../WatchClientIntegrationTest.java | 16 ++- 4 files changed, 100 insertions(+), 45 deletions(-) rename src/test/java/com/openshift/internal/restclient/{ => okhttp}/WatchClientTest.java (64%) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index 642000cd..e9f352f7 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -13,7 +13,10 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.atomic.AtomicReference; import org.apache.commons.lang.StringUtils; @@ -26,6 +29,7 @@ import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IClient; import com.openshift.restclient.IOpenShiftWatchListener; import com.openshift.restclient.IWatcher; import com.openshift.restclient.OpenShiftException; @@ -45,12 +49,13 @@ public class WatchClient implements IWatcher, IHttpConstants { + private static final int CODE_NORAMAL_STOP = 1000; private static final Logger LOGGER = LoggerFactory.getLogger(WatchClient.class); private DefaultClient client; private OkHttpClient okClient; - private static AtomicReference status = new AtomicReference<>(Status.Stopped); - private WebSocket wsClient; + private AtomicReference status = new AtomicReference<>(Status.Stopped); private IApiTypeMapper typeMappings; + private Map endpointMap = Collections.synchronizedMap(new HashMap<>()); private enum Status { Started, @@ -67,46 +72,45 @@ public WatchClient(DefaultClient client, IApiTypeMapper typeMapper, OkHttpClient @Override public void stop() { - if(status.get() == Status.Stopping - || status.get() == Status.Stopped) { - return; + if(status.compareAndSet(Status.Started, Status.Stopping)) { + Map endpoints = new HashMap<>(endpointMap); + endpointMap.clear(); + endpoints.values().forEach(w->w.close()); + status.set(Status.Stopped); } - try { - if(wsClient != null) { - wsClient.close(1000, "Client was asked to stop."); - wsClient = null; - status.set(Status.Stopped); - } - } catch (Exception e) { - LOGGER.debug("Unable to stop the watch client",e); - } } public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatchListener listener) { - try { - for (String kind : kinds) { - WatchEndpoint socket = new WatchEndpoint(listener, kind); - final String resourceVersion = getResourceVersion(kind, namespace, socket); - - final String endpoint = new URLBuilder(client.getBaseURL(), this.typeMappings) - .kind(kind) - .namespace(namespace) - .watch() - .addParmeter(ResourcePropertyKeys.RESOURCE_VERSION, resourceVersion) - .websocket(); - Request request = client.newRequestBuilderTo(endpoint) - .header(PROPERTY_ORIGIN, client.getBaseURL().toString()) - .header(PROPERTY_USER_AGENT, "openshift-restclient-java") - .build(); - WebSocketCall call = WebSocketCall.create(okClient, request); - call.enqueue(socket); - } - } catch (Exception e) { + if(status.compareAndSet(Status.Stopped, Status.Starting)) { try { - throw ResponseCodeInterceptor.createOpenShiftException(client, 500, String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), null, e); - } catch (IOException e1) { - throw new OpenShiftException(e1, "IOException trying to create an OpenShift specific exception"); + for (String kind : kinds) { + WatchEndpoint socket = new WatchEndpoint(client, listener, kind); + final String resourceVersion = getResourceVersion(kind, namespace, socket); + + final String endpoint = new URLBuilder(client.getBaseURL(), this.typeMappings) + .kind(kind) + .namespace(namespace) + .watch() + .addParmeter(ResourcePropertyKeys.RESOURCE_VERSION, resourceVersion) + .websocket(); + Request request = client.newRequestBuilderTo(endpoint) + .header(PROPERTY_ORIGIN, client.getBaseURL().toString()) + .header(PROPERTY_USER_AGENT, "openshift-restclient-java") + .build(); + WebSocketCall call = WebSocketCall.create(okClient.newBuilder().build(), request); + endpointMap.put(kind, socket); + call.enqueue(socket); + } + status.set(Status.Started); + } catch (Exception e) { + endpointMap.clear(); + status.set(Status.Stopped); + try { + throw ResponseCodeInterceptor.createOpenShiftException(client, 0, String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), null, e); + } catch (IOException e1) { + throw new OpenShiftException(e1, "IOException trying to create an OpenShift specific exception"); + } } } return this; @@ -121,15 +125,29 @@ private String getResourceVersion(String kind, String namespace, WatchEndpoint e return list.getResourceVersion(); } - private class WatchEndpoint implements WebSocketListener{ + static class WatchEndpoint implements WebSocketListener{ private IOpenShiftWatchListener listener; private List resources; private final String kind; + private final IClient client; + private WebSocket wsClient; - public WatchEndpoint(IOpenShiftWatchListener listener, String kind) { + public WatchEndpoint(IClient client, IOpenShiftWatchListener listener, String kind) { this.listener = listener; this.kind = kind; + this.client = client; + } + + void close() { + try { + if(wsClient != null) { + wsClient.close(CODE_NORAMAL_STOP, "Client was asked to stop."); + wsClient = null; + } + } catch (Exception e) { + LOGGER.debug("Unable to stop the watch client",e); + } } public void setResources(List resources) { @@ -140,12 +158,11 @@ public void setResources(List resources) { public void onClose(int statusCode, String reason) { LOGGER.debug("WatchSocket closed for kind: {}, code: {}, reason: {}", new Object[]{kind, statusCode, reason}); listener.disconnected(); - status.set(Status.Stopped); } @Override public void onFailure(IOException err, Response response) { - LOGGER.debug("WatchSocket Error for kind " + kind, err); + LOGGER.debug("WatchSocket Error for kind {}: {}", kind, err); try { if(response == null) { listener.error(ResponseCodeInterceptor.createOpenShiftException(client, 0, "", "", err)); @@ -175,7 +192,6 @@ public void onMessage(ResponseBody body) throws IOException { @Override public void onOpen(WebSocket socket, Response response) { LOGGER.debug("WatchSocket connected for {}", kind); - status.set(Status.Started); wsClient = socket; listener.connected(resources); } diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 2db125c8..c802341a 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -33,6 +33,7 @@ import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.utils.SSLUtils; +import okhttp3.Dispatcher; import okhttp3.OkHttpClient; /** @@ -51,6 +52,9 @@ public class ClientBuilder { private String token; private String password; + private int maxRequests = 64; + private int maxRequestsPerHost = 10; + private int readTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; private TimeUnit readTimeoutUnit = TimeUnit.MILLISECONDS; private int connectTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; @@ -150,10 +154,17 @@ public IClient build() { ResponseCodeInterceptor responseCodeInterceptor = new ResponseCodeInterceptor(); OpenShiftAuthenticator authenticator = new OpenShiftAuthenticator(); + Dispatcher dispatcher = new Dispatcher(); + + //hiding these for now to since not certain + //if we need to really expose them. + dispatcher.setMaxRequests(maxRequests); + dispatcher.setMaxRequestsPerHost(maxRequestsPerHost); OkHttpClient.Builder builder = new OkHttpClient.Builder() .addInterceptor(responseCodeInterceptor) .authenticator(authenticator) + .dispatcher(dispatcher) .readTimeout(readTimeout, readTimeoutUnit) .writeTimeout(writeTimeout, writeTimeoutUnit) .connectTimeout(connectTimeout, connectTimeoutUnit) diff --git a/src/test/java/com/openshift/internal/restclient/WatchClientTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java similarity index 64% rename from src/test/java/com/openshift/internal/restclient/WatchClientTest.java rename to src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java index d8b68298..3d754137 100644 --- a/src/test/java/com/openshift/internal/restclient/WatchClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java @@ -8,20 +8,38 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient; +package com.openshift.internal.restclient.okhttp; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.*; + +import java.io.IOException; import org.junit.Test; +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.okhttp.WatchClient.WatchEndpoint; +import com.openshift.restclient.IOpenShiftWatchListener; +import com.openshift.restclient.ResourceKind; import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; /** * @author Andre Dietisheim */ public class WatchClientTest { + + @Test + public void testOnFailureCallBackNotifiesListener() { + DefaultClient client = null; + + IOpenShiftWatchListener listener = mock(IOpenShiftWatchListener.class); + + WatchEndpoint endpoint = new WatchEndpoint(client, listener, ResourceKind.BUILD); + endpoint.onFailure(new IOException(), null); + verify(listener).error(any(Throwable.class)); + } @Test public void changeTypeShouldEqualSameChangeType() { diff --git a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java index 468f3990..c501982e 100644 --- a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java +++ b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java @@ -39,6 +39,16 @@ public class WatchClientIntegrationTest { private IntegrationTestHelper helper = new IntegrationTestHelper(); private IClient client; private IResource project; + public static final String [] KINDS = new String[] { + ResourceKind.BUILD_CONFIG, + ResourceKind.DEPLOYMENT_CONFIG, + ResourceKind.SERVICE, + ResourceKind.POD, + ResourceKind.REPLICATION_CONTROLLER, + ResourceKind.BUILD, + ResourceKind.IMAGE_STREAM, + ResourceKind.ROUTE + }; private ExecutorService service; private boolean isError; @@ -58,10 +68,10 @@ public void teardown() { } @SuppressWarnings("rawtypes") - @Test(timeout=30000) + @Test(timeout=60000) public void test() throws Exception{ List results = new ArrayList(); - CountDownLatch latch = new CountDownLatch(2); + CountDownLatch latch = new CountDownLatch(KINDS.length); IOpenShiftWatchListener listener = new IOpenShiftWatchListener() { @SuppressWarnings("unchecked") @@ -90,7 +100,7 @@ public void error(Throwable err) { IWatcher watcher = null; try { - watcher = client.watch(project.getName(), listener, ResourceKind.SERVICE, ResourceKind.POD); + watcher = client.watch(project.getName(), listener, KINDS); latch.await(); assertFalse("Expected connection without error",isError); IService service = client.getResourceFactory().stub(ResourceKind.SERVICE,"hello-world", project.getName()); From a821fd51cbec9fa9ea9f25a6f4b2603b3ba5271e Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Thu, 7 Jul 2016 14:57:55 -0400 Subject: [PATCH 005/258] [JBIDE-22644] Fix oc binary secure flag issue by clearing env vars --- .../capability/resources/AbstractOpenShiftBinaryCapability.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index b5f82a8d..5bddd03b 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -155,6 +155,7 @@ private void startProcess(final String location, final OpenShiftBinaryOption... String cmdLine = new StringBuilder(location).append(' ').append(buildArgs(Arrays.asList(options))).toString(); String[] args = StringUtils.split(cmdLine, " "); ProcessBuilder builder = new ProcessBuilder(args); + builder.environment().clear(); LOG.debug("OpenShift binary args: {}", builder.command()); try { process = builder.start(); From 50285d05451c0a49966716c42396842b2cd652b0 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Mon, 25 Jul 2016 16:39:11 -0400 Subject: [PATCH 006/258] explicitly call disconnect when closing and cancel wscall in attempt to force threads to shutdown --- .../internal/restclient/okhttp/WatchClient.java | 13 ++++++++++++- .../com/openshift/restclient/ClientBuilder.java | 9 +-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index e9f352f7..547f047d 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -99,6 +99,7 @@ public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatc .header(PROPERTY_USER_AGENT, "openshift-restclient-java") .build(); WebSocketCall call = WebSocketCall.create(okClient.newBuilder().build(), request); + socket.setCall(call); endpointMap.put(kind, socket); call.enqueue(socket); } @@ -132,6 +133,7 @@ static class WatchEndpoint implements WebSocketListener{ private final String kind; private final IClient client; private WebSocket wsClient; + private WebSocketCall call; public WatchEndpoint(IClient client, IOpenShiftWatchListener listener, String kind) { this.listener = listener; @@ -139,14 +141,23 @@ public WatchEndpoint(IClient client, IOpenShiftWatchListener listener, String ki this.client = client; } + public void setCall(WebSocketCall call) { + this.call = call; + } + void close() { try { if(wsClient != null) { wsClient.close(CODE_NORAMAL_STOP, "Client was asked to stop."); - wsClient = null; } + if(call != null) { + call.cancel(); + } + listener.disconnected(); } catch (Exception e) { LOGGER.debug("Unable to stop the watch client",e); + }finally { + wsClient = null; } } diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index c802341a..4be0088f 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -134,14 +134,7 @@ public ClientBuilder withConnectTimeout(int connectInMillis) { } /** - * Build a client using the config loading rules defined http://janetkuo.github.io/kubernetes/v1.0/docs/user-guide/kubeconfig-file.html. Brief summary - * of loading order: - * - * 1. use explicit values set in builder - * a. username/token - * b. authStrategy - * 2. currentContext of config file located at $KUBECONFIG - * 3. currentContext of config file located at ~/.kube/config + * Build a client * * @return * @throws KeyManagementException From 75ba3834205ff2eebc8082c9a5fb755b24b765aa Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Tue, 26 Jul 2016 13:06:23 -0400 Subject: [PATCH 007/258] [OSJC-262] Retrieve logs via websocket --- .../internal/restclient/ApiTypeMapper.java | 3 +- .../internal/restclient/DefaultClient.java | 3 + .../internal/restclient/URLBuilder.java | 5 + .../capability/CapabilityInitializer.java | 3 + .../resources/PodLogRetrievalAsync.java | 145 ++++++++++++++++++ .../restclient/okhttp/WatchClient.java | 4 +- .../restclient/okhttp/WebSocketAdapter.java | 48 ++++++ .../openshift/restclient/IApiTypeMapper.java | 2 +- .../restclient/capability/IStoppable.java | 26 ++++ .../resources/IPodLogRetrievalAsync.java | 143 +++++++++++++++++ .../restclient/http/IHttpConstants.java | 2 + .../internal/restclient/URLBuilderTest.java | 8 +- .../IPodLogRetrievalAsyncOptionsTest.java | 69 +++++++++ .../PodLogRetrievalAsyncIntegrationTest.java | 90 +++++++++++ .../resources/PodLogRetrievalAsyncTest.java | 103 +++++++++++++ 15 files changed, 649 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java create mode 100644 src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java create mode 100644 src/main/java/com/openshift/restclient/capability/IStoppable.java create mode 100644 src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/IPodLogRetrievalAsyncOptionsTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index 76530157..2b807fd3 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -33,6 +33,7 @@ import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.UnsupportedEndpointException; import com.openshift.restclient.model.IResource; import okhttp3.OkHttpClient; @@ -80,7 +81,7 @@ public IVersionedApiResource getEndpointFor(String apiVersion, String kind) { init(); IVersionedApiResource apiresource = endpointFor(apiVersion, kind); if(apiresource == null) { - throw new OpenShiftException("No endpoint found for %s, version %s", kind, apiVersion); + throw new UnsupportedEndpointException("No endpoint found for %s, version %s", kind, apiVersion); } return apiresource; } diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 38e5a49c..da0954c4 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -372,6 +372,9 @@ public boolean equals(Object obj) { @SuppressWarnings("unchecked") @Override public T adapt(Class klass) { + if(DefaultClient.class.equals(klass)){ + return (T) this; + } if(OkHttpClient.class.equals(klass)) { return (T) this.client; } diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index 57ddf2fa..a5ff4614 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -203,4 +203,9 @@ public String websocket() { return url; } + public URLBuilder addParameters(Map params) { + params.forEach((k,v)->addParmeter(k, v)); + return this; + } + } diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index 5cf8712b..cf1ad636 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -20,6 +20,7 @@ import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPodLogRetrieval; import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPortForwarding; import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryRSync; +import com.openshift.internal.restclient.capability.resources.PodLogRetrievalAsync; import com.openshift.internal.restclient.capability.resources.ProjectTemplateListCapability; import com.openshift.internal.restclient.capability.resources.ProjectTemplateProcessing; import com.openshift.internal.restclient.capability.resources.PropertyAccessCapability; @@ -39,6 +40,7 @@ import com.openshift.restclient.capability.resources.IDeploymentTraceability; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; import com.openshift.restclient.capability.resources.IPodLogRetrieval; +import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; import com.openshift.restclient.capability.resources.IPortForwardable; import com.openshift.restclient.capability.resources.IProjectTemplateList; import com.openshift.restclient.capability.resources.IProjectTemplateProcessing; @@ -103,6 +105,7 @@ public static void initializeCapabilities(Map, ICap public static void initializeCapabilities(Map, ICapability> capabilities, IPod pod, IClient client){ initializeCapability(capabilities, IPortForwardable.class, new OpenShiftBinaryPortForwarding(pod, client)); initializeCapability(capabilities, IPodLogRetrieval.class, new OpenShiftBinaryPodLogRetrieval(pod, client)); + initializeCapability(capabilities, IPodLogRetrievalAsync.class, new PodLogRetrievalAsync(pod, client)); initializeCapability(capabilities, IRSyncable.class, new OpenShiftBinaryRSync(client)); } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java new file mode 100644 index 00000000..e4db009a --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java @@ -0,0 +1,145 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.URLBuilder; +import com.openshift.internal.restclient.okhttp.WebSocketAdapter; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.UnsupportedEndpointException; +import com.openshift.restclient.capability.IStoppable; +import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.model.IPod; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.ws.WebSocket; +import okhttp3.ws.WebSocketCall; + +/** + * Impl of Pod log retrieval using websocket + * @author jeff.cantrill + * + */ +public class PodLogRetrievalAsync implements IPodLogRetrievalAsync{ + + private static final Logger LOG = LoggerFactory.getLogger(PodLogRetrievalAsync.class); + private static final String CAPABILITY = "log"; + private final IPod pod; + private final DefaultClient client; + private final IApiTypeMapper mapper; + + public PodLogRetrievalAsync(IPod pod, IClient client) { + this.pod = pod; + this.client = client.adapt(DefaultClient.class); + this.mapper = client.adapt(IApiTypeMapper.class); + } + + @Override + public boolean isSupported() { + if(client != null && mapper != null) { + try { + return mapper.getEndpointFor(pod.getApiVersion(), pod.getKind()).isSupported(CAPABILITY); + }catch(UnsupportedEndpointException e) { + //endpoint not found for version/kind + } + } + return false; + } + + @Override + public String getName() { + return PodLogRetrievalAsync.class.getSimpleName(); + } + + @Override + public IStoppable start(IPodLogListener listener) { + return start(listener, null); + } + + @Override + public IStoppable start(IPodLogListener listener, Options options) { + Map parameters = options != null ? options.getMap() : new HashMap<>(); + PodLogListenerAdapter adapter = new PodLogListenerAdapter(listener); + + OkHttpClient okClient = client.adapt(OkHttpClient.class); + final String endpoint = new URLBuilder(client.getBaseURL(), mapper) + .kind(pod.getKind()) + .namespace(pod.getNamespace()) + .name(pod.getName()) + .subresource(CAPABILITY) + .addParameters(parameters) + .websocket(); + Request request = client.newRequestBuilderTo(endpoint) + .build(); + WebSocketCall call = WebSocketCall.create(okClient, request); + call.enqueue(adapter); + + return adapter; + } + + static class PodLogListenerAdapter extends WebSocketAdapter implements IStoppable{ + + private final IPodLogListener listener; + private WebSocket wsClient; + private AtomicBoolean open = new AtomicBoolean(false); + + public PodLogListenerAdapter(IPodLogListener listener) { + this.listener = listener; + } + + @Override + public void stop() { + try { + if(open.get()) { + wsClient.close(IHttpConstants.STATUS_NORMAL_STOP, "Client asking to stop."); + } + } catch (Exception e) { + LOG.debug("Unable to stop the watch client",e); + }finally { + wsClient = null; + } + } + + @Override + public void onOpen(WebSocket webSocket, Response response) { + if(open.compareAndSet(false, true)) { + wsClient = webSocket; + listener.onOpen(); + } + } + + @Override + public void onClose(int code, String reason) { + if(open.compareAndSet(true, false)) { + listener.onClose(code, reason); + } + } + + @Override + public void onMessage(ResponseBody message) throws IOException { + listener.onMessage(message.string()); + } + + } +} diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index 547f047d..b502e1ee 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -49,7 +49,6 @@ public class WatchClient implements IWatcher, IHttpConstants { - private static final int CODE_NORAMAL_STOP = 1000; private static final Logger LOGGER = LoggerFactory.getLogger(WatchClient.class); private DefaultClient client; private OkHttpClient okClient; @@ -148,7 +147,8 @@ public void setCall(WebSocketCall call) { void close() { try { if(wsClient != null) { - wsClient.close(CODE_NORAMAL_STOP, "Client was asked to stop."); + wsClient.close(STATUS_NORMAL_STOP, "Client was asked to stop."); + wsClient = null; } if(call != null) { call.cancel(); diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java b/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java new file mode 100644 index 00000000..7f20eebe --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.okhttp; + +import java.io.IOException; + +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.ws.WebSocket; +import okhttp3.ws.WebSocketListener; +import okio.Buffer; + +/** + * Adapter to WebSocketListener + * @author jeff.cantrill + * + */ +public class WebSocketAdapter implements WebSocketListener{ + + @Override + public void onOpen(WebSocket webSocket, Response response) { + } + + @Override + public void onFailure(IOException e, Response response) { + } + + @Override + public void onMessage(ResponseBody message) throws IOException { + } + + @Override + public void onPong(Buffer payload) { + } + + @Override + public void onClose(int code, String reason) { + } + +} \ No newline at end of file diff --git a/src/main/java/com/openshift/restclient/IApiTypeMapper.java b/src/main/java/com/openshift/restclient/IApiTypeMapper.java index fb1e06f8..2bfeb347 100644 --- a/src/main/java/com/openshift/restclient/IApiTypeMapper.java +++ b/src/main/java/com/openshift/restclient/IApiTypeMapper.java @@ -29,7 +29,7 @@ public interface IApiTypeMapper { * @param version the apiVersion, null or empty is best guess * @param kind * @return - * @throws OpenShiftException if unable to determine the endpoint for the given kind + * @throws UnsupportedEndpointException if unable to determine the endpoint for the given kind */ IVersionedApiResource getEndpointFor(String apiVersion, String kind); diff --git a/src/main/java/com/openshift/restclient/capability/IStoppable.java b/src/main/java/com/openshift/restclient/capability/IStoppable.java new file mode 100644 index 00000000..82952e90 --- /dev/null +++ b/src/main/java/com/openshift/restclient/capability/IStoppable.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.capability; + +/** + * Handle to something that can be + * explicitily stopped or terminated + * + * @author jeff.cantrill + * + */ +public interface IStoppable { + + /** + * Stop the process + */ + void stop(); +} diff --git a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java new file mode 100644 index 00000000..ff4fabf3 --- /dev/null +++ b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.capability.resources; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; + +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.capability.IStoppable; + +/** + * Retrieve logs in an async call + * @author jeff.cantrill + * + */ +public interface IPodLogRetrievalAsync extends ICapability{ + + /** + * Start retrieving logs using the given listener and options + * @param listener + * @return A Handle to allow termination of log streaming + */ + IStoppable start(IPodLogListener listener); + + /** + * Start retrieving logs using the given listener and options + * @param listener + * @param options options for retrieving logs + * @return A Handle to allow termination of log streaming + */ + IStoppable start(IPodLogListener listener, Options options); + + + /** + * A callback for log messages + * @author jeff.cantrill + * + */ + interface IPodLogListener{ + + /** + * Callback received on initial connection + */ + void onOpen(); + + /** + * A log message + * @param message + */ + void onMessage(String message); + + /** + * Callback received when the connection + * to the pod is terminated from the server-side + * @param code a valid http response code + * @param reason a reason for termination, may be null + */ + void onClose(int code, String reason); + } + + /** + * Options for retrieving logs using a + * fluent builder style + * + * @author jeff.cantrill + * + */ + public static class Options{ + + private static final String CONTAINER = "container"; + private static final String FOLLOW = "follow"; + private boolean follow = false; + private String container = null; + private Map options = new HashMap<>(); + + /** + * The container from which to retrieve logs + * @param container + * @return + */ + public Options container(String container) { + this.container = container; + return this; + } + + /** + * follow the logs, defaults to false + * @return + */ + public Options follow() { + return follow(true); + } + + /** + * follow the logs + * @param value + * @return + */ + public Options follow(boolean value) { + this.follow = value; + return this; + } + + /** + * Add an option that is not explicitly + * defined. These will override any + * explicit options if there are collisions + * + * @param name + * @param value + * @return + */ + public Options parameter(String name, String value) { + options.put(name, value); + return this; + } + + /** + * The collective options + * @return a map of all the options + */ + public Map getMap(){ + if(!options.containsKey(FOLLOW) && follow) { + options.put(FOLLOW, "true"); + } + if(!options.containsKey(CONTAINER) && StringUtils.isNotBlank(container)) { + options.put(CONTAINER, container); + } + return Collections.unmodifiableMap(options); + } + } +} diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index 2bf06663..cd5d46c7 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -26,6 +26,8 @@ public interface IHttpConstants { public static final int STATUS_UNAUTHORIZED = 401; public static final int STATUS_FORBIDDEN = 403; public static final int STATUS_NOT_FOUND = 404; + + public static final int STATUS_NORMAL_STOP = 1000; public static final String PROPERTY_CONTENT_TYPE = "Content-Type"; public static final String PROPERTY_AUTHORIZATION = "Authorization"; diff --git a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java index b5a442bc..2d600b6c 100644 --- a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java @@ -14,6 +14,8 @@ import static org.mockito.Mockito.*; import java.net.MalformedURLException; import java.net.URL; +import java.util.HashMap; +import java.util.Map; import org.junit.Before; import org.junit.Test; @@ -41,12 +43,16 @@ public void setup() throws MalformedURLException { public void testBuildingURLForAWatchService() throws Exception { IResource resource = givenAResource(ResourceKind.SERVICE, KubernetesAPIVersion.v1,"foo"); + Map params = new HashMap<>(); + params.put("foo", "bar"); + String url = builder. resource(resource) .watch() .addParmeter("resourceVersion", "123") + .addParameters(params) .build().toString(); - assertEquals(String.format("%s/api/v1/namespaces/foo/services?watch=true&resourceVersion=123", BASE_URL),url.toString()); + assertEquals(String.format("%s/api/v1/namespaces/foo/services?watch=true&resourceVersion=123&foo=bar", BASE_URL),url.toString()); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/IPodLogRetrievalAsyncOptionsTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/IPodLogRetrievalAsyncOptionsTest.java new file mode 100644 index 00000000..a383af91 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/IPodLogRetrievalAsyncOptionsTest.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import static org.junit.Assert.*; + +import org.junit.Before; +import org.junit.Test; + +import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.Options; + +public class IPodLogRetrievalAsyncOptionsTest { + + private Options options = new Options(); + @Before + public void setUp() throws Exception { + } + + @Test + public void testFollowDoesNotOverrideParameter() { + assertEquals("false", options + .follow() + .parameter("follow", "false") + .getMap().get("follow")); + + } + + @Test + public void testFollowIsAddedWhenTrue() { + assertEquals("true", options.follow().getMap().get("follow")); + } + + @Test + public void testFollowIsNotAddedWhenFalse() { + assertNull(options.follow(false).getMap().get("follow")); + } + + @Test + public void testContainerDoesNotOverrideParameter() { + assertEquals("foo", options + .container("bar") + .parameter("container", "foo") + .getMap().get("container")); + + } + + @Test + public void testContainerAddedWhenNotEmpty() { + assertEquals("bar", options + .container("bar") + .getMap().get("container")); + + } + @Test + public void testContainerNotAddedWhenEmpty() { + assertNull(options + .container(" ") + .getMap().get("container")); + + } +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java new file mode 100644 index 00000000..1618e450 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import static org.junit.Assert.assertNotNull; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.CapabilityVisitor; +import com.openshift.restclient.capability.IStoppable; +import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; +import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.IPodLogListener; +import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.Options; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IResource; + +/** + * + * @author Jeff Cantrill + * + */ +public class PodLogRetrievalAsyncIntegrationTest { + + private static final Logger LOG = LoggerFactory.getLogger(PodLogRetrievalAsyncIntegrationTest.class); + + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private CountDownLatch latch; + + + @Test + public void testAsyncLogRetrieval() throws Exception { + latch = new CountDownLatch(2); + DefaultClient client = (DefaultClient) helper.createClientForBasicAuth(); + List pods = client.list(ResourceKind.POD, "default"); + IPod pod = (IPod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); + assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); + + final String container = pod.getContainers().iterator().next().getName(); + + IStoppable stop = pod.accept(new CapabilityVisitor() { + + @Override + public IStoppable visit(IPodLogRetrievalAsync capability) { + return capability.start(new IPodLogListener() { + + @Override + public void onOpen() { + LOG.debug("onOpen"); + latch.countDown(); + } + + @Override + public void onMessage(String message) { + LOG.debug(message); + } + + @Override + public void onClose(int code, String reason) { + LOG.debug("onClose code:{} reason:{}", code, reason); + latch.countDown(); + } + }, new Options() + .follow() + .container(container)); + } + }, null); + assertNotNull("Exp. to support the capability", stop); + latch.await(10, TimeUnit.SECONDS); + stop.stop(); + latch.await(5, TimeUnit.SECONDS); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java new file mode 100644 index 00000000..04ec11b4 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.TypeMapperFixture; +import com.openshift.internal.restclient.capability.resources.PodLogRetrievalAsync.PodLogListenerAdapter; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.IPodLogListener; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.MocksFactory; + +import okhttp3.MediaType; +import okhttp3.ResponseBody; +import okhttp3.ws.WebSocket; + +@RunWith(MockitoJUnitRunner.class) +public class PodLogRetrievalAsyncTest extends TypeMapperFixture{ + + private DefaultClient client; + @Mock + private IApiTypeMapper mapper; + private PodLogRetrievalAsync capability; + private IPod pod; + private PodLogListenerAdapter adapter; + + @Mock + private IPodLogListener listener; + + @Before + public void setUp() throws Exception { + super.setUp(); + client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); + pod = new MocksFactory().mock(IPod.class); + capability = new PodLogRetrievalAsync(pod, client); + + adapter = new PodLogListenerAdapter(listener); + } + + @Test + public void testIsSupported() { + assertTrue("Exp. capability to be supported because the pod endpoint exists", capability.isSupported()); + } + + @Test + public void testIsNotSupportedWhenEndpointDoesNotExist() { + when(pod.getApiVersion()).thenReturn("somenoneexitentversion"); + assertFalse("Exp. capability to not be supported because the pod endpoint does not exist exists", capability.isSupported()); + } + + @Test + public void testAdapterCallsListenerCycle() throws Exception { + adapter.onOpen(null, null); + adapter.onOpen(null, null); + verify(listener).onOpen(); + + ResponseBody body = ResponseBody.create(MediaType.parse("text"), "a body"); + adapter.onMessage(body); + verify(listener).onMessage("a body"); + + adapter.onClose(1986, "the reason"); + adapter.onClose(1986, "the reason"); + verify(listener).onClose(1986, "the reason"); + } + + @Test + public void testStopWhenConnected() throws Exception { + WebSocket socket = mock(WebSocket.class); + adapter.onOpen(socket, null); + + adapter.stop(); + verify(socket).close(eq(IHttpConstants.STATUS_NORMAL_STOP), anyString()); + } + + @Test + public void testStopSwallowsException() throws Exception { + WebSocket socket = mock(WebSocket.class); + doThrow(Exception.class).when(socket).close(anyInt(), anyString()); + adapter.onOpen(socket, null); + + adapter.stop(); + verify(socket).close(eq(IHttpConstants.STATUS_NORMAL_STOP), anyString()); + } + +} From 72cc3c6f32d731d990dd29db34e9046429d92600 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Mon, 1 Aug 2016 18:29:28 +0200 Subject: [PATCH 008/258] [OSJC-264] - Commit a821fd51cbec9fa9ea9f25a6f4b2603b3ba5271e breaks rsync feature Replace env clear by remove('KUBECONFIG') Signed-off-by: Jeff MAURY --- .../capability/resources/AbstractOpenShiftBinaryCapability.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 5bddd03b..09ae1630 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -155,7 +155,7 @@ private void startProcess(final String location, final OpenShiftBinaryOption... String cmdLine = new StringBuilder(location).append(' ').append(buildArgs(Arrays.asList(options))).toString(); String[] args = StringUtils.split(cmdLine, " "); ProcessBuilder builder = new ProcessBuilder(args); - builder.environment().clear(); + builder.environment().remove("KUBECONFIG"); LOG.debug("OpenShift binary args: {}", builder.command()); try { process = builder.start(); From 989bd8f9190a3f24fef22e22a697e60e7559921f Mon Sep 17 00:00:00 2001 From: Dan McPherson Date: Tue, 2 Aug 2016 08:55:03 -0400 Subject: [PATCH 009/258] Formatting fixes --- .../com/openshift/internal/restclient/APIModelVersion.java | 2 +- .../com/openshift/internal/restclient/OpenShiftAPIVersion.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/APIModelVersion.java b/src/main/java/com/openshift/internal/restclient/APIModelVersion.java index ed58adb6..d672677f 100644 --- a/src/main/java/com/openshift/internal/restclient/APIModelVersion.java +++ b/src/main/java/com/openshift/internal/restclient/APIModelVersion.java @@ -16,7 +16,7 @@ public interface APIModelVersion { int getOrder(); - + static class VersionComparitor implements Comparator { @Override public int compare(APIModelVersion v1, APIModelVersion v2) { diff --git a/src/main/java/com/openshift/internal/restclient/OpenShiftAPIVersion.java b/src/main/java/com/openshift/internal/restclient/OpenShiftAPIVersion.java index 7285d3e5..57193bf0 100644 --- a/src/main/java/com/openshift/internal/restclient/OpenShiftAPIVersion.java +++ b/src/main/java/com/openshift/internal/restclient/OpenShiftAPIVersion.java @@ -18,8 +18,9 @@ public enum OpenShiftAPIVersion implements APIModelVersion{ @Deprecated v1beta3(2), v1(3); - + private int order; + OpenShiftAPIVersion(int order){ this.order = order; } From 05606d5af1c5838629c25c110db979e7790801ac Mon Sep 17 00:00:00 2001 From: dbocharov Date: Tue, 2 Aug 2016 18:28:10 +0200 Subject: [PATCH 010/258] osjc-266: add information about the volume name to PVC --- .../restclient/model/volume/PersistentVolumeClaim.java | 5 +++++ .../restclient/model/volume/IPersistentVolumeClaim.java | 5 +++++ .../com/openshift/internal/restclient/model/v1/PVCTest.java | 5 +++++ src/test/resources/samples/openshift3/v1_pvc.json | 3 ++- 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java index 3779a3a4..f5f48703 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java @@ -31,6 +31,7 @@ public class PersistentVolumeClaim extends KubernetesResource implements IPersis private static final String PVC_ACCESS_MODES = "spec.accessModes"; private static final String PVC_REQUESTED_STORAGE = "spec.resources.requests.storage"; private static final String STATUS_PHASE = "status.phase"; + private static final String PVC_VOLUME_NAME = "spec.volumeName"; public PersistentVolumeClaim(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); @@ -69,4 +70,8 @@ public String getStatus() { return asString(STATUS_PHASE); } + @Override + public String getVolumeName() { + return asString(PVC_VOLUME_NAME); + } } diff --git a/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaim.java b/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaim.java index 20d34f36..e16c8c5d 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaim.java +++ b/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaim.java @@ -52,4 +52,9 @@ public interface IPersistentVolumeClaim extends IResource { * @return */ String getStatus(); + + /** + * The volume name + */ + String getVolumeName(); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java index 0dd3f774..91066437 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java @@ -64,5 +64,10 @@ public void testSetRequestedStorage() { claim.setRequestedStorage("1Gi"); assertEquals("1Gi", claim.getRequestedStorage()); } + + @Test + public void testGetVolumeName() { + assertEquals("pv02", claim.getVolumeName()); + } } diff --git a/src/test/resources/samples/openshift3/v1_pvc.json b/src/test/resources/samples/openshift3/v1_pvc.json index 1a64954f..91a4a896 100644 --- a/src/test/resources/samples/openshift3/v1_pvc.json +++ b/src/test/resources/samples/openshift3/v1_pvc.json @@ -20,7 +20,8 @@ "requests": { "storage": "15m" } - } + }, + "volumeName": "pv02" }, "status": { "phase": "Pending" From 994fd4ea3b46beafbddb52fcf19a980602100e46 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Wed, 3 Aug 2016 10:14:11 +0200 Subject: [PATCH 011/258] [JBIDE-22861] - Extend API to allow control of max web socket call limits Signed-off-by: Jeff MAURY --- .../openshift/restclient/ClientBuilder.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 4be0088f..8f137d99 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -133,6 +133,28 @@ public ClientBuilder withConnectTimeout(int connectInMillis) { return this; } + /** + * The maximum concurrent websocket requests for this client. + * + * @param maxRequests the maximum number of concurrent web socket requests + * @return the client builder + */ + public ClientBuilder withMaxRequests(int maxRequests) { + this.maxRequests = maxRequests; + return this; + } + + /** + * The maximum concurrent websocket request for this client for a single host. + * + * @param maxRequestsPerHost the maximum number of concurrent web socket requests for a single host + * @return the client builder + */ + public ClientBuilder withMaxRequestsPerHost(int maxRequestsPerHost) { + this.maxRequestsPerHost = maxRequestsPerHost; + return this; + } + /** * Build a client * From 988167b1ae311f884636e4a9da056584a346775d Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Mon, 8 Aug 2016 12:16:23 -0400 Subject: [PATCH 012/258] [OSJC-267] Add property accessors for events --- .../restclient/model/KubernetesEvent.java | 60 ++++++++++++- .../openshift/restclient/model/IEvent.java | 71 ++++++++++++++- .../restclient/model/v1/EventTest.java | 90 +++++++++++++++++++ .../openshift/restclient/utils/Samples.java | 1 + .../samples/openshift3/v1_event.json | 29 ++++++ 5 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java create mode 100644 src/test/resources/samples/openshift3/v1_event.json diff --git a/src/main/java/com/openshift/internal/restclient/model/KubernetesEvent.java b/src/main/java/com/openshift/internal/restclient/model/KubernetesEvent.java index 6258ff00..812f16cb 100644 --- a/src/main/java/com/openshift/internal/restclient/model/KubernetesEvent.java +++ b/src/main/java/com/openshift/internal/restclient/model/KubernetesEvent.java @@ -14,8 +14,10 @@ import org.jboss.dmr.ModelNode; +import com.openshift.internal.util.JBossDmrExtentions; import com.openshift.restclient.IClient; import com.openshift.restclient.model.IEvent; +import com.openshift.restclient.model.IObjectReference; /** * @author Jeff Cantrill @@ -24,7 +26,63 @@ public class KubernetesEvent extends KubernetesResource implements IEvent { public KubernetesEvent(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); - // TODO Auto-generated constructor stub } + @Override + public String getReason() { + return asString("reason"); + } + + @Override + public String getMessage() { + return asString("message"); + } + + @Override + public IObjectReference getInvolvedObject() { + return new ObjectReference(get("involvedObject")); + } + + @Override + public String getFirstSeenTimestamp() { + return asString("firstTimestamp"); + } + + @Override + public String getLastSeenTimestamp() { + return asString("lastTimestamp"); + } + + @Override + public int getCount() { + return asInt("count"); + } + + @Override + public String getType() { + return asString("type"); + } + + @Override + public IEventSource getEventSource() { + return new EventSource(get("source"), this.getPropertyKeys()); + } + + private static class EventSource extends ModelNodeAdapter implements IEventSource{ + + protected EventSource(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public String getComponent() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "component"); + } + + @Override + public String getHost() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "host"); + } + + } } diff --git a/src/main/java/com/openshift/restclient/model/IEvent.java b/src/main/java/com/openshift/restclient/model/IEvent.java index c7772b9d..8c53dfcb 100644 --- a/src/main/java/com/openshift/restclient/model/IEvent.java +++ b/src/main/java/com/openshift/restclient/model/IEvent.java @@ -16,5 +16,74 @@ * @author Jeff Cantrill */ public interface IEvent extends IResource { - + + /** + * The reason for the event + * @return + */ + String getReason(); + + /** + * The additional message associated with the event + * @return + */ + String getMessage(); + + /** + * A reference to the Object that was involved in + * this event + * + * @return + */ + IObjectReference getInvolvedObject(); + + /** + * The first time this event was recorded + * @return + */ + String getFirstSeenTimestamp(); + + /** + * The last time this event was recorded + * @return + */ + String getLastSeenTimestamp(); + + /** + * The number of times this event has occured + * @return + */ + int getCount(); + + /** + * The type of this event (e.g. Normal, Warning) + * @return + */ + String getType(); + + /** + * Optional information of the component reporting this event + * @return + */ + IEventSource getEventSource(); + + /** + * Event source information + * @author jeff.cantrill + * + */ + static interface IEventSource{ + + /** + * The component from which this event was generated + * @return + */ + String getComponent(); + + /** + * The host name on which this event was generated + * @return + */ + String getHost(); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java new file mode 100644 index 00000000..948d5c85 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.v1; + +import static org.junit.Assert.*; + +import java.util.HashMap; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.openshift.internal.restclient.model.KubernetesEvent; +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.IEvent; +import com.openshift.restclient.model.IEvent.IEventSource; +import com.openshift.restclient.model.IObjectReference; +import com.openshift.restclient.utils.Samples; + +@RunWith(MockitoJUnitRunner.class) +public class EventTest { + + private static String JSON = Samples.V1_EVENT.getContentAsString(); + + @Mock + private IClient client; + private IEvent event; + + @Before + public void setUp() throws Exception { + ModelNode node = ModelNode.fromJSONString(JSON); + event = new KubernetesEvent(node, client, new HashMap<>()); + } + + @Test + public void testGetEventSource() { + IEventSource source = event.getEventSource(); + assertNotNull(source); + assertEquals("deploymentconfig-controller", source.getComponent()); + assertEquals("", source.getHost()); + } + + @Test + public void testGetType() { + assertEquals("Normal", event.getType()); + } + + @Test + public void testGetCount() { + assertEquals(1, event.getCount()); + } + + @Test + public void testGetFirstSeen() { + assertEquals("2016-08-08T01:49:26Z", event.getFirstSeenTimestamp()); + } + + @Test + public void testGetLastSeen() { + assertEquals("2016-08-08T01:49:26Z", event.getLastSeenTimestamp()); + } + + @Test + public void testGetReason() { + assertEquals("DeploymentCreated", event.getReason()); + } + + @Test + public void testGetInvolvedObject() { + IObjectReference ref = event.getInvolvedObject(); + assertNotNull(ref); + } + + @Test + public void testGetMessage() { + assertEquals("Created new deployment \"nodejs-1\" for version 1", event.getMessage()); + } + +} diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 4736faf0..75af955e 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -31,6 +31,7 @@ public enum Samples { V1_BUILD_CONFIG("openshift3/v1_build_config.json"), V1_BUILD_CONFIG_LIST("openshift3/v1_build_config_list.json"), V1_DEPLOYMENT_CONIFIG("openshift3/v1_deployment_config.json"), + V1_EVENT("openshift3/v1_event.json"), V1_IMAGE_STREAM("openshift3/v1_image_stream.json"), V1_IMAGE_STREAM_IMPORT("openshift3/v1_image_stream_import.json"), V1_BUILD("openshift3/v1_build.json"), diff --git a/src/test/resources/samples/openshift3/v1_event.json b/src/test/resources/samples/openshift3/v1_event.json new file mode 100644 index 00000000..0bc9edb5 --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_event.json @@ -0,0 +1,29 @@ +{ + "kind": "Event", + "apiVersion": "v1", + "metadata": { + "name": "nodejs.1468b1fa2928e73e", + "namespace": "myproject", + "selfLink": "/api/v1/namespaces/myproject/events/nodejs.1468b1fa2928e73e", + "uid": "567a41b5-5d0a-11e6-9808-507b9dfa4ab3", + "resourceVersion": "450", + "creationTimestamp": "2016-08-08T01:49:26Z" + }, + "involvedObject": { + "kind": "DeploymentConfig", + "namespace": "myproject", + "name": "nodejs", + "uid": "234e71be-5d0a-11e6-9808-507b9dfa4ab3", + "apiVersion": "v1", + "resourceVersion": "445" + }, + "reason": "DeploymentCreated", + "message": "Created new deployment \"nodejs-1\" for version 1", + "source": { + "component": "deploymentconfig-controller" + }, + "firstTimestamp": "2016-08-08T01:49:26Z", + "lastTimestamp": "2016-08-08T01:49:26Z", + "count": 1, + "type": "Normal" +} \ No newline at end of file From 7f157eacb51ca479a47aab5d56ed4972928b4807 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Tue, 9 Aug 2016 12:35:44 +0200 Subject: [PATCH 013/258] [JBIDE-22861] - Extend API to allow control of max web socket call limits - Fixed Javadoc Signed-off-by: Jeff MAURY --- src/main/java/com/openshift/restclient/ClientBuilder.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 8f137d99..477bc96f 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -134,9 +134,9 @@ public ClientBuilder withConnectTimeout(int connectInMillis) { } /** - * The maximum concurrent websocket requests for this client. + * The maximum concurrent requests for this client. * - * @param maxRequests the maximum number of concurrent web socket requests + * @param maxRequests the maximum number of concurrent requests * @return the client builder */ public ClientBuilder withMaxRequests(int maxRequests) { @@ -145,9 +145,9 @@ public ClientBuilder withMaxRequests(int maxRequests) { } /** - * The maximum concurrent websocket request for this client for a single host. + * The maximum concurrent request for this client for a single host. * - * @param maxRequestsPerHost the maximum number of concurrent web socket requests for a single host + * @param maxRequestsPerHost the maximum number of concurrent requests for a single host * @return the client builder */ public ClientBuilder withMaxRequestsPerHost(int maxRequestsPerHost) { From 2cfa789f59d7c75f50ba0b00c6d04c6a0901b8d2 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Wed, 3 Aug 2016 12:46:17 -0400 Subject: [PATCH 014/258] add cause to build request --- .../capability/resources/BuildTrigger.java | 34 ++++++++++++++++++- .../restclient/model/build/BuildRequest.java | 28 +++++++++++++++ .../resources/IBuildTriggerable.java | 31 +++++++++++++++++ .../restclient/model/build/IBuildRequest.java | 21 ++++++++++++ .../BuildCapabilitiesIntegrationTest.java | 12 +++++++ 5 files changed, 125 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java index 6e6475b6..d4c300d2 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java @@ -10,6 +10,11 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; + import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.resources.IBuildTriggerable; @@ -30,17 +35,21 @@ public class BuildTrigger implements IBuildTriggerable { private IResource resource; private IClient client; private final String subresource; + private String commitId; + private List causes; public BuildTrigger(IBuildConfig buildConfig, IClient client) { this.resource = buildConfig; this.client = client; this.subresource = BUILDCONFIG_SUBRESOURCE; + this.causes = new ArrayList<>(); } public BuildTrigger(IBuild build, IClient client) { this.resource = build; this.client = client; this.subresource = BUILD_SUBRESOURCE; + this.causes = new ArrayList<>(); } @Override @@ -56,15 +65,38 @@ public String getName() { @Override public IBuild trigger() { IBuildRequest request = client.getResourceFactory().stub(ResourceKind.BUILD_REQUEST, resource.getName()); + if(StringUtils.isNotEmpty(commitId)) + request.setCommitId(commitId); + causes.forEach(c->request.addBuildCause(c)); return client.create(resource.getKind(), resource.getNamespace(), resource.getName(), subresource, request); } - @Override + @Override @Deprecated public IBuild trigger(String commitId) { IBuildRequest request = client.getResourceFactory().stub(ResourceKind.BUILD_REQUEST, resource.getName()); request.setCommitId(commitId); return client.create(resource.getKind(), resource.getNamespace(), resource.getName(), subresource, request); } + + @Override + public void setCommitId(String commitId) { + this.commitId = commitId; + } + + @Override + public String getCommitId() { + return commitId; + } + + @Override + public void addBuildCause(String cause) { + causes.add(cause); + } + + @Override + public List getBuildCauses() { + return new ArrayList<>(causes); + } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java index 67fc88f2..99e8d6b0 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java @@ -10,6 +10,8 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.build; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.jboss.dmr.ModelNode; @@ -32,6 +34,8 @@ public class BuildRequest extends KubernetesResource implements IBuildRequest{ private static final String REVISION = "revision"; private static final String REVISION_GIT_COMMIT = REVISION + "." + GIT + "." + COMMIT; private static final String REVISION_TYPE = REVISION + "." + TYPE; + private static final String TRIGGERED_BY = "triggeredBy"; + private static final String MESSAGE = "message"; public BuildRequest(ModelNode node, IClient client, Map propertyKeys) { @@ -45,4 +49,28 @@ public void setCommitId(String commitId) { set(REVISION_GIT_COMMIT, commitId); } + + @Override + public void addBuildCause(String cause) { + ModelNode triggeredBys = get(TRIGGERED_BY); + triggeredBys.add(MESSAGE, cause); + } + + + @Override + public String getCommitId() { + return get(REVISION_GIT_COMMIT).asString(); + } + + + @Override + public List getBuildCauses() { + List causes = get(TRIGGERED_BY).asList(); + ArrayList ret = new ArrayList<>(); + for (ModelNode cause : causes) { + ret.add(cause.asString()); + } + return ret; + } + } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java b/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java index d2802186..1cfd9514 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java @@ -10,6 +10,8 @@ ******************************************************************************/ package com.openshift.restclient.capability.resources; +import java.util.List; + import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.model.IBuild; @@ -30,7 +32,36 @@ public interface IBuildTriggerable extends ICapability { * Trigger a build with the given source level commit id * @param commitId * @return The build that was triggered + * @deprecated + * Replaced by calling {@link #setCommitId(String)}, followed + * by {@link #trigger()}. */ IBuild trigger(String commitId); + + /** + * Set the commit level for the SCM extraction + * of the source code the build operates against + * @param commitId the specific hexadecimal commit ID associated with a SCM log level + */ + void setCommitId(String commitId); + + /** + * Get the commit level for the SCM extraction + * of the source code the build operates against + * @return the specific hexadecimal commit ID associated with a SCM log level + */ + String getCommitId(); + + /** + * Add a human readable short explanation of why this build request was issued + * @param cause the description to add to the list of causes for this request + */ + void addBuildCause(String cause); + + /** + * Get the list of human readable short explanations of why this build request was issued + * @return list of reasons for the build + */ + List getBuildCauses(); } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java b/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java index c71b04f1..481dfd0e 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java @@ -11,6 +11,8 @@ package com.openshift.restclient.model.build; +import java.util.List; + import com.openshift.restclient.model.IResource; /** @@ -25,4 +27,23 @@ public interface IBuildRequest extends IResource { * @param commitId the specific hexadecimal commit ID associated with a git log level */ void setCommitId(String commitId); + + /** + * Get the commit level for the git clone extraction + * of the source code the build operates against + * @return the specific hexadecimal commit ID associated with a git log level + */ + String getCommitId(); + + /** + * Add a human readable short explanation of why this build request was issued + * @param cause the description to add to the list of causes for this request + */ + void addBuildCause(String cause); + + /** + * Get the list of human readable short explanations of why this build request was issued + * @return list of reasons for the build + */ + List getBuildCauses(); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java index 3bb7c724..9c34a26d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java @@ -109,6 +109,18 @@ public IBuild visit(IBuildTriggerable capability) { }, null); assertNotNull("Exp. to be able to trigger a build from a build", build); LOG.debug("Triggered build {}", build); + + //add a build cause + LOG.debug("Triggering build with build cause..."); + build = build.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBuildTriggerable capability) { + capability.addBuildCause("test cause"); + return capability.trigger(); + } + }, null); + assertNotNull("Exp. to be able to add a build cause for a build", build); + LOG.debug("Triggered build {}", build); } @After From 702413c7200ad98f1e6b6c1116afb8ad0a0b5e84 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Tue, 9 Aug 2016 10:52:16 -0400 Subject: [PATCH 015/258] Update hash/equals to use baseUrl.toString in follow-up to [jbide-22471] --- .../java/com/openshift/internal/restclient/DefaultClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index da0954c4..fed26b5e 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -327,7 +327,7 @@ public String getToken() { public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + ((baseUrl == null) ? 0 : baseUrl.hashCode()); + result = prime * result + ((baseUrl == null) ? 0 : baseUrl.toString().hashCode()); result = prime * result + ((kubernetesVersion == null) ? 0 : kubernetesVersion.hashCode()); result = prime * result + ((openShiftVersion == null) ? 0 : openShiftVersion.hashCode()); result = prime * result + ((authContext == null || authContext.getToken() == null) ? 0 : authContext.getToken().hashCode()); @@ -346,7 +346,7 @@ public boolean equals(Object obj) { if (baseUrl == null) { if (other.baseUrl != null) return false; - } else if (!baseUrl.equals(other.baseUrl)) + } else if (!baseUrl.toString().equals(other.baseUrl.toString())) return false; if (kubernetesVersion == null) { if (other.kubernetesVersion != null) From 47aa4ce2a4b9e2409aa019a8d870a6602b0ee216 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 6 Jul 2016 16:28:22 -0400 Subject: [PATCH 016/258] update readme to include compatibility --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 06bb0089..7191118a 100755 --- a/README.md +++ b/README.md @@ -11,6 +11,14 @@ Download -------- You may either build from source using maven (mvn clean package) which, using the master branch, will generate a snapshot build of the lastest updates. You may also retrieve final released jars from [Maven Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.openshift%22%20AND%20a%3A%22openshift-restclient-java%22). +Compatibility +--------- +Versions of this client known to be compatible with origin + +| Client Version | OpenShift Origin Server | +|--------------------------|-------------------------| +| 5.0.0-SNAPSHOT | latest, v1.3.0-alpha.2 | + Usage ----- @@ -64,3 +72,4 @@ The client as well as resources supported by OpenShift may have certain capabili } }, null); +Various examples of using the capabilities may be found in the integration tests. From f4421aa446fbae107e8261efb38b977b152d635b Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 10 Aug 2016 16:01:04 -0400 Subject: [PATCH 017/258] [OSJC-269] Fix setting spec.output for BuildConfig --- README.md | 11 ++++- .../restclient/model/BuildConfig.java | 42 +------------------ .../restclient/model/KubernetesResource.java | 4 ++ .../model/build/BuildConfigBuilder.java | 22 ++++++---- .../restclient/model/IBuildConfig.java | 2 +- .../restclient/model/IObjectReference.java | 20 ++++++++- .../model/build/IBuildConfigBuilder.java | 1 - .../model/build/BuildConfigBuilderTest.java | 3 +- .../restclient/model/v1/ObjectRefTest.java | 34 ++++++++++++--- 9 files changed, 80 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 7191118a..9d74a4b4 100755 --- a/README.md +++ b/README.md @@ -13,11 +13,12 @@ You may either build from source using maven (mvn clean package) which, using th Compatibility --------- -Versions of this client known to be compatible with origin +Versions of this client known to be compatible with OpenShift | Client Version | OpenShift Origin Server | |--------------------------|-------------------------| | 5.0.0-SNAPSHOT | latest, v1.3.0-alpha.2 | +| | v1.3.0-alpha.3 | Usage @@ -73,3 +74,11 @@ The client as well as resources supported by OpenShift may have certain capabili }, null); Various examples of using the capabilities may be found in the integration tests. + +Testing +------- + +To run the integration tests: +1. Define a user with cluster admin privilege +1. Download the oc binary +1. Run the tests: `mvn integration-test -Pintegration-tests -DserverURL=https://localhost:8443 -Ddefault.cluster.admin=foo -Ddefault.cluster.password=bar -Ddefault.openshift.location=/tmp/oc` diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index b376d362..ec0a8b10 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -20,11 +20,9 @@ import com.openshift.internal.restclient.model.build.DockerBuildStrategy; import com.openshift.internal.restclient.model.build.GitBuildSource; import com.openshift.internal.restclient.model.build.ImageChangeTrigger; -import com.openshift.internal.restclient.model.build.STIBuildStrategy; import com.openshift.internal.restclient.model.build.SourceBuildStrategy; import com.openshift.internal.restclient.model.build.WebhookTrigger; import com.openshift.restclient.IClient; -import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IObjectReference; import com.openshift.restclient.model.build.BuildSourceType; @@ -37,7 +35,6 @@ import com.openshift.restclient.model.build.IDockerBuildStrategy; import com.openshift.restclient.model.build.IGitBuildSource; import com.openshift.restclient.model.build.IImageChangeTrigger; -import com.openshift.restclient.model.build.ISTIBuildStrategy; import com.openshift.restclient.model.build.ISourceBuildStrategy; import com.openshift.restclient.model.build.IWebhookTrigger; @@ -59,10 +56,6 @@ public class BuildConfig extends KubernetesResource implements IBuildConfig { public static final String BUILDCONFIG_DOCKER_NOCACHE = "spec.strategy.dockerStrategy.noCache"; public static final String BUILDCONFIG_DOCKER_BASEIMAGE = "spec.strategy.dockerStrategy.baseImage"; private static final String BUILDCONFIG_OUTPUT_REPO = "spec.output.to.name"; - private static final String BUILDCONFIG_STI_IMAGE = "spec.strategy.sourceStrategy.from.name"; - private static final String BUILDCONFIG_STI_SCRIPTS = "spec.strategy.sourceStrategy.scripts"; - private static final String BUILDCONFIG_STI_INCREMENTAL = "spec.strategy.sourceStrategy.incremental"; - private static final String BUILDCONFIG_STI_ENV = "spec.strategy.sourceStrategy.env"; private static final String BUILDCONFIG_TRIGGERS = "spec.triggers"; private static final String BUILD_CONFIG_WEBHOOK_GITHUB_SECRET = "github.secret"; private static final String BUILD_CONFIG_WEBHOOK_GENERIC_SECRET = "generic.secret"; @@ -79,12 +72,9 @@ public BuildConfig(ModelNode node, IClient client, Map overri @Override public IObjectReference getBuildOutputReference() { - ModelNode node = get("spec.output.to"); - if(!node.isDefined()) return null; - return new ObjectReference(node); + return new ObjectReference(get("spec.output.to")); } - @Override public List getBuildTriggers() { List triggers = new ArrayList(); @@ -93,16 +83,13 @@ public List getBuildTriggers() { for (ModelNode node : list) { String type = node.get(TYPE).asString(); switch(type){ - case BuildTriggerType.generic: case BuildTriggerType.GENERIC: triggers.add(new WebhookTrigger(BuildTriggerType.GENERIC, asString(node, BUILD_CONFIG_WEBHOOK_GENERIC_SECRET), url)); break; - case BuildTriggerType.github: case BuildTriggerType.GITHUB: triggers.add(new WebhookTrigger(BuildTriggerType.GITHUB, asString(node, BUILD_CONFIG_WEBHOOK_GITHUB_SECRET), url)); break; - case BuildTriggerType.imageChange: case BuildTriggerType.IMAGE_CHANGE: triggers.add(new ImageChangeTrigger(BuildTriggerType.IMAGE_CHANGE, asString(node, BUILD_CONFIG_IMAGECHANGE_IMAGE), @@ -123,7 +110,6 @@ public void addBuildTrigger(IBuildTrigger trigger) { ModelNode triggers = get(BUILDCONFIG_TRIGGERS); ModelNode triggerNode = triggers.add(); switch(trigger.getType()) { - case BuildTriggerType.generic: case BuildTriggerType.GENERIC: if(!(trigger instanceof IWebhookTrigger)) { throw new IllegalArgumentException("IBuildTrigger of type generic does not implement IWebhookTrigger"); @@ -131,7 +117,6 @@ public void addBuildTrigger(IBuildTrigger trigger) { IWebhookTrigger generic = (IWebhookTrigger)trigger; triggerNode.get(getPath(BUILD_CONFIG_WEBHOOK_GENERIC_SECRET)).set(generic.getSecret()); break; - case BuildTriggerType.github: case BuildTriggerType.GITHUB: if(!(trigger instanceof IWebhookTrigger)) { throw new IllegalArgumentException("IBuildTrigger of type github does not implement IWebhookTrigger"); @@ -139,7 +124,6 @@ public void addBuildTrigger(IBuildTrigger trigger) { IWebhookTrigger github = (IWebhookTrigger)trigger; triggerNode.get(getPath(BUILD_CONFIG_WEBHOOK_GITHUB_SECRET)).set(github.getSecret()); break; - case BuildTriggerType.imageChange: case BuildTriggerType.IMAGE_CHANGE:{ if(!(trigger instanceof IImageChangeTrigger)) { throw new IllegalArgumentException("IBuildTrigger of type imageChange does not implement IImageChangeTrigger"); @@ -211,22 +195,6 @@ public void setBuildStrategy(IBuildStrategy strategy) { setEnvMap(BUILDCONFIG_CUSTOM_ENV, custom.getEnvironmentVariables()); } break; - case BuildStrategyType.STI: - if ( !(strategy instanceof ISTIBuildStrategy)) { - throw new IllegalArgumentException("IBuildStrategy of type Custom does not implement ISTIBuildStrategy"); - } - ISTIBuildStrategy sti = (ISTIBuildStrategy)strategy; - if(sti.getImage() != null) { - set(BUILDCONFIG_STI_IMAGE, sti.getImage().toString()); - } - if(sti.getScriptsLocation() != null) { - set(BUILDCONFIG_STI_SCRIPTS, sti.getScriptsLocation()); - } - set(BUILDCONFIG_STI_INCREMENTAL, sti.incremental()); - if(sti.getEnvironmentVariables() != null) { - setEnvMap(BUILDCONFIG_STI_ENV, sti.getEnvironmentVariables()); - } - break; case BuildStrategyType.SOURCE: ISourceBuildStrategy source = (ISourceBuildStrategy) strategy; get(SOURCE_STRATEGY).set(ModelNode.fromJSONString(source.toString())); @@ -248,13 +216,6 @@ public void setBuildStrategy(IBuildStrategy strategy) { set(BUILDCONFIG_TYPE, strategy.getType()); } - - public void setOutput(DockerImageURI imageUri){ - //FIXME -// ModelNode output = getNode().get(new String []{"parameters","output"}); -// output.get("imageTag").set(imageUri.getUriWithoutHost()); -// output.get("registry").set(imageUri.getRepositoryHost()); - } @SuppressWarnings("unchecked") @Override @@ -266,7 +227,6 @@ public T getBuildStrategy() { asBoolean(BUILDCONFIG_CUSTOM_EXPOSEDOCKERSOCKET), getEnvMap(BUILDCONFIG_CUSTOM_ENV) ); - case BuildStrategyType.STI: case BuildStrategyType.SOURCE: return (T) new SourceBuildStrategy(get(SOURCE_STRATEGY), getPropertyKeys()); diff --git a/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java b/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java index 804770d3..242cf34d 100644 --- a/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java +++ b/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java @@ -196,6 +196,10 @@ public Map getLabels() { } /*---------- utility methods ------*/ + protected boolean has(String key) { + return node.has(getPath(key)); + } + protected ModelNode get(String key){ return get(node, key); } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java index 006a00b3..7a41b80f 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java @@ -10,24 +10,28 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.build; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.UUID; +import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import com.openshift.internal.restclient.model.BuildConfig; -import com.openshift.internal.util.JBossDmrExtentions; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IEnvironmentVariable; +import com.openshift.restclient.model.IObjectReference; import com.openshift.restclient.model.build.BuildTriggerType; import com.openshift.restclient.model.build.IBuildConfigBuilder; - +/** + * Impl of a builder to create buildconfigs + * @author jeff.cantrill + * + */ public class BuildConfigBuilder implements IBuildConfigBuilder { private SourceStrategyBuilder sourceStrategyBuilder; @@ -77,11 +81,13 @@ public IBuildConfig build() { bc.setBuildSource(gitSourceBuilder.build()); } - - //TODO move into bc - ModelNode node = bc.getNode(); - JBossDmrExtentions.set(node, Collections.emptyMap(), "spec.output.to.kind", ResourceKind.IMAGE_STREAM_TAG); - JBossDmrExtentions.set(node, Collections.emptyMap(), "spec.output.to.name", imageStreamTagOutput); + DockerImageURI uri = new DockerImageURI(imageStreamTagOutput); + IObjectReference outRef = bc.getBuildOutputReference(); + outRef.setKind(ResourceKind.IMAGE_STREAM_TAG); + outRef.setName(uri.getNameAndTag()); + if(StringUtils.isNotBlank(uri.getUserName())) { + outRef.setNamespace(uri.getUserName()); + } bc.addBuildTrigger(new WebhookTrigger(BuildTriggerType.GENERIC, UUID.randomUUID().toString(), null)); if(buildOnImageChange) { diff --git a/src/main/java/com/openshift/restclient/model/IBuildConfig.java b/src/main/java/com/openshift/restclient/model/IBuildConfig.java index 72bf4b5a..3336e10b 100644 --- a/src/main/java/com/openshift/restclient/model/IBuildConfig.java +++ b/src/main/java/com/openshift/restclient/model/IBuildConfig.java @@ -22,7 +22,7 @@ public interface IBuildConfig extends IResource{ /** * To defines an optional location to push the output of this build to. * Kind must be one of 'ImageStreamTag' or 'DockerImage'. - * @return + * @return a mutable object reference */ IObjectReference getBuildOutputReference(); diff --git a/src/main/java/com/openshift/restclient/model/IObjectReference.java b/src/main/java/com/openshift/restclient/model/IObjectReference.java index 815594aa..a0399af7 100644 --- a/src/main/java/com/openshift/restclient/model/IObjectReference.java +++ b/src/main/java/com/openshift/restclient/model/IObjectReference.java @@ -23,13 +23,19 @@ public interface IObjectReference { * @return */ String getKind(); + + /** + * The obj ref kind + * @param kind + */ + void setKind(String kind); /** * returns the api version of this resource * @return */ String getApiVersion(); - + /** * returns the resource version of this resource * @return @@ -41,12 +47,24 @@ public interface IObjectReference { * @return */ String getName(); + + /** + * The name of the obj ref + * @param name + */ + void setName(String name); /** * Returns the scope of this resource * @return */ String getNamespace(); + + /** + * The namespace for the object ref + * @param namespace + */ + void setNamespace(String namespace); String getFieldPath(); diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java index 392b4c4c..ff4a3dd7 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java @@ -16,7 +16,6 @@ import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IEnvironmentVariable; import com.openshift.restclient.model.IResourceBuilder; -import com.openshift.restclient.model.build.IBuildConfigBuilder.IGitSourceBuilder; public interface IBuildConfigBuilder extends IResourceBuilder, ICapability { diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java index c82ed291..64583f75 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java @@ -70,7 +70,7 @@ public void testBuild() { .fromImageStreamTag("builder:latest") .inNamespace("other") .end() - .toImageStreamTag("target:latest") + .toImageStreamTag("foo/target:latest") .build(); List triggerTypes = Arrays.asList(BuildTriggerType.CONFIG_CHANGE, @@ -96,6 +96,7 @@ public void testBuild() { IObjectReference out = bc.getBuildOutputReference(); assertEquals(ResourceKind.IMAGE_STREAM_TAG, out.getKind()); assertEquals("target:latest", out.getName()); + assertEquals("foo", out.getNamespace()); } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ObjectRefTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ObjectRefTest.java index 9df96343..0425c39c 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ObjectRefTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ObjectRefTest.java @@ -11,10 +11,11 @@ import static org.junit.Assert.*; import org.jboss.dmr.ModelNode; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; import com.openshift.internal.restclient.model.ObjectReference; +import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IObjectReference; import com.openshift.restclient.utils.Samples; @@ -23,11 +24,13 @@ */ public class ObjectRefTest { - private static IObjectReference objRef; + private static final String CONTENT = Samples.V1_OBJECT_REF.getContentAsString(); + private IObjectReference objRef; + private ModelNode node; - @BeforeClass - public static void setup(){ - ModelNode node = ModelNode.fromJSONString(Samples.V1_OBJECT_REF.getContentAsString()); + @Before + public void setup(){ + node = ModelNode.fromJSONString(CONTENT); objRef = new ObjectReference(node); } @@ -35,14 +38,35 @@ public static void setup(){ public void testGetKind(){ assertEquals("ServiceAccount", objRef.getKind()); } + + @Test + public void testSetKind() { + objRef.setKind(ResourceKind.BUILD); + assertEquals(ResourceKind.BUILD, new ObjectReference(node.clone()).getKind()); + } + @Test public void testGetNamespace(){ assertEquals("test", objRef.getNamespace()); } + + @Test + public void testSetNamespace() { + objRef.setNamespace("newnamespace"); + assertEquals("newnamespace", new ObjectReference(node.clone()).getNamespace()); + } + @Test public void testGetName(){ assertEquals("builder", objRef.getName()); } + + @Test + public void testSetName() { + objRef.setName("newname"); + assertEquals("newname", new ObjectReference(node.clone()).getName()); + } + @Test public void testGetUID(){ assertEquals("ce20b132-7986-11e5-b1e5-080027bdffff", objRef.getUID()); From 7548109d89bbd7de29f6bc9efcda077dc27a82d8 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 10 Aug 2016 16:53:05 -0400 Subject: [PATCH 018/258] bump pom for 5.0.0-RC1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f716accb..f79e5188 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.0.0-SNAPSHOT + 5.0.0-RC1 jar OpenShift Java REST Client http://openshift.redhat.com From 9be2cdbe478eeb02a6d97f3c9c7c82ce123ff870 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Fri, 12 Aug 2016 11:29:30 -0400 Subject: [PATCH 019/258] bump pom.xml to 5.1.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f79e5188..eebd0081 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.0.0-RC1 + 5.1.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 52f65664f54b99c68447ff9a25182606f47fc9f6 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Mon, 15 Aug 2016 14:58:46 +0200 Subject: [PATCH 020/258] Add support for exec type lifecycle hooks --- .../internal/restclient/model/Container.java | 14 ++- .../internal/restclient/model/ExecAction.java | 76 +++++++++++++++ .../internal/restclient/model/Lifecycle.java | 92 +++++++++++++++++++ .../restclient/model/IContainer.java | 4 +- .../restclient/model/IExecAction.java | 23 +++++ .../openshift/restclient/model/IHandler.java | 24 +++++ .../restclient/model/ILifecycle.java | 29 ++++++ .../restclient/model/v1/LifecycleTest.java | 80 ++++++++++++++++ .../internal/restclient/model/v1/PodTest.java | 19 ++-- .../openshift/restclient/utils/Samples.java | 2 +- .../samples/openshift3/v1_lifecycle.json | 17 ++++ 11 files changed, 366 insertions(+), 14 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/model/ExecAction.java create mode 100644 src/main/java/com/openshift/internal/restclient/model/Lifecycle.java create mode 100644 src/main/java/com/openshift/restclient/model/IExecAction.java create mode 100644 src/main/java/com/openshift/restclient/model/IHandler.java create mode 100644 src/main/java/com/openshift/restclient/model/ILifecycle.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/v1/LifecycleTest.java create mode 100644 src/test/resources/samples/openshift3/v1_lifecycle.json diff --git a/src/main/java/com/openshift/internal/restclient/model/Container.java b/src/main/java/com/openshift/internal/restclient/model/Container.java index 8b040bab..72d38703 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Container.java +++ b/src/main/java/com/openshift/internal/restclient/model/Container.java @@ -19,6 +19,7 @@ import java.util.Map.Entry; import java.util.Set; +import com.openshift.restclient.model.ILifecycle; import org.jboss.dmr.ModelNode; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; @@ -142,13 +143,18 @@ public String getImagePullPolicy() { } @Override - public void setLifecycle(String lifecycle) { - set(node, propertyKeys, LIFECYCLE, lifecycle); + public void setLifecycle(ILifecycle lifecycle) { + ModelNode lifecycleNode = ModelNode.fromJSONString(lifecycle.toJson()); + get(node, propertyKeys, LIFECYCLE).set(lifecycleNode); } @Override - public String getLifecycle() { - return asString(node, propertyKeys, LIFECYCLE); + public ILifecycle getLifecycle() { + if (node.has(LIFECYCLE)) { + return Lifecycle.fromJson(get(node, propertyKeys, LIFECYCLE)); + } else { + return new Lifecycle.Builder().build(); + } } @Override diff --git a/src/main/java/com/openshift/internal/restclient/model/ExecAction.java b/src/main/java/com/openshift/internal/restclient/model/ExecAction.java new file mode 100644 index 00000000..6986043a --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/ExecAction.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model; + +import com.openshift.restclient.model.IExecAction; +import org.jboss.dmr.ModelNode; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * @author Ulf Lilleengen + */ +public class ExecAction implements IExecAction { + + private static final String COMMAND = "command"; + private java.util.List command; + + private ExecAction(java.util.List command) { + this.command = command; + } + + @Override + public java.util.List getCommand() { + return command; + } + + @Override + public String toJson() { + ModelNode node = new ModelNode(); + ModelNode commandNode = node.get(COMMAND); + for (String cmd : command) { + commandNode.add().set(cmd); + } + return node.toJSONString(true); + } + + public static IExecAction fromJson(ModelNode execNode) { + Builder builder = new ExecAction.Builder(); + if (execNode.has(COMMAND)) { + ModelNode commandNode = execNode.get(COMMAND); + commandNode.asList().stream() + .map(ModelNode::asString) + .forEach(builder::command); + } + return builder.build(); + } + + @Override + public String getType() { + return EXEC; + } + + public static class Builder implements IBuilder { + private java.util.List commands = new ArrayList<>(); + + @Override + public IBuilder command(String command) { + commands.add(command); + return this; + } + + @Override + public IExecAction build() { + return new ExecAction(Collections.unmodifiableList(commands)); + } + } +} diff --git a/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java b/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java new file mode 100644 index 00000000..dbb0edab --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model; + +import com.openshift.restclient.UnsupportedOperationException; +import com.openshift.restclient.model.IHandler; +import com.openshift.restclient.model.ILifecycle; +import org.jboss.dmr.ModelNode; + +import java.util.Optional; + +/** + * @author Ulf Lilleengen + */ +public class Lifecycle implements ILifecycle { + private static final String PRESTOP = "preStop"; + private static final String POSTSTART = "postStart"; + + private final Optional postStart; + private final Optional preStop; + + private Lifecycle(Optional preStop, Optional postStart) { + this.preStop = preStop; + this.postStart = postStart; + } + + @Override + public Optional getPostStart() { + return postStart; + } + + @Override + public Optional getPreStop() { + return preStop; + } + + @Override + public String toJson() { + ModelNode node = new ModelNode(); + preStop.ifPresent(handler -> node.get(PRESTOP).get(handler.getType()).set(ModelNode.fromJSONString(handler.toJson()))); + postStart.ifPresent(handler -> node.get(POSTSTART).get(handler.getType()).set(ModelNode.fromJSONString(handler.toJson()))); + return node.toJSONString(true); + } + + public static ILifecycle fromJson(ModelNode json) { + Builder builder = new Builder(); + if (json.has(PRESTOP)) { + builder.preStop(parseHandler(json.get(PRESTOP)).orElse(null)); + } + + if (json.has(POSTSTART)) { + builder.postStart(parseHandler(json.get(POSTSTART)).orElse(null)); + } + return builder.build(); + } + + private static Optional parseHandler(ModelNode node) { + if (node.has(IHandler.EXEC)) { + return Optional.of(ExecAction.fromJson(node.get(IHandler.EXEC))); + } else { + return Optional.empty(); + } + } + + public static class Builder implements IBuilder { + + private IHandler preStop = null; + private IHandler postStart = null; + + public ILifecycle build() { + return new Lifecycle(Optional.ofNullable(preStop), Optional.ofNullable(postStart)); + } + + public Builder postStart(IHandler handler) { + this.postStart = handler; + return this; + } + + public Builder preStop(IHandler handler) { + this.preStop = handler; + return this; + } + } +} diff --git a/src/main/java/com/openshift/restclient/model/IContainer.java b/src/main/java/com/openshift/restclient/model/IContainer.java index 18e0b99b..9c1179b0 100644 --- a/src/main/java/com/openshift/restclient/model/IContainer.java +++ b/src/main/java/com/openshift/restclient/model/IContainer.java @@ -53,8 +53,8 @@ public interface IContainer { void setImagePullPolicy(String policy); String getImagePullPolicy(); - void setLifecycle(String lifecycle); - String getLifecycle(); + void setLifecycle(ILifecycle lifecycle); + ILifecycle getLifecycle(); @Deprecated void setVolumes(Set volumes); diff --git a/src/main/java/com/openshift/restclient/model/IExecAction.java b/src/main/java/com/openshift/restclient/model/IExecAction.java new file mode 100644 index 00000000..c4b9ed13 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/IExecAction.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.model; + +/** + * @author Ulf Lilleengen + */ +public interface IExecAction extends IHandler { + java.util.List getCommand(); + + interface IBuilder { + IBuilder command(String command); + IExecAction build(); + } +} diff --git a/src/main/java/com/openshift/restclient/model/IHandler.java b/src/main/java/com/openshift/restclient/model/IHandler.java new file mode 100644 index 00000000..47012191 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/IHandler.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.model; + +import com.openshift.internal.restclient.model.JSONSerializeable; + +/** + * @author Ulf Lilleengen + */ +public interface IHandler extends JSONSerializeable { + static final String EXEC = "exec"; + static final String HTTP = "httpGet"; + static final String TCP = "tcpSocket"; + + String getType(); +} diff --git a/src/main/java/com/openshift/restclient/model/ILifecycle.java b/src/main/java/com/openshift/restclient/model/ILifecycle.java new file mode 100644 index 00000000..a4164d21 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/ILifecycle.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.model; + +import com.openshift.internal.restclient.model.JSONSerializeable; + +import java.util.Optional; + +/** + * @author Ulf Lilleengen + */ +public interface ILifecycle extends JSONSerializeable { + Optional getPostStart(); + Optional getPreStop(); + + interface IBuilder { + IBuilder preStop(IHandler handler); + IBuilder postStart(IHandler handler); + ILifecycle build(); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/LifecycleTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/LifecycleTest.java new file mode 100644 index 00000000..b5a7ca50 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/v1/LifecycleTest.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.v1; + +import com.openshift.internal.restclient.model.ExecAction; +import com.openshift.internal.restclient.model.Lifecycle; +import com.openshift.restclient.model.IExecAction; +import com.openshift.restclient.model.IHandler; +import com.openshift.restclient.model.ILifecycle; +import com.openshift.restclient.utils.Samples; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Ulf Lilleengen + */ +public class LifecycleTest { + private ILifecycle lifecycle; + + @Before + public void setup() { + ModelNode node = ModelNode.fromJSONString(Samples.V1_LIFECYCLE.getContentAsString()); + lifecycle = Lifecycle.fromJson(node); + } + + @Test + public void testPostStart() { + assertTrue(lifecycle.getPostStart().isPresent()); + assertEquals(IHandler.EXEC, lifecycle.getPostStart().get().getType()); + IExecAction exec = (IExecAction)lifecycle.getPostStart().get(); + assertEquals(1, exec.getCommand().size()); + assertEquals("postcmd1", exec.getCommand().get(0)); + } + + @Test + public void testPreStop() { + assertTrue(lifecycle.getPreStop().isPresent()); + assertEquals(IHandler.EXEC, lifecycle.getPreStop().get().getType()); + IExecAction exec = (IExecAction)lifecycle.getPreStop().get(); + assertEquals(2, exec.getCommand().size()); + assertEquals("precmd1", exec.getCommand().get(0)); + assertEquals("precmd2", exec.getCommand().get(1)); + } + + @Test + public void testBuilder() { + lifecycle = new Lifecycle.Builder() + .preStop(new ExecAction.Builder() + .command("cmd1") + .build()) + .postStart(new ExecAction.Builder() + .command("cmd2") + .build()) + .build(); + + assertTrue(lifecycle.getPreStop().isPresent()); + assertTrue(lifecycle.getPostStart().isPresent()); + + assertEqualJson("{\"preStop\":{\"exec\":{\"command\":[\"cmd1\"]}},\"postStart\":{\"exec\":{\"command\":[\"cmd2\"]}}}", lifecycle.toJson()); + } + + private static void assertEqualJson(String expected, String actual) { + ModelNode expectedNode = ModelNode.fromJSONString(expected); + ModelNode actualNode = ModelNode.fromJSONString(actual); + assertEquals(expectedNode.toJSONString(true), actualNode.toJSONString(true)); + } +} + diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index a9256122..37668034 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -16,18 +16,15 @@ import java.util.Optional; import java.util.Set; +import com.openshift.internal.restclient.model.*; +import com.openshift.restclient.model.*; import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; -import com.openshift.internal.restclient.model.Pod; -import com.openshift.internal.restclient.model.Port; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.model.IContainer; -import com.openshift.restclient.model.IPod; -import com.openshift.restclient.model.IPort; import com.openshift.restclient.utils.Samples; /** @@ -81,11 +78,19 @@ public void getContainerPorts() { public void testAddContainer() { Collection initial = pod.getContainers(); IContainer foo = pod.addContainer("foo"); - foo.setLifecycle("bar"); + + + foo.setLifecycle(new Lifecycle.Builder() + .preStop(new ExecAction.Builder() + .command("cmd1") + .command("cmd2") + .build()) + .build()); + Collection containers = pod.getContainers(); assertEquals(initial.size() + 1, containers.size()); - Optional container = containers.stream().filter(c->"foo".equals(c.getName()) && "bar".equals(c.getLifecycle())).findFirst(); + Optional container = containers.stream().filter(c->"foo".equals(c.getName()) && "cmd1".equals(((IExecAction)c.getLifecycle().getPreStop().get()).getCommand().get(0))).findFirst(); assertTrue("Exp. the container to be added", container.isPresent()); } } diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 75af955e..c16a2738 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -57,7 +57,7 @@ public enum Samples { V1_EMPTYDIR_VOLUME_SOURCE("openshift3/v1_empty_dir_volume_source.json"), V1_SECRET_VOLUME_SOURCE("openshift3/v1_secret_volume_source.json"), V1_PVC_VOLUME_SOURCE("openshift3/v1_pvc_volume_source.json"), - + V1_LIFECYCLE("openshift3/v1_lifecycle.json"), V1_DOCKER_IMAGE_MANIFEST("dockerregistry/v1_image_manifest.json"); private static final String SAMPLES_FOLDER = "/samples/"; diff --git a/src/test/resources/samples/openshift3/v1_lifecycle.json b/src/test/resources/samples/openshift3/v1_lifecycle.json new file mode 100644 index 00000000..2d156c94 --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_lifecycle.json @@ -0,0 +1,17 @@ +{ + "preStop": { + "exec":{ + "command": [ + "precmd1", + "precmd2" + ] + } + }, + "postStart": { + "exec": { + "command": [ + "postcmd1" + ] + } + } +} From eda5420c6ab10ac8ccf3eef002252bfc8f2ebf18 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 7 Sep 2016 10:16:17 +0200 Subject: [PATCH 021/258] [JBIDE-22883] bumped to 5.2.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index eebd0081..6ce5b127 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.1.0-SNAPSHOT + 5.2.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 8510253c20d2bb20459cc7549ff00a315ac209bd Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 9 Sep 2016 22:25:17 +0200 Subject: [PATCH 022/258] [JBIDE-23015] - Creating a route should have a default port - Extends Route model Signed-off-by: Jeff MAURY --- .../internal/restclient/model/Route.java | 51 ++++++++++++++++++- .../restclient/model/route/IRoute.java | 14 +++++ .../restclient/model/route/ITargetPort.java | 45 ++++++++++++++++ .../restclient/model/v1/RouteTest.java | 41 ++++++++++++++- .../openshift/restclient/utils/Samples.java | 2 + .../openshift3/v1_route_port_name.json | 31 +++++++++++ .../openshift3/v1_route_port_numeric.json | 31 +++++++++++ 7 files changed, 211 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/openshift/restclient/model/route/ITargetPort.java create mode 100644 src/test/resources/samples/openshift3/v1_route_port_name.json create mode 100644 src/test/resources/samples/openshift3/v1_route_port_numeric.json diff --git a/src/main/java/com/openshift/internal/restclient/model/Route.java b/src/main/java/com/openshift/internal/restclient/model/Route.java index 08610535..7e8b53af 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Route.java +++ b/src/main/java/com/openshift/internal/restclient/model/Route.java @@ -16,6 +16,7 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.route.IRoute; import com.openshift.restclient.model.route.ITLSConfig; +import com.openshift.restclient.model.route.ITargetPort; /** * @author Jeff Cantrill @@ -32,6 +33,8 @@ public class Route extends KubernetesResource implements IRoute { private static final String ROUTE_TLS_KEY = "spec.tls.key"; private static final String ROUTE_TLS_CACERT = "spec.tls.caCertificate"; private static final String ROUTE_TLS_DESTINATION_CACERT = "spec.tls.destinationCACertificate"; + private static final String ROUTE_PORT = "spec.port"; + private static final String ROUTE_PORT_TARGETPORT = "spec.port.targetPort"; public Route(ModelNode node, IClient client, Map propertyKeys) { @@ -86,8 +89,26 @@ public ITLSConfig createTLSConfig() { } return config; } - - @Override + + @Override + public ITargetPort getPort() { + if (get(ROUTE_PORT).isDefined()) { + return new TargetPort(); + } + return null; + } + + @Override + public ITargetPort createPort() { + ITargetPort targetPort = getPort(); + if (targetPort == null) { + get(ROUTE_PORT).set(new ModelNode()); + targetPort = new TargetPort(); + } + return targetPort; + } + + @Override public String getURL() { String scheme = getTLSConfig() == null ? "http" : "https"; String path = getPath(); @@ -152,4 +173,30 @@ public void setDestinationCertificate(String destinationCertificate) { } } + + private class TargetPort implements ITargetPort { + @Override + public String getTargetPortName() { + return asString(ROUTE_PORT_TARGETPORT); + } + + @Override + public void setTargetPortName(String portName) { + get(ROUTE_PORT_TARGETPORT).set(portName); + } + + @Override + public Integer getTargetPort() { + if (has(ROUTE_PORT_TARGETPORT)) { + return asInt(ROUTE_PORT_TARGETPORT); + } else { + return -1; + } + } + + @Override + public void setTargetPort(Integer port) { + get(ROUTE_PORT_TARGETPORT).set(port); + } + } } diff --git a/src/main/java/com/openshift/restclient/model/route/IRoute.java b/src/main/java/com/openshift/restclient/model/route/IRoute.java index e3963309..d4498a88 100644 --- a/src/main/java/com/openshift/restclient/model/route/IRoute.java +++ b/src/main/java/com/openshift/restclient/model/route/IRoute.java @@ -87,4 +87,18 @@ public interface IRoute extends IResource { * @return java.lang.String The route url */ String getURL(); + + /** + * Retrieves the target port of this route. + * + * @return target port or null if there is not one + */ + ITargetPort getPort(); + + /** + * Create a target port if one is not defined or return + * the existing one + * @return + */ + ITargetPort createPort(); } diff --git a/src/main/java/com/openshift/restclient/model/route/ITargetPort.java b/src/main/java/com/openshift/restclient/model/route/ITargetPort.java new file mode 100644 index 00000000..4b086322 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/route/ITargetPort.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.restclient.model.route; + +/** + * Target port for routes. If both attributes are present, then name is preferred. + * + * @author Jeff Maury + */ +public interface ITargetPort { + + /** + * Returns the target port name. + * + * @return target port name. + */ + String getTargetPortName(); + + /** + * Sets the target port name. + * + * @param portName target port name + */ + void setTargetPortName(String portName); + + /** + * Returns the target port value. + * + * @return target port value. + */ + Integer getTargetPort(); + + /** + * Sets the target port value. + * + * @param portName target port value + */ + void setTargetPort(Integer port); +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java index 810f0d2f..b910d96f 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java @@ -22,6 +22,7 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.route.IRoute; import com.openshift.restclient.model.route.ITLSConfig; +import com.openshift.restclient.model.route.ITargetPort; import com.openshift.restclient.model.route.TLSTerminationType; import com.openshift.restclient.utils.Samples; @@ -51,7 +52,7 @@ public void getTLSConfigWhenUndefined() { assertNull(tlsConfig); } - @Test + @Test public void createTLSConfigWhenUndefined() { ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); @@ -63,7 +64,43 @@ public void createTLSConfigWhenUndefined() { assertEquals("", tls.getKey()); } - @Test + @Test + public void getPortWhenUndefined() { + ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); + route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); + ITargetPort port = route.getPort(); + assertNull(port); + } + + @Test + public void createPortWhenUndefined() { + ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); + route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); + ITargetPort port = route.createPort(); + assertNotNull(port); + assertEquals("", port.getTargetPortName()); + assertEquals(-1, port.getTargetPort().intValue()); + } + + @Test + public void getNumericPortWhenDefined() { + ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_PORT_NUMERIC.getContentAsString()); + route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); + ITargetPort port = route.getPort(); + assertNotNull(port); + assertEquals(8080, port.getTargetPort().intValue()); + } + + @Test + public void getNamePortWhenDefined() { + ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_PORT_NAME.getContentAsString()); + route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); + ITargetPort port = route.getPort(); + assertNotNull(port); + assertEquals("http-8080", port.getTargetPortName()); + } + + @Test public void testGetHost() { assertEquals("www.example.com", route.getHost()); } diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index c16a2738..6c8728c3 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -45,6 +45,8 @@ public enum Samples { V1_ROLE_BINDING("openshift3/v1_role_binding.json"), V1_ROUTE("openshift3/v1_route.json"), V1_ROUTE_WO_TLS("openshift3/v1_route_wo_tls.json"), + V1_ROUTE_PORT_NUMERIC("openshift3/v1_route_port_numeric.json"), + V1_ROUTE_PORT_NAME("openshift3/v1_route_port_name.json"), V1_SERVICE("openshift3/v1_service.json"), V1_SERVICE_ACCOUNT("openshift3/v1_service_account.json"), V1_Status("openshift3/v1_status.json"), diff --git a/src/test/resources/samples/openshift3/v1_route_port_name.json b/src/test/resources/samples/openshift3/v1_route_port_name.json new file mode 100644 index 00000000..14f8ed35 --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_route_port_name.json @@ -0,0 +1,31 @@ +{ + "kind": "Route", + "apiVersion": "v1", + "metadata": { + "name": "route-edge", + "namespace": "test", + "selfLink": "/osapi/v1beta3/namespaces/test/routes/route-edge", + "uid": "5dfdb081-0fab-11e5-9467-080027893417", + "resourceVersion": "383", + "creationTimestamp": "2015-06-10T20:00:39Z", + "labels": { + "foo": "bar", + "template": "application-template-stibuild" + }, + "annotations": { + "openshift.io/host.generated": "false" + } + }, + "spec": { + "host": "www.example.com", + "path" : "/abc", + "to": { + "kind": "Service", + "name": "frontend" + }, + "port": { + "targetPort": "http-8080" + } + }, + "status": {} +} diff --git a/src/test/resources/samples/openshift3/v1_route_port_numeric.json b/src/test/resources/samples/openshift3/v1_route_port_numeric.json new file mode 100644 index 00000000..36db0db6 --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_route_port_numeric.json @@ -0,0 +1,31 @@ +{ + "kind": "Route", + "apiVersion": "v1", + "metadata": { + "name": "route-edge", + "namespace": "test", + "selfLink": "/osapi/v1beta3/namespaces/test/routes/route-edge", + "uid": "5dfdb081-0fab-11e5-9467-080027893417", + "resourceVersion": "383", + "creationTimestamp": "2015-06-10T20:00:39Z", + "labels": { + "foo": "bar", + "template": "application-template-stibuild" + }, + "annotations": { + "openshift.io/host.generated": "false" + } + }, + "spec": { + "host": "www.example.com", + "path" : "/abc", + "to": { + "kind": "Service", + "name": "frontend" + }, + "port": { + "targetPort": 8080 + } + }, + "status": {} +} From 1b08297abb3c3614ff68bc261e1bb470025efeb1 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 16 Sep 2016 09:53:49 +0200 Subject: [PATCH 023/258] [JBIDE-23014] - Allow connections to configure the cluster namespace from which to get clusterwide templates - Extend IProjectTemplateList to allow custom common namespace Signed-off-by: Jeff MAURY --- .../resources/ProjectTemplateListCapability.java | 11 ++++++++--- .../capability/resources/IProjectTemplateList.java | 8 ++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java index e59748f9..6cef47f8 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java @@ -42,9 +42,14 @@ public Collection getTemplates() { return client.list(ResourceKind.TEMPLATE, project.getNamespace()); } - @Override - public Collection getCommonTemplates() { - return client.list(ResourceKind.TEMPLATE,COMMON_NAMESPACE); + @Override + public Collection getCommonTemplates() { + return getCommonTemplates(COMMON_NAMESPACE); + } + + @Override + public Collection getCommonTemplates(String clusterNamespace) { + return client.list(ResourceKind.TEMPLATE,clusterNamespace==null?COMMON_NAMESPACE:clusterNamespace); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateList.java b/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateList.java index 08d1c828..29e1747b 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateList.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateList.java @@ -30,4 +30,12 @@ public interface IProjectTemplateList extends ICapability { * @return */ Collection getCommonTemplates(); + + /** + * Retrieve the common templates from the server (e.g. 'openshift' namespace) + * @return + */ + default Collection getCommonTemplates(String clusterNamespace) { + throw new UnsupportedOperationException(); + } } From 1f25a80ce73e3789d7fa7a081a72ade122120da6 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 19 Sep 2016 17:02:15 +0200 Subject: [PATCH 024/258] [OSJC-271] allow accessing template label within rc --- .../model/ReplicationController.java | 5 ++++ .../model/IReplicationController.java | 7 ++++- .../model/v1/ReplicationControllerTest.java | 27 ++++++++++++++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java index 23d22370..a7809495 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java +++ b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java @@ -247,6 +247,11 @@ public Collection getContainers() { return Collections.emptyList(); } + @Override + public Map getTemplateLabels() { + return asMap(SPEC_TEMPLATE_LABELS); + } + @Override public void addTemplateLabel(String key, String value) { ModelNode labels = get(SPEC_TEMPLATE_LABELS); diff --git a/src/main/java/com/openshift/restclient/model/IReplicationController.java b/src/main/java/com/openshift/restclient/model/IReplicationController.java index 9a0d4581..0ec75bad 100644 --- a/src/main/java/com/openshift/restclient/model/IReplicationController.java +++ b/src/main/java/com/openshift/restclient/model/IReplicationController.java @@ -14,7 +14,6 @@ import java.util.Set; import com.openshift.restclient.images.DockerImageURI; -import com.openshift.restclient.model.volume.IVolume; import com.openshift.restclient.model.volume.IVolumeSource; /** @@ -162,6 +161,12 @@ public interface IReplicationController extends IResource{ */ Collection getContainers(); + /** + * Returns the labels for the template in this replication controller + * @return + */ + Map getTemplateLabels(); + /** * Add or update a label to the template spec; * @param key diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java index 7fc0695d..7be4b1b2 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java @@ -9,6 +9,8 @@ package com.openshift.internal.restclient.model.v1; import static com.openshift.internal.util.JBossDmrExtentions.getPath; +import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.MapAssert.*; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -17,11 +19,16 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; -import com.openshift.internal.restclient.model.volume.EmptyDirVolumeSource; -import com.openshift.internal.restclient.model.volume.SecretVolumeSource; -import com.openshift.restclient.model.volume.ISecretVolumeSource; import org.jboss.dmr.ModelNode; import org.json.JSONException; import org.junit.Before; @@ -31,6 +38,8 @@ import com.openshift.internal.restclient.model.ModelNodeBuilder; import com.openshift.internal.restclient.model.ReplicationController; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; +import com.openshift.internal.restclient.model.volume.EmptyDirVolumeSource; +import com.openshift.internal.restclient.model.volume.SecretVolumeSource; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.images.DockerImageURI; @@ -290,6 +299,16 @@ public void testAddContainerAllowsContainerToBeFurtherManipulated() throws JSON JSONAssert.assertEquals(exp.toJSONString(false), container.toJSONString(), true); } + + @Test + public void shouldReturnTemplateLabels() { + Map labels = rc.getTemplateLabels(); + assertThat(labels) + .hasSize(3) + .includes(entry("deployment", "database-1")) + .includes(entry("deploymentconfig", "database")) + .includes(entry("name", "database")); + } @Test public void testSetVolumes() { From 817c5e219b53ea6a54c6752983989fea8c6dbac1 Mon Sep 17 00:00:00 2001 From: pweil- Date: Wed, 21 Sep 2016 07:55:12 -0400 Subject: [PATCH 025/258] fix testing section of README for numbered list --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9d74a4b4..5f68f48f 100755 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ Testing ------- To run the integration tests: + 1. Define a user with cluster admin privilege 1. Download the oc binary 1. Run the tests: `mvn integration-test -Pintegration-tests -DserverURL=https://localhost:8443 -Ddefault.cluster.admin=foo -Ddefault.cluster.password=bar -Ddefault.openshift.location=/tmp/oc` From d4650b3c6b2ffc9dcbf0b3aaed2b4b9f57ddf4f4 Mon Sep 17 00:00:00 2001 From: jupierce Date: Tue, 27 Sep 2016 11:14:14 -0400 Subject: [PATCH 026/258] Adding environment variable support to BuildRequest --- .../capability/resources/BuildTrigger.java | 11 +++- .../restclient/model/build/BuildRequest.java | 24 +++++--- .../resources/IBuildTriggerable.java | 11 +++- .../restclient/model/build/IBuildRequest.java | 8 +++ .../model/build/BuildRequestTest.java | 59 +++++++++++++++++++ 5 files changed, 101 insertions(+), 12 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java index d4c300d2..ebb76878 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java @@ -11,6 +11,7 @@ package com.openshift.internal.restclient.capability.resources; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import org.apache.commons.lang.StringUtils; @@ -37,6 +38,7 @@ public class BuildTrigger implements IBuildTriggerable { private final String subresource; private String commitId; private List causes; + private HashMap envVars = new HashMap(); public BuildTrigger(IBuildConfig buildConfig, IClient client) { this.resource = buildConfig; @@ -68,6 +70,7 @@ public IBuild trigger() { if(StringUtils.isNotEmpty(commitId)) request.setCommitId(commitId); causes.forEach(c->request.addBuildCause(c)); + envVars.forEach((name, value)->request.setEnvironmentVariable(name, value)); return client.create(resource.getKind(), resource.getNamespace(), resource.getName(), subresource, request); } @@ -97,7 +100,11 @@ public void addBuildCause(String cause) { public List getBuildCauses() { return new ArrayList<>(causes); } - - + + @Override + public void setEnvironmentVariable(String name, String value) { + envVars.put(name, value); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java index 99e8d6b0..8a541e02 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java @@ -10,15 +10,14 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.build; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.jboss.dmr.ModelNode; - import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.restclient.IClient; import com.openshift.restclient.model.build.IBuildRequest; +import org.jboss.dmr.ModelNode; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; /** * @@ -26,7 +25,7 @@ * */ public class BuildRequest extends KubernetesResource implements IBuildRequest{ - + private static final String COMMIT = "commit"; private static final String GIT = "git"; private static final String BIGGIT = "Git"; @@ -36,7 +35,8 @@ public class BuildRequest extends KubernetesResource implements IBuildRequest{ private static final String REVISION_TYPE = REVISION + "." + TYPE; private static final String TRIGGERED_BY = "triggeredBy"; private static final String MESSAGE = "message"; - + private static final String ENV = "env"; + public BuildRequest(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); @@ -73,4 +73,12 @@ public List getBuildCauses() { return ret; } + @Override + public void setEnvironmentVariable(String name, String value) { + ModelNode envs = get(ENV); + ModelNode entry = envs.add(); + entry.get(NAME).set(name); + entry.get(VALUE).set(value); + } + } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java b/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java index 1cfd9514..0caeb75f 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java @@ -10,11 +10,11 @@ ******************************************************************************/ package com.openshift.restclient.capability.resources; -import java.util.List; - import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.model.IBuild; +import java.util.List; + /** * Capability to trigger a build based on the build configuration * @author Jeff Cantrill @@ -64,4 +64,11 @@ public interface IBuildTriggerable extends ICapability { */ List getBuildCauses(); + /** + * Sets an environment variable for this build request + * @param name The name of the environment variable + * @param value The value of the environment variable + */ + void setEnvironmentVariable(String name, String value); + } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java b/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java index 481dfd0e..afefd555 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java @@ -46,4 +46,12 @@ public interface IBuildRequest extends IResource { * @return list of reasons for the build */ List getBuildCauses(); + + /** + * Sets an environment variable in this build request + * @param name The name of the environment variable to set + * @param value The value of the variable + */ + void setEnvironmentVariable(String name, String value); + } diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java new file mode 100644 index 00000000..c18f39dc --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.internal.restclient.model.build; + +import com.openshift.internal.restclient.model.BuildConfig; +import com.openshift.restclient.IClient; +import com.openshift.restclient.images.DockerImageURI; +import com.openshift.restclient.model.build.BuildStrategyType; +import com.openshift.restclient.model.build.IBuildStrategy; +import com.openshift.restclient.model.build.ICustomBuildStrategy; +import com.openshift.restclient.model.build.IDockerBuildStrategy; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; + +import static com.openshift.internal.util.JBossDmrExtentions.getPath; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public class BuildRequestTest { + @Mock private IClient client; + private BuildRequest config; + private ModelNode node = new ModelNode(); + + @Before + public void setup(){ + config = new BuildRequest(node, client, null); + } + + @Test + public void testBuildRequestEnvVars(){ + + config.setEnvironmentVariable( "env1", "value1" ); + assertEquals( 1, node.get( "env" ).asList().size() ); + + config.setEnvironmentVariable( "env2", "value2" ); + assertEquals( 2, node.get( "env" ).asList().size() ); + + for ( ModelNode mn : node.get( "env" ).asList() ) { + if ( mn.get("name").asString().equals( "env1" ) ) { + assertEquals(mn.get("value").asString(), "value1"); + } else if (mn.get("name").asString().equals("env2")) { + assertEquals(mn.get( "value").asString(), "value2"); + } else { + fail( "Unexpected environment variable: " + mn.toJSONString(false) ); + } + } + + } + +} From e4db43f9b8186a22dd1d7c980bc88eb7c6cc2d93 Mon Sep 17 00:00:00 2001 From: I003306 Date: Thu, 29 Sep 2016 08:04:28 +0200 Subject: [PATCH 027/258] add SubContext to UrlBuilder --- .../internal/restclient/DefaultClient.java | 9 ++++++++- .../openshift/internal/restclient/URLBuilder.java | 9 +++++++++ .../java/com/openshift/restclient/IClient.java | 14 ++++++++++++++ .../internal/restclient/URLBuilderTest.java | 14 +++++++++++++- 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index fed26b5e..95342e46 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -180,9 +180,15 @@ enum HttpMethod{ private T execute(HttpMethod method, String kind, String namespace, String name, String subresource, IResource payload) { return execute(method.toString(), kind, namespace, name, subresource, payload); } - + @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload) { + + return execute(method, kind, namespace, name, subresource, payload, null); + } + + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, String subContext) { if(ResourceKind.LIST.equals(kind)) throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) @@ -190,6 +196,7 @@ public T execute(String method, String kind, String namesp .name(name) .namespace(namespace) .subresource(subresource) + .subContext(subContext) .build(); try { diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index a5ff4614..7a0170ef 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -48,6 +48,7 @@ public class URLBuilder { private String apiVersion; private String namespace; private String subResource; + private String subContext; /** @@ -114,6 +115,11 @@ public URLBuilder subresource(String value) { return this; } + public URLBuilder subContext(String value) { + this.subContext = value; + return this; + } + /** * Builds a URL based on the information provided. Either a resource or * a resource kind must be provided @@ -160,6 +166,9 @@ private void buildWithNamespaceInPath(StringBuilder url) { if(StringUtils.isNotBlank(subResource)) { url.append("/").append(subResource); } + if (StringUtils.isNotBlank(subContext)){ + url.append("/").append(subContext); + } url = appendParameters(url); } diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index d2fe1267..fdeabd46 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -138,6 +138,20 @@ public interface IClient extends ICapable, Cloneable { */ T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload); + /** + * Raw execution of a request + * @param httpMethod HttpMethod (e.g. POST) + * @param kind + * @param namespace + * @param name + * @param subresource subresource or capability + * @param payload the payload to sumit. only valid on non-get operations + * @param subcontext additional subContext + * @return + */ + T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload, String subcontext); + + /** * * @return the base URL of this endpoint diff --git a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java index 2d600b6c..30b8ff49 100644 --- a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java @@ -85,7 +85,19 @@ public void testAddingASubResource() { .build().toString(); assertEquals(String.format("%s/api/v1/namespaces/foo/replicationcontrollers/bar/status", BASE_URL),url.toString()); } - + + @Test + public void testAddingASubContext() { + IResource resource = givenAResource(ResourceKind.POD, KubernetesAPIVersion.v1, "https:demo-app-8-3gehi:8778"); + String url = builder. + resource(resource) + .name("bar") + .subresource("proxy") + .subContext("jolokia/exec/java.util.logging:type=Logging/getLoggerLevel/abc") + .build().toString(); + assertEquals(String.format("%s/api/v1/namespaces/https:demo-app-8-3gehi:8778/pods/bar/proxy/jolokia/exec/java.util.logging:type=Logging/getLoggerLevel/abc", BASE_URL),url.toString()); + } + private String whenBuildingTheURLFor(IResource resource, String namespace) { return builder. resource(resource) From 692e7bea9d92d54f3e757b6a3a2e12da7dca04ac Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 24 Aug 2016 11:03:35 -0400 Subject: [PATCH 028/258] [JBIDE-23030] Add dc#scale capability --- .../internal/restclient/DefaultClient.java | 20 ++- .../internal/restclient/ResourceFactory.java | 40 +++--- .../api/capabilities/ScaleCapability.java | 66 +++++++++ .../restclient/api/models/TypeMeta.java | 46 +++++++ .../restclient/apis/TypeMetaFactory.java | 106 +++++++++++++++ .../apis/autoscaling/models/Scale.java | 118 ++++++++++++++++ .../capability/AbstractCapability.java | 48 +++++++ .../capability/CapabilityInitializer.java | 8 ++ .../restclient/model/JSONSerializeable.java | 18 +++ .../model/ReplicationController.java | 3 + .../com/openshift/restclient/IClient.java | 21 ++- .../restclient/IResourceFactory.java | 12 +- .../restclient/api/ITypeFactory.java | 43 ++++++ .../api/capabilities/IScalable.java | 31 +++++ .../restclient/api/models/IAnnotatable.java | 51 +++++++ .../api/models/IApiVersionable.java | 26 ++++ .../restclient/api/models/IKindable.java | 27 ++++ .../restclient/api/models/ILabelable.java | 35 +++++ .../restclient/api/models/INameSetable.java | 27 ++++ .../api/models/INamespaceSetable.java | 27 ++++ .../restclient/api/models/IObjectMeta.java | 44 ++++++ .../restclient/api/models/ITypeMeta.java | 22 +++ .../apis/autoscaling/models/IScale.java | 36 +++++ .../restclient/http/IHttpConstants.java | 1 + .../restclient/model/Annotatable.java | 40 ++---- .../openshift/restclient/model/IResource.java | 29 +--- .../restclient/IntegrationTestHelper.java | 31 ++++- .../ScaleCapabilityIntegrationTest.java | 127 ++++++++++++++++++ .../restclient/apis/TypeMetaFactoryTest.java | 54 ++++++++ .../extensions/model/v1beta1/ScaleTest.java | 67 +++++++++ .../model/v1/UnrecognizedResourceTest.java | 2 +- .../openshift/restclient/utils/Samples.java | 3 + .../openshiftv3IntegrationTest.properties | 2 +- .../api/extensions/v1beta1_scale.json | 15 +++ 34 files changed, 1147 insertions(+), 99 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java create mode 100644 src/main/java/com/openshift/internal/restclient/api/models/TypeMeta.java create mode 100644 src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java create mode 100644 src/main/java/com/openshift/internal/restclient/apis/autoscaling/models/Scale.java create mode 100644 src/main/java/com/openshift/internal/restclient/capability/AbstractCapability.java create mode 100644 src/main/java/com/openshift/restclient/api/ITypeFactory.java create mode 100644 src/main/java/com/openshift/restclient/api/capabilities/IScalable.java create mode 100644 src/main/java/com/openshift/restclient/api/models/IAnnotatable.java create mode 100644 src/main/java/com/openshift/restclient/api/models/IApiVersionable.java create mode 100644 src/main/java/com/openshift/restclient/api/models/IKindable.java create mode 100644 src/main/java/com/openshift/restclient/api/models/ILabelable.java create mode 100644 src/main/java/com/openshift/restclient/api/models/INameSetable.java create mode 100644 src/main/java/com/openshift/restclient/api/models/INamespaceSetable.java create mode 100644 src/main/java/com/openshift/restclient/api/models/IObjectMeta.java create mode 100644 src/main/java/com/openshift/restclient/api/models/ITypeMeta.java create mode 100644 src/main/java/com/openshift/restclient/apis/autoscaling/models/IScale.java create mode 100644 src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/apis/TypeMetaFactoryTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/apis/extensions/model/v1beta1/ScaleTest.java create mode 100644 src/test/resources/samples/openshift3/api/extensions/v1beta1_scale.json diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 95342e46..5ba48e65 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -25,6 +25,7 @@ import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.authorization.AuthorizationContext; +import com.openshift.internal.restclient.model.JSONSerializeable; import com.openshift.internal.restclient.okhttp.WatchClient; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; @@ -34,6 +35,7 @@ import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.UnsupportedOperationException; +import com.openshift.restclient.api.ITypeFactory; import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.ICapability; @@ -181,14 +183,22 @@ private T execute(HttpMethod method, String kind, String n return execute(method.toString(), kind, namespace, name, subresource, payload); } + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, String subContext) { + return (T) execute(this.factory, method, kind, namespace, name, subresource, subContext, payload); + } + + @Override @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload) { - - return execute(method, kind, namespace, name, subresource, payload, null); + return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload); } @SuppressWarnings("unchecked") - public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, String subContext) { + public T execute(ITypeFactory factory, String method, String kind, String namespace, String name, String subresource, String subContext, JSONSerializeable payload) { + if(factory == null) { + throw new OpenShiftException("ITypeFactory is null while trying to call IClient#execute"); + } if(ResourceKind.LIST.equals(kind)) throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) @@ -207,14 +217,14 @@ public T execute(String method, String kind, String namesp try(Response result = client.newCall(request).execute()){ String response = result.body().string(); LOGGER.debug("Response: {}", response); - return (T) factory.create(response); + return (T) factory.createInstanceFrom(response); } } catch (IOException e){ throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); } } - private RequestBody getPayload(String method, IResource payload) { + private RequestBody getPayload(String method, JSONSerializeable payload) { switch(method.toUpperCase()){ case "GET": case "DELETE": diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 158c240c..1f93edcd 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; @@ -139,22 +140,17 @@ public List createList(String json, String kind){ private List buildList(final String version, List items, String kind) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { List resources = new ArrayList(items.size()); for (ModelNode item : items) { - resources.add(create(item, version, kind, false)); + resources.add(create(item, version, kind)); } return resources; } @Override @SuppressWarnings("unchecked") - public T create(InputStream input) { - return (T) create(input, false); - } - - @Override - public IResource create(InputStream input, boolean strict) { + public IResource create(InputStream input) { try { String resource = IOUtils.toString(input, "UTF-8"); - return create(resource, strict); + return create(resource); } catch (IOException e) { throw new ResourceFactoryException(e, "There was an exception creating the resource from the InputStream"); } @@ -162,18 +158,18 @@ public IResource create(InputStream input, boolean strict) { @Override - @SuppressWarnings("unchecked") - public T create(String response) { - return (T) create(response, false); + public Object createInstanceFrom(String response) { + return create(response); } @Override - public IResource create(String response, boolean strict) { + @SuppressWarnings("unchecked") + public T create(String response) { try { ModelNode node = ModelNode.fromJSONString(response); String version = node.get(APIVERSION).asString(); String kind = node.get(KIND).asString(); - return create(node, version, kind, strict); + return (T) create(node, version, kind); } catch (UnsupportedVersionException e) { throw e; }catch(Exception e) { @@ -185,15 +181,10 @@ public IResource create(String response, boolean strict) { @Override @SuppressWarnings("unchecked") public T create(String version, String kind) { - return (T) create(version, kind, false); + return (T) create(new ModelNode(), version, kind); } - @Override - public IResource create(String version, String kind, boolean strict) { - return create(new ModelNode(), version, kind, strict); - } - - private IResource create(ModelNode node, String version, String kind, boolean strict) { + private IResource create(ModelNode node, String version, String kind) { try { node.get(APIVERSION).set(version); node.get(KIND).set(kind.toString()); @@ -218,7 +209,7 @@ private IResource create(ModelNode node, String version, String kind, boolean st public T stub(String kind, String name, String namespace) { //TODO get k8e or os String version = client.getOpenShiftAPIVersion(); - KubernetesResource resource = (KubernetesResource) create(version, kind, true); + KubernetesResource resource = (KubernetesResource) create(version, kind); resource.setName(name); resource.setNamespace(namespace); if(StringUtils.isNotEmpty(namespace)) { @@ -227,6 +218,11 @@ public T stub(String kind, String name, String namespace) return (T) resource; } + @Override + public Object stubKind(String kind, Optional name, Optional namespace) { + return stub(kind, name.get(), namespace.get()); + } + @Override public T stub(String kind, String name) { return stub(kind, name, null); @@ -236,7 +232,5 @@ public T stub(String kind, String name) { public void setClient(IClient client) { this.client = client; } - - } diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java new file mode 100644 index 00000000..55a673a5 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.api.capabilities; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import com.openshift.internal.restclient.capability.AbstractCapability; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.api.ITypeFactory; +import com.openshift.restclient.api.capabilities.IScalable; +import com.openshift.restclient.apis.autoscaling.models.IScale; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.model.IReplicationController; + +/** + * Implementation of the scalable interface. Applies + * to a deploymentconfig for the moment + * @author jeff.cantrill + * + */ +public class ScaleCapability extends AbstractCapability implements IScalable { + + private static final Map ARG_KINDS = new HashMap<>(); + static { + ARG_KINDS.put(ResourceKind.DEPLOYMENT_CONFIG, "extensions/v1beta1.Scale"); + ARG_KINDS.put(ResourceKind.REPLICATION_CONTROLLER, "autoscaling/v1.Scale"); + } + + private static final int MIN_VALUE = 0; + private static final String CAPABILITY = "scale"; + private final IClient client; + private IReplicationController rc; + private final ITypeFactory factory; + + public ScaleCapability(IReplicationController rc, IClient client, ITypeFactory factory) { + super(rc, client, CAPABILITY); + this.client = client; + this.rc = rc; + this.factory = factory; + } + + @Override + public String getName() { + return ScaleCapability.class.getSimpleName(); + } + + @Override + public IScale scaleTo(int replicas) { + replicas = replicas >= MIN_VALUE ? replicas : MIN_VALUE; + IScale arg = (IScale) factory.stubKind(ARG_KINDS.get(rc.getKind()), Optional.of(rc.getName()), Optional.of(rc.getNamespace())); + arg.setSpecReplicas(replicas); + return (IScale) client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespace(), rc.getName(), CAPABILITY, null, arg); + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/api/models/TypeMeta.java b/src/main/java/com/openshift/internal/restclient/api/models/TypeMeta.java new file mode 100644 index 00000000..ec539ebb --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/api/models/TypeMeta.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.api.models; + +import static com.openshift.internal.util.JBossDmrExtentions.asString; + +import java.util.Map; + +import org.jboss.dmr.ModelNode; + +import com.openshift.internal.restclient.model.ModelNodeAdapter; +import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; +import com.openshift.restclient.api.models.ITypeMeta; + +public class TypeMeta extends ModelNodeAdapter implements ITypeMeta, ResourcePropertyKeys { + + /** + * + * @param node + * @param propertyKeys overrides based on version + */ + public TypeMeta(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public String getApiVersion() { + return asString(getNode(), getPropertyKeys(), APIVERSION ); + } + + @Override + public String getKind() { + return asString(getNode(), getPropertyKeys(), KIND); + } + + + +} diff --git a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java new file mode 100644 index 00000000..c9b492ae --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java @@ -0,0 +1,106 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.apis; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.lang.StringUtils; +import org.jboss.dmr.ModelNode; + +import com.openshift.internal.restclient.api.models.TypeMeta; +import com.openshift.internal.restclient.apis.autoscaling.models.Scale; +import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; +import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; +import com.openshift.internal.util.JBossDmrExtentions; +import com.openshift.restclient.OpenShiftException; +import com.openshift.restclient.ResourceFactoryException; +import com.openshift.restclient.UnsupportedVersionException; +import com.openshift.restclient.api.ITypeFactory; +import com.openshift.restclient.api.models.INameSetable; +import com.openshift.restclient.api.models.INamespaceSetable; +import com.openshift.restclient.api.models.ITypeMeta; + +public class TypeMetaFactory implements ITypeFactory, ResourcePropertyKeys { + + private static final String DELIMITER = "."; + private static final Map> IMPL_MAP = new HashMap<>(); + + static { + IMPL_MAP.put("Scale", Scale.class); + } + + @Override + public Object stubKind(String kind, Optional name, Optional namespace) { + if(StringUtils.isEmpty(kind)) { + throw new OpenShiftException("Unable to stub a kind when the kind passed in is empty"); + } + try { + String version = ""; + if(kind.contains(DELIMITER)) { + int delimeter = kind.indexOf(DELIMITER); + version = StringUtils.left(kind, delimeter); + kind = StringUtils.right(kind, kind.length() - delimeter - DELIMITER.length()); + } + Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); + ModelNode node = new ModelNode(); + JBossDmrExtentions.set(node, properyKeyMap, APIVERSION, version); + JBossDmrExtentions.set(node, properyKeyMap, KIND, kind); + + ITypeMeta instance = null; + if(IMPL_MAP.containsKey(kind)) { + Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, Map.class); + instance = constructor.newInstance(node, properyKeyMap); + }else { + instance = new TypeMeta(node, properyKeyMap); + } + + if(name.isPresent() && instance instanceof INameSetable) { + ((INameSetable) instance).setName(name.get()); + } + if(namespace.isPresent() && instance instanceof INamespaceSetable) { + ((INamespaceSetable) instance).setNamespace(namespace.get()); + } + + return instance; + } catch (UnsupportedVersionException e) { + throw e; + } catch (Exception e) { + throw new ResourceFactoryException(e,"Unable to stub instance from %s", kind); + } + } + + + + @Override + public Object createInstanceFrom(String response) { + try { + ModelNode node = ModelNode.fromJSONString(response); + String version = node.get(APIVERSION).asString(); + String kind = node.get(KIND).asString(); + + Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); + if(IMPL_MAP.containsKey(kind)) { + Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, Map.class); + return constructor.newInstance(node, properyKeyMap); + } + return new TypeMeta(node, properyKeyMap); + + } catch (UnsupportedVersionException e) { + throw e; + } catch (Exception e) { + throw new ResourceFactoryException(e,"Unable to create from %s", response); + } + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/apis/autoscaling/models/Scale.java b/src/main/java/com/openshift/internal/restclient/apis/autoscaling/models/Scale.java new file mode 100644 index 00000000..b462d8d1 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/apis/autoscaling/models/Scale.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.apis.autoscaling.models; + +import static com.openshift.internal.util.JBossDmrExtentions.*; + +import java.util.Collections; +import java.util.Map; + +import org.jboss.dmr.ModelNode; + +import com.openshift.internal.restclient.api.models.TypeMeta; +import com.openshift.restclient.apis.autoscaling.models.IScale; + +public class Scale extends TypeMeta implements IScale { + + private static final String SPEC_REPLICAS = "spec.replicas"; + + public Scale() { + super(new ModelNode(), Collections.emptyMap()); + } + + /** + * + * @param node + * @param propertyKeys overrides based on version + */ + public Scale(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public int getSpecReplicas() { + return asInt(getNode(), getPropertyKeys(), SPEC_REPLICAS); + } + + @Override + public void setSpecReplicas(int replicas) { + set(getNode(), getPropertyKeys(), SPEC_REPLICAS, replicas); + } + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), METADATA_NAME); + } + + @Override + public void setName(String name) { + set(getNode(), getPropertyKeys(), METADATA_NAME, name); + } + + @Override + public String getCreationTimeStamp() { + return asString(getNode(), getPropertyKeys(), CREATION_TIMESTAMP); + } + + @Override + public String getNamespace() { + return asString(getNode(), getPropertyKeys(), METADATA_NAMESPACE); + } + + @Override + public void setNamespace(String namespace) { + set(getNode(), getPropertyKeys(), METADATA_NAMESPACE, namespace); + } + + + @Override + public String getResourceVersion() { + return asString(getNode(), getPropertyKeys(), METADATA_RESOURCE_VERSION); + } + + @Override + public Map getLabels() { + return asMap(getNode(), getPropertyKeys(), LABELS); + } + + @Override + public void addLabel(String key, String value) { + ModelNode labels = getNode().get(getPath(LABELS)); + labels.get(key).set(value); + } + + @Override + public Map getAnnotations() { + return asMap(getNode(), getPropertyKeys(), ANNOTATIONS); + } + + @Override + public String getAnnotation(String key) { + return getAnnotations().get(key); + } + + @Override + public void setAnnotation(String name, String value) { + if(value == null) return; + ModelNode annotations = get(getNode(), getPropertyKeys(), ANNOTATIONS); + annotations.get(name).set(value); + } + + @Override + public boolean isAnnotatedWith(String key) { + Map annotations = getAnnotations(); + return annotations.containsKey(key); + } + + + + +} diff --git a/src/main/java/com/openshift/internal/restclient/capability/AbstractCapability.java b/src/main/java/com/openshift/internal/restclient/capability/AbstractCapability.java new file mode 100644 index 00000000..0c5dfe7d --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/capability/AbstractCapability.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability; + +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.UnsupportedEndpointException; +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.model.IResource; + +/** + * Capability base + * @author jeff.cantrill + * + */ +public abstract class AbstractCapability implements ICapability { + + private IApiTypeMapper mapper; + private IResource resource; + private final String capability; + + protected AbstractCapability(IResource resource, IClient client, String capability) { + this.capability = capability; + this.resource = resource; + this.mapper = client.adapt(IApiTypeMapper.class); + } + + @Override + public boolean isSupported() { + if(mapper != null) { + try { + return mapper.getEndpointFor(resource.getApiVersion(), resource.getKind()).isSupported(capability); + }catch(UnsupportedEndpointException e) { + //endpoint not found for version/kind + } + } + return false; + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index cf1ad636..114b1726 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -10,6 +10,8 @@ import java.util.Map; +import com.openshift.internal.restclient.api.capabilities.ScaleCapability; +import com.openshift.internal.restclient.apis.TypeMetaFactory; import com.openshift.internal.restclient.capability.resources.BuildCanceller; import com.openshift.internal.restclient.capability.resources.BuildTrigger; import com.openshift.internal.restclient.capability.resources.ClientCapability; @@ -31,6 +33,7 @@ import com.openshift.internal.restclient.model.Service; import com.openshift.internal.restclient.model.build.BuildConfigBuilder; import com.openshift.restclient.IClient; +import com.openshift.restclient.api.capabilities.IScalable; import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.capability.resources.IBuildCancelable; import com.openshift.restclient.capability.resources.IBuildTriggerable; @@ -55,6 +58,7 @@ import com.openshift.restclient.model.IDeploymentConfig; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.IReplicationController; import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.build.IBuildConfigBuilder; @@ -127,6 +131,10 @@ public static void initializeCapabilities(Map, ICap initializeCapability(capabilities, IDeployCapability.class, new DeployCapability(config, client)); } + public static void initializeCapabilities(Map, ICapability> capabilities, IReplicationController rc, IClient client){ + initializeCapability(capabilities, IScalable.class, new ScaleCapability(rc, client, new TypeMetaFactory())); + } + public static void initializeCapabilities(Map, ICapability> capabilities, IResource resource, IClient client){ initializeCapability(capabilities, ITemplateTraceability.class, new TemplateTraceability(resource)); initializeCapability(capabilities, IDeploymentConfigTraceability.class, new DeploymentConfigTraceability(resource, client)); diff --git a/src/main/java/com/openshift/internal/restclient/model/JSONSerializeable.java b/src/main/java/com/openshift/internal/restclient/model/JSONSerializeable.java index 31b74057..4538492a 100644 --- a/src/main/java/com/openshift/internal/restclient/model/JSONSerializeable.java +++ b/src/main/java/com/openshift/internal/restclient/model/JSONSerializeable.java @@ -10,7 +10,25 @@ ******************************************************************************/ package com.openshift.internal.restclient.model; +/** + * Something that can be serialized to JSON + * @author jeff.cantrill + * + */ public interface JSONSerializeable { + /** + * The JSON representation + * @return + */ String toJson(); + + /** + * The JSON representation + * @param compact true if it should be compact; false otherwise + * @return + */ + default String toJson(boolean compact) { + return toJson(); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java index a7809495..65c21bd1 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java +++ b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java @@ -8,6 +8,8 @@ ******************************************************************************/ package com.openshift.internal.restclient.model; +import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -57,6 +59,7 @@ public class ReplicationController extends KubernetesResource implements IReplic public ReplicationController(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); this.propertyKeys = propertyKeys; + initializeCapabilities(getModifiableCapabilities(), this, getClient()); } @Override diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index fdeabd46..b81a3ff7 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -13,6 +13,8 @@ import java.util.List; import java.util.Map; +import com.openshift.internal.restclient.model.JSONSerializeable; +import com.openshift.restclient.api.ITypeFactory; import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.capability.ICapable; import com.openshift.restclient.model.IList; @@ -135,6 +137,7 @@ public interface IClient extends ICapable, Cloneable { * @param subresource subresource or capability * @param payload the payload to sumit. only valid on non-get operations * @return + * */ T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload); @@ -145,12 +148,24 @@ public interface IClient extends ICapable, Cloneable { * @param namespace * @param name * @param subresource subresource or capability - * @param payload the payload to sumit. only valid on non-get operations - * @param subcontext additional subContext + * @param subcontext additional subContext (e.g. jolokia endpoint) + * Raw execution of a request that requires consumers to handle the response * @return */ T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload, String subcontext); - + + /** + * @param factory The factory to use for interpreting the response + * @param httpMethod HttpMethod (e.g. POST) + * @param kind + * @param namespace + * @param name + * @param subresource subresource or capability + * @param payload the payload to sumit. only valid on non-get operations + * @param subcontext additional subContext + * @return the raw payload string + */ + T execute(ITypeFactory factory, String httpMethod, String kind, String namespace, String name, String subresource, String subContext, JSONSerializeable payload); /** * diff --git a/src/main/java/com/openshift/restclient/IResourceFactory.java b/src/main/java/com/openshift/restclient/IResourceFactory.java index 0fca1253..36d034d2 100644 --- a/src/main/java/com/openshift/restclient/IResourceFactory.java +++ b/src/main/java/com/openshift/restclient/IResourceFactory.java @@ -11,6 +11,7 @@ import java.io.InputStream; import java.util.List; +import com.openshift.restclient.api.ITypeFactory; import com.openshift.restclient.model.IResource; /** @@ -19,7 +20,7 @@ * * @author Jeff Cantrill */ -public interface IResourceFactory { +public interface IResourceFactory extends ITypeFactory{ /** * Create a list of resources of the given kind @@ -39,9 +40,6 @@ public interface IResourceFactory { */ T create(String response) ; - @Deprecated - IResource create(String response, boolean strict) ; - /** * Create a resource from a response string * @param input Read the given input stream which assumes the input @@ -51,9 +49,6 @@ public interface IResourceFactory { */ T create(InputStream input) ; - @Deprecated - IResource create(InputStream input, boolean strict) ; - /** * Create(or stub) a resource for a given version and kind * @param version @@ -62,9 +57,6 @@ public interface IResourceFactory { */ T create(String version, String kind); - @Deprecated - IResource create(String version, String kind, boolean strict); - /** * Stub out the given resource kind using a version determined by the factory * @param kind diff --git a/src/main/java/com/openshift/restclient/api/ITypeFactory.java b/src/main/java/com/openshift/restclient/api/ITypeFactory.java new file mode 100644 index 00000000..2a157a63 --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/ITypeFactory.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api; + +import java.util.Optional; + +import com.openshift.restclient.ResourceFactoryException; + +/** + * A factory that is able of producing + * types from a response + * @author jeff.cantrill + * + */ +public interface ITypeFactory { + + /** + * Create a resource from a response string + * @param response + * @return + * @throws ResourceFactoryException if it is unable to create resources + */ + Object createInstanceFrom(String response); + + /** + * Stub out the given resource kind using a version determined by the factory + * @param kind - Required. For arg types it may be in the form of apigroup/version.kind + * @param name - The name of the kind which may only be significant for instances that + * can be persisted by the server (e.g. Service) + * @param namespace - The namespace of the kind which may only be significant for instance + * that can be persisted + * @return + */ + Object stubKind(String kind, Optional name, Optional namespace); +} diff --git a/src/main/java/com/openshift/restclient/api/capabilities/IScalable.java b/src/main/java/com/openshift/restclient/api/capabilities/IScalable.java new file mode 100644 index 00000000..81db7d43 --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/capabilities/IScalable.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.capabilities; + +import com.openshift.restclient.OpenShiftException; +import com.openshift.restclient.apis.autoscaling.models.IScale; +import com.openshift.restclient.capability.ICapability; + +/** + * Allow a resource to scale + * @author jeff.cantrill + * + */ +public interface IScalable extends ICapability { + + /** + * Scale to the desired replicas. Value + * less then 0 will scale to 0 + * @param replicas + * @throws OpenShiftException if there are errors + */ + IScale scaleTo(int replicas); +} diff --git a/src/main/java/com/openshift/restclient/api/models/IAnnotatable.java b/src/main/java/com/openshift/restclient/api/models/IAnnotatable.java new file mode 100644 index 00000000..16e8bfaf --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/IAnnotatable.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +import java.util.Map; + +/** + * A resource that can be annotated + * @author jeff.cantrill + * + */ +public interface IAnnotatable{ + + /** + * Returns true if the resource is annotated with + * the given key + * @param key + * @return true if the annotation key exists + */ + boolean isAnnotatedWith(String key); + + /** + * Retrieves the annotated value for the given key + * @param key + * @return + */ + String getAnnotation(String key); + + /** + * Set the resource annotation + * @param key + * @param value + */ + void setAnnotation(String key, String value); + + /** + * Retrieves the annotations associated with the resource + * @return + */ + Map getAnnotations(); + + +} diff --git a/src/main/java/com/openshift/restclient/api/models/IApiVersionable.java b/src/main/java/com/openshift/restclient/api/models/IApiVersionable.java new file mode 100644 index 00000000..5db900d9 --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/IApiVersionable.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +/** + * A model that can be versioned + * @author jeff.cantrill + * + */ +public interface IApiVersionable { + + /** + * The api version of the resource + * as found at apiVersion + * @return + */ + String getApiVersion(); +} diff --git a/src/main/java/com/openshift/restclient/api/models/IKindable.java b/src/main/java/com/openshift/restclient/api/models/IKindable.java new file mode 100644 index 00000000..939ee58e --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/IKindable.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +/** + * A resource that can describe itself by + * the kind it is + * @author jeff.cantrill + * + */ +public interface IKindable { + + /** + * The kind of the resource as would be found + * at kind + * @return + */ + String getKind(); +} diff --git a/src/main/java/com/openshift/restclient/api/models/ILabelable.java b/src/main/java/com/openshift/restclient/api/models/ILabelable.java new file mode 100644 index 00000000..e05e27de --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/ILabelable.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +import java.util.Map; + +/** + * A resource that can be labeled + * @author jeff.cantrill + * + */ +public interface ILabelable { + + /** + * Retrieves the labels associated with the resource + * @return + */ + Map getLabels(); + + /** + * Add or update a label; + * @param key + * @param value + */ + void addLabel(String key, String value); + +} diff --git a/src/main/java/com/openshift/restclient/api/models/INameSetable.java b/src/main/java/com/openshift/restclient/api/models/INameSetable.java new file mode 100644 index 00000000..8c5a065f --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/INameSetable.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +/** + * A resource where the client can + * define the name on the object + * (e.g. ObjectRef) + * @author jeff.cantrill + * + */ +public interface INameSetable { + + /** + * The name of the resource + * @param name + */ + void setName(String name); +} diff --git a/src/main/java/com/openshift/restclient/api/models/INamespaceSetable.java b/src/main/java/com/openshift/restclient/api/models/INamespaceSetable.java new file mode 100644 index 00000000..f8be2e8c --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/INamespaceSetable.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +/** + * A resource where the client can + * define the namespace on the object + * (e.g. ObjectRef) + * @author jeff.cantrill + * + */ +public interface INamespaceSetable { + + /** + * The namespace for the object ref + * @param namespace + */ + void setNamespace(String namespace); +} diff --git a/src/main/java/com/openshift/restclient/api/models/IObjectMeta.java b/src/main/java/com/openshift/restclient/api/models/IObjectMeta.java new file mode 100644 index 00000000..d5728e1f --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/IObjectMeta.java @@ -0,0 +1,44 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +/** + * ObjectMeta info as defined by the server + * @author jeff.cantrill + * + */ +public interface IObjectMeta extends ILabelable, IAnnotatable { + + /** + * Returns the identifier for this resource + * @return + */ + String getName(); + + /** + * Returns the timestamp of when this resource + * was created + * @return + */ + String getCreationTimeStamp(); + + /** + * Returns the scope of this resource + * @return + */ + String getNamespace(); + + /** + * A value that represents the version of this resource + * @return + */ + String getResourceVersion(); +} diff --git a/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java b/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java new file mode 100644 index 00000000..05924502 --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java @@ -0,0 +1,22 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +import com.openshift.internal.restclient.model.JSONSerializeable; + +/** + * Marker interface to kubernetes TypeMeta + * @author jeff.cantrill + * + */ +public interface ITypeMeta extends IApiVersionable, IKindable, JSONSerializeable { + +} diff --git a/src/main/java/com/openshift/restclient/apis/autoscaling/models/IScale.java b/src/main/java/com/openshift/restclient/apis/autoscaling/models/IScale.java new file mode 100644 index 00000000..3ecb02d3 --- /dev/null +++ b/src/main/java/com/openshift/restclient/apis/autoscaling/models/IScale.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.apis.autoscaling.models; + +import com.openshift.restclient.api.models.INameSetable; +import com.openshift.restclient.api.models.INamespaceSetable; +import com.openshift.restclient.api.models.IObjectMeta; +import com.openshift.restclient.api.models.ITypeMeta; + +/** + * Scale object payload to scalable resources + * @author jeff.cantrill + * + */ +public interface IScale extends ITypeMeta, IObjectMeta, INamespaceSetable, INameSetable { + + /** + * The number of desired replicas + * @return + */ + int getSpecReplicas(); + + /** + * Set the number of desired replicas + * @param replicas + */ + void setSpecReplicas(int replicas); +} diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index cd5d46c7..ba783ab6 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -62,4 +62,5 @@ public interface IHttpConstants { public static final int DEFAULT_READ_TIMEOUT = 2 * 60 * 1000; public static final int NO_TIMEOUT = -1; + static final String PUT = "PUT"; } diff --git a/src/main/java/com/openshift/restclient/model/Annotatable.java b/src/main/java/com/openshift/restclient/model/Annotatable.java index ad6937c4..c664cd6b 100644 --- a/src/main/java/com/openshift/restclient/model/Annotatable.java +++ b/src/main/java/com/openshift/restclient/model/Annotatable.java @@ -10,36 +10,14 @@ ******************************************************************************/ package com.openshift.restclient.model; -import java.util.Map; - -public interface Annotatable { - - /** - * Returns true if the resource is annotated with - * the given key - * @param key - * @return true if the annotation key exists - */ - boolean isAnnotatedWith(String key); - - /** - * Retrieves the annotated value for the given key - * @param key - * @return - */ - String getAnnotation(String key); - - /** - * Set the resource annotation - * @param key - * @param value - */ - void setAnnotation(String key, String value); - - /** - * Retrieves the annotations associated with the resource - * @return - */ - Map getAnnotations(); +import com.openshift.restclient.api.models.IAnnotatable; +/** + * + * @author jeff.cantrill + * + * @deprecated + * {@link IAnnotatable} +*/ +public interface Annotatable extends IAnnotatable{ } diff --git a/src/main/java/com/openshift/restclient/model/IResource.java b/src/main/java/com/openshift/restclient/model/IResource.java index 8b51fb51..0c7a89f4 100644 --- a/src/main/java/com/openshift/restclient/model/IResource.java +++ b/src/main/java/com/openshift/restclient/model/IResource.java @@ -11,6 +11,9 @@ import java.util.Map; import java.util.Set; +import com.openshift.internal.restclient.model.JSONSerializeable; +import com.openshift.restclient.api.models.IAnnotatable; +import com.openshift.restclient.api.models.ITypeMeta; import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.capability.ICapable; @@ -19,7 +22,7 @@ * * @author Jeff Cantrill */ -public interface IResource extends ICapable, Annotatable { +public interface IResource extends ICapable, Annotatable, IAnnotatable, JSONSerializeable, ITypeMeta { Map getMetadata(); @@ -28,16 +31,6 @@ public interface IResource extends ICapable, Annotatable { */ Set> getCapabilities(); - /** - * @return the resource kind - */ - String getKind(); - - /** - * @return the version of this resource - */ - String getApiVersion(); - /** * Returns the timestamp of when this resource * was created @@ -112,17 +105,5 @@ public interface IResource extends ICapable, Annotatable { Map getAnnotations(); String getResourceVersion(); - - /** - * - * @return the json string representing the resource - */ - String toJson(); - - /** - * - * @param compact true if the string should be compact; default: false - * @return the json string representing the resource - */ - String toJson(boolean compact); + } diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index 68a6ebe9..1793ae35 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -9,7 +9,9 @@ package com.openshift.internal.restclient; import java.io.IOException; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Properties; import java.util.Random; @@ -17,23 +19,29 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.openshift.internal.restclient.model.DeploymentConfig; import com.openshift.internal.restclient.model.ModelNodeBuilder; import com.openshift.internal.restclient.model.Pod; +import com.openshift.internal.restclient.model.ReplicationController; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.ClientBuilder; import com.openshift.restclient.IClient; import com.openshift.restclient.NotFoundException; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.images.DockerImageURI; +import com.openshift.restclient.model.IDeploymentConfig; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.IReplicationController; import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.deploy.DeploymentTriggerType; import static org.junit.Assert.fail; /** * @author Jeff Cantrill */ -public class IntegrationTestHelper { +public class IntegrationTestHelper implements ResourcePropertyKeys { public static final long MILLISECONDS_PER_SECOND = 1000; public static final long MILLISECONDS_PER_MIN = MILLISECONDS_PER_SECOND * 60; @@ -103,6 +111,27 @@ public static IPod stubPod(IClient client, IProject project) { .build(); return new Pod(builder, client, new HashMap<>()); } + + public static IDeploymentConfig stubDeploymentConfig(IClient client, IProject project) { + IDeploymentConfig dc = new ResourceFactory(client).create("v1", ResourceKind.DEPLOYMENT_CONFIG); + ((DeploymentConfig)dc).setName("hello-openshift"); + ((DeploymentConfig)dc).setNamespace(project.getName()); + dc.setReplicas(1); + dc.setReplicaSelector("foo","bar"); + dc.addContainer(dc.getName(), new DockerImageURI("openshift/hello-openshift"), new HashSet<>(), Collections.emptyMap(), Collections.emptyList()); + dc.addTrigger(DeploymentTriggerType.CONFIG_CHANGE); + return dc; + } + + public static IReplicationController stubReplicationController(IClient client, IProject project) { + IReplicationController rc = new ResourceFactory(client).create("v1", ResourceKind.REPLICATION_CONTROLLER); + ((ReplicationController)rc).setName("hello-openshift-rc"); + ((ReplicationController)rc).setNamespace(project.getName()); + rc.setReplicas(1); + rc.setReplicaSelector("foo","bar"); + rc.addContainer(rc.getName(), new DockerImageURI("openshift/hello-openshift"), new HashSet<>(), Collections.emptyMap(), Collections.emptyList()); + return rc; + } /** * Loads the properties from the given {@code propertyFileName}, then diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java new file mode 100644 index 00000000..c741550e --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.api.capabilities; + +import static org.junit.Assert.*; + +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.internal.restclient.PodStatusRunningConditional; +import com.openshift.restclient.IClient; +import com.openshift.restclient.IOpenShiftWatchListener; +import com.openshift.restclient.IWatcher; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.api.capabilities.IScalable; +import com.openshift.restclient.apis.autoscaling.models.IScale; +import com.openshift.restclient.capability.CapabilityVisitor; +import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.IReplicationController; +import com.openshift.restclient.model.IResource; + +public class ScaleCapabilityIntegrationTest { + + private static final int REPLICAS = 2; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IClient client; + private IProject project; + private IWatcher watch; + private CountDownLatch initializationLatch = new CountDownLatch(2); + private CountDownLatch replicaLatch = new CountDownLatch(1); + private IReplicationController dc; + private AtomicBoolean foundFirstPod = new AtomicBoolean(false); + private PodStatusRunningConditional conditional = new PodStatusRunningConditional(); + + @Before + public void setUp() throws Exception { + client = helper.createClientForBasicAuth(); + project = helper.generateProject(client); + } + + @After + public void teardown() throws Exception{ + if(watch != null) { + try { + watch.stop(); + }catch(Exception e) { + } + } + IntegrationTestHelper.cleanUpResource(client, project); + } + @Test(timeout=3*1000*60) + public void testScalingReplicationController() throws Exception { + dc = client.create(IntegrationTestHelper.stubReplicationController(client, project)); + runTest(); + } + + @Test(timeout=3*1000*60) + public void testScalingDeploymentConfig() throws Exception { + dc = client.create(IntegrationTestHelper.stubDeploymentConfig(client, project)); + runTest(); + } + + private void runTest() throws Exception { + watch = client.watch(project.getName(), new IOpenShiftWatchListener() { + + @Override + public void connected(List resources) { + initializationLatch.countDown(); + } + + @Override + public void disconnected() { + + } + + @Override + public void received(IResource resource, ChangeType change) { + if(ChangeType.MODIFIED.equals(change) && !resource.getName().endsWith("deploy") && conditional.isReady(resource)) { + if(foundFirstPod.get()){ + replicaLatch.countDown(); + }else { + foundFirstPod.set(true); + initializationLatch.countDown(); + } + } + } + + @Override + public void error(Throwable err) { + + } + + }, ResourceKind.POD); + + if(initializationLatch.await(1, TimeUnit.MINUTES)){ + scaleTo(REPLICAS); + assertTrue("The pods either did not scale as expected or the test timed out", replicaLatch.await(2, TimeUnit.MINUTES)); + }; + + } + + private void scaleTo(int replicas) { + IScale result = dc.accept(new CapabilityVisitor() { + + @Override + public IScale visit(IScalable capability) { + return capability.scaleTo(replicas); + } + }, null); + assertNotNull("Exp. to receive a non-null result", result); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/apis/TypeMetaFactoryTest.java b/src/test/java/com/openshift/internal/restclient/apis/TypeMetaFactoryTest.java new file mode 100644 index 00000000..198221c5 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/apis/TypeMetaFactoryTest.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.apis; + +import static org.junit.Assert.*; + +import org.junit.Test; + +import java.util.Optional; + +import com.openshift.internal.restclient.apis.TypeMetaFactory; +import com.openshift.restclient.api.ITypeFactory; +import com.openshift.restclient.api.models.ITypeMeta; +import com.openshift.restclient.apis.autoscaling.models.IScale; +import com.openshift.restclient.model.IBuild; +import com.openshift.restclient.utils.Samples; + +public class TypeMetaFactoryTest { + + private final ITypeFactory factory = new TypeMetaFactory(); + + @Test + public void testStubKind() { + Object obj = factory.stubKind("extensions/v1beta1.Scale", Optional.of("foo"), Optional.of("bar")); + assertTrue(obj instanceof IScale); + IScale scale = (IScale) obj; + assertEquals("foo", scale.getName()); + assertEquals("bar", scale.getNamespace()); + assertEquals("Scale", scale.getKind()); + assertEquals("extensions/v1beta1", scale.getApiVersion()); + } + + @Test + public void testExtensionScale() { + Object response = factory.createInstanceFrom(Samples.V1BETA1_API_EXT_SCALE.getContentAsString()); + assertTrue(response instanceof IScale); + } + + @Test + public void testUnrecognized() { + Object response = factory.createInstanceFrom(Samples.V1_BUILD.getContentAsString()); + assertFalse(response instanceof IBuild); + assertTrue(response instanceof ITypeMeta); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/apis/extensions/model/v1beta1/ScaleTest.java b/src/test/java/com/openshift/internal/restclient/apis/extensions/model/v1beta1/ScaleTest.java new file mode 100644 index 00000000..f675ec1c --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/apis/extensions/model/v1beta1/ScaleTest.java @@ -0,0 +1,67 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.apis.extensions.model.v1beta1; + +import static org.junit.Assert.*; + +import java.util.Collections; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import com.openshift.internal.restclient.apis.autoscaling.models.Scale; +import com.openshift.restclient.apis.autoscaling.models.IScale; +import com.openshift.restclient.utils.Samples; + +public class ScaleTest { + + private static final String JSON = Samples.V1BETA1_API_EXT_SCALE.getContentAsString(); + IScale scale; + + @Before + public void setUp() throws Exception { + ModelNode node = ModelNode.fromJSONString(JSON); + scale = new Scale(node, Collections.emptyMap()); + } + + @Test + public void testGetSetName() { + assertEquals("logging-kibana", scale.getName()); + scale.setName("other"); + assertEquals("other", scale.getName()); + } + + @Test + public void testGetSetNamespace() { + assertEquals("logging", scale.getNamespace()); + scale.setNamespace("other-ns"); + assertEquals("other-ns", scale.getNamespace()); + } + + @Test + public void testGetApiVersion() { + assertEquals("extensions/v1beta1", scale.getApiVersion()); + } + + @Test + public void testGetKind() { + assertEquals("Scale", scale.getKind()); + } + + @Test + public void testSetGetSpecReplicas() { + assertEquals(2, scale.getSpecReplicas()); + scale.setSpecReplicas(30); + assertEquals(30, scale.getSpecReplicas()); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java index 8202cbec..a56ca701 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java @@ -30,7 +30,7 @@ public class UnrecognizedResourceTest{ @Before public void setUp(){ IClient client = mock(IClient.class); - service = new ResourceFactory(client).create(Samples.V1_UNRECOGNIZED.getContentAsString(), false); + service = new ResourceFactory(client).create(Samples.V1_UNRECOGNIZED.getContentAsString()); } @Test diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 6c8728c3..5ab37682 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -25,6 +25,9 @@ public enum Samples { GROUP_ENDPONT_APIS("openshift3/apis_endpoint.json"), GROUP_ENDPONT_APIS_EXTENSIONS("openshift3/apis_endpoint_extensions.json"), + // api/extensions + V1BETA1_API_EXT_SCALE("openshift3/api/extensions/v1beta1_scale.json"), + //v1 V1_KUBE_CONFIG("openshift3/v1_kubeconfig.yaml"), diff --git a/src/test/resources/openshiftv3IntegrationTest.properties b/src/test/resources/openshiftv3IntegrationTest.properties index bb93f461..fafe0864 100644 --- a/src/test/resources/openshiftv3IntegrationTest.properties +++ b/src/test/resources/openshiftv3IntegrationTest.properties @@ -1,5 +1,5 @@ -serverURL=https://127.0.0.1:8443 +serverURL=https://localhost:8443 #osadm policy add-cluster-role-to-user cluster-admin $ADMIN_USER --config=openshift.local.config/master/admin.kubeconfig diff --git a/src/test/resources/samples/openshift3/api/extensions/v1beta1_scale.json b/src/test/resources/samples/openshift3/api/extensions/v1beta1_scale.json new file mode 100644 index 00000000..b3a8eee2 --- /dev/null +++ b/src/test/resources/samples/openshift3/api/extensions/v1beta1_scale.json @@ -0,0 +1,15 @@ +{ + "kind": "Scale", + "apiVersion": "extensions/v1beta1", + "metadata": { + "name": "logging-kibana", + "namespace": "logging", + "creationTimestamp": "2016-08-22T20:09:51Z" + }, + "spec": { + "replicas": 2 + }, + "status": { + "replicas": 0 + } +} \ No newline at end of file From 41ae06ef66ec9a3cb19a2458bc018f15b2e0a2d7 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Fri, 30 Sep 2016 18:06:33 -0400 Subject: [PATCH 029/258] fix list returning objects. It's not a thing --- .../java/com/openshift/internal/restclient/model/List.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/List.java b/src/main/java/com/openshift/internal/restclient/model/List.java index 421cc308..abb2a44f 100644 --- a/src/main/java/com/openshift/internal/restclient/model/List.java +++ b/src/main/java/com/openshift/internal/restclient/model/List.java @@ -41,10 +41,9 @@ public List(ModelNode node, IClient client, Map propertyKeys) @Override public Collection getItems(){ if(items == null) { - String key = getNode().has(OBJECTS) ? OBJECTS : ITEMS; - ModelNode listNode = get(key); + ModelNode listNode = get(ITEMS); if (listNode.isDefined()) { - Collection nodes = get(key).asList(); + Collection nodes = listNode.asList(); items = new ArrayList<>(nodes.size()); IResourceFactory factory = getClient().getResourceFactory(); if (factory != null) { @@ -71,7 +70,7 @@ public void addAll(Collection items) { if(this.items == null) { this.items = new ArrayList<>(); } - ModelNode itemNode = get(OBJECTS); + ModelNode itemNode = get(ITEMS); for (IResource resource : items) { itemNode.add(ModelNode.fromJSONString(resource.toString())); this.items.add(resource); From a51db95afface66c2fd51ea86f2833769600ab12 Mon Sep 17 00:00:00 2001 From: jupierce Date: Thu, 29 Sep 2016 15:14:13 -0400 Subject: [PATCH 030/258] Adding pod exec function --- .../internal/restclient/DefaultClient.java | 13 +- .../internal/restclient/URLBuilder.java | 35 ++- .../restclient/api/capabilities/PodExec.java | 177 +++++++++++++++ .../capability/CapabilityInitializer.java | 3 + .../okhttp/ResponseCodeInterceptor.java | 23 +- .../restclient/api/capabilities/IPodExec.java | 150 +++++++++++++ .../restclient/capability/IStoppable.java | 2 +- .../internal/restclient/URLBuilderTest.java | 34 ++- .../capabilities/PodExecIntegrationTest.java | 210 ++++++++++++++++++ .../api/capabilities/PodExecTest.java | 115 ++++++++++ 10 files changed, 720 insertions(+), 42 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java create mode 100644 src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java create mode 100644 src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 5ba48e65..176c9671 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -253,10 +253,14 @@ public String getServerReadyStatus() { } public Request.Builder newRequestBuilderTo(String endpoint){ + return newRequestBuilderTo(endpoint, MEDIATYPE_APPLICATION_JSON); + } + + public Request.Builder newRequestBuilderTo(String endpoint,String acceptMediaType){ Request.Builder builder = new Request.Builder() - .url(endpoint.toString()) - .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON); - + .url(endpoint.toString()) + .header(PROPERTY_ACCEPT, acceptMediaType); + String token = null; if(this.authContext != null && StringUtils.isNotBlank(this.authContext.getToken())){ token = this.authContext.getToken(); @@ -264,7 +268,8 @@ public Request.Builder newRequestBuilderTo(String endpoint){ builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)); return builder; } - + + @Override public T update(T resource) { return execute(HttpMethod.PUT, resource.getKind(), resource.getNamespace(), resource.getName(), null, resource); diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index 7a0170ef..51d51957 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -8,19 +8,6 @@ ******************************************************************************/ package com.openshift.internal.restclient; -import java.io.UnsupportedEncodingException; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; import com.openshift.restclient.OpenShiftException; @@ -28,6 +15,18 @@ import com.openshift.restclient.UnsupportedEndpointException; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IResource; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Map; /** * Helper class to build the URL connection string in the proper @@ -42,7 +41,7 @@ public class URLBuilder { private String baseUrl; private String kind; private String name; - private Map params = new HashMap(); + private ArrayList> params = new ArrayList<>(); private final IApiTypeMapper typeMappings; private String apiVersion; @@ -105,7 +104,7 @@ public URLBuilder resource(IResource resource) { } public URLBuilder addParmeter(String key, String value) { - params.put(key, value); + params.add(new AbstractMap.SimpleEntry<>( key, value )); return this; } @@ -175,10 +174,8 @@ private void buildWithNamespaceInPath(StringBuilder url) { private StringBuilder appendParameters(StringBuilder url) { if (!params.isEmpty()) { url.append(IHttpConstants.QUESTION_MARK); - for (Iterator> iterator = params.entrySet() - .iterator(); iterator.hasNext();) { - Entry entry = (Entry) iterator - .next(); + for ( Iterator> iterator = params.iterator(); iterator.hasNext(); ) { + AbstractMap.SimpleEntry entry = iterator.next(); try { if(StringUtils.isNotBlank(entry.getValue())) { url.append(entry.getKey()) diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java new file mode 100644 index 00000000..b936ff18 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java @@ -0,0 +1,177 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.api.capabilities; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.URLBuilder; +import com.openshift.internal.restclient.capability.AbstractCapability; +import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; +import com.openshift.internal.restclient.okhttp.WebSocketAdapter; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.capability.IStoppable; +import com.openshift.restclient.api.capabilities.IPodExec; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.model.IPod; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import okhttp3.ws.WebSocket; +import okhttp3.ws.WebSocketCall; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +public class PodExec extends AbstractCapability implements IPodExec { + + private static final Logger LOG = LoggerFactory.getLogger(IPodExec.class); + private static final String CAPABILITY = "exec"; + + private static final String COMMAND = "command"; + + private static final String K8S_PROTOCOL_HEADER = "X-Stream-Protocol-Version"; + + private static final String K8S_PROTOCOL = "channel.k8s.io"; + + public static final int CHANNEL_STDOUT = 1; + public static final int CHANNEL_STDERR = 2; + public static final int CHANNEL_EXECERR = 3; + + private final IPod pod; + private final DefaultClient client; + private final IApiTypeMapper mapper; + + public PodExec(IPod pod, IClient client) { + super( pod, client, CAPABILITY ); + this.pod = pod; + this.client = client.adapt(DefaultClient.class); + this.mapper = client.adapt(IApiTypeMapper.class); + } + + @Override + public String getName() { + return PodExec.class.getSimpleName(); + } + + @Override + public IStoppable start( IPodExecOutputListener listener, Options options, String... commands ) { + + if ( options == null ) { + options = new Options(); + } + + Map parameters = options.getMap(); + + OkHttpClient okClient = client.adapt(OkHttpClient.class); + + URLBuilder urlBuilder = new URLBuilder(client.getBaseURL(), mapper) + .resource(pod) + .subresource(CAPABILITY) + .addParameters(parameters); + + // The main command and all arguments are specified as 'command' parameters + for ( String command : commands ) { + urlBuilder.addParmeter( COMMAND, command ); + } + + final String endpoint = urlBuilder.websocket(); + + Request request = client.newRequestBuilderTo(endpoint, IHttpConstants.MEDIATYPE_ANY) + .method( "GET", null ) + .addHeader(K8S_PROTOCOL_HEADER, K8S_PROTOCOL ) + // Unless we mark this as ignored, exceptions triggered by interceptor would be lost in dispatcher thread + .tag( new ResponseCodeInterceptor.Ignore() {} ) + .build(); + + WebSocketCall call = WebSocketCall.create(okClient, request); + ExecOutputListenerAdapter adapter = new ExecOutputListenerAdapter(call, listener); + call.enqueue(adapter); + return adapter; + } + + static class ExecOutputListenerAdapter extends WebSocketAdapter implements IStoppable{ + + private final IPodExecOutputListener listener; + private final WebSocketCall call; + private AtomicBoolean open = new AtomicBoolean(false); + + public ExecOutputListenerAdapter(WebSocketCall call, IPodExecOutputListener listener) { + this.call = call; + this.listener = listener; + } + + @Override + public void stop() { + call.cancel(); + } + + @Override + public void onOpen(WebSocket webSocket, Response response) { + if(open.compareAndSet(false, true)) { + listener.onOpen(); + } + } + + @Override + public void onClose(int code, String reason) { + if( open.compareAndSet(true, false) ) { + listener.onClose(code, reason); + } + } + + @Override + public void onFailure(IOException e, Response response) { + listener.onFailure(e); + } + + public void deliver( int channel, String msg ) { + switch ( channel ) { + case CHANNEL_STDOUT: + listener.onStdOut(msg); + break; + case CHANNEL_STDERR: + listener.onStdErr(msg); + break; + case CHANNEL_EXECERR: + listener.onExecErr(msg); + break; + default: + LOG.warn("Unable to deliver exec message of type [%d]: %s", channel, msg ); + } + } + + @Override + public void onMessage(ResponseBody message) throws IOException { + + /** + * https://godoc.org/k8s.io/kubernetes/pkg/util/wsstream + * The Websocket subprotocol "channel.k8s.io" prepends each binary message + * with a byte indicating the channel number (zero indexed) the message was + * sent on. Messages in both directions should prefix their messages with + * this channel byte. When used for remote execution, the channel numbers + * are by convention defined to match the POSIX file-descriptors assigned + * to STDIN, STDOUT, and STDERR (0, 1, and 2). No other conversion is + * performed on the raw subprotocol - writes are sent as they are received + * by the server. + */ + + int channel = message.byteStream().read(); + String msg = message.string(); + deliver( channel, msg ); + } + + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index 114b1726..a6230680 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -22,6 +22,7 @@ import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPodLogRetrieval; import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPortForwarding; import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryRSync; +import com.openshift.internal.restclient.api.capabilities.PodExec; import com.openshift.internal.restclient.capability.resources.PodLogRetrievalAsync; import com.openshift.internal.restclient.capability.resources.ProjectTemplateListCapability; import com.openshift.internal.restclient.capability.resources.ProjectTemplateProcessing; @@ -42,6 +43,7 @@ import com.openshift.restclient.capability.resources.IDeploymentConfigTraceability; import com.openshift.restclient.capability.resources.IDeploymentTraceability; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; +import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.capability.resources.IPodLogRetrieval; import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; import com.openshift.restclient.capability.resources.IPortForwardable; @@ -110,6 +112,7 @@ public static void initializeCapabilities(Map, ICap initializeCapability(capabilities, IPortForwardable.class, new OpenShiftBinaryPortForwarding(pod, client)); initializeCapability(capabilities, IPodLogRetrieval.class, new OpenShiftBinaryPodLogRetrieval(pod, client)); initializeCapability(capabilities, IPodLogRetrievalAsync.class, new PodLogRetrievalAsync(pod, client)); + initializeCapability(capabilities, IPodExec.class, new PodExec(pod, client)); initializeCapability(capabilities, IRSyncable.class, new OpenShiftBinaryRSync(client)); } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index 435c53a6..6b600863 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -10,11 +10,6 @@ ******************************************************************************/ package com.openshift.internal.restclient.okhttp; -import java.io.IOException; - -import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; - import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.authorization.AuthorizationDetails; import com.openshift.internal.restclient.model.Status; @@ -26,9 +21,12 @@ import com.openshift.restclient.authorization.ResourceForbiddenException; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IStatus; - import okhttp3.Interceptor; import okhttp3.Response; +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + +import java.io.IOException; /** * Interpret response codes and handle accordingly @@ -43,7 +41,14 @@ public class ResponseCodeInterceptor implements Interceptor, IHttpConstants { private static final Logger LOGGER = Logger.getLogger(ResponseCodeInterceptor.class); private IClient client; - + + /** + * If a request tag() implements this interface, HTTP errors + * will not throw OpenShift exceptions. + */ + public interface Ignore{} + + @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); @@ -56,7 +61,9 @@ public Response intercept(Chain chain) throws IOException { response = makeSuccessIfAuthorized(response); break; default: - throw createOpenShiftException(client, response, null); + if ( response.request().tag() instanceof Ignore == false ) { + throw createOpenShiftException(client, response, null); + } } } return response; diff --git a/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java b/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java new file mode 100644 index 00000000..7fd81483 --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java @@ -0,0 +1,150 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.capabilities; + +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.capability.IStoppable; + +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * Runs container exec + */ +public interface IPodExec extends ICapability{ + + /** + * Execute a command on a named container in this pod + * @param listener Listener for command output + * @param options Options for the exec + * @param commands A command to run and any arguments + * @return A Handle to allow termination of the connection + */ + IStoppable start( IPodExecOutputListener listener, Options options, String... commands ); + + + /** + * A callback for exec output + * + */ + interface IPodExecOutputListener{ + + /** + * Callback received on initial connection + */ + void onOpen(); + + /** + * Exec received stdout message + * @param message + */ + void onStdOut(String message); + + /** + * Exec received stderr message + * @param message + */ + void onStdErr(String message); + + /** + * Exec (channel 3) error message + * @param message + */ + void onExecErr(String message); + + /** + * Called by lower level errors + * @param e Exception causing failure + */ + void onFailure(IOException e); + + /** + * Callback received when the connection + * to the pod is terminated from the server-side + * @param code a valid http response code + * @param reason a reason for termination, may be null + */ + void onClose(int code, String reason); + } + + /** + * Options for exec + */ + class Options{ + + public static final String CONTAINER = "container"; + public static final String STDOUT = "stdout"; + public static final String STDERR = "stderr"; + private Map options = new HashMap<>(); + private Map secondaries = new HashMap<>(); + + private Options storeSecondary(String key, Object v ) { + secondaries.put( key, v.toString() ); + return this; + } + + /** + * The container from which to retrieve logs + * @param container + * @return + */ + public Options container(String container) { + return storeSecondary(CONTAINER, container); + } + + /** + * Enable stdout + * @param value + * @return + */ + public Options stdOut(boolean value) { + return storeSecondary(STDOUT, value); + } + + /** + * Enable stderr + * @param value + * @return + */ + public Options stdErr(boolean value) { + return storeSecondary(STDERR, value); + } + + /** + * Add an option that is not explicitly + * defined. These will override any + * explicit options if there are collisions + * + * @param name + * @param value + * @return + */ + public Options parameter(String name, String value) { + options.put(name, value); + return this; + } + + /** + * The collective options + * @return a map of all the options + */ + public Map getMap(){ + HashMap combined = new HashMap<>(secondaries); + combined.putAll(options); + return Collections.unmodifiableMap(combined); + } + } + + + +} diff --git a/src/main/java/com/openshift/restclient/capability/IStoppable.java b/src/main/java/com/openshift/restclient/capability/IStoppable.java index 82952e90..ebdc900f 100644 --- a/src/main/java/com/openshift/restclient/capability/IStoppable.java +++ b/src/main/java/com/openshift/restclient/capability/IStoppable.java @@ -12,7 +12,7 @@ /** * Handle to something that can be - * explicitily stopped or terminated + * explicitly stopped or terminated * * @author jeff.cantrill * diff --git a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java index 30b8ff49..0d1e84dd 100644 --- a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java @@ -10,20 +10,21 @@ ******************************************************************************/ package com.openshift.internal.restclient; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.IResource; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; -import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.model.IResource; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * @author Jeff Cantrill @@ -54,7 +55,20 @@ public void testBuildingURLForAWatchService() throws Exception { .build().toString(); assertEquals(String.format("%s/api/v1/namespaces/foo/services?watch=true&resourceVersion=123&foo=bar", BASE_URL),url.toString()); } - + + @Test + public void testDuplicateParameters() throws Exception { + IResource resource = givenAResource(ResourceKind.SERVICE, KubernetesAPIVersion.v1,"foo"); + String url = builder. + resource(resource) + .watch() + .addParmeter("resourceVersion", "123") + .addParmeter("x", "1") + .addParmeter("x", "2") + .build().toString(); + assertEquals(String.format("%s/api/v1/namespaces/foo/services?watch=true&resourceVersion=123&x=1&x=2", BASE_URL),url.toString()); + } + @Test public void testBuildingURLForAProjectUsingResource() throws Exception { IResource resource = givenAResource(ResourceKind.PROJECT, KubernetesAPIVersion.v1,"foo"); diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java new file mode 100644 index 00000000..6e3de6e0 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.api.capabilities; + +import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.api.capabilities.IPodExec; +import com.openshift.restclient.capability.CapabilityVisitor; +import com.openshift.restclient.capability.IStoppable; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IResource; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import static org.junit.Assert.*; + + +public class PodExecIntegrationTest { + + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private Exception ex; + private IPod pod; + + private static class TestExecListener implements IPodExec.IPodExecOutputListener { + + private static final Logger LOG = LoggerFactory.getLogger(PodExecIntegrationTest.class); + + + public final CountDownLatch testDone = new CountDownLatch(1); + public final AtomicBoolean openCalled = new AtomicBoolean(false); + public final AtomicBoolean closeCalled = new AtomicBoolean(false); + public final AtomicBoolean failureCalled = new AtomicBoolean(false); + public final AtomicBoolean execErrCalled = new AtomicBoolean(false); + public final List messages = Collections.synchronizedList( new ArrayList() ); + + @Override + public void onOpen() { + assertTrue(openCalled.compareAndSet(false,true)); + } + + @Override + public void onStdOut(String message) { + LOG.debug( "onStdOut: " + message ); + message = message.trim(); + if ( message.isEmpty() == false ) { // Observing that actual output appears after empty newline + messages.add( PodExec.CHANNEL_STDOUT+message ); + } + } + + @Override + public void onStdErr(String message) { + LOG.debug( "onStdErr: " + message ); + message = message.trim(); + messages.add( PodExec.CHANNEL_STDERR+message ); + } + + @Override + public void onExecErr(String message) { + LOG.debug( "onExecError: " + message ); + execErrCalled.set(true); + message = message.trim(); + messages.add( PodExec.CHANNEL_EXECERR+message ); + } + + @Override + public void onClose(int code, String reason) { + assertTrue(closeCalled.compareAndSet(false,true)); + testDone.countDown(); + } + + @Override + public void onFailure(IOException e) { + failureCalled.set(true); + LOG.error( "Potentially expected error occurred", e ); + testDone.countDown(); + } + + } + + @Before + public void setUp() throws Exception { + IClient client = helper.createClientForBasicAuth(); + List pods = client.list(ResourceKind.POD, "default"); + pod = (IPod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); + assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); + } + + @Test + public void testPodExec() throws Exception { + String[] echoCommand = { "echo", "a", "b", "c" }; + TestExecListener echoListener = new TestExecListener(); + + pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start( echoListener, null, echoCommand ); + } + }, null); + + echoListener.testDone.await( 60, TimeUnit.SECONDS ); + assertTrue( echoListener.openCalled.get() ); + assertTrue( echoListener.closeCalled.get() ); + assertTrue( !echoListener.failureCalled.get() ); + assertTrue( !echoListener.execErrCalled.get() ); + assertEquals( 1, echoListener.messages.size() ); + assertEquals( "1a b c", echoListener.messages.get(0)); + } + + @Test + public void testPodExecWithContainerSpecified() throws Exception { + String[] echoCommand = { "echo", "a", "b", "c" }; + TestExecListener echoListener = new TestExecListener(); + + final String container = pod.getContainers().iterator().next().getName(); + IPodExec.Options options = new IPodExec.Options(); + options.container( container ); + + pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start( echoListener, options, echoCommand ); + } + }, null); + + echoListener.testDone.await( 60, TimeUnit.SECONDS ); + assertTrue( echoListener.openCalled.get() ); + assertTrue( echoListener.closeCalled.get() ); + assertTrue( !echoListener.failureCalled.get() ); + assertTrue( !echoListener.execErrCalled.get() ); + assertEquals( 1, echoListener.messages.size() ); + assertEquals( "1a b c", echoListener.messages.get(0)); + } + + @Test + public void testCommandNotFound() throws Exception { + String[] badCommand = { "/bin/doesnotexist" }; + TestExecListener badListener = new TestExecListener(); + + pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start( badListener, null, badCommand ); + } + }, null); + + badListener.testDone.await( 60, TimeUnit.SECONDS ); + assertTrue( badListener.openCalled.get() ); + assertTrue( badListener.closeCalled.get() ); + assertTrue( badListener.execErrCalled.get() ); + // both execErr and stdErr will be called + assertEquals( 2, badListener.messages.size() ); + } + + @Test + public void testPodExecStop() throws Exception { + String[] longCommand = { "sleep", "500" }; + TestExecListener longListener = new TestExecListener(); + + IStoppable stopLong = pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start( longListener, null, longCommand ); + } + }, null); + + // Trigger a cancel on the web socket before long delay can complete + stopLong.stop(); + longListener.testDone.await( 60, TimeUnit.SECONDS ); + assertTrue( longListener.failureCalled.get() ); + } + + @Test + public void testContainerDoesNotExist() throws Exception { + String[] dateCommand = { "date" }; + TestExecListener dateListener = new TestExecListener(); + IPodExec.Options options = new IPodExec.Options(); + options.container( "will-not-exist-in-docker-registry-pod" ); + + pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start( dateListener, options, dateCommand ); + } + }, null); + + dateListener.testDone.await( 60, TimeUnit.SECONDS ); + assertTrue( dateListener.failureCalled.get() ); + } + + +} diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java new file mode 100644 index 00000000..2bcde2d3 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.api.capabilities; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.internal.restclient.TypeMapperFixture; +import com.openshift.internal.restclient.capability.resources.PodLogRetrievalAsync; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.api.capabilities.IPodExec; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.MocksFactory; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class PodExecTest extends TypeMapperFixture { + + private DefaultClient client; + @Mock + private IApiTypeMapper mapper; + private PodLogRetrievalAsync capability; + private IPod pod; + private PodExec.ExecOutputListenerAdapter adapter; + + @Mock + private IPodExec.IPodExecOutputListener listener; + + @Before + public void setUp() throws Exception { + super.setUp(); + client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); + pod = new MocksFactory().mock(IPod.class); + capability = new PodLogRetrievalAsync(pod, client); + adapter = new PodExec.ExecOutputListenerAdapter(null, listener); + } + + @Test + public void testIsSupported() { + assertTrue("Exp. capability to be supported because the pod endpoint exists", capability.isSupported()); + } + + @Test + public void testIsNotSupportedWhenEndpointDoesNotExist() { + when(pod.getApiVersion()).thenReturn("somenoneexitentversion"); + assertFalse("Exp. capability to not be supported because the pod endpoint does not exist exists", capability.isSupported()); + } + + @Test + public void testAdapterCallsListenerCycle() throws Exception { + adapter.onOpen(null, null); + adapter.onOpen(null, null); + verify(listener).onOpen(); + + + adapter.deliver(PodExec.CHANNEL_STDOUT, "ImStdOut"); + adapter.deliver(PodExec.CHANNEL_STDERR, "ImStdErr"); + adapter.deliver(PodExec.CHANNEL_EXECERR, "ImExecErr"); + + verify(listener).onStdOut("ImStdOut"); + verify(listener).onStdErr("ImStdErr"); + verify(listener).onExecErr("ImExecErr"); + + adapter.onClose(1986, "the reason"); + adapter.onClose(1986, "the reason"); + verify(listener).onClose(1986, "the reason"); + } + + @Test + public void testExecOptions() throws Exception { + IPodExec.Options options = new IPodExec.Options(); + assertEquals( 0, options.getMap().size() ); + + options.stdErr( false ); + options.stdOut( false ); + options.container( "test" ); + + assertEquals( 3, options.getMap().size() ); + + assertEquals( "false", options.getMap().get(IPodExec.Options.STDERR) ); + assertEquals( "false", options.getMap().get(IPodExec.Options.STDOUT) ); + assertEquals( "test", options.getMap().get(IPodExec.Options.CONTAINER) ); + + options.parameter( IPodExec.Options.STDERR, "true" ); + options.parameter( IPodExec.Options.STDOUT, "true" ); + options.parameter( IPodExec.Options.CONTAINER, "override" ); + + // Re-set these options to ensure they do not override parameter API + options.stdErr( false ); + options.stdOut( false ); + options.container( "test" ); + + assertEquals( "true", options.getMap().get(IPodExec.Options.STDERR) ); + assertEquals( "true", options.getMap().get(IPodExec.Options.STDOUT) ); + assertEquals( "override", options.getMap().get(IPodExec.Options.CONTAINER) ); + + } + +} \ No newline at end of file From c901cac7b37d6e0d346f7fdaf8d4c3c9338ff1ad Mon Sep 17 00:00:00 2001 From: jupierce Date: Wed, 5 Oct 2016 14:27:30 -0400 Subject: [PATCH 031/258] Expose errors during async log retrieval --- .../resources/PodLogRetrievalAsync.java | 25 ++++++++++------- .../resources/IPodLogRetrievalAsync.java | 18 ++++++++---- .../PodLogRetrievalAsyncIntegrationTest.java | 28 ++++++++++++------- 3 files changed, 46 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java index e4db009a..78ca230f 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java @@ -10,16 +10,9 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.URLBuilder; +import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; import com.openshift.internal.restclient.okhttp.WebSocketAdapter; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; @@ -28,13 +21,19 @@ import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IPod; - import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; import okhttp3.ws.WebSocket; import okhttp3.ws.WebSocketCall; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; /** * Impl of Pod log retrieval using websocket @@ -91,7 +90,8 @@ public IStoppable start(IPodLogListener listener, Options options) { .addParameters(parameters) .websocket(); Request request = client.newRequestBuilderTo(endpoint) - .build(); + .tag( new ResponseCodeInterceptor.Ignore(){} ) + .build(); WebSocketCall call = WebSocketCall.create(okClient, request); call.enqueue(adapter); @@ -140,6 +140,11 @@ public void onClose(int code, String reason) { public void onMessage(ResponseBody message) throws IOException { listener.onMessage(message.string()); } + + @Override + public void onFailure(IOException e, Response response) { + listener.onFailure(e); + } } } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java index ff4fabf3..27ebbfc7 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java @@ -10,15 +10,15 @@ ******************************************************************************/ package com.openshift.restclient.capability.resources; +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.capability.IStoppable; +import org.apache.commons.lang.StringUtils; + +import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import org.apache.commons.lang.StringUtils; - -import com.openshift.restclient.capability.ICapability; -import com.openshift.restclient.capability.IStoppable; - /** * Retrieve logs in an async call * @author jeff.cantrill @@ -67,6 +67,14 @@ interface IPodLogListener{ * @param reason a reason for termination, may be null */ void onClose(int code, String reason); + + /** + * Callback received when the web socket connection + * fails + * @param e the exception which occurred + */ + void onFailure(IOException e); + } /** diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java index 1618e450..56cc1dde 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java @@ -10,16 +10,6 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.assertNotNull; - -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.restclient.ResourceKind; @@ -30,6 +20,17 @@ import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.Options; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IResource; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; /** * @@ -76,6 +77,13 @@ public void onClose(int code, String reason) { LOG.debug("onClose code:{} reason:{}", code, reason); latch.countDown(); } + + @Override + public void onFailure(IOException e) { + LOG.error( "Unexpected websocket failure", e ); + fail( "Unexpected websocket failure" ); + } + }, new Options() .follow() .container(container)); From f1d86f51d665bbecde4246848e2cca6a0412b2a9 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 6 Oct 2016 14:43:44 +0200 Subject: [PATCH 032/258] [OSJC-272] moved JSONSerializable to public package --- .../java/com/openshift/internal/restclient/DefaultClient.java | 2 +- .../openshift/internal/restclient/model/ModelNodeAdapter.java | 1 + src/main/java/com/openshift/restclient/IClient.java | 2 +- .../java/com/openshift/restclient/api/models/ITypeMeta.java | 2 +- .../com/openshift/restclient/model/IEnvironmentVariable.java | 2 -- src/main/java/com/openshift/restclient/model/IHandler.java | 2 -- src/main/java/com/openshift/restclient/model/ILifecycle.java | 2 -- src/main/java/com/openshift/restclient/model/IResource.java | 1 - .../{internal => }/restclient/model/JSONSerializeable.java | 2 +- 9 files changed, 5 insertions(+), 11 deletions(-) rename src/main/java/com/openshift/{internal => }/restclient/model/JSONSerializeable.java (94%) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 176c9671..309cf65d 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -25,7 +25,6 @@ import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.authorization.AuthorizationContext; -import com.openshift.internal.restclient.model.JSONSerializeable; import com.openshift.internal.restclient.okhttp.WatchClient; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; @@ -42,6 +41,7 @@ import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IList; import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.JSONSerializeable; import okhttp3.MediaType; import okhttp3.OkHttpClient; diff --git a/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java b/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java index 2fd1723c..ade6ecac 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java +++ b/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java @@ -15,6 +15,7 @@ import org.jboss.dmr.ModelNode; import com.openshift.internal.util.JBossDmrExtentions; +import com.openshift.restclient.model.JSONSerializeable; /** * Adapter class between what we want diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index b81a3ff7..5dfd0f2d 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -13,12 +13,12 @@ import java.util.List; import java.util.Map; -import com.openshift.internal.restclient.model.JSONSerializeable; import com.openshift.restclient.api.ITypeFactory; import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.capability.ICapable; import com.openshift.restclient.model.IList; import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.JSONSerializeable; /** * Client is the the simplest interface for interacting with the OpenShift diff --git a/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java b/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java index 05924502..7590dbbd 100644 --- a/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java +++ b/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java @@ -10,7 +10,7 @@ ******************************************************************************/ package com.openshift.restclient.api.models; -import com.openshift.internal.restclient.model.JSONSerializeable; +import com.openshift.restclient.model.JSONSerializeable; /** * Marker interface to kubernetes TypeMeta diff --git a/src/main/java/com/openshift/restclient/model/IEnvironmentVariable.java b/src/main/java/com/openshift/restclient/model/IEnvironmentVariable.java index db10232b..7cdbc01f 100644 --- a/src/main/java/com/openshift/restclient/model/IEnvironmentVariable.java +++ b/src/main/java/com/openshift/restclient/model/IEnvironmentVariable.java @@ -10,8 +10,6 @@ ******************************************************************************/ package com.openshift.restclient.model; -import com.openshift.internal.restclient.model.JSONSerializeable; - /** * Environment variable representation to * allow more complex values then diff --git a/src/main/java/com/openshift/restclient/model/IHandler.java b/src/main/java/com/openshift/restclient/model/IHandler.java index 47012191..d5bacb61 100644 --- a/src/main/java/com/openshift/restclient/model/IHandler.java +++ b/src/main/java/com/openshift/restclient/model/IHandler.java @@ -10,8 +10,6 @@ ******************************************************************************/ package com.openshift.restclient.model; -import com.openshift.internal.restclient.model.JSONSerializeable; - /** * @author Ulf Lilleengen */ diff --git a/src/main/java/com/openshift/restclient/model/ILifecycle.java b/src/main/java/com/openshift/restclient/model/ILifecycle.java index a4164d21..fd65831e 100644 --- a/src/main/java/com/openshift/restclient/model/ILifecycle.java +++ b/src/main/java/com/openshift/restclient/model/ILifecycle.java @@ -10,8 +10,6 @@ ******************************************************************************/ package com.openshift.restclient.model; -import com.openshift.internal.restclient.model.JSONSerializeable; - import java.util.Optional; /** diff --git a/src/main/java/com/openshift/restclient/model/IResource.java b/src/main/java/com/openshift/restclient/model/IResource.java index 0c7a89f4..304d7e4b 100644 --- a/src/main/java/com/openshift/restclient/model/IResource.java +++ b/src/main/java/com/openshift/restclient/model/IResource.java @@ -11,7 +11,6 @@ import java.util.Map; import java.util.Set; -import com.openshift.internal.restclient.model.JSONSerializeable; import com.openshift.restclient.api.models.IAnnotatable; import com.openshift.restclient.api.models.ITypeMeta; import com.openshift.restclient.capability.ICapability; diff --git a/src/main/java/com/openshift/internal/restclient/model/JSONSerializeable.java b/src/main/java/com/openshift/restclient/model/JSONSerializeable.java similarity index 94% rename from src/main/java/com/openshift/internal/restclient/model/JSONSerializeable.java rename to src/main/java/com/openshift/restclient/model/JSONSerializeable.java index 4538492a..6a280afa 100644 --- a/src/main/java/com/openshift/internal/restclient/model/JSONSerializeable.java +++ b/src/main/java/com/openshift/restclient/model/JSONSerializeable.java @@ -8,7 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.model; +package com.openshift.restclient.model; /** * Something that can be serialized to JSON From fe9f06175574f87c3ce3b600943479ba63f5ab0c Mon Sep 17 00:00:00 2001 From: John Moon Date: Thu, 6 Oct 2016 13:31:19 -0400 Subject: [PATCH 033/258] Fixes for contianer command args and service port names --- .../internal/restclient/model/Container.java | 28 +++++++++++++- .../internal/restclient/model/Service.java | 14 +++++-- .../internal/util/JBossDmrExtentions.java | 37 +++++++++++++++++++ .../restclient/model/IContainer.java | 7 ++++ .../openshift/restclient/model/IService.java | 2 + .../internal/restclient/model/v1/PodTest.java | 13 +++++++ .../restclient/model/v1/ServiceTest.java | 9 +++++ .../internal/util/JBossDmrExtentionsTest.java | 16 +++++++- .../resources/samples/openshift3/v1_pod.json | 10 ++++- 9 files changed, 128 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Container.java b/src/main/java/com/openshift/internal/restclient/model/Container.java index 72d38703..d0435bfe 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Container.java +++ b/src/main/java/com/openshift/internal/restclient/model/Container.java @@ -15,18 +15,20 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import com.openshift.restclient.model.ILifecycle; import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.internal.restclient.model.volume.EmptyDirVolume; import com.openshift.internal.restclient.model.volume.VolumeMount; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IContainer; +import com.openshift.restclient.model.ILifecycle; import com.openshift.restclient.model.IPort; import com.openshift.restclient.model.volume.IVolume; import com.openshift.restclient.model.volume.IVolumeMount; @@ -36,6 +38,8 @@ public class Container extends ModelNodeAdapter implements IContainer, ResourceP private static final String IMAGE = "image"; private static final String ENV = "env"; private static final String IMAGE_PULL_POLICY = "imagePullPolicy"; + private static final String COMMAND = "command"; + private static final String COMMANDARGS = "args"; private static final String LIFECYCLE = "lifecycle"; private static final String VOLUMEMOUNTS = "volumeMounts"; @@ -136,11 +140,31 @@ public Set getPorts() { public void setImagePullPolicy(String policy) { set(node, propertyKeys, IMAGE_PULL_POLICY, policy); } - + @Override public String getImagePullPolicy() { return asString(node, propertyKeys, IMAGE_PULL_POLICY); } + + @Override + public void setCommand(List command) { + set(node, propertyKeys, COMMAND, command.toArray(new String[0])); + } + + @Override + public List getCommand() { + return asList(node, propertyKeys, COMMAND, ModelType.STRING); + } + + @Override + public void setCommandArgs(List args) { + set(node, propertyKeys, COMMANDARGS, args.toArray(new String[0])); + } + + @Override + public List getCommandArgs() { + return asList(node, propertyKeys, COMMANDARGS, ModelType.STRING); + } @Override public void setLifecycle(ILifecycle lifecycle) { diff --git a/src/main/java/com/openshift/internal/restclient/model/Service.java b/src/main/java/com/openshift/internal/restclient/model/Service.java index 1afb6918..e12882f8 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Service.java +++ b/src/main/java/com/openshift/internal/restclient/model/Service.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Map; +import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; @@ -49,12 +50,17 @@ public void setPort(int port){ } public IServicePort addPort(int port, int targetPort) { - ServicePort servicePort = new ServicePort(get(SERVICE_PORT).add()); - if(port > 0) servicePort.setPort(port); - if(targetPort >0) servicePort.setTargetPort(targetPort); - return servicePort; + return addPort(port, targetPort, null); } + public IServicePort addPort(int port, int targetPort, String name) { + ServicePort servicePort = new ServicePort(get(SERVICE_PORT).add()); + if(port > 0) servicePort.setPort(port); + if(targetPort >0) servicePort.setTargetPort(targetPort); + if(StringUtils.isNotEmpty(name)) servicePort.setName(name); + return servicePort; + } + @Override public int getPort(){ IServicePort port = getLowestPort(); diff --git a/src/main/java/com/openshift/internal/util/JBossDmrExtentions.java b/src/main/java/com/openshift/internal/util/JBossDmrExtentions.java index 1823f0d6..6c57d1e6 100644 --- a/src/main/java/com/openshift/internal/util/JBossDmrExtentions.java +++ b/src/main/java/com/openshift/internal/util/JBossDmrExtentions.java @@ -177,6 +177,43 @@ public static Set asSet(ModelNode root, Map propertyKeys, Str return set; } + /** + * Returns an ordered List for items that need to be ordered + * such as command Args for containers. + * + * @param root + * @param propertyKeys + * @param key + * @param type + * @return + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static List asList(ModelNode root, Map propertyKeys, String key, ModelType type){ + List list = new ArrayList(); + String [] path = getPath(propertyKeys, key); + if(root.has(path)){ + ModelNode node = root.get(path); + if( !node.isDefined()) + return list; + for (ModelNode entry : node.asList()) { + Object instance = null; + switch(type) { + case STRING: + instance = entry.asString(); + break; + case BOOLEAN: + instance = entry.asBoolean(); + break; + case INT: + instance = entry.asInt(); + default: + } + list.add(instance); + } + } + return list; + } + public static void set(ModelNode root, Map propertyKeys, String key, Set values) { String [] path = getPath(propertyKeys, key); ModelNode node = root.get(path); diff --git a/src/main/java/com/openshift/restclient/model/IContainer.java b/src/main/java/com/openshift/restclient/model/IContainer.java index 9c1179b0..b3f03559 100644 --- a/src/main/java/com/openshift/restclient/model/IContainer.java +++ b/src/main/java/com/openshift/restclient/model/IContainer.java @@ -10,6 +10,7 @@ ******************************************************************************/ package com.openshift.restclient.model; +import java.util.List; import java.util.Map; import java.util.Set; @@ -56,6 +57,12 @@ public interface IContainer { void setLifecycle(ILifecycle lifecycle); ILifecycle getLifecycle(); + void setCommand(List command); + List getCommand(); + + void setCommandArgs(List args); + List getCommandArgs(); + @Deprecated void setVolumes(Set volumes); @Deprecated diff --git a/src/main/java/com/openshift/restclient/model/IService.java b/src/main/java/com/openshift/restclient/model/IService.java index fc939996..dd37990e 100644 --- a/src/main/java/com/openshift/restclient/model/IService.java +++ b/src/main/java/com/openshift/restclient/model/IService.java @@ -40,6 +40,8 @@ public interface IService extends IResource{ IServicePort addPort(int port, int targetPort); + IServicePort addPort(int port, int targetPort, String name); + /** * Sets the container name that the service * routes traffic to. diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index 37668034..5ae93208 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -13,6 +13,7 @@ import java.util.Collection; import java.util.HashSet; +import java.util.List; import java.util.Optional; import java.util.Set; @@ -93,4 +94,16 @@ public void testAddContainer() { Optional container = containers.stream().filter(c->"foo".equals(c.getName()) && "cmd1".equals(((IExecAction)c.getLifecycle().getPreStop().get()).getCommand().get(0))).findFirst(); assertTrue("Exp. the container to be added", container.isPresent()); } + + @Test + public void getContainerCommands() { + Collection containers = pod.getContainers(); + IContainer container = containers.iterator().next(); + List cmd = container.getCommand(); + List cmdArgs = container.getCommandArgs(); + assertEquals(cmd.get(0),"/bin/sh"); + assertEquals(cmdArgs.get(0), "-c"); + assertEquals(cmdArgs.get(1), "echo 'hello'"); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java index 70fd55fe..85f403e6 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java @@ -128,4 +128,13 @@ public void testSetPorts() { assertEquals(port, ports[0]); } + @Test + public void testAddPorts() { + IServicePort port = service.addPort(8299, 9299, "testport"); + service.setPorts(Arrays.asList(port)); + IServicePort [] ports = service.getPorts().toArray(new IServicePort[] {}); + assertEquals(1, service.getPorts().size()); + assertEquals(port, ports[0]); + } + } diff --git a/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java b/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java index 88e5cdda..1d8203c5 100644 --- a/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java +++ b/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java @@ -12,6 +12,7 @@ import static com.openshift.internal.util.JBossDmrExtentions.*; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.jboss.dmr.ModelNode; @@ -24,12 +25,13 @@ */ public class JBossDmrExtentionsTest { - private ModelNode node = ModelNode.fromJSONString("{\"foo\":\"bar\", \"int\":\"3\", \"bool\":\"true\"}"); + private ModelNode node = ModelNode.fromJSONString("{\"foo\":\"bar\", \"int\":\"3\", \"bool\":\"true\", \"list\": [\"1\", \"2\", \"3\"]}"); private Map paths = new HashMap(); private static final String KEY_FOO = "foo"; private static final String KEY_XYZ = "xyz"; private static final String KEY_BOOL = "bool"; private static final String KEY_INT = "int"; + private static final String KEY_LIST = "list"; @Before public void setup() { @@ -37,6 +39,7 @@ public void setup() { paths.put(KEY_XYZ, new String[] {"xyz"}); paths.put(KEY_BOOL, new String[] {"bool"}); paths.put(KEY_INT, new String[] {"int"}); + paths.put(KEY_LIST, new String[] {"list"}); } @Test @@ -71,6 +74,9 @@ public void testGettersDoNotAddNodeToJsonTree() { asBoolean(node, paths, "openshift.bool"); assertFalse(node.has("openshift","bool")); + + asList(node, paths, "openshift.list", ModelType.STRING); + assertFalse(node.has("openshift","set")); } @Test @@ -106,5 +112,13 @@ public void asStringForUndefinedShouldReturnEmptySpace() { public void asStringForAValueShouldReturnTheValue() { assertEquals("bar", asString(node, paths, KEY_FOO)); } + + @Test + public void asListForStringReturnsOrderedValues() { + List l = asList(node, paths, KEY_LIST, ModelType.STRING); + assertEquals("1", l.get(0)); + assertEquals("2", l.get(1)); + assertEquals("3", l.get(2)); + } } diff --git a/src/test/resources/samples/openshift3/v1_pod.json b/src/test/resources/samples/openshift3/v1_pod.json index f17e2e93..6c7a1e5a 100644 --- a/src/test/resources/samples/openshift3/v1_pod.json +++ b/src/test/resources/samples/openshift3/v1_pod.json @@ -71,7 +71,15 @@ } ], "terminationMessagePath": "/dev/termination-log", - "imagePullPolicy": "IfNotPresent" + "imagePullPolicy": "IfNotPresent", + "command" : [ + "/bin/sh" + ], + "args" : [ + "-c", + "echo 'hello'" + ] + } ], "restartPolicy": "Never", From cde0cf8235c4dcdb732a6b13f589980671d287e4 Mon Sep 17 00:00:00 2001 From: I003306 Date: Tue, 9 Aug 2016 15:30:25 +0200 Subject: [PATCH 034/258] setter for proxyAuthenticator okhttp (cherry picked from commit b9ab0d5) --- .../java/com/openshift/restclient/ClientBuilder.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 477bc96f..366bf4d0 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -33,6 +33,7 @@ import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.utils.SSLUtils; +import okhttp3.Authenticator; import okhttp3.Dispatcher; import okhttp3.OkHttpClient; @@ -51,6 +52,7 @@ public class ClientBuilder { private String userName; private String token; private String password; + private Authenticator proxyAuthenticator; private int maxRequests = 64; private int maxRequestsPerHost = 10; @@ -121,6 +123,11 @@ public ClientBuilder withWriteTimeout(int timeout, TimeUnit unit) { this.writeTimeoutUnit = unit; return this; } + + public ClientBuilder proxyAuthenticator(Authenticator proxyAuthenticator) { + this.proxyAuthenticator = proxyAuthenticator; + return this; + } /** * The connect timeout parameter used for establishing @@ -185,6 +192,11 @@ public IClient build() { .connectTimeout(connectTimeout, connectTimeoutUnit) .hostnameVerifier(this.sslCertificateCallback) .sslSocketFactory(sslContext.getSocketFactory(), trustManager); + + if (proxyAuthenticator != null) { + builder.proxyAuthenticator(proxyAuthenticator); + } + OkHttpClient okClient = builder.build(); IResourceFactory factory = defaultIfNull(resourceFactory, new ResourceFactory(null)); From e57f9e7480358860e3ad24887d34b404e379ae3b Mon Sep 17 00:00:00 2001 From: John Moon Date: Mon, 10 Oct 2016 11:32:11 -0400 Subject: [PATCH 035/258] add serviceAccountName to RC --- .../restclient/model/ReplicationController.java | 11 +++++++++++ .../restclient/model/IReplicationController.java | 13 +++++++++++++ .../model/v1/ReplicationControllerTest.java | 11 +++++++++++ .../openshift3/v1_replication_controller.json | 3 ++- 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java index 65c21bd1..4e014a86 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java +++ b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java @@ -51,6 +51,7 @@ public class ReplicationController extends KubernetesResource implements IReplic protected static final String SPEC_REPLICAS = "spec.replicas"; protected static final String SPEC_SELECTOR = "spec.selector"; protected static final String STATUS_REPLICA = "status.replicas"; + protected static final String SERVICEACCOUNTNAME = "spec.template.spec.serviceAccountName"; protected static final String IMAGE = "image"; protected static final String ENV = "env"; @@ -364,4 +365,14 @@ public void addVolume(IVolumeSource volumeSource) { } volList.add(ModelNode.fromJSONString(volumeSource.toJSONString())); } + + @Override + public void setServiceAccountName(String serviceAccountName) { + set(SERVICEACCOUNTNAME, serviceAccountName); + } + + @Override + public String getServiceAccountName() { + return asString(SERVICEACCOUNTNAME); + } } diff --git a/src/main/java/com/openshift/restclient/model/IReplicationController.java b/src/main/java/com/openshift/restclient/model/IReplicationController.java index 0ec75bad..beab1158 100644 --- a/src/main/java/com/openshift/restclient/model/IReplicationController.java +++ b/src/main/java/com/openshift/restclient/model/IReplicationController.java @@ -195,4 +195,17 @@ public interface IReplicationController extends IResource{ void setVolumes(Set volumes); void setContainers(Collection containers); + + /** + * Sets the service account to run this replication controller under. + * + * @param volumes The service account to assign to the spec. + */ + void setServiceAccountName(String serviceAccount); + + /** + * Retrieves the service account used by the controller + * @return + */ + String getServiceAccountName(); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java index 7be4b1b2..2fb7d2ff 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java @@ -176,6 +176,17 @@ public void getReplicaSelector() { assertEquals(labels, rc.getReplicaSelector()); } + @Test + public void getServiceAccountName() { + assertEquals("dbServiceAccountName", rc.getServiceAccountName()); + } + + @Test + public void setServiceAccountName() { + rc.setServiceAccountName("newDBServiceAccountName"); + assertEquals("newDBServiceAccountName", rc.getServiceAccountName()); + } + @Test public void getDesiredReplicaCount(){ assertEquals(1, rc.getDesiredReplicaCount()); diff --git a/src/test/resources/samples/openshift3/v1_replication_controller.json b/src/test/resources/samples/openshift3/v1_replication_controller.json index 7a717b17..ca23a6db 100644 --- a/src/test/resources/samples/openshift3/v1_replication_controller.json +++ b/src/test/resources/samples/openshift3/v1_replication_controller.json @@ -77,7 +77,8 @@ } ], "restartPolicy": "Always", - "dnsPolicy": "ClusterFirst" + "dnsPolicy": "ClusterFirst", + "serviceAccountName": "dbServiceAccountName", } } }, From 4bb28b84e96183b38862c8f32782309ccb0a8f84 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Mon, 10 Oct 2016 17:42:06 +0200 Subject: [PATCH 036/258] jbide-22914: deploy latest does not work correctly --- .../restclient/capability/resources/DeployCapability.java | 6 +++--- .../internal/restclient/okhttp/ResponseCodeInterceptor.java | 2 +- .../java/com/openshift/restclient/NotFoundException.java | 6 ++++++ .../capability/resources/DeployCapabilityTest.java | 3 ++- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java index 3294e2a1..068d53c6 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java @@ -62,8 +62,8 @@ public void deploy() { LOG.debug("Skipping deployment because deployment status %s for %s is not in %s", new Object [] {status, deploymentName, COMPLETED_STATES}); return; } - }catch(OpenShiftException e) { - if(e.getStatus() == null || e.getStatus().getCode() != IHttpConstants.STATUS_NOT_FOUND) { + } catch(OpenShiftException e) { + if (e.getStatus() == null || e.getStatus().getCode() != IHttpConstants.STATUS_NOT_FOUND) { //swallow exception like cli throw e; } @@ -82,7 +82,7 @@ private String getLatestDeploymentName() { } private String getStatusFor(IReplicationController rc) { - if(rc.isAnnotatedWith(IReplicationController.DEPLOYMENT_PHASE)) { + if (rc.isAnnotatedWith(IReplicationController.DEPLOYMENT_PHASE)) { return rc.getAnnotation(IReplicationController.DEPLOYMENT_PHASE); } return ""; diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index 6b600863..69930fda 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -109,7 +109,7 @@ public static OpenShiftException createOpenShiftException(IClient client, Respon AuthorizationDetails details = new AuthorizationDetails(response.headers(), link); return new com.openshift.restclient.authorization.UnauthorizedException(details, status); case IHttpConstants.STATUS_NOT_FOUND: - return new NotFoundException(status == null ? "Not Found" : status.getMessage()); + return new NotFoundException(e, status, status == null ? "Not Found" : status.getMessage()); default: return new OpenShiftException(e, status, "Exception trying to %s %s response code: %s", response.request().method(), response.request().url().toString(), responseCode); } diff --git a/src/main/java/com/openshift/restclient/NotFoundException.java b/src/main/java/com/openshift/restclient/NotFoundException.java index 63fd3a22..9f539707 100644 --- a/src/main/java/com/openshift/restclient/NotFoundException.java +++ b/src/main/java/com/openshift/restclient/NotFoundException.java @@ -10,6 +10,8 @@ ******************************************************************************/ package com.openshift.restclient; +import com.openshift.restclient.model.IStatus; + /** * @author jeff.cantrill */ @@ -28,4 +30,8 @@ public NotFoundException(String message) { public NotFoundException(Throwable cause) { super(cause, ""); } + + public NotFoundException(Throwable cause, IStatus status, String message, Object... arguments) { + super(cause, status, message, arguments); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java index 129d1049..378b564b 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java @@ -21,6 +21,7 @@ import org.mockito.runners.MockitoJUnitRunner; import com.openshift.restclient.IClient; +import com.openshift.restclient.NotFoundException; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.capability.resources.IDeployCapability; import com.openshift.restclient.http.IHttpConstants; @@ -121,7 +122,7 @@ private void givenTheDeploymentIsRetrieved() { private void givenTheLatestDeploymentIsNotFound() { IStatus status = mock(IStatus.class); when(status.getCode()).thenReturn(IHttpConstants.STATUS_NOT_FOUND); - OpenShiftException e = new OpenShiftException(new RuntimeException(), status, ""); + NotFoundException e = new NotFoundException(null, status, "Not Found"); when(client.get(anyString(),anyString(),anyString())).thenThrow(e); } } From 704ca23cdf36e4ec489cd7316e73c82ded69d511 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Wed, 12 Oct 2016 19:04:59 -0400 Subject: [PATCH 037/258] add trigger of deployment off of instantiate endpoint --- .../restclient/apis/TypeMetaFactory.java | 3 + .../capability/CapabilityInitializer.java | 3 + .../resources/DeploymentTrigger.java | 105 ++++++++++++++++++ .../model/deploy/DeploymentRequest.java | 66 +++++++++++ .../openshift/restclient/ResourceKind.java | 1 + .../resources/IDeploymentTriggerable.java | 66 +++++++++++ .../restclient/http/IHttpConstants.java | 1 + .../model/deploy/IDeploymentRequest.java | 61 ++++++++++ .../model/deploy/DeployRequestTest.java | 43 +++++++ 9 files changed, 349 insertions(+) create mode 100644 src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java create mode 100644 src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentRequest.java create mode 100644 src/main/java/com/openshift/restclient/capability/resources/IDeploymentTriggerable.java create mode 100644 src/main/java/com/openshift/restclient/model/deploy/IDeploymentRequest.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/deploy/DeployRequestTest.java diff --git a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java index c9b492ae..7990a735 100644 --- a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java +++ b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java @@ -20,6 +20,7 @@ import com.openshift.internal.restclient.api.models.TypeMeta; import com.openshift.internal.restclient.apis.autoscaling.models.Scale; +import com.openshift.internal.restclient.model.deploy.DeploymentRequest; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.internal.util.JBossDmrExtentions; @@ -38,6 +39,8 @@ public class TypeMetaFactory implements ITypeFactory, ResourcePropertyKeys { static { IMPL_MAP.put("Scale", Scale.class); + //its own factory? + IMPL_MAP.put("DeploymentRequest", DeploymentRequest.class); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index a6230680..6f6e1710 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -18,6 +18,7 @@ import com.openshift.internal.restclient.capability.resources.DeployCapability; import com.openshift.internal.restclient.capability.resources.DeploymentConfigTraceability; import com.openshift.internal.restclient.capability.resources.DeploymentTraceability; +import com.openshift.internal.restclient.capability.resources.DeploymentTrigger; import com.openshift.internal.restclient.capability.resources.ImageStreamImportCapability; import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPodLogRetrieval; import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPortForwarding; @@ -44,6 +45,7 @@ import com.openshift.restclient.capability.resources.IDeploymentTraceability; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; import com.openshift.restclient.api.capabilities.IPodExec; +import com.openshift.restclient.capability.resources.IDeploymentTriggerable; import com.openshift.restclient.capability.resources.IPodLogRetrieval; import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; import com.openshift.restclient.capability.resources.IPortForwardable; @@ -132,6 +134,7 @@ public static void initializeCapabilities(Map, ICa public static void initializeCapabilities(Map, ICapability> capabilities, IDeploymentConfig config, IClient client){ initializeCapability(capabilities, IDeployCapability.class, new DeployCapability(config, client)); + initializeCapability(capabilities, IDeploymentTriggerable.class, new DeploymentTrigger(config, client, new TypeMetaFactory())); } public static void initializeCapabilities(Map, ICapability> capabilities, IReplicationController rc, IClient client){ diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java new file mode 100644 index 00000000..19273fc2 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import java.util.Optional; + +import com.openshift.internal.restclient.capability.AbstractCapability; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.api.ITypeFactory; +import com.openshift.restclient.capability.resources.IDeployCapability; +import com.openshift.restclient.capability.resources.IDeploymentTriggerable; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.model.IDeploymentConfig; +import com.openshift.restclient.model.deploy.IDeploymentRequest; + +/** + * + * @author Gabe Montero + * + */ +public class DeploymentTrigger extends AbstractCapability implements IDeploymentTriggerable { + private static final String DEPLOYMENT_ENDPOINT = "instantiate"; + private static final String DEPLOYMENT_REQUEST = "DeploymentRequest"; + + + private IClient client; + private IDeploymentConfig config; + private ITypeFactory factory; + private boolean latest; + private boolean force; + private String resourceName; + + + public DeploymentTrigger(IDeploymentConfig resource, IClient client, ITypeFactory factory) { + super(resource, client, DEPLOYMENT_ENDPOINT); + this.client = client; + this.config = resource; + this.factory = factory; + } + + @Override + public String getName() { + return DeploymentTrigger.class.getSimpleName(); + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public IDeploymentConfig trigger() { + if (super.isSupported()) { + IDeploymentRequest request = (IDeploymentRequest) factory.stubKind(DEPLOYMENT_REQUEST, Optional.of(config.getName()), Optional.empty()); + request.setForce(force); + request.setLatest(latest); + request.setName(resourceName); + return (IDeploymentConfig) client.execute(client.getResourceFactory(), IHttpConstants.POST, config.getKind(), config.getNamespace(), config.getName(), DEPLOYMENT_ENDPOINT, null, request); + } else { + IDeployCapability deployer = config.getCapability(IDeployCapability.class); + deployer.deploy(); + return client.get(ResourceKind.DEPLOYMENT_CONFIG, config.getName(), config.getNamespace()); + } + } + + @Override + public void setLatest(boolean latest) { + this.latest = latest; + } + + @Override + public boolean isLatest() { + return latest; + } + + @Override + public void setForce(boolean force) { + this.force = force; + } + + @Override + public boolean isForce() { + return force; + } + + @Override + public void setResourceName(String name) { + this.resourceName = name; + } + + @Override + public String getResourceName() { + return resourceName; + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentRequest.java b/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentRequest.java new file mode 100644 index 00000000..001ef2f9 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentRequest.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.deploy; + +import static com.openshift.internal.util.JBossDmrExtentions.*; + +import java.util.Map; + +import org.jboss.dmr.ModelNode; + +import com.openshift.internal.restclient.api.models.TypeMeta; +import com.openshift.restclient.model.deploy.IDeploymentRequest; + +/** + * + * @author Gabe Montero + * + */ +public class DeploymentRequest extends TypeMeta implements IDeploymentRequest { + + private static final String LATEST = "latest"; + private static final String FORCE = "force"; + + public DeploymentRequest(ModelNode node, Map overrideProperties) { + super(node, overrideProperties); + } + + @Override + public void setLatest(boolean latest) { + set(getNode(), getPropertyKeys(), LATEST, latest); + } + + @Override + public boolean isLatest() { + return asBoolean(getNode(), getPropertyKeys(), LATEST); + } + + @Override + public void setForce(boolean force) { + set(getNode(), getPropertyKeys(), FORCE, force); + } + + @Override + public boolean isForce() { + return asBoolean(getNode(), getPropertyKeys(), FORCE); + } + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), NAME); + } + + @Override + public void setName(String name) { + set(getNode(), getPropertyKeys(), NAME, name); + } + +} diff --git a/src/main/java/com/openshift/restclient/ResourceKind.java b/src/main/java/com/openshift/restclient/ResourceKind.java index 82d20a8b..924aef53 100644 --- a/src/main/java/com/openshift/restclient/ResourceKind.java +++ b/src/main/java/com/openshift/restclient/ResourceKind.java @@ -60,6 +60,7 @@ public final class ResourceKind { * RESTful operations */ public static final String BUILD_REQUEST = "BuildRequest"; + @Deprecated public static final String CONFIG = "Config";//not rest resource; public static final String LIST = "List"; diff --git a/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTriggerable.java b/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTriggerable.java new file mode 100644 index 00000000..fec93964 --- /dev/null +++ b/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTriggerable.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.capability.resources; + +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.model.IDeploymentConfig; + +/** + * Capability to trigger a deployment via the instantiate endpoint + * @author gmontero + */ +public interface IDeploymentTriggerable extends ICapability { + + /** + * Trigger a deployment based on a deployment config + * @return The updated deployment config after the deployment was triggered + */ + IDeploymentConfig trigger(); + + /** + * If set the true latest will update the deployment config with the latest state from all triggers. + * @param latest + */ + void setLatest(boolean latest); + + /** + * Returns the current setting of the latest flag. + * @return + */ + boolean isLatest(); + + /** + * If set to try force will try to force a new deployment to run. If the deployment config is paused, + * then setting this to true will return an Invalid error. + * @param force + */ + void setForce(boolean force); + + /** + * Returns the latest setting of the force flag. + * @return + */ + boolean isForce(); + + /** + * The name of the deployment config; note, the name in the corresponding oapi type + * is not in the k8s metadata object + * @param name of the deployment config + */ + void setResourceName(String name); + + /** + * Returns the name of the deployment config seeded into the deployment request + * @return + */ + String getResourceName(); + +} diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index ba783ab6..edc7cb94 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -63,4 +63,5 @@ public interface IHttpConstants { public static final int NO_TIMEOUT = -1; static final String PUT = "PUT"; + static final String POST = "POST"; } diff --git a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentRequest.java b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentRequest.java new file mode 100644 index 00000000..6df02761 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentRequest.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.model.deploy; + +import com.openshift.restclient.api.models.INameSetable; +import com.openshift.restclient.api.models.ITypeMeta; + +/** + * Resource payload for triggering a deployment via the instantiate endpoint + * @author gmontero + * + */ +public interface IDeploymentRequest extends ITypeMeta, INameSetable { + + /** + * If set the true latest will update the deployment config with the latest state from all triggers. + * @param latest + */ + void setLatest(boolean latest); + + /** + * Returns the current setting of the latest flag. + * @return + */ + boolean isLatest(); + + /** + * If set to try force will try to force a new deployment to run. If the deployment config is paused, + * then setting this to true will return an Invalid error. + * @param force + */ + void setForce(boolean force); + + /** + * Returns the latest setting of the force flag. + * @return + */ + boolean isForce(); + + /** + * The name of the deployment config; note, the name in the corresponding oapi type + * is not in the k8s metadata object + * @param name of the deployment config + */ + void setName(String name); + + /** + * Returns the name of the deployment config seeded into the deployment request + * @return + */ + String getName(); + +} diff --git a/src/test/java/com/openshift/internal/restclient/model/deploy/DeployRequestTest.java b/src/test/java/com/openshift/internal/restclient/model/deploy/DeployRequestTest.java new file mode 100644 index 00000000..16f9d0c9 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/deploy/DeployRequestTest.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.internal.restclient.model.deploy; + +import com.openshift.restclient.IClient; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; + +public class DeployRequestTest { + @Mock private IClient client; + private DeploymentRequest config; + private ModelNode node = new ModelNode(); + + @Before + public void setup(){ + config = new DeploymentRequest(node, new HashMap()); + } + + @Test + public void testDeploymentRequest(){ + + config.setForce( true ); + assertTrue("Exp. isForce to be true when set to true", config.isForce()); + config.setLatest(true); + assertEquals("Exp. isLatest to be true when set to true",true, config.isLatest()); + config.setName("foo"); + assertEquals("foo", config.getName()); + + } + +} From 2bdb585b78dd8a80edd4e60bc0d242a77357bd14 Mon Sep 17 00:00:00 2001 From: Mario Loriedo Date: Sun, 16 Oct 2016 11:21:50 -0600 Subject: [PATCH 038/258] Added setter and getter for Service type Signed-off-by: Mario Loriedo --- .../internal/restclient/model/Service.java | 6 +++++ .../openshift/restclient/model/IService.java | 10 ++++++++ .../restclient/model/v1/ServiceTest.java | 23 +++++++++++-------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Service.java b/src/main/java/com/openshift/internal/restclient/model/Service.java index e12882f8..299289e7 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Service.java +++ b/src/main/java/com/openshift/internal/restclient/model/Service.java @@ -146,4 +146,10 @@ public List getPods() { if(getClient() == null) return new ArrayList(); return getClient().list(ResourceKind.POD, getNamespace(), getSelector()); } + + @Override + public String getType() { return asString("spec.type"); } + + @Override + public void setType(String type) { set("spec.type", type); } } diff --git a/src/main/java/com/openshift/restclient/model/IService.java b/src/main/java/com/openshift/restclient/model/IService.java index dd37990e..e5da15b8 100644 --- a/src/main/java/com/openshift/restclient/model/IService.java +++ b/src/main/java/com/openshift/restclient/model/IService.java @@ -94,4 +94,14 @@ public interface IService extends IResource{ */ void setPorts(List ports); + /** + * Returns the type of the service. + * @return + */ + String getType(); + + /** + * Sets the type of the service. + */ + void setType(String type); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java index 85f403e6..e25db91e 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java @@ -127,14 +127,19 @@ public void testSetPorts() { assertEquals(1, service.getPorts().size()); assertEquals(port, ports[0]); } - + @Test - public void testAddPorts() { - IServicePort port = service.addPort(8299, 9299, "testport"); - service.setPorts(Arrays.asList(port)); - IServicePort [] ports = service.getPorts().toArray(new IServicePort[] {}); - assertEquals(1, service.getPorts().size()); - assertEquals(port, ports[0]); - } - + public void testAddPorts() { + IServicePort port = service.addPort(8299, 9299, "testport"); + service.setPorts(Arrays.asList(port)); + IServicePort [] ports = service.getPorts().toArray(new IServicePort[] {}); + assertEquals(1, service.getPorts().size()); + assertEquals(port, ports[0]); + } + + @Test + public void testSetType() { + service.setType("NodePort"); + assertEquals("NodePort", service.getType()); + } } From 515edcb06f4082e01f5c105025de2bfb7209e4d6 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 19 Oct 2016 15:53:21 -0400 Subject: [PATCH 039/258] add configmap back in --- .../openshift/internal/restclient/ResourceFactory.java | 2 ++ .../internal/restclient/model/v1/ConfigMapTest.java | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 1f93edcd..eef001d8 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -25,6 +25,7 @@ import com.openshift.internal.restclient.model.Build; import com.openshift.internal.restclient.model.BuildConfig; +import com.openshift.internal.restclient.model.ConfigMap; import com.openshift.internal.restclient.model.DeploymentConfig; import com.openshift.internal.restclient.model.ImageStream; import com.openshift.internal.restclient.model.KubernetesEvent; @@ -107,6 +108,7 @@ public class ResourceFactory implements IResourceFactory{ IMPL_MAP.put(ResourceKind.SERVICE, Service.class); IMPL_MAP.put(ResourceKind.SECRET, Secret.class); IMPL_MAP.put(ResourceKind.SERVICE_ACCOUNT, ServiceAccount.class); + IMPL_MAP.put(ResourceKind.CONFIG_MAP, ConfigMap.class); //fallback IMPL_MAP.put(ResourceKind.UNRECOGNIZED, KubernetesResource.class); diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java index 41484320..9acc46a5 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java @@ -8,6 +8,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.v1; +import com.openshift.internal.restclient.ResourceFactory; import com.openshift.internal.restclient.model.ConfigMap; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.restclient.IClient; @@ -30,14 +31,18 @@ public class ConfigMapTest { private static final String VERSION = "v1"; private IConfigMap configMap; + private IClient client; @Before public void setUp(){ - IClient client = mock(IClient.class); + client = mock(IClient.class); ModelNode node = ModelNode.fromJSONString(Samples.V1_CONFIG_MAP.getContentAsString()); configMap = new ConfigMap(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.CONFIG_MAP)); } - + @Test + public void testIsRegisteredWithFactory() { + configMap = new ResourceFactory(client).create(Samples.V1_CONFIG_MAP.getContentAsString()); + } @Test public void testGetData() { assertEquals(Collections.singletonMap("key1", "config1"), configMap.getData()); From 6b346e9ffd98639ccb7b51d301c9634342cf9beb Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 19 Oct 2016 15:34:29 -0400 Subject: [PATCH 040/258] [OSJC-275] Add volumes to deploymentconfigs --- .../internal/restclient/ResourceFactory.java | 8 +++ .../internal/restclient/model/Container.java | 10 ++++ .../model/ReplicationController.java | 15 +++++- .../model/volume/HostPathVolumeSource.java | 42 +++++++++++++++ .../restclient/model/volume/VolumeSource.java | 2 + .../restclient/IResourceFactory.java | 10 ++++ .../restclient/model/IContainer.java | 12 ++++- .../model/IReplicationController.java | 10 ++++ .../model/volume/IHostPathVolumeSource.java | 27 ++++++++++ .../DefaultClientIntegrationTest.java | 7 +++ .../restclient/ResourceFactoryTest.java | 6 +++ .../model/v1/HostPathVolumeSourceTest.java | 51 +++++++++++++++++++ .../model/v1/ReplicationControllerTest.java | 7 +++ 13 files changed, 204 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/model/volume/HostPathVolumeSource.java create mode 100644 src/main/java/com/openshift/restclient/model/volume/IHostPathVolumeSource.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 1f93edcd..0da70123 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -184,6 +184,14 @@ public T create(String version, String kind) { return (T) create(new ModelNode(), version, kind); } + @Override + @SuppressWarnings("unchecked") + public T create(String version, String kind, String name) { + T resource = (T) create(new ModelNode(), version, kind); + ((KubernetesResource)resource).setName(name); + return resource; + } + private IResource create(ModelNode node, String version, String kind) { try { node.get(APIVERSION).set(version); diff --git a/src/main/java/com/openshift/internal/restclient/model/Container.java b/src/main/java/com/openshift/internal/restclient/model/Container.java index d0435bfe..1f171526 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Container.java +++ b/src/main/java/com/openshift/internal/restclient/model/Container.java @@ -59,6 +59,7 @@ public Container(ModelNode node, Map propertyKeys) { this.node = node; this.propertyKeys = propertyKeys; } + @Override public void setName(String name) { set(node, propertyKeys, NAME, name); @@ -222,6 +223,15 @@ public Set getVolumeMounts() { return volumes; } + + @Override + public IVolumeMount addVolumeMount(String name) { + ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); + VolumeMount volume = new VolumeMount(mounts.add()); + volume.setName(name); + return volume; + } + @Override public String toJSONString() { return super.toJson(false); diff --git a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java index 4e014a86..7c449319 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java +++ b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java @@ -365,8 +365,21 @@ public void addVolume(IVolumeSource volumeSource) { } volList.add(ModelNode.fromJSONString(volumeSource.toJSONString())); } + + - @Override + @SuppressWarnings("unchecked") + @Override + public T addVolume(String volumetype, String name) { + ModelNode volList = get(VOLUMES); + ModelNode node = volList.add(); + node.get(volumetype).set(new ModelNode()); + IVolumeSource source = VolumeSource.create(node); + source.setName(name); + return (T) source; + } + + @Override public void setServiceAccountName(String serviceAccountName) { set(SERVICEACCOUNTNAME, serviceAccountName); } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/HostPathVolumeSource.java b/src/main/java/com/openshift/internal/restclient/model/volume/HostPathVolumeSource.java new file mode 100644 index 00000000..fc7870fc --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/volume/HostPathVolumeSource.java @@ -0,0 +1,42 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.volume; + +import static com.openshift.internal.util.JBossDmrExtentions.*; + +import org.jboss.dmr.ModelNode; + +import com.openshift.restclient.model.volume.IHostPathVolumeSource; + +/** + * Implementation of a hostpath volume source + * @author jeff.cantrill + * + */ +public class HostPathVolumeSource extends VolumeSource implements IHostPathVolumeSource{ + + private static final String PATH = "hostPath.path"; + + public HostPathVolumeSource(ModelNode node) { + super(node); + } + + @Override + public String getPath() { + return asString(getNode(), getPropertyKeys(), PATH); + } + + @Override + public void setPath(String path) { + set(getNode(), getPropertyKeys(), PATH, path); + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/VolumeSource.java b/src/main/java/com/openshift/internal/restclient/model/volume/VolumeSource.java index 80233cbc..a708b156 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/VolumeSource.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/VolumeSource.java @@ -60,6 +60,8 @@ public static IVolumeSource create(ModelNode node) { return new SecretVolumeSource(node); } else if (node.has(VolumeType.PERSISTENT_VOLUME_CLAIM)) { return new PersistentVolumeClaimVolumeSource(node); + } else if (node.has(VolumeType.HOST_PATH)) { + return new HostPathVolumeSource(node); } else { return new VolumeSource(node) {}; } diff --git a/src/main/java/com/openshift/restclient/IResourceFactory.java b/src/main/java/com/openshift/restclient/IResourceFactory.java index 36d034d2..1e2b2a6c 100644 --- a/src/main/java/com/openshift/restclient/IResourceFactory.java +++ b/src/main/java/com/openshift/restclient/IResourceFactory.java @@ -57,6 +57,16 @@ public interface IResourceFactory extends ITypeFactory{ */ T create(String version, String kind); + /** + * Create(or stub) a resource for a given version and kind and name + * @param version + * @param kind + * @param name + * + * @return + */ + T create(String version, String kind, String name); + /** * Stub out the given resource kind using a version determined by the factory * @param kind diff --git a/src/main/java/com/openshift/restclient/model/IContainer.java b/src/main/java/com/openshift/restclient/model/IContainer.java index b3f03559..a9b9f194 100644 --- a/src/main/java/com/openshift/restclient/model/IContainer.java +++ b/src/main/java/com/openshift/restclient/model/IContainer.java @@ -14,13 +14,13 @@ import java.util.Map; import java.util.Set; +import com.openshift.restclient.api.models.INameSetable; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.volume.IVolume; import com.openshift.restclient.model.volume.IVolumeMount; -public interface IContainer { +public interface IContainer extends INameSetable{ - void setName(String name); String getName(); void setImage(DockerImageURI tag); @@ -71,5 +71,13 @@ public interface IContainer { void setVolumeMounts(Set volumes); Set getVolumeMounts(); + /** + * Add a volumemount with the given name + * @param name + * @return IVolumeMount + */ + IVolumeMount addVolumeMount(String name); + + String toJSONString(); } diff --git a/src/main/java/com/openshift/restclient/model/IReplicationController.java b/src/main/java/com/openshift/restclient/model/IReplicationController.java index beab1158..ecc93a9c 100644 --- a/src/main/java/com/openshift/restclient/model/IReplicationController.java +++ b/src/main/java/com/openshift/restclient/model/IReplicationController.java @@ -186,6 +186,16 @@ public interface IReplicationController extends IResource{ * @param volumeSource The volume to add to the pod spec */ void addVolume(IVolumeSource volumeSource); + + /** + * Add a volume source of the given type with the given name. Unimplemented types + * will return a generic volumesource impl + * + * @param volumetype + * @param name + * @return + */ + T addVolume(String volumetype, String name); /** * Sets the volumes associated with the pod spec. Existing volumes will be overwritten. diff --git a/src/main/java/com/openshift/restclient/model/volume/IHostPathVolumeSource.java b/src/main/java/com/openshift/restclient/model/volume/IHostPathVolumeSource.java new file mode 100644 index 00000000..de363915 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/volume/IHostPathVolumeSource.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.model.volume; + +/** + * VolumeSource for hostpath volumes of a pod + * @author jeff.cantrill + * + */ +public interface IHostPathVolumeSource extends IVolumeSource { + + /** + * Host path mapped into a pod + * @return + */ + String getPath(); + + void setPath(String path); +} diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index c7d49d99..6c3ea1e6 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -29,11 +29,18 @@ import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.authorization.UnauthorizedException; +import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IBuildConfig; +import com.openshift.restclient.model.IContainer; +import com.openshift.restclient.model.IDeploymentConfig; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.build.IBuildConfigBuilder; +import com.openshift.restclient.model.deploy.DeploymentTriggerType; import com.openshift.restclient.model.project.IProjectRequest; import com.openshift.restclient.model.template.ITemplate; +import com.openshift.restclient.model.volume.IHostPathVolumeSource; +import com.openshift.restclient.model.volume.IVolumeMount; +import com.openshift.restclient.model.volume.VolumeType; /** * @author Jeff Cantrill diff --git a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java index 6cbca45d..064307a8 100644 --- a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java +++ b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java @@ -61,4 +61,10 @@ public void testStubWithNamespace() { assertEquals("bar", service.getNamespace()); } + @Test + public void testCreateWithKindAndName() { + IService service = factory.create("v1", ResourceKind.SERVICE, "foo"); + assertEquals("foo", service.getName()); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java new file mode 100644 index 00000000..ae432ef6 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.v1; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import com.openshift.internal.restclient.model.ModelNodeBuilder; +import com.openshift.internal.restclient.model.volume.VolumeSource; +import com.openshift.restclient.model.volume.IHostPathVolumeSource; + +public class HostPathVolumeSourceTest { + + private IHostPathVolumeSource source; + + @Before + public void setUp() throws Exception { + ModelNode node = new ModelNodeBuilder() + .set("name", "somevolumesourcename") + .set("hostPath", new ModelNodeBuilder() + .set("path", "/foo").build()).build(); + source = (IHostPathVolumeSource) VolumeSource.create(node); + } + + @Test + public void testName() { + assertThat(source.getName(), is("somevolumesourcename")); + source.setName("thenewname"); + assertThat(source.getName(), is("thenewname")); + } + + @Test + public void testPath() { + assertThat(source.getPath(), is("/foo")); + source.setPath("thenewpath"); + assertThat(source.getPath(), is("thenewpath")); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java index 2fb7d2ff..1ff2a40a 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java @@ -294,6 +294,9 @@ public void testAddContainerAllowsContainerToBeFurtherManipulated() throws JSON container.setPorts(ports); container.setVolumeMounts(mounts); + IVolumeMount fooVolumeMount = container.addVolumeMount("foobar"); + fooVolumeMount.setMountPath("/tmp2"); + ModelNode exp = new ModelNodeBuilder() .set("name", uri.getName()) .set("image",uri.toString()) @@ -306,6 +309,10 @@ public void testAddContainerAllowsContainerToBeFurtherManipulated() throws JSON .set("mountPath", "/tmp") .set("readOnly", false) ) + .add("volumeMounts", new ModelNodeBuilder() + .set("name", "foobar") + .set("mountPath", "/tmp2") + ) .build(); JSONAssert.assertEquals(exp.toJSONString(false), container.toJSONString(), true); From 22848aacaf2accc243c8dfd32ae6d93266d8e425 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Thu, 27 Oct 2016 17:57:35 +0200 Subject: [PATCH 041/258] jbide-23184: Add Capability to Watch Projects --- .../restclient/okhttp/WatchClient.java | 15 ++++++++--- .../restclient/okhttp/WatchClientTest.java | 27 +++++++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index b502e1ee..f87e1310 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -11,6 +11,7 @@ package com.openshift.internal.restclient.okhttp; import java.io.IOException; +import java.net.ProtocolException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -31,9 +32,9 @@ import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; import com.openshift.restclient.IOpenShiftWatchListener; +import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; import com.openshift.restclient.IWatcher; import com.openshift.restclient.OpenShiftException; -import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IList; import com.openshift.restclient.model.IResource; @@ -175,10 +176,16 @@ public void onClose(int statusCode, String reason) { public void onFailure(IOException err, Response response) { LOGGER.debug("WatchSocket Error for kind {}: {}", kind, err); try { - if(response == null) { + if (response == null) { listener.error(ResponseCodeInterceptor.createOpenShiftException(client, 0, "", "", err)); - }else { - listener.error(ResponseCodeInterceptor.createOpenShiftException(client, response.code(), response.body().string(), response.request().url().toString(), err)); + } else if (response.code() == IHttpConstants.STATUS_OK && err instanceof ProtocolException) { + // Just swallow it. Means the feature isn't supported in this OS server version yet. + // WebSocket creates error "Expected HTTP 101 response but was '200 OK'" + // This is described in the web socket specification. + LOGGER.debug("The feature isn't supported", err); + } else { + listener.error(ResponseCodeInterceptor.createOpenShiftException(client, response.code(), + response.body().string(), response.request().url().toString(), err)); } } catch (IOException e) { LOGGER.error("IOException trying to notify listener of specific OpenShiftException", err); diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java index 3d754137..eed1f6cf 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java @@ -13,17 +13,26 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; -import static org.mockito.Mockito.*; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; import java.io.IOException; +import java.net.ProtocolException; import org.junit.Test; import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.okhttp.WatchClient.WatchEndpoint; import com.openshift.restclient.IOpenShiftWatchListener; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.http.IHttpConstants; + +import okhttp3.Protocol; +import okhttp3.Request; +import okhttp3.Response; /** * @author Andre Dietisheim @@ -40,6 +49,20 @@ public void testOnFailureCallBackNotifiesListener() { endpoint.onFailure(new IOException(), null); verify(listener).error(any(Throwable.class)); } + + @Test + public void shouldIgnoreUnsupportedFeatureResponseOnFailure() { + DefaultClient client = mock(DefaultClient.class); + IOpenShiftWatchListener listener = mock(IOpenShiftWatchListener.class); + + WatchEndpoint endpoint = new WatchEndpoint(client, listener, ResourceKind.BUILD); + Response.Builder responseBuilder = new Response.Builder(); + responseBuilder.code(IHttpConstants.STATUS_OK) + .protocol(Protocol.HTTP_2) + .request(new Request.Builder().url("http://localhost").build()); + endpoint.onFailure(new ProtocolException(), responseBuilder.build()); + verify(listener, never()).error(any()); + } @Test public void changeTypeShouldEqualSameChangeType() { From c46acfc5d2da658fa8ff17873285be0d047215ef Mon Sep 17 00:00:00 2001 From: Marko Luksa Date: Fri, 28 Oct 2016 09:51:06 +0200 Subject: [PATCH 042/258] Fixed NPE --- .../internal/restclient/okhttp/ResponseCodeInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index 69930fda..a79fc2c5 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -86,7 +86,7 @@ public void setClient(DefaultClient client) { } public static IStatus getStatus(String response) { - if(response.startsWith("{")) { + if(response != null && response.startsWith("{")) { return new Status(response); } return null; From d6698ee353aaa9679ab9b33bcfe65efd016886cc Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Wed, 2 Nov 2016 13:25:45 +0100 Subject: [PATCH 043/258] jbide-23358: OpenShift Explorer: Pod status is not reflecting reality --- .../internal/restclient/model/Pod.java | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index b1785317..f1810538 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -33,8 +34,20 @@ public class Pod extends KubernetesResource implements IPod { private static final String POD_IP = "status.podIP"; private static final String POD_HOST = "status.hostIP"; - private static final String POD_STATUS = "status.phase"; private static final String POD_CONTAINERS = "spec.containers"; + private static final String POD_DELETION_TIMESTAMP = "metadata.deletionTimestamp"; + + private static final String POD_STATUS_PHASE = "status.phase"; + private static final String POD_STATUS_REASON = "status.reason"; + private static final String POD_STATUS_CONTAINER_STATUSES = "status.containerStatuses"; + + // container reasons fields and corresponding status prefixes + private static final Map POD_STATUS_CONTAINER_STATES = new HashMap() {{ + put("state.waiting.reason", ""); + put("state.terminated.reason", ""); + put("state.terminated.signal", "Signal: "); + put("state.terminated.exitCode", "Exit Code: "); + }}; public Pod(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); @@ -61,10 +74,38 @@ public Collection getImages() { } return images; } + + /** + * The logic of the method is a copied from 'podStatus' function of + * [app/scripts/filters/resources.js] of [openshift/origin-web-console] + */ @Override public String getStatus() { - return asString(POD_STATUS); + if (get(POD_DELETION_TIMESTAMP).isDefined()) { + return "Terminating"; + } + ModelNode node = get(POD_STATUS_CONTAINER_STATUSES); + if (node.getType() == ModelType.LIST) { + for (ModelNode containerStatus : node.asList()) { + for (String containerReason: POD_STATUS_CONTAINER_STATES.keySet()) { + String status = getContainerStatusIfDefined( + containerStatus, containerReason, POD_STATUS_CONTAINER_STATES.get(containerReason)); + if (status != null) { + return status; + } + } + } + } + return get(POD_STATUS_REASON).isDefined() ? asString(POD_STATUS_REASON) : asString(POD_STATUS_PHASE); + } + + private String getContainerStatusIfDefined(ModelNode containerStatus, String path, String statusPrefix) { + ModelNode node = containerStatus.get(getPath(path)); + if (node.isDefined()) { + return statusPrefix + node.asString(); + } + return null; } @Override From 4bc2bf0d761cd7d8c602560a447b837ed1bb7bb0 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Wed, 2 Nov 2016 23:42:23 +0100 Subject: [PATCH 044/258] jbide-23358: tests & review comments --- .../internal/restclient/model/Pod.java | 11 ++-- .../internal/restclient/model/v1/PodTest.java | 56 ++++++++++++++++--- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index f1810538..05d433d5 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -19,9 +19,11 @@ import java.util.Set; import java.util.stream.Collectors; +import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; +import com.openshift.internal.util.JBossDmrExtentions; import com.openshift.restclient.IClient; import com.openshift.restclient.model.IContainer; import com.openshift.restclient.model.IPod; @@ -82,7 +84,7 @@ public Collection getImages() { @Override public String getStatus() { - if (get(POD_DELETION_TIMESTAMP).isDefined()) { + if (has(POD_DELETION_TIMESTAMP)) { return "Terminating"; } ModelNode node = get(POD_STATUS_CONTAINER_STATUSES); @@ -101,11 +103,8 @@ public String getStatus() { } private String getContainerStatusIfDefined(ModelNode containerStatus, String path, String statusPrefix) { - ModelNode node = containerStatus.get(getPath(path)); - if (node.isDefined()) { - return statusPrefix + node.asString(); - } - return null; + String statusPostfix = JBossDmrExtentions.asString(containerStatus, null, path); + return StringUtils.isEmpty(statusPostfix) ? null : statusPrefix + statusPostfix; } @Override diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index 5ae93208..36e52463 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -8,7 +8,9 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import java.util.Collection; @@ -17,15 +19,21 @@ import java.util.Optional; import java.util.Set; -import com.openshift.internal.restclient.model.*; -import com.openshift.restclient.model.*; import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; +import com.openshift.internal.restclient.model.ExecAction; +import com.openshift.internal.restclient.model.Lifecycle; +import com.openshift.internal.restclient.model.Pod; +import com.openshift.internal.restclient.model.Port; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.IContainer; +import com.openshift.restclient.model.IExecAction; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IPort; import com.openshift.restclient.utils.Samples; /** @@ -37,24 +45,58 @@ public class PodTest { private IPod pod; @Before - public void setup(){ + public void setup() { IClient client = mock(IClient.class); ModelNode node = ModelNode.fromJSONString(Samples.V1_POD.getContentAsString()); pod = new Pod(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.POD)); } @Test - public void testGetHost(){ + public void testGetHost() { assertEquals("127.0.0.1", pod.getHost()); } @Test - public void testGetStatus(){ + public void testGetStatusPhase() { assertEquals("Running", pod.getStatus()); } @Test - public void testGetImages(){ + public void testGetStatusDeletion() { + ((Pod)pod).getNode().get("metadata", "deletionTimestamp").set("2016-11-02T16:31:55Z"); + assertEquals(pod.getStatus(), "Terminating"); + } + + @Test + public void testGetStatusWaitingReason() { + ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") + .set("waiting", new ModelNode().set("reason", "ReasonNotToWork")); + assertEquals(pod.getStatus(), "ReasonNotToWork"); + } + + @Test + public void testGetStatusTerminateReason() { + ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") + .set("terminated", new ModelNode().set("reason", "ReasonToTerminate")); + assertEquals(pod.getStatus(), "ReasonToTerminate"); + } + + @Test + public void testGetStatusTerminatedSignal() { + ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") + .set("terminated", new ModelNode().set("signal", "Alarm! Terminate!")); + assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); + } + + @Test + public void testGetStatusTerminatedExit() { + ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") + .set("terminated", new ModelNode().set("exitCode", "Let's go! Time to exit!")); + assertEquals(pod.getStatus(), "Exit Code: Let's go! Time to exit!"); + } + + @Test + public void testGetImages() { String [] exp = new String []{"openshift/origin-deployer:v0.6"}; assertArrayEquals(exp, pod.getImages().toArray()); } From a17499a9f0dc46f83a4a214500e224e4dd0d7e18 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Thu, 3 Nov 2016 11:22:57 +0100 Subject: [PATCH 045/258] jbide-23358: review remarks: improve readability --- .../internal/restclient/model/Pod.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index 05d433d5..64c6faf6 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -90,21 +90,23 @@ public String getStatus() { ModelNode node = get(POD_STATUS_CONTAINER_STATUSES); if (node.getType() == ModelType.LIST) { for (ModelNode containerStatus : node.asList()) { - for (String containerReason: POD_STATUS_CONTAINER_STATES.keySet()) { - String status = getContainerStatusIfDefined( - containerStatus, containerReason, POD_STATUS_CONTAINER_STATES.get(containerReason)); - if (status != null) { - return status; - } + String status = getContainerStatusStringIfExist(containerStatus); + if (status != null) { + return status; } } } - return get(POD_STATUS_REASON).isDefined() ? asString(POD_STATUS_REASON) : asString(POD_STATUS_PHASE); + return has(POD_STATUS_REASON) ? asString(POD_STATUS_REASON) : asString(POD_STATUS_PHASE); } - private String getContainerStatusIfDefined(ModelNode containerStatus, String path, String statusPrefix) { - String statusPostfix = JBossDmrExtentions.asString(containerStatus, null, path); - return StringUtils.isEmpty(statusPostfix) ? null : statusPrefix + statusPostfix; + private String getContainerStatusStringIfExist(ModelNode containerStatus) { + for (String path: POD_STATUS_CONTAINER_STATES.keySet()) { + String statusPostfix = JBossDmrExtentions.asString(containerStatus, null, path); + if (StringUtils.isNotEmpty(statusPostfix)) { + return POD_STATUS_CONTAINER_STATES.get(path) + statusPostfix; + } + } + return null; } @Override From 76a5ca4bd60823542d4669c97ef2e942be1851fa Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 3 Nov 2016 16:33:05 +0100 Subject: [PATCH 046/258] bumped to 5.2.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6ce5b127..26f449e5 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.2.0-SNAPSHOT + 5.2.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From 7eebc6a78b28a7bbf2bf17a8c9b06aca87b35591 Mon Sep 17 00:00:00 2001 From: Viacheslav Kabanovich Date: Tue, 8 Nov 2016 10:52:54 -0800 Subject: [PATCH 047/258] JBIDE-21463 Properties: Build pod has state of exit code 0 instead of correct status completed Logic of Pod.getStatus() is fixed to copy that of resources.js .filter('podStatus') --- .../internal/restclient/model/Pod.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index 64c6faf6..ef32b932 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -15,6 +15,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -44,11 +45,11 @@ public class Pod extends KubernetesResource implements IPod { private static final String POD_STATUS_CONTAINER_STATUSES = "status.containerStatuses"; // container reasons fields and corresponding status prefixes - private static final Map POD_STATUS_CONTAINER_STATES = new HashMap() {{ - put("state.waiting.reason", ""); - put("state.terminated.reason", ""); - put("state.terminated.signal", "Signal: "); - put("state.terminated.exitCode", "Exit Code: "); + private static final List POD_STATUS_CONTAINER_STATES = new ArrayList() {{ + add(new String[]{"state.waiting.reason", ""}); + add(new String[]{"state.terminated.reason", ""}); + add(new String[]{"state.terminated.signal", "Signal: "}); + add(new String[]{"state.terminated.exitCode", "Exit Code: "}); }}; public Pod(ModelNode node, IClient client, Map propertyKeys) { @@ -100,10 +101,12 @@ public String getStatus() { } private String getContainerStatusStringIfExist(ModelNode containerStatus) { - for (String path: POD_STATUS_CONTAINER_STATES.keySet()) { + for (String[] pathAndLabel: POD_STATUS_CONTAINER_STATES) { + String path = pathAndLabel[0]; String statusPostfix = JBossDmrExtentions.asString(containerStatus, null, path); if (StringUtils.isNotEmpty(statusPostfix)) { - return POD_STATUS_CONTAINER_STATES.get(path) + statusPostfix; + String label = pathAndLabel[1]; + return label + statusPostfix; } } return null; From 084d339039d4c6851b90a831f97a051b9136f417 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Wed, 9 Nov 2016 17:59:52 +0100 Subject: [PATCH 048/258] [OSJC-274] - When creating an app from a builder image template, expanding the buildconfig causes Signed-off-by: Jeff MAURY --- pom.xml | 2 +- .../restclient/model/BuildConfig.java | 52 ++++++++++--------- .../restclient/model/BuildConfigTest.java | 45 ++++++++++++++++ 3 files changed, 73 insertions(+), 26 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/model/BuildConfigTest.java diff --git a/pom.xml b/pom.xml index 26f449e5..2558cff9 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.2.0.Final + 5.3.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index ec0a8b10..8024d7ce 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -78,31 +78,33 @@ public IObjectReference getBuildOutputReference() { @Override public List getBuildTriggers() { List triggers = new ArrayList(); - List list = get(BUILDCONFIG_TRIGGERS).asList(); - final String url = getClient() != null ? getClient().getResourceURI(this) : ""; - for (ModelNode node : list) { - String type = node.get(TYPE).asString(); - switch(type){ - case BuildTriggerType.GENERIC: - triggers.add(new WebhookTrigger(BuildTriggerType.GENERIC, - asString(node, BUILD_CONFIG_WEBHOOK_GENERIC_SECRET), url)); - break; - case BuildTriggerType.GITHUB: - triggers.add(new WebhookTrigger(BuildTriggerType.GITHUB, asString(node, BUILD_CONFIG_WEBHOOK_GITHUB_SECRET), url)); - break; - case BuildTriggerType.IMAGE_CHANGE: - triggers.add(new ImageChangeTrigger(BuildTriggerType.IMAGE_CHANGE, - asString(node, BUILD_CONFIG_IMAGECHANGE_IMAGE), - asString(node, BUILD_CONFIG_IMAGECHANGE_NAME), - asString(node, BUILD_CONFIG_IMAGECHANGE_TAG)) - ); - break; - case BuildTriggerType.CONFIG_CHANGE: - triggers.add(new ImageChangeTrigger(BuildTriggerType.CONFIG_CHANGE, null, null)); - default: - } - } - return triggers; + if (has(BUILDCONFIG_TRIGGERS)) { + List list = get(BUILDCONFIG_TRIGGERS).asList(); + final String url = getClient() != null && StringUtils.isNotEmpty(getNamespace()) ? getClient().getResourceURI(this) : ""; + for (ModelNode node : list) { + String type = node.get(TYPE).asString(); + switch (type) { + case BuildTriggerType.GENERIC: + triggers.add(new WebhookTrigger(BuildTriggerType.GENERIC, + asString(node, BUILD_CONFIG_WEBHOOK_GENERIC_SECRET), url)); + break; + case BuildTriggerType.GITHUB: + triggers.add(new WebhookTrigger(BuildTriggerType.GITHUB, + asString(node, BUILD_CONFIG_WEBHOOK_GITHUB_SECRET), url)); + break; + case BuildTriggerType.IMAGE_CHANGE: + triggers.add(new ImageChangeTrigger(BuildTriggerType.IMAGE_CHANGE, + asString(node, BUILD_CONFIG_IMAGECHANGE_IMAGE), + asString(node, BUILD_CONFIG_IMAGECHANGE_NAME), + asString(node, BUILD_CONFIG_IMAGECHANGE_TAG))); + break; + case BuildTriggerType.CONFIG_CHANGE: + triggers.add(new ImageChangeTrigger(BuildTriggerType.CONFIG_CHANGE, null, null)); + default: + } + } + } + return triggers; } @Override diff --git a/src/test/java/com/openshift/internal/restclient/model/BuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/BuildConfigTest.java new file mode 100644 index 00000000..ef8bfdcb --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/BuildConfigTest.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.HashMap; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.IBuildConfig; + +/** + * Tests unrelated to the underlying model structure and + * should api version independent + * @author Jeff Maury + * + */ +public class BuildConfigTest { + + private IBuildConfig config; + + @Before + public void setUp() throws Exception { + config = new BuildConfig(new ModelNode(), mock(IClient.class), new HashMap<>()); + } + + @Test + public void testBuildTriggersShouldReturn() { + assertEquals(0, config.getBuildTriggers().size()); + } + +} From 2c1584f2cbddd015e9a026f5d34525dba56aa9b2 Mon Sep 17 00:00:00 2001 From: Viacheslav Kabanovich Date: Wed, 9 Nov 2016 19:29:20 -0800 Subject: [PATCH 049/258] JBIDE-23463 test is added --- .../internal/restclient/model/v1/PodTest.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index 36e52463..4323b6e6 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -81,6 +81,19 @@ public void testGetStatusTerminateReason() { assertEquals(pod.getStatus(), "ReasonToTerminate"); } + /** + * Check that if both reason and exit code are set, status returns the reason. + */ + @Test + public void testGetStatusTerminateReasonAndExit() { + ModelNode node = new ModelNode(); + node.get("reason").set("ReasonToTerminate"); + node.get("exitCode").set("Let's go! Time to exit!"); + ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") + .set("terminated", node); + assertEquals(pod.getStatus(), "ReasonToTerminate"); + } + @Test public void testGetStatusTerminatedSignal() { ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") @@ -88,6 +101,19 @@ public void testGetStatusTerminatedSignal() { assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); } + /** + * Check that if both signal and exit code are set, status returns the signal. + */ + @Test + public void testGetStatusTerminatedSignalAndExit() { + ModelNode node = new ModelNode(); + node.get("signal").set("Alarm! Terminate!"); + node.get("exitCode").set("Let's go! Time to exit!"); + ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") + .set("terminated", node); + assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); + } + @Test public void testGetStatusTerminatedExit() { ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") From 7b01b5f1f4d440a711ec717a41c2f5aa8de8fa5e Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 22 Nov 2016 16:10:50 +0100 Subject: [PATCH 050/258] bumping to 5.4.0-SNAPSHOT after releasing 5.3.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2558cff9..3b841aa4 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.3.0-SNAPSHOT + 5.4.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From dff780bf84aba9024fda3dfda92efc97b4577f2b Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Tue, 13 Dec 2016 15:33:51 -0500 Subject: [PATCH 051/258] [OSJC-242] Add Endpoints --- .../internal/restclient/ResourceFactory.java | 2 + .../restclient/api/models/Endpoints.java | 143 ++++++++++++++++++ .../openshift/restclient/ResourceKind.java | 1 + .../restclient/api/models/IEndpoints.java | 51 +++++++ .../restclient/model/v1/EndpointsTest.java | 78 ++++++++++ .../openshift/restclient/utils/Samples.java | 1 + .../samples/openshift3/api/v1_endpoints.json | 56 +++++++ 7 files changed, 332 insertions(+) create mode 100644 src/main/java/com/openshift/internal/restclient/api/models/Endpoints.java create mode 100644 src/main/java/com/openshift/restclient/api/models/IEndpoints.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java create mode 100644 src/test/resources/samples/openshift3/api/v1_endpoints.json diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 97008a66..9c9a6d77 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -23,6 +23,7 @@ import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; +import com.openshift.internal.restclient.api.models.Endpoints; import com.openshift.internal.restclient.model.Build; import com.openshift.internal.restclient.model.BuildConfig; import com.openshift.internal.restclient.model.ConfigMap; @@ -97,6 +98,7 @@ public class ResourceFactory implements IResourceFactory{ IMPL_MAP.put(ResourceKind.USER, OpenShiftUser.class); //Kubernetes Kinds + IMPL_MAP.put(ResourceKind.ENDPOINTS, Endpoints.class); IMPL_MAP.put(ResourceKind.EVENT, KubernetesEvent.class); IMPL_MAP.put(ResourceKind.LIMIT_RANGE, LimitRange.class); IMPL_MAP.put(ResourceKind.POD, Pod.class); diff --git a/src/main/java/com/openshift/internal/restclient/api/models/Endpoints.java b/src/main/java/com/openshift/internal/restclient/api/models/Endpoints.java new file mode 100644 index 00000000..4df412c5 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/api/models/Endpoints.java @@ -0,0 +1,143 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.api.models; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.jboss.dmr.ModelNode; + +import com.openshift.internal.restclient.model.KubernetesResource; +import com.openshift.internal.restclient.model.ModelNodeAdapter; +import com.openshift.internal.restclient.model.ObjectReference; +import com.openshift.internal.util.JBossDmrExtentions; +import com.openshift.restclient.IClient; +import com.openshift.restclient.api.models.IEndpoints; +import com.openshift.restclient.model.IObjectReference; + +public class Endpoints extends KubernetesResource implements IEndpoints { + + public Endpoints(ModelNode node, IClient client, Map overrideProperties) { + super(node, client, overrideProperties); + } + + @Override + public List getSubSets() { + List root = get("subsets").asList(); + ArrayList subsets = new ArrayList(root.size()); + for (ModelNode n : root) { + subsets.add(new EndpointSubset(n, getPropertyKeys())); + } + return subsets; + } + + private static class EndpointSubset extends ModelNodeAdapter implements IEndpointSubset { + + protected EndpointSubset(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public List getAddresses() { + List root = JBossDmrExtentions.get(getNode(), getPropertyKeys(), "addresses").asList(); + ArrayList addresses = new ArrayList(root.size()); + for (ModelNode n : root) { + addresses.add(new EndpointAddress(n, getPropertyKeys())); + } + return addresses; + } + + @Override + public List getNotReadyAddresses() { + List root = JBossDmrExtentions.get(getNode(), getPropertyKeys(), "notreadyaddresses").asList(); + ArrayList addresses = new ArrayList(root.size()); + for (ModelNode n : root) { + addresses.add(new EndpointAddress(n, getPropertyKeys())); + } + return addresses; + } + + @Override + public List getPorts() { + List root = JBossDmrExtentions.get(getNode(), getPropertyKeys(), PORTS).asList(); + ArrayList ports = new ArrayList(root.size()); + for (ModelNode n : root) { + ports.add(new EndpointPort(n, getPropertyKeys())); + } + return ports; + } + + } + + private static class EndpointAddress extends ModelNodeAdapter implements IEndpointAddress{ + + private static final String TARGET_REF = "targetRef"; + + protected EndpointAddress(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public String getIP() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "ip"); + } + + @Override + public String getHostName() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "hostname"); + } + + @Override + public String getNodeName() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "nodeName"); + } + + @Override + public String getName() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), NAME); + } + + @Override + public IObjectReference getTargetRef() { + if(getNode().has(JBossDmrExtentions.getPath(getPropertyKeys(), TARGET_REF))) { + ModelNode node = JBossDmrExtentions.get(getNode(), getPropertyKeys(), TARGET_REF); + return new ObjectReference(node); + } + return null; + } + + } + + private static class EndpointPort extends ModelNodeAdapter implements IEndpointPort { + + protected EndpointPort(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public String getName() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), NAME); + } + + @Override + public int getPort() { + return JBossDmrExtentions.asInt(getNode(), getPropertyKeys(), "port"); + } + + @Override + public String getProtocol() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), PROTOCOL); + } + + } +} + diff --git a/src/main/java/com/openshift/restclient/ResourceKind.java b/src/main/java/com/openshift/restclient/ResourceKind.java index 924aef53..390f9a8a 100644 --- a/src/main/java/com/openshift/restclient/ResourceKind.java +++ b/src/main/java/com/openshift/restclient/ResourceKind.java @@ -44,6 +44,7 @@ public final class ResourceKind { public static final String USER = "User"; //Kubernetes Kinds + public static final String ENDPOINTS = "Endpoints"; public static final String EVENT = "Event"; public static final String LIMIT_RANGE = "LimitRange"; public static final String POD = "Pod"; diff --git a/src/main/java/com/openshift/restclient/api/models/IEndpoints.java b/src/main/java/com/openshift/restclient/api/models/IEndpoints.java new file mode 100644 index 00000000..55857b71 --- /dev/null +++ b/src/main/java/com/openshift/restclient/api/models/IEndpoints.java @@ -0,0 +1,51 @@ + +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.api.models; + +import java.util.List; + +import com.openshift.restclient.model.IObjectReference; +import com.openshift.restclient.model.IResource; + +/** + * Endpoint representation 'api/Endpoint' + * @author jeff.cantrill + * + */ +public interface IEndpoints extends IResource{ + + List getSubSets(); + + interface IEndpointSubset { + + List getAddresses(); + List getNotReadyAddresses(); + List getPorts(); + } + + interface IEndpointAddress{ + + String getIP(); + String getHostName(); + String getNodeName(); + String getName(); + IObjectReference getTargetRef(); + } + + interface IEndpointPort{ + + String getName(); + int getPort(); + String getProtocol(); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java new file mode 100644 index 00000000..927e26b9 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.v1; + +import static org.fest.assertions.Assertions.*; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import com.openshift.internal.restclient.ResourceFactory; +import com.openshift.restclient.IClient; +import com.openshift.restclient.api.models.IEndpoints; +import com.openshift.restclient.api.models.IEndpoints.IEndpointAddress; +import com.openshift.restclient.api.models.IEndpoints.IEndpointPort; +import com.openshift.restclient.api.models.IEndpoints.IEndpointSubset; +import com.openshift.restclient.utils.Samples; + +@RunWith(MockitoJUnitRunner.class) +public class EndpointsTest { + + private static String JSON = Samples.V1_ENDPOINTS.getContentAsString(); + + @Mock + private IClient client; + private IEndpoints endpoint; + + @Before + public void setUp() throws Exception { + ResourceFactory factory = new ResourceFactory(client); + endpoint = factory.create(JSON); + } + + @Test + public void testDeserialization() { + List subSets = endpoint.getSubSets(); + assertThat(subSets).isNotEmpty(); + IEndpointSubset subset = subSets.get(0); + + List addresses = subset.getAddresses(); + assertThat(addresses).isNotEmpty(); + IEndpointAddress address = addresses.get(0); + assertThat(address.getName()).isEmpty(); + assertThat(address.getHostName()).isEmpty(); + assertThat(address.getNodeName()).isEmpty(); + assertThat(address.getIP()).isEqualTo("192.168.121.62"); + assertThat(address.getTargetRef()).isNotNull(); + + List notReady = subset.getNotReadyAddresses(); + assertThat(notReady).isNotEmpty(); + address = notReady.get(0); + assertThat(address.getName()).isEqualTo("notready"); + assertThat(address.getHostName()).isEqualTo("foo.bar"); + assertThat(address.getNodeName()).isEqualTo("xyz.abc"); + assertThat(address.getIP()).isEqualTo("192.168.121.68"); + assertThat(address.getTargetRef()).isNull(); + + List ports = subset.getPorts(); + assertThat(ports).isNotEmpty(); + IEndpointPort port = ports.get(0); + assertThat(port.getName()).isEqualTo("443-tcp"); + assertThat(port.getPort()).isEqualTo(443); + assertThat(port.getProtocol()).isEqualTo("TCP"); + } + +} diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 5ab37682..5356a799 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -34,6 +34,7 @@ public enum Samples { V1_BUILD_CONFIG("openshift3/v1_build_config.json"), V1_BUILD_CONFIG_LIST("openshift3/v1_build_config_list.json"), V1_DEPLOYMENT_CONIFIG("openshift3/v1_deployment_config.json"), + V1_ENDPOINTS("openshift3/api/v1_endpoints.json"), V1_EVENT("openshift3/v1_event.json"), V1_IMAGE_STREAM("openshift3/v1_image_stream.json"), V1_IMAGE_STREAM_IMPORT("openshift3/v1_image_stream_import.json"), diff --git a/src/test/resources/samples/openshift3/api/v1_endpoints.json b/src/test/resources/samples/openshift3/api/v1_endpoints.json new file mode 100644 index 00000000..06600028 --- /dev/null +++ b/src/test/resources/samples/openshift3/api/v1_endpoints.json @@ -0,0 +1,56 @@ +{ + "kind": "Endpoints", + "apiVersion": "v1", + "metadata": { + "name": "router", + "namespace": "default", + "selfLink": "/api/v1/namespaces/default/endpoints/router", + "uid": "0cfabcdf-c16b-11e6-80f6-525400320112", + "resourceVersion": "603", + "creationTimestamp": "2016-12-13T19:33:40Z", + "labels": { + "router": "router" + } + }, + "subsets": [ + { + "addresses": [ + { + "ip": "192.168.121.62", + "targetRef": { + "kind": "Pod", + "namespace": "default", + "name": "router-1-sk2p5", + "uid": "1a1f7dad-c16b-11e6-80f6-525400320112", + "resourceVersion": "601" + } + } + ], + "notreadyaddresses": [ + { + "name": "notready", + "ip": "192.168.121.68", + "hostname": "foo.bar", + "nodeName": "xyz.abc" + } + ], + "ports": [ + { + "name": "443-tcp", + "port": 443, + "protocol": "TCP" + }, + { + "name": "1936-tcp", + "port": 1936, + "protocol": "TCP" + }, + { + "name": "80-tcp", + "port": 80, + "protocol": "TCP" + } + ] + } + ] +} From 75506a672611ca016368fee3487911043dc8bd6b Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Fri, 16 Dec 2016 10:52:33 -0500 Subject: [PATCH 052/258] Add IRC channel to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 5f68f48f..73dd1f25 100755 --- a/README.md +++ b/README.md @@ -7,6 +7,8 @@ This is the Java REST client for the version 3 architecture of [OpenShift](https a work in progress to provide similiar functionality and features of the command-line interface and is used by JBoss Tools for OpenShift. For compatibility with OpenShift 2.x see https://github.com/openshift/openshift-java-client/. +For questions or feedback, reach us on IRC on #openshift-client on Freenode or post to our [mailing list](https://lists.openshift.redhat.com/openshiftmm/listinfo/dev) + Download -------- You may either build from source using maven (mvn clean package) which, using the master branch, will generate a snapshot build of the lastest updates. You may also retrieve final released jars from [Maven Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.openshift%22%20AND%20a%3A%22openshift-restclient-java%22). From 011190fea04533aad17f02bb5a5190cfde7e68b4 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Fri, 16 Dec 2016 10:50:36 -0500 Subject: [PATCH 053/258] Use reflection to determine class from API group --- .../internal/restclient/ApiTypeMapper.java | 9 ++-- .../internal/restclient/ResourceFactory.java | 43 ++++++++++++++++--- .../restclient/okhttp/WatchClient.java | 4 +- .../openshift/restclient/IApiTypeMapper.java | 7 +++ .../restclient/DefaultClientTest.java | 8 ++-- .../restclient/TypeMapperFixture.java | 6 +++ ...tBinaryPodLogRetrievalIntegrationTest.java | 12 ++++-- ...ftBinaryRSyncRetrievalIntegrationTest.java | 7 +-- .../restclient/model/v1/EndpointsTest.java | 10 ++--- 9 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index 2b807fd3..e09aa437 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -48,10 +48,6 @@ */ public class ApiTypeMapper implements IApiTypeMapper, ResourcePropertyKeys{ - private static final String FWD_SLASH = "/"; - private static final String KUBE_API = "api"; - private static final String OS_API = "oapi"; - private static final String API_GROUPS_API = "apis"; private static final Logger LOGGER = LoggerFactory.getLogger(ApiTypeMapper.class); private final String baseUrl; private final OkHttpClient client; @@ -356,7 +352,10 @@ public boolean isSupported(String capability) { @Override public String toString() { - return String.format("%s/%s/%s/%s/%s", prefix, apiGroupName, version, name, version,kind); + if(apiGroupName == null) { + return String.format("%s/%s/%s", prefix, version, name); + } + return String.format("%s/%s/%s/%s/%s", prefix, apiGroupName, version, name); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 9c9a6d77..2fdba9b6 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -23,7 +23,6 @@ import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; -import com.openshift.internal.restclient.api.models.Endpoints; import com.openshift.internal.restclient.model.Build; import com.openshift.internal.restclient.model.BuildConfig; import com.openshift.internal.restclient.model.ConfigMap; @@ -57,6 +56,8 @@ import com.openshift.internal.restclient.model.template.Template; import com.openshift.internal.restclient.model.user.OpenShiftUser; import com.openshift.internal.restclient.model.volume.PersistentVolumeClaim; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceFactoryException; @@ -98,7 +99,6 @@ public class ResourceFactory implements IResourceFactory{ IMPL_MAP.put(ResourceKind.USER, OpenShiftUser.class); //Kubernetes Kinds - IMPL_MAP.put(ResourceKind.ENDPOINTS, Endpoints.class); IMPL_MAP.put(ResourceKind.EVENT, KubernetesEvent.class); IMPL_MAP.put(ResourceKind.LIMIT_RANGE, LimitRange.class); IMPL_MAP.put(ResourceKind.POD, Pod.class); @@ -201,12 +201,13 @@ private IResource create(ModelNode node, String version, String kind) { node.get(APIVERSION).set(version); node.get(KIND).set(kind.toString()); Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); - if(IMPL_MAP.containsKey(kind)) { - Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, IClient.class, Map.class); - return constructor.newInstance(node, client, properyKeyMap); - } if(kind.endsWith("List")) { - return new com.openshift.internal.restclient.model.List(node, client, properyKeyMap); + return new com.openshift.internal.restclient.model.List(node, client, properyKeyMap); + } + Class klass = getResourceClass(version, kind); + if(klass != null) { + Constructor constructor = klass.getConstructor(ModelNode.class, IClient.class, Map.class); + return constructor.newInstance(node, client, properyKeyMap); } return new KubernetesResource(node, client, properyKeyMap); } catch (UnsupportedVersionException e) { @@ -215,6 +216,34 @@ private IResource create(ModelNode node, String version, String kind) { throw new ResourceFactoryException(e,"Unable to create %s resource kind %s from %s", version, kind, node); } } + + @SuppressWarnings("unchecked") + private Class getResourceClass(String version, String kind){ + if(IMPL_MAP.containsKey(kind)) { + return IMPL_MAP.get(kind); + } + IApiTypeMapper mapper = this.client.adapt(IApiTypeMapper.class); + if(mapper != null) { + IVersionedApiResource endpoint = mapper.getEndpointFor(version, kind); + String extension = ""; + switch(endpoint.getPrefix()) { + case IApiTypeMapper.KUBE_API: + case IApiTypeMapper.OS_API: + break; + default: + String extPlusVersion = endpoint.getApiGroupName(); + extension = StringUtils.split(extPlusVersion, IApiTypeMapper.FWD_SLASH)[0]; + } + try { + String classname = String.format("com.openshift.internal.restclient.%s%s.models.%s", endpoint.getPrefix(), extension, endpoint.getKind()); + return (Class)Class.forName(classname); + }catch(ClassNotFoundException e) { + //class doesnt exist in the exp location. + //fallback to an explicit registration + } + } + return null; + } @SuppressWarnings("unchecked") @Override diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index f87e1310..7e0e2601 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -27,7 +27,6 @@ import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.URLBuilder; -import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; @@ -197,8 +196,7 @@ public void onFailure(IOException err, Response response) { public void onMessage(ResponseBody body) throws IOException { String message = body.string(); LOGGER.debug(message); - KubernetesResource payload = client.getResourceFactory().create(message); - ModelNode node = payload.getNode(); + ModelNode node = ModelNode.fromJSONString(message); IOpenShiftWatchListener.ChangeType event = new ChangeType(node.get("type").asString()); IResource resource = client.getResourceFactory().create(node.get("object").toJSONString(true)); if(StringUtils.isEmpty(resource.getKind())) { diff --git a/src/main/java/com/openshift/restclient/IApiTypeMapper.java b/src/main/java/com/openshift/restclient/IApiTypeMapper.java index 2bfeb347..a6e4b290 100644 --- a/src/main/java/com/openshift/restclient/IApiTypeMapper.java +++ b/src/main/java/com/openshift/restclient/IApiTypeMapper.java @@ -21,6 +21,13 @@ * */ public interface IApiTypeMapper { + + static final String KUBE_API = "api"; + static final String OS_API = "oapi"; + static final String API_GROUPS_API = "apis"; + static final String FWD_SLASH = "/"; + + String getPreferedVersionFor(String endpoint); diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 23fcaabd..4019a94b 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -13,7 +13,6 @@ import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertEquals; -import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.List; @@ -54,12 +53,13 @@ public void setUp() throws Exception{ this.baseUrl = new URL("http://myopenshift"); givenAClient(); givenAPodList(); - getHttpClient().whenRequestTo("http://myopenshift/api/v1/namespaces/aNamespace/pods").thenReturn(responseOf(response.toJSONString(false))); + getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api/v1/namespaces/aNamespace/pods").thenReturn(responseOf(response.toJSONString(false))); } - private void givenAClient() throws MalformedURLException{ + private void givenAClient() throws Exception{ factory = new ResourceFactory(null); - client = new DefaultClient(baseUrl, getHttpClient(), factory, getApiTypeMapper(), new AuthorizationContext(null)); + client = (DefaultClient) getIClient();//new DefaultClient(baseUrl, getHttpClient(), factory, getApiTypeMapper(), new AuthorizationContext(null)); + factory = client.getResourceFactory(); } private void givenAPodList(){ diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 2351e1db..078a03ba 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -14,12 +14,14 @@ import static org.mockito.Mockito.*; import java.io.IOException; +import java.net.URL; import org.junit.Before; import org.mockito.ArgumentMatcher; import org.mockito.stubbing.OngoingStubbing; import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IClient; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.utils.Samples; @@ -47,6 +49,10 @@ protected TestOkHttpClient getHttpClient() { return client; } + protected IClient getIClient() throws Exception { + return new DefaultClient(new URL(base), client, new ResourceFactory(null), mapper, null); + } + @Before public void setUp() throws Exception { client.whenRequestTo(ANY).thenReturn(responseOf("")); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java index 2896ad99..6e0876b2 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java @@ -17,12 +17,15 @@ import java.util.List; import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability; +import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; import com.openshift.restclient.capability.resources.IPodLogRetrieval; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IResource; @@ -33,7 +36,7 @@ * */ public class OpenshiftBinaryPodLogRetrievalIntegrationTest { - + private static final Logger LOG = LoggerFactory.getLogger(OpenshiftBinaryPodLogRetrievalIntegrationTest.class); private IntegrationTestHelper helper = new IntegrationTestHelper(); private Exception ex; @@ -49,15 +52,18 @@ public void testLogRetrieval() { @Override public Exception visit(IPodLogRetrieval cap) { + StringBuilder builder = new StringBuilder(); try { - BufferedInputStream os = new BufferedInputStream(cap.getLogs(false, ""));//HELLO_OPENSHIFT)); + BufferedInputStream os = new BufferedInputStream(cap.getLogs(false, OpenShiftBinaryOption.SKIP_TLS_VERIFY)); int c; while((c = os.read()) != -1) { - System.out.print((char)c); + builder.append((char)c); } } catch (Exception e) { + LOG.error("There was an error:", e); return e; }finally { + LOG.info(builder.toString()); cap.stop(); } return null; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java index 9f36d946..39a78f75 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java @@ -34,6 +34,7 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability; +import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; import com.openshift.restclient.capability.resources.IRSyncable; import com.openshift.restclient.capability.resources.IRSyncable.LocalPeer; import com.openshift.restclient.capability.resources.IRSyncable.PodPeer; @@ -85,15 +86,15 @@ public void testRSyncLogRetrieval() throws IOException { public List visit(IRSyncable cap) { try { final BufferedReader reader = new BufferedReader(new InputStreamReader( - cap.sync(new LocalPeer(localTempDir.getAbsolutePath()), new PodPeer(targetDir, pod)))); + cap.sync(new LocalPeer(localTempDir.getAbsolutePath()), new PodPeer(targetDir, pod), OpenShiftBinaryOption.SKIP_TLS_VERIFY))); List logs = IOUtils.readLines(reader); // wait until end of 'rsync' cap.await(); return logs; } catch (Exception e) { - e.printStackTrace(); + LOG.error("Exception rsycing to pod:",e); } - return null; + return new ArrayList<>(); } }, new ArrayList<>()); diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java index 927e26b9..3ccfc025 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java @@ -20,8 +20,8 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import com.openshift.internal.restclient.ResourceFactory; -import com.openshift.restclient.IClient; +import com.openshift.internal.restclient.TypeMapperFixture; +import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.api.models.IEndpoints; import com.openshift.restclient.api.models.IEndpoints.IEndpointAddress; import com.openshift.restclient.api.models.IEndpoints.IEndpointPort; @@ -29,17 +29,17 @@ import com.openshift.restclient.utils.Samples; @RunWith(MockitoJUnitRunner.class) -public class EndpointsTest { +public class EndpointsTest extends TypeMapperFixture{ private static String JSON = Samples.V1_ENDPOINTS.getContentAsString(); @Mock - private IClient client; private IEndpoints endpoint; @Before public void setUp() throws Exception { - ResourceFactory factory = new ResourceFactory(client); + super.setUp(); + IResourceFactory factory = getIClient().getResourceFactory(); endpoint = factory.create(JSON); } From 93bfdf7b2a8a97b554c0b266bf5257e5f889c7a9 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Tue, 13 Dec 2016 10:27:59 -0500 Subject: [PATCH 054/258] [OSJC-241] Add int test for authorization kinds --- README.md | 1 + .../AuthorizationKindsIntegrationTest.java | 52 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java diff --git a/README.md b/README.md index 5f68f48f..b6c8f78e 100755 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Versions of this client known to be compatible with OpenShift | Client Version | OpenShift Origin Server | |--------------------------|-------------------------| +| 5.4.0-SNAPSHOT | v1.3.0 | | 5.0.0-SNAPSHOT | latest, v1.3.0-alpha.2 | | | v1.3.0-alpha.3 | diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java new file mode 100644 index 00000000..1bdc1040 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java @@ -0,0 +1,52 @@ + /******************************************************************************* + * Copyright (c) 2016 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.internal.restclient.authorization; + +import static org.fest.assertions.Assertions.assertThat; + +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.authorization.IRole; + +/** + * @author Jeff Cantrill + */ +public class AuthorizationKindsIntegrationTest { + + private IClient client; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + + @Before + public void setup () { + client = helper.createClientForBasicAuth(); + } + + @Test + public void testListRolesAssumingClusterAdmin(){ + List roles= client.list(ResourceKind.ROLE, "default"); + assertThat(roles).isNotEmpty(); + } + + @Test + public void testListPoliciesAssumingClusterAdmin(){ + client.list(ResourceKind.POLICY, "default"); + } + + @Test + public void testListPolicyBindingsAssumingClusterAdmin(){ + client.list(ResourceKind.POLICY_BINDING, "default"); + } + +} From a59941959532f1c7b779403ce75ce05d26948c23 Mon Sep 17 00:00:00 2001 From: Bjarte Stien Karlsen Date: Thu, 15 Dec 2016 15:33:51 +0100 Subject: [PATCH 055/258] client side filtering of get requests --- .../internal/restclient/DefaultClient.java | 58 +++++-- .../api/capabilities/ScaleCapability.java | 4 +- .../resources/DeploymentTrigger.java | 4 +- .../model/build/BuildConfigBuilder.java | 15 +- .../com/openshift/restclient/IClient.java | 39 ++++- .../restclient/model/IResourceBuilder.java | 6 +- .../DefaultClientFilterIntegrationTest.java | 155 ++++++++++++++++++ .../restclient/DefaultClientTest.java | 41 +---- 8 files changed, 257 insertions(+), 65 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 309cf65d..8ad7c3da 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -8,6 +8,8 @@ ******************************************************************************/ package com.openshift.internal.restclient; +import static java.util.stream.Collectors.joining; + import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeClientCapabilities; import java.io.IOException; @@ -15,6 +17,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -123,21 +126,31 @@ public List list(String kind, String namespace) { @SuppressWarnings("unchecked") @Override public List list(String kind, String namespace, Map labels) { - IList list = get(kind, namespace); - ArrayList items = new ArrayList((Collection)list.getItems()); - return filterItems(items, labels); //client filter until we can figure out how to restrict with a server call + + String labelQuery=""; + if(labels != null && !labels.isEmpty()){ + labelQuery = labels.entrySet().stream() + .map(e -> e.getKey() + "=" + e.getValue()) + .collect(joining(",")); + } + return list(kind, namespace, labelQuery); } - - private List filterItems(List items, Map labels){ - if(labels.isEmpty()) return items; - List filtered = new ArrayList(); - for (T item : items) { - if( item.getLabels().entrySet().containsAll(labels.entrySet())){ - filtered.add(item); - } + + @SuppressWarnings("unchecked") + @Override + public List list(String kind, String namespace, String labelQuery) { + + Map params = new HashMap<>(); + if(labelQuery != null && !labelQuery.isEmpty()){ + params.put("labelSelector", labelQuery); } - return filtered; + + IList resources = execute(HttpMethod.GET.toString(), kind, namespace, null, null, null, params); + List items = new ArrayList<>(); + items.addAll((Collection) resources.getItems()); + return items; } + @Override public Collection create(IList list, String namespace){ @@ -185,20 +198,33 @@ private T execute(HttpMethod method, String kind, String n @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, String subContext) { - return (T) execute(this.factory, method, kind, namespace, name, subresource, subContext, payload); + return (T) execute(this.factory, method, kind, namespace, name, subresource, subContext, payload, + Collections.emptyMap()); } @Override @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload) { - return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload); + return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload, + Collections.emptyMap()); } + @Override + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, Map params) { + return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload,params); + } @SuppressWarnings("unchecked") - public T execute(ITypeFactory factory, String method, String kind, String namespace, String name, String subresource, String subContext, JSONSerializeable payload) { + public T execute(ITypeFactory factory, String method, String kind, String namespace, String name, + String subresource, String subContext, JSONSerializeable payload, Map params) { if(factory == null) { throw new OpenShiftException("ITypeFactory is null while trying to call IClient#execute"); } + + if(params == null){ + params = Collections.emptyMap(); + } + if(ResourceKind.LIST.equals(kind)) throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) @@ -207,6 +233,7 @@ public T execute(ITypeFactory factory, String method, String kind, String na .namespace(namespace) .subresource(subresource) .subContext(subContext) + .addParameters(params) .build(); try { @@ -286,6 +313,7 @@ public IList get(String kind, String namespace) { return execute(HttpMethod.GET, kind, namespace, null, null, null); } + @Override public T get(String kind, String name, String namespace) { return execute(HttpMethod.GET, kind, namespace, name, null, null); diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java index 55a673a5..bc021707 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java @@ -10,6 +10,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.api.capabilities; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Optional; @@ -60,7 +61,8 @@ public IScale scaleTo(int replicas) { replicas = replicas >= MIN_VALUE ? replicas : MIN_VALUE; IScale arg = (IScale) factory.stubKind(ARG_KINDS.get(rc.getKind()), Optional.of(rc.getName()), Optional.of(rc.getNamespace())); arg.setSpecReplicas(replicas); - return (IScale) client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespace(), rc.getName(), CAPABILITY, null, arg); + return (IScale) client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespace(), rc.getName(), CAPABILITY, null, arg, + Collections.emptyMap()); } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java index 19273fc2..26bb7c98 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java @@ -10,6 +10,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; +import java.util.Collections; import java.util.Optional; import com.openshift.internal.restclient.capability.AbstractCapability; @@ -64,7 +65,8 @@ public IDeploymentConfig trigger() { request.setForce(force); request.setLatest(latest); request.setName(resourceName); - return (IDeploymentConfig) client.execute(client.getResourceFactory(), IHttpConstants.POST, config.getKind(), config.getNamespace(), config.getName(), DEPLOYMENT_ENDPOINT, null, request); + return (IDeploymentConfig) client.execute(client.getResourceFactory(), IHttpConstants.POST, config.getKind(), config.getNamespace(), config.getName(), DEPLOYMENT_ENDPOINT, null, request, + Collections.emptyMap()); } else { IDeployCapability deployer = config.getCapability(IDeployCapability.class); deployer.deploy(); diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java index 7a41b80f..b8962bd3 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java @@ -43,7 +43,8 @@ public class BuildConfigBuilder implements IBuildConfigBuilder { private final IClient client; private String name; private String namespace; - + private Map labels; + public BuildConfigBuilder(IClient client) { this.client = client; } @@ -70,6 +71,12 @@ public IBuildConfigBuilder inNamespace(String namespace) { return this; } + @Override + public IBuildConfigBuilder withLabels(Map labels) { + this.labels = labels; + return this; + } + @Override public IBuildConfig build() { BuildConfig bc = client.getResourceFactory().stub(ResourceKind.BUILD_CONFIG, this.name, this.namespace); @@ -81,6 +88,12 @@ public IBuildConfig build() { bc.setBuildSource(gitSourceBuilder.build()); } + if (labels != null && !labels.isEmpty()) { + for (Map.Entry label : labels.entrySet()) { + bc.addLabel(label.getKey(), label.getValue()); + } + } + DockerImageURI uri = new DockerImageURI(imageStreamTagOutput); IObjectReference outRef = bc.getBuildOutputReference(); outRef.setKind(ResourceKind.IMAGE_STREAM_TAG); diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index 5dfd0f2d..fde3ed46 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -37,7 +37,6 @@ public interface IClient extends ICapable, Cloneable { * @return */ List list(String kind); - /** * Lists the given given resource kind scoping it to a specific namespace @@ -50,7 +49,7 @@ public interface IClient extends ICapable, Cloneable { /** * Lists the given given resource kind scoping it to a specific namespace - * + * * @param kind * @param namespace The namespace to scope the possible results of this list * @param labels The label used to filter the resource @@ -58,10 +57,21 @@ public interface IClient extends ICapable, Cloneable { */ List list(String kind, String namespace, Map labels); + /** + * Lists the given given resource kind scoping it to a specific namespace + * + * @param kind + * @param namespace The namespace to scope the possible results of this list + * @param labelQuery The label used to filter the resource + * @return + */ + List list(String kind, String namespace, String labelQuery); + /** * - * @param service + * @param kind * @param name + * @param namespace * @return * @throws OpenShiftException if operation not supported for resource type */ @@ -141,6 +151,20 @@ public interface IClient extends ICapable, Cloneable { */ T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload); + /** + * Raw execution of a request + * @param httpMethod HttpMethod (e.g. POST) + * @param kind + * @param namespace + * @param name + * @param subresource subresource or capability + * @param payload the payload to sumit. only valid on non-get operations + * @param params map of query parameters + * @return + * + */ + T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload, Map params); + /** * Raw execution of a request * @param httpMethod HttpMethod (e.g. POST) @@ -157,15 +181,18 @@ public interface IClient extends ICapable, Cloneable { /** * @param factory The factory to use for interpreting the response * @param httpMethod HttpMethod (e.g. POST) - * @param kind + * @param kind * @param namespace * @param name * @param subresource subresource or capability * @param payload the payload to sumit. only valid on non-get operations - * @param subcontext additional subContext + * @param subContext additional subContext + * @param params * @return the raw payload string */ - T execute(ITypeFactory factory, String httpMethod, String kind, String namespace, String name, String subresource, String subContext, JSONSerializeable payload); + T execute(ITypeFactory factory, String httpMethod, String kind, String namespace, String name, + String subresource, String subContext, JSONSerializeable payload, + Map params); /** * diff --git a/src/main/java/com/openshift/restclient/model/IResourceBuilder.java b/src/main/java/com/openshift/restclient/model/IResourceBuilder.java index 38baf7b8..52b4b541 100644 --- a/src/main/java/com/openshift/restclient/model/IResourceBuilder.java +++ b/src/main/java/com/openshift/restclient/model/IResourceBuilder.java @@ -10,6 +10,8 @@ ******************************************************************************/ package com.openshift.restclient.model; +import java.util.Map; + /** * A builder for building up resources * @author jeff.cantrill @@ -21,7 +23,9 @@ public interface IResourceBuilder labels); + T build(); interface Endable{ diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java new file mode 100644 index 00000000..2ba36f6c --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java @@ -0,0 +1,155 @@ +package com.openshift.internal.restclient; + +import com.openshift.internal.restclient.model.build.BuildConfigBuilder; +import com.openshift.internal.restclient.model.project.OpenshiftProjectRequest; +import com.openshift.restclient.IClient; +import com.openshift.restclient.IResourceFactory; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.IBuildConfig; +import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.IResource; +import org.junit.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.stream.Collectors; + +import static com.openshift.internal.restclient.IntegrationTestHelper.*; +import static com.openshift.restclient.ResourceKind.BUILD_CONFIG; +import static org.junit.Assert.*; + +public class DefaultClientFilterIntegrationTest { + + private static final String VERSION = "v1"; + + private static final Logger LOG = LoggerFactory.getLogger(DefaultClientFilterIntegrationTest.class); + + private static IClient client; + + private static IResourceFactory factory; + + private static IProject project; + + private static IntegrationTestHelper helper = new IntegrationTestHelper(); + + @BeforeClass + public static void setup() { + + client = helper.createClientForBasicAuth(); + factory = new ResourceFactory(client); + OpenshiftProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); + projectRequest.setName(helper.generateNamespace()); + project = (IProject) client.create(projectRequest); + + createBuildConfigWithLabels(project, "build1", new HashMap() {{ + put("foo", "yes"); + put("bar", "no"); + put("baz", "no"); + }}); + + createBuildConfigWithLabels(project, "build2", new HashMap() {{ + put("foo", "no"); + put("bar", "yes"); + + }}); + + createBuildConfigWithLabels(project, "build3", new HashMap() {{ + put("foo", "yes"); + put("bar", "yes"); + }}); + + createBuildConfigWithLabels(project, "build4", new HashMap<>()); + + } + + @AfterClass + public static void cleanup() { + cleanUpResource(client, project); + } + + @Test + public void testFilteringWithOneLabel() { + List list = client.list(BUILD_CONFIG, project.getNamespace(), new HashMap() {{ + put("foo", "yes"); + }}); + + assertEquals(2, list.size()); + Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); + assertTrue("Should contain build1", names.contains("build1")); + assertTrue("Should contain build3", names.contains("build3")); + + } + + @Test + public void testFilteringWithTwoLabel() { + List list = client.list(BUILD_CONFIG, project.getNamespace(), new HashMap() {{ + put("foo", "yes"); + put("bar", "no"); + }}); + + assertEquals(1, list.size()); + IBuildConfig bc = list.get(0); + assertEquals("build1", bc.getName()); + } + + @Test + public void testFilteringWithLabelExist() { + List list = client.list(BUILD_CONFIG, project.getNamespace(), "baz"); + + assertEquals(1, list.size()); + IBuildConfig bc = list.get(0); + assertEquals("build1", bc.getName()); + } + + @Test + public void testFilteringWithLabelNotExist() { + List list = + client.list(BUILD_CONFIG, project.getNamespace(), "!baz"); + + Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); + + assertEquals(3, list.size()); + assertTrue("Should contain build2", names.contains("build2")); + assertTrue("Should contain build3", names.contains("build3")); + assertTrue("Should contain build4", names.contains("build4")); + + } + + @Test + public void testFilteringWithLabelNotEqualTo() { + List list = client.list(BUILD_CONFIG, project.getNamespace(), "foo != yes"); + + + Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); + + assertEquals(2, list.size()); + assertTrue("Should contain build2", names.contains("build2")); + assertTrue("Should contain build4", names.contains("build4")); } + + @Test + public void testFilteringWithLabelCombinedLabelQuery() { + List list = client.list(BUILD_CONFIG, project.getNamespace(), "foo,bar=no"); + + assertEquals(1, list.size()); + IBuildConfig bc = list.get(0); + assertEquals("build1", bc.getName()); + } + + + + private static IBuildConfig createBuildConfigWithLabels(IProject project, String name, HashMap labelFilter) { + + IBuildConfig bc = new BuildConfigBuilder(client) + .named(name) + .inNamespace(project.getNamespace()) + .usingSourceStrategy() + .fromDockerImage("centos/ruby-22-centos7:latest") + .end() + .toImageStreamTag("ruby-hello-world:latest") + .withLabels(labelFilter) + .build(); + return client.create(bc); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 4019a94b..0221bfe1 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -20,6 +20,7 @@ import org.jboss.dmr.ModelNode; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; @@ -94,47 +95,7 @@ private DefaultClient givenClient(URL baseUrl, String token, String user) { DefaultClient client = new DefaultClient(baseUrl, null, null, null, new AuthorizationContext(token,user,null)); return client; } - - @SuppressWarnings("serial") - @Test - public void testListResourceFilteringWithExactMatch() throws Exception { - Map labels = new HashMap(){{ - put("name","backend"); - put("env","production"); - }}; - List pods = client.list(ResourceKind.POD, "aNamespace", labels); - assertEquals("Expected 1 pod to be returned", 1, pods.size()); - assertEquals("Expected the frontend pod", podBackEnd, pods.get(0)); - } - - @Test - public void testListResourceFilteringNoMatch() throws Exception { - Map labels = new HashMap(); - labels.put("foo", "bar"); - List pods = client.list(ResourceKind.POD, "aNamespace", labels); - assertEquals("Expected no pod to be returned", 0, pods.size()); - } - @SuppressWarnings("serial") - @Test - public void testListResourceFilteringWithPartialMatch() throws Exception { - Map labels = new HashMap(){{ - put("name","frontend"); - }}; - List pods = client.list(ResourceKind.POD, "aNamespace", labels); - assertEquals("Expected 1 pod to be returned", 1, pods.size()); - assertEquals("Expected the backend pod", podFrontEnd, pods.get(0)); - } - - @SuppressWarnings("serial") - @Test - public void testListResourceFilteringSingleLabel() throws Exception { - Map labels = new HashMap(){{ - put("env","production"); - }}; - List pods = client.list(ResourceKind.POD, "aNamespace", labels); - assertEquals("Expected all pods to be returned", 3, pods.size()); - } @Test public void clientShouldEqualClientWithSameUrl() throws Exception { From 8f707cd1f50e63b92e39273ceaf422531e8a516d Mon Sep 17 00:00:00 2001 From: Bjarte Stien Karlsen Date: Thu, 15 Dec 2016 15:33:51 +0100 Subject: [PATCH 056/258] fix using a namespaced url without namespace --- .../internal/restclient/DefaultClient.java | 17 +++++++-- .../internal/restclient/URLBuilder.java | 6 ++-- .../com/openshift/restclient/IClient.java | 36 ++++++++++++++++--- .../internal/restclient/URLBuilderTest.java | 2 +- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 8ad7c3da..33947ed5 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -108,6 +108,11 @@ public IWatcher watch(String namespace, IOpenShiftWatchListener listener, String return watcher.watch(Arrays.asList(kinds), namespace, listener); } + @Override + public IWatcher watch(IOpenShiftWatchListener listener, String...kinds) { + return this.watch("", listener, kinds); + } + @Override public String getResourceURI(IResource resource) { return new URLBuilder(getBaseURL(), typeMapper, resource).build().toString(); @@ -115,12 +120,18 @@ public String getResourceURI(IResource resource) { @Override public List list(String kind) { - return list(kind,""); //assumes namespace=default + return list(kind,""); } - + + @Override + public List list(String kind, Map labels) { + return list(kind,"", labels); + } + + @Override public List list(String kind, String namespace) { - return list(kind, namespace, new HashMap()); + return list(kind, namespace, new HashMap<>()); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index 51d51957..1f6f5c69 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -140,7 +140,7 @@ public URL build() { throw new RuntimeException(e); } } - + private void buildWithNamespaceInPath(StringBuilder url) { if(!typeMappings.isSupported(apiVersion, kind)) { throw new UnsupportedEndpointException("Unable to determine the api endpoint for kind '%s'", kind); @@ -149,9 +149,9 @@ private void buildWithNamespaceInPath(StringBuilder url) { IVersionedApiResource apiResource = typeMappings.getEndpointFor(apiVersion, kind); url.append(apiResource.getPrefix()).append("/").append(apiResource.getVersion()); if(namespace == null && apiResource.isNamespaced()) { - throw new OpenShiftException("The api endpoint for kind '%s' requires a namespace", kind); + LOG.debug("The api endpoint for kind '{}' requires a namespace but none was provided. Will only work for priviledged user.", kind); } - if(apiResource.isNamespaced()) { + if(namespace != null) { url.append("/namespaces/") .append(namespace); } diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index fde3ed46..1d331903 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -28,16 +28,44 @@ * */ public interface IClient extends ICapable, Cloneable { - + + /* + * Watch for changes + * + * @param namespace The namespace to watch for changes in + * @param listener The listener to be notified on events + * @param kids The kinds to watch for + + */ IWatcher watch(String namespace, IOpenShiftWatchListener listener, String...kinds); - + + /* + * Watch for changes + * + * @param namespace The namespace to watch for changes in + * @param listener The listener to be notified on events + * @param kids The kinds to watch for + */ + IWatcher watch(IOpenShiftWatchListener listener, String...kinds); + + /** * Lists all possible resources of the given kind in the default namespace * @param kind * @return */ List list(String kind); - + + /** + * Lists the given given resource kind scoping it to a specific namespace + * + * @param kind + * @param labels The label used to filter the resource + * @return + */ + List list(String kind, Map labels); + + /** * Lists the given given resource kind scoping it to a specific namespace * @@ -68,7 +96,7 @@ public interface IClient extends ICapable, Cloneable { List list(String kind, String namespace, String labelQuery); /** - * + * * @param kind * @param name * @param namespace diff --git a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java index 0d1e84dd..e687f98e 100644 --- a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java @@ -77,7 +77,7 @@ public void testBuildingURLForAProjectUsingResource() throws Exception { resource(resource) .name("foo") .build().toString(); - assertEquals(String.format("%s/oapi/v1/projects/foo", BASE_URL),url.toString()); + assertEquals(String.format("%s/oapi/v1/namespaces/foo/projects/foo", BASE_URL),url.toString()); } @Test From 30e0ae5817d72bc60bf63aefa65e92f9dc911cc3 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 17 Jan 2017 15:08:24 -0500 Subject: [PATCH 057/258] adjust to removal of service.spec.portalIP --- .../internal/restclient/model/Service.java | 14 +++++++++++--- .../com/openshift/restclient/model/IService.java | 7 +++++++ .../internal/restclient/model/v1/ServiceTest.java | 5 +++++ .../resources/samples/openshift3/v1_service.json | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Service.java b/src/main/java/com/openshift/internal/restclient/model/Service.java index 299289e7..af3b1224 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Service.java +++ b/src/main/java/com/openshift/internal/restclient/model/Service.java @@ -18,7 +18,6 @@ import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; -import org.jboss.dmr.ModelType; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; @@ -136,9 +135,18 @@ public String getTargetPort() { return port != null ? port.getTargetPort() : "0"; } - @Override + @Override @Deprecated public String getPortalIP() { - return asString("spec.portalIP"); + String tmp = asString("spec.portalIP"); + if (StringUtils.isBlank(tmp)) { + tmp = getClusterIP(); + } + return tmp; + } + + @Override + public String getClusterIP() { + return asString("spec.clusterIP"); } @Override diff --git a/src/main/java/com/openshift/restclient/model/IService.java b/src/main/java/com/openshift/restclient/model/IService.java index e5da15b8..b3587ad9 100644 --- a/src/main/java/com/openshift/restclient/model/IService.java +++ b/src/main/java/com/openshift/restclient/model/IService.java @@ -75,8 +75,15 @@ public interface IService extends IResource{ * Returns the IP of the service. * @return */ + @Deprecated String getPortalIP(); + /** + * Returns the IP of the service. + * @return + */ + String getClusterIP(); + /** * Retrieves the pods for this service * @return diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java index e25db91e..460ccb7a 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java @@ -49,6 +49,11 @@ public void testGetPortalIP() { assertEquals("172.30.57.114", service.getPortalIP()); } + @Test + public void testGetClusterIP() { + assertEquals("172.30.57.114", service.getClusterIP()); + } + @Test public void testGetTargetPort() { assertEquals("3306", service.getTargetPort()); diff --git a/src/test/resources/samples/openshift3/v1_service.json b/src/test/resources/samples/openshift3/v1_service.json index 1fcee341..44738f64 100644 --- a/src/test/resources/samples/openshift3/v1_service.json +++ b/src/test/resources/samples/openshift3/v1_service.json @@ -33,7 +33,7 @@ "selector": { "name": "database" }, - "portalIP": "172.30.57.114", + "clusterIP": "172.30.57.114", "type": "ClusterIP", "sessionAffinity": "None" }, From af8923e10446b2552161382c483ca34a1ef19262 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Wed, 18 Jan 2017 17:20:12 -0500 Subject: [PATCH 058/258] allow use of okhttp3 default hostname verifier with cert callback --- .../java/com/openshift/restclient/ClientBuilder.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 366bf4d0..a0ab34a4 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -46,6 +46,7 @@ public class ClientBuilder { private String baseUrl; private ISSLCertificateCallback sslCertificateCallback = new NoopSSLCertificateCallback(); + private boolean sslCertCallbackWithDefaultHostnameVerifier = false; private X509Certificate certificate; private String certificateAlias; private IResourceFactory resourceFactory; @@ -77,6 +78,11 @@ public ClientBuilder sslCertificateCallback(ISSLCertificateCallback callback) { return this; } + public ClientBuilder sslCertCallbackWithDefaultHostnameVerifier(boolean b) { + this.sslCertCallbackWithDefaultHostnameVerifier = b; + return this; + } + public ClientBuilder sslCertificate(String alias, X509Certificate cert) { this.certificateAlias = alias; this.certificate = cert; @@ -190,9 +196,11 @@ public IClient build() { .readTimeout(readTimeout, readTimeoutUnit) .writeTimeout(writeTimeout, writeTimeoutUnit) .connectTimeout(connectTimeout, connectTimeoutUnit) - .hostnameVerifier(this.sslCertificateCallback) .sslSocketFactory(sslContext.getSocketFactory(), trustManager); + if (!this.sslCertCallbackWithDefaultHostnameVerifier) + builder.hostnameVerifier(sslCertificateCallback); + if (proxyAuthenticator != null) { builder.proxyAuthenticator(proxyAuthenticator); } From 5cd67d0f09e79d9dff5bbded72ab63e2ea79c227 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Fri, 20 Jan 2017 13:20:54 -0500 Subject: [PATCH 059/258] bump pom to 5.5.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3b841aa4..01a85fe9 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.4.0-SNAPSHOT + 5.5.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 4de8c19ef626cc59cc085b551ad36fd3852a740a Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Mon, 6 Feb 2017 09:17:38 -0500 Subject: [PATCH 060/258] [JBIDE-23865] Treat projects differently when building URL --- .../openshift/internal/restclient/URLBuilder.java | 2 +- .../restclient/DefaultClientIntegrationTest.java | 14 +++++--------- .../internal/restclient/URLBuilderTest.java | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index 1f6f5c69..4045fd97 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -151,7 +151,7 @@ private void buildWithNamespaceInPath(StringBuilder url) { if(namespace == null && apiResource.isNamespaced()) { LOG.debug("The api endpoint for kind '{}' requires a namespace but none was provided. Will only work for priviledged user.", kind); } - if(namespace != null) { + if(!ResourceKind.PROJECT.equals(kind) && namespace != null) { url.append("/namespaces/") .append(namespace); } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index 6c3ea1e6..74c35479 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -10,9 +10,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static com.openshift.internal.restclient.IntegrationTestHelper.*; -import java.net.MalformedURLException; import java.util.List; import org.junit.Before; @@ -26,21 +26,13 @@ import com.openshift.internal.restclient.model.template.Template; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; -import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.authorization.UnauthorizedException; -import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IBuildConfig; -import com.openshift.restclient.model.IContainer; -import com.openshift.restclient.model.IDeploymentConfig; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.build.IBuildConfigBuilder; -import com.openshift.restclient.model.deploy.DeploymentTriggerType; import com.openshift.restclient.model.project.IProjectRequest; import com.openshift.restclient.model.template.ITemplate; -import com.openshift.restclient.model.volume.IHostPathVolumeSource; -import com.openshift.restclient.model.volume.IVolumeMount; -import com.openshift.restclient.model.volume.VolumeType; /** * @author Jeff Cantrill @@ -76,6 +68,10 @@ public void testAuthContextIsAuthorizedWithoutPasswordThrows() { client.getAuthorizationContext().isAuthorized(); } + public void testListprojects() { + assertTrue(client.list(ResourceKind.PROJECT, "default").size() > 0); + } + @Test public void testReady() { client.getServerReadyStatus(); diff --git a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java index e687f98e..0d1e84dd 100644 --- a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java @@ -77,7 +77,7 @@ public void testBuildingURLForAProjectUsingResource() throws Exception { resource(resource) .name("foo") .build().toString(); - assertEquals(String.format("%s/oapi/v1/namespaces/foo/projects/foo", BASE_URL),url.toString()); + assertEquals(String.format("%s/oapi/v1/projects/foo", BASE_URL),url.toString()); } @Test From 433f49e475cd775520a73dddd4149191471b261a Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 6 Feb 2017 22:33:21 +0100 Subject: [PATCH 061/258] [JBIDE-23862] ensure path to oc is quoted if it contains " " --- .../resources/AbstractOpenShiftBinaryCapability.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 09ae1630..f5632dec 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -217,6 +217,17 @@ protected String getOpenShiftBinaryLocation() { String.format("The OpenShift 'oc' binary location was not specified. Set the property %s", OPENSHIFT_BINARY_LOCATION)); } + + location = addQuotesIfRequired(location); return location; } + + private String addQuotesIfRequired(String location) { + if (!StringUtils.isEmpty(location) + && location.contains(" ")) { + location = "\"" + location + "\""; + } + return location; + } + } From 2a12192b419de31d266dff6492ae71b03e591cac Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 8 Feb 2017 22:07:13 +0100 Subject: [PATCH 062/258] [JBIDE-23822] dont use erroneous --user= when "oc rsync" --- .../restclient/capability/resources/OpenShiftBinaryRSync.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java index bf8cd25c..575e2f74 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java @@ -142,7 +142,7 @@ public String getName() { @Override protected String buildArgs(final List options) { final StringBuilder argsBuilder = new StringBuilder("rsync "); - argsBuilder.append(getUserFlag()).append(getTokenFlag()).append(getServerFlag()); + argsBuilder.append(getTokenFlag()).append(getServerFlag()); if(options.contains(OpenShiftBinaryOption.SKIP_TLS_VERIFY)) { argsBuilder.append(getSkipTlsVerifyFlag()); } From 76dc5dd199501c3f2f5c2d58469125bd50cfc9e6 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 15 Feb 2017 14:51:56 +0100 Subject: [PATCH 063/258] bumping to 5.6.0-SNAPSHOT after releasing 5.5.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 01a85fe9..4d98d592 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.5.0-SNAPSHOT + 5.6.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 3e8171d783b4336eaa0f632a1d0764d88b501199 Mon Sep 17 00:00:00 2001 From: Daniel Urban Date: Thu, 30 Mar 2017 10:37:20 +0200 Subject: [PATCH 064/258] Thread safely initialize ApiTypeMapper (#264) --- .../internal/restclient/ApiTypeMapper.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index e09aa437..42ab9c87 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -19,7 +19,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -52,8 +51,8 @@ public class ApiTypeMapper implements IApiTypeMapper, ResourcePropertyKeys{ private final String baseUrl; private final OkHttpClient client; private List resourceEndpoints; - private Map preferedVersion = new HashMap<>(2); - private AtomicBoolean initialized = new AtomicBoolean(false); + private final Map preferedVersion = new HashMap<>(2); + private boolean initialized = false; public ApiTypeMapper(String baseUrl, OkHttpClient client) { this.baseUrl = baseUrl; @@ -117,24 +116,20 @@ private IVersionedApiResource formatEndpointFor(String prefix, String version, S return new VersionedApiResource(prefix, version, ResourceKind.pluralize(kind, true, true)); } - private void init() { - if(initialized.compareAndSet(false, true)) { - try { - List resourceEndpoints = new ArrayList<>(); - Collection groups = getLegacyGroups(); - groups.addAll(getApiGroups()); - groups.forEach(g->{ - Collection versions = g.getVersions(); - versions.forEach(v->{ - Collection resources = getResources(g, v); - addEndpoints(resourceEndpoints, g.getPrefix(), g.getName(), v, resources); - }); + private synchronized void init() { + if(!this.initialized) { + List resourceEndpoints = new ArrayList<>(); + Collection groups = getLegacyGroups(); + groups.addAll(getApiGroups()); + groups.forEach(g->{ + Collection versions = g.getVersions(); + versions.forEach(v->{ + Collection resources = getResources(g, v); + addEndpoints(resourceEndpoints, g.getPrefix(), g.getName(), v, resources); }); - this.resourceEndpoints = resourceEndpoints; - }catch(Exception e) { - initialized.set(false); - throw e; - } + }); + this.resourceEndpoints = resourceEndpoints; + this.initialized = true; } } From 148a0c0dde597c0bef3b199dbb242f29e139289e Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 5 Apr 2017 09:38:41 -0400 Subject: [PATCH 065/258] fixes #266. Remove dependency on jsch --- pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pom.xml b/pom.xml index 4d98d592..751de181 100755 --- a/pom.xml +++ b/pom.xml @@ -148,11 +148,6 @@ jboss-dmr 1.3.0.Final - - com.jcraft - jsch - 0.1.51 - org.apache.commons commons-io From ebc667601cc37524df7f98b95f050b17e229a46c Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 7 Apr 2017 17:56:15 +0200 Subject: [PATCH 066/258] add support for Build Strategy "JenkinsPipeline" #268 --- .../internal/restclient/model/Build.java | 9 +- .../restclient/model/BuildConfig.java | 20 +- .../restclient/model/EnvironmentVariable.java | 42 +++- .../model/build/BuildConfigBuilder.java | 47 ++++- .../model/build/DockerBuildStrategy.java | 1 - .../model/build/JenkinsPipelineStrategy.java | 90 ++++++++ .../model/build/BuildStrategyType.java | 1 + .../model/build/IBuildConfigBuilder.java | 11 +- .../model/build/IJenkinsPipelineStrategy.java | 32 +++ .../utils/EnvironmentVariableUtils.java | 38 ++++ .../model/v1/EnvironmentVariableTest.java | 92 ++++++++ .../model/v1/PipelineBuildConfigTest.java | 199 ++++++++++++++++++ .../openshift/restclient/utils/Samples.java | 3 +- .../openshift3/v1_buildconfig_pipeline.json | 44 ++++ 14 files changed, 617 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java create mode 100644 src/main/java/com/openshift/restclient/model/build/IJenkinsPipelineStrategy.java create mode 100644 src/main/java/com/openshift/restclient/utils/EnvironmentVariableUtils.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java create mode 100644 src/test/resources/samples/openshift3/v1_buildconfig_pipeline.json diff --git a/src/main/java/com/openshift/internal/restclient/model/Build.java b/src/main/java/com/openshift/internal/restclient/model/Build.java index 5b337ea4..312b699e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Build.java +++ b/src/main/java/com/openshift/internal/restclient/model/Build.java @@ -17,6 +17,7 @@ import com.openshift.internal.restclient.model.build.CustomBuildStrategy; import com.openshift.internal.restclient.model.build.DockerBuildStrategy; import com.openshift.internal.restclient.model.build.GitBuildSource; +import com.openshift.internal.restclient.model.build.JenkinsPipelineStrategy; import com.openshift.internal.restclient.model.build.SourceBuildStrategy; import com.openshift.restclient.IClient; import com.openshift.restclient.images.DockerImageURI; @@ -100,6 +101,7 @@ public T getBuildSource() { @SuppressWarnings("unchecked") public T getBuildStrategy() { switch(asString("spec.strategy.type")){ + case BuildStrategyType.CUSTOM: return (T) new CustomBuildStrategy( asString("spec.strategy.customStrategy.image"), @@ -110,12 +112,15 @@ public T getBuildStrategy() { return (T) new SourceBuildStrategy(get("spec.strategy"), getPropertyKeys()); case BuildStrategyType.DOCKER: - return (T) new DockerBuildStrategy( asString("spec.strategy.dockerStrategy.contextDir"), asBoolean("spec.strategy.dockerStrategy.noCache"), asString("spec.strategy.dockerStrategy.baseImage") ); + + case BuildStrategyType.JENKINS_PIPELINE: + return (T) new JenkinsPipelineStrategy(get("spec.strategy"), getPropertyKeys()); + default: } return null; @@ -130,7 +135,5 @@ public String getPushSecret() { public IBuildStatus getBuildStatus() { return new BuildStatus(get("status"), this.propertyKeys); } - - } diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index 8024d7ce..f32b30e5 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -20,6 +20,7 @@ import com.openshift.internal.restclient.model.build.DockerBuildStrategy; import com.openshift.internal.restclient.model.build.GitBuildSource; import com.openshift.internal.restclient.model.build.ImageChangeTrigger; +import com.openshift.internal.restclient.model.build.JenkinsPipelineStrategy; import com.openshift.internal.restclient.model.build.SourceBuildStrategy; import com.openshift.internal.restclient.model.build.WebhookTrigger; import com.openshift.restclient.IClient; @@ -35,6 +36,7 @@ import com.openshift.restclient.model.build.IDockerBuildStrategy; import com.openshift.restclient.model.build.IGitBuildSource; import com.openshift.restclient.model.build.IImageChangeTrigger; +import com.openshift.restclient.model.build.IJenkinsPipelineStrategy; import com.openshift.restclient.model.build.ISourceBuildStrategy; import com.openshift.restclient.model.build.IWebhookTrigger; @@ -62,7 +64,7 @@ public class BuildConfig extends KubernetesResource implements IBuildConfig { private static final String BUILD_CONFIG_IMAGECHANGE_IMAGE = "imageChange.image"; private static final String BUILD_CONFIG_IMAGECHANGE_NAME = "imageChange.from.name"; private static final String BUILD_CONFIG_IMAGECHANGE_TAG = "imageChange.tag"; - private static final String SOURCE_STRATEGY = "spec.strategy"; + private static final String BUILD_STRATEGY = "spec.strategy"; public BuildConfig(ModelNode node, IClient client, Map overrideProperties) { @@ -199,7 +201,7 @@ public void setBuildStrategy(IBuildStrategy strategy) { break; case BuildStrategyType.SOURCE: ISourceBuildStrategy source = (ISourceBuildStrategy) strategy; - get(SOURCE_STRATEGY).set(ModelNode.fromJSONString(source.toString())); + get(BUILD_STRATEGY).set(ModelNode.fromJSONString(source.toString())); break; case BuildStrategyType.DOCKER: if ( !(strategy instanceof IDockerBuildStrategy)) { @@ -214,6 +216,13 @@ public void setBuildStrategy(IBuildStrategy strategy) { } set(BUILDCONFIG_DOCKER_NOCACHE, docker.isNoCache()); break; + case BuildStrategyType.JENKINS_PIPELINE: + if ( !(strategy instanceof IJenkinsPipelineStrategy)) { + throw new IllegalArgumentException("IBuildStrategy of type Custom does not implement IJenkinsPipelineStrategy"); + } + IJenkinsPipelineStrategy jenkins = (IJenkinsPipelineStrategy)strategy; + get(BUILD_STRATEGY).set(ModelNode.fromJSONString(jenkins.toString())); + break; } set(BUILDCONFIG_TYPE, strategy.getType()); @@ -223,6 +232,7 @@ public void setBuildStrategy(IBuildStrategy strategy) { @Override public T getBuildStrategy() { switch(asString(BUILDCONFIG_TYPE)){ + case BuildStrategyType.CUSTOM: return (T) new CustomBuildStrategy( asString(BUILDCONFIG_CUSTOM_IMAGE), @@ -230,7 +240,7 @@ public T getBuildStrategy() { getEnvMap(BUILDCONFIG_CUSTOM_ENV) ); case BuildStrategyType.SOURCE: - return (T) new SourceBuildStrategy(get(SOURCE_STRATEGY), getPropertyKeys()); + return (T) new SourceBuildStrategy(get(BUILD_STRATEGY), getPropertyKeys()); case BuildStrategyType.DOCKER: return (T) new DockerBuildStrategy( @@ -238,6 +248,10 @@ public T getBuildStrategy() { asBoolean(BUILDCONFIG_DOCKER_NOCACHE), asString(BUILDCONFIG_DOCKER_BASEIMAGE) ); + + case BuildStrategyType.JENKINS_PIPELINE: + return (T) new JenkinsPipelineStrategy(get(BUILD_STRATEGY), getPropertyKeys()); + default: } return null; diff --git a/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java b/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java index ad24b03f..62ce34de 100644 --- a/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java +++ b/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java @@ -10,7 +10,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.model; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asString; import java.util.Map; @@ -84,4 +84,44 @@ public String getKey() { return null; } + + @Override + public boolean equals(Object object) { + if (!(object instanceof IEnvironmentVariable)) { + return false; + } + + IEnvironmentVariable otherVar = (IEnvironmentVariable) object; + String thisName = getName(); + String otherName = otherVar.getName(); + if (thisName == null) { + if (otherName != null) { + return false; + } + } else { + if (!thisName.equals(otherName)) { + return false; + } + } + + String thisValue = getValue(); + String otherValue = otherVar.getValue(); + if (thisValue == null) { + if (otherValue != null) { + return false; + } + } else { + if (!thisValue.equals(otherValue)) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + String name = getName(); + String value = getValue(); + return 37 * (name == null? 0 : name.hashCode()) + (value == null? 0 : value.hashCode()); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java index b8962bd3..5f8aa54d 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java @@ -36,6 +36,7 @@ public class BuildConfigBuilder implements IBuildConfigBuilder { private SourceStrategyBuilder sourceStrategyBuilder; private GitSourceBuilder gitSourceBuilder; + private JenkinsPipelineStrategyBuilder jenkinsPipelineStrategyBuilder; private String imageStreamTagOutput; private boolean buildOnConfigChange; private boolean buildOnImageChange; @@ -80,10 +81,13 @@ public IBuildConfigBuilder withLabels(Map labels) { @Override public IBuildConfig build() { BuildConfig bc = client.getResourceFactory().stub(ResourceKind.BUILD_CONFIG, this.name, this.namespace); - + if(sourceStrategyBuilder != null) { bc.setBuildStrategy(sourceStrategyBuilder.build(bc.getPropertyKeys())); + } else if (jenkinsPipelineStrategyBuilder != null) { + bc.setBuildStrategy(jenkinsPipelineStrategyBuilder.build(bc.getPropertyKeys())); } + if(gitSourceBuilder != null) { bc.setBuildSource(gitSourceBuilder.build()); } @@ -152,6 +156,12 @@ public IGitSourceBuilder fromGitSource() { return gitSourceBuilder; } + @Override + public IJenkinsPipelineStrategyBuilder usingJenkinsPipelineStrategy() { + jenkinsPipelineStrategyBuilder = new JenkinsPipelineStrategyBuilder(this); + return jenkinsPipelineStrategyBuilder; + } + class GitSourceBuilder implements IGitSourceBuilder { private IBuildConfigBuilder builder; @@ -245,9 +255,42 @@ public ISourceStrategyBuilder fromDockerImage(String tag) { this.fromKind = "DockerImage"; return this; } + } + + class JenkinsPipelineStrategyBuilder implements IJenkinsPipelineStrategyBuilder { + private IBuildConfigBuilder builder; + private String jenkinsFilePath; + private String jenkinsFile; + JenkinsPipelineStrategyBuilder(IBuildConfigBuilder builder){ + this.builder = builder; + } - } + @Override + public IJenkinsPipelineStrategyBuilder usingJenkinsfile(String file) { + this.jenkinsFile = file; + return this; + } + @Override + public IJenkinsPipelineStrategyBuilder usingJenkinsfilePath(String filePath) { + this.jenkinsFilePath = filePath; + return this; + } + + private JenkinsPipelineStrategy build(Map overrides) { + JenkinsPipelineStrategy strategy = new JenkinsPipelineStrategy(new ModelNode(), overrides); + strategy.setJenkinsfilePath(jenkinsFilePath); + strategy.setJenkinsfile(jenkinsFile); + return strategy; + } + + @Override + public IBuildConfigBuilder end() { + return builder; + } + + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/DockerBuildStrategy.java b/src/main/java/com/openshift/internal/restclient/model/build/DockerBuildStrategy.java index e94d3c1d..35c9f16e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/DockerBuildStrategy.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/DockerBuildStrategy.java @@ -40,7 +40,6 @@ public String getContextDir() { @Override public boolean isNoCache() { - // TODO Auto-generated method stub return noCache; } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java b/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java new file mode 100644 index 00000000..7a5ac19d --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java @@ -0,0 +1,90 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.build; + +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; + +import org.jboss.dmr.ModelNode; + +import com.openshift.internal.restclient.model.EnvironmentVariable; +import com.openshift.internal.restclient.model.ModelNodeAdapter; +import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; +import com.openshift.internal.util.JBossDmrExtentions; +import com.openshift.restclient.model.IEnvironmentVariable; +import com.openshift.restclient.model.build.BuildStrategyType; +import com.openshift.restclient.model.build.IJenkinsPipelineStrategy; + +/** + * @author Andre Dietisheim + */ +public class JenkinsPipelineStrategy extends ModelNodeAdapter implements IJenkinsPipelineStrategy, ResourcePropertyKeys { + + public JenkinsPipelineStrategy(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + set(node, propertyKeys, TYPE, BuildStrategyType.JENKINS_PIPELINE); + } + + @Override + public String getType() { + return asString(getNode(), getPropertyKeys(), TYPE); + } + + @Override + public void setJenkinsfilePath(String filePath) { + set(getNode(),getPropertyKeys(), JENKINS_FILE_PATH, filePath); + } + + @Override + public String getJenkinsfilePath() { + return asString(getNode(), getPropertyKeys(), JENKINS_FILE_PATH); + } + + @Override + public void setJenkinsfile(String file) { + set(getNode(),getPropertyKeys(), JENKINS_FILE, file); + } + + @Override + public String getJenkinsfile() { + return asString(getNode(), getPropertyKeys(), JENKINS_FILE); + } + + @Override + public Collection getEnvVars() { + String [] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); + ModelNode envNode = getNode().get(path); + if (envNode.isDefined()) { + return envNode.asList() + .stream() + .map(n -> new EnvironmentVariable(n, getPropertyKeys())) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } + + @Override + public void setEnvVars(Collection envVars) { + if (envVars == null) { + return; + } + String [] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); + ModelNode envNode = getNode().get(path); + envNode.clear(); + envVars.forEach(v->envNode.add(ModelNode.fromJSONString(v.toJson()))); + } + +} diff --git a/src/main/java/com/openshift/restclient/model/build/BuildStrategyType.java b/src/main/java/com/openshift/restclient/model/build/BuildStrategyType.java index a8c2dd79..a3b02316 100644 --- a/src/main/java/com/openshift/restclient/model/build/BuildStrategyType.java +++ b/src/main/java/com/openshift/restclient/model/build/BuildStrategyType.java @@ -22,5 +22,6 @@ public interface BuildStrategyType { static final String SOURCE = "Source"; static final String CUSTOM = "Custom"; + static final String JENKINS_PIPELINE = "JenkinsPipeline"; } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java index ff4a3dd7..1a544a2d 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java @@ -20,6 +20,7 @@ public interface IBuildConfigBuilder extends IResourceBuilder, ICapability { ISourceStrategyBuilder usingSourceStrategy(); + IJenkinsPipelineStrategyBuilder usingJenkinsPipelineStrategy(); IGitSourceBuilder fromGitSource(); IBuildConfigBuilder toImageStreamTag(String tag); IBuildConfigBuilder buildOnSourceChange(boolean onSourceChange); @@ -33,7 +34,7 @@ interface IGitSourceBuilder extends Endable{ IGitSourceBuilder fromGitUrl(String url); IGitSourceBuilder usingGitReference(String ref); IGitSourceBuilder inContextDir(String contextDir); - + } interface ISourceStrategyBuilder extends Endable{ @@ -59,4 +60,12 @@ interface ISourceStrategyBuilder extends Endable{ } + interface IJenkinsPipelineStrategyBuilder extends Endable { + + IBuildConfigBuilder end(); + + IJenkinsPipelineStrategyBuilder usingJenkinsfile(String file); + IJenkinsPipelineStrategyBuilder usingJenkinsfilePath(String filePath); + } + } diff --git a/src/main/java/com/openshift/restclient/model/build/IJenkinsPipelineStrategy.java b/src/main/java/com/openshift/restclient/model/build/IJenkinsPipelineStrategy.java new file mode 100644 index 00000000..819c886d --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/build/IJenkinsPipelineStrategy.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.restclient.model.build; + +import java.util.Collection; + +import com.openshift.restclient.model.IEnvironmentVariable; + +/** + * @author Andre Dietisheim + */ +public interface IJenkinsPipelineStrategy extends IBuildStrategy { + + static final String JENKINS_FILE = "jenkinsPipelineStrategy.jenkinsfile"; + static final String JENKINS_FILE_PATH = "jenkinsPipelineStrategy.jenkinsfilePath"; + static final String ENV = "jenkinsPipelineStrategy.env"; + + void setJenkinsfilePath(String filePath); + String getJenkinsfilePath(); + + void setJenkinsfile(String jenkinsFile); + String getJenkinsfile(); + + Collection getEnvVars(); + void setEnvVars(Collection envVars); +} diff --git a/src/main/java/com/openshift/restclient/utils/EnvironmentVariableUtils.java b/src/main/java/com/openshift/restclient/utils/EnvironmentVariableUtils.java new file mode 100644 index 00000000..32ac5f31 --- /dev/null +++ b/src/main/java/com/openshift/restclient/utils/EnvironmentVariableUtils.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.restclient.utils; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; + +import com.openshift.restclient.model.IEnvironmentVariable; + + +/** + * @author Andre Dietisheim + */ +public class EnvironmentVariableUtils { + + private EnvironmentVariableUtils(){ + } + + public static Map toMapOfStrings(Collection envVars){ + if (envVars == null) { + return null; + } + if (envVars.isEmpty()) { + return Collections.emptyMap(); + } + + return envVars.stream() + .collect(Collectors.toMap(envVar -> envVar.getName(), envVar -> envVar.getValue())); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java new file mode 100644 index 00000000..ef5485a5 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.internal.restclient.model.v1; + +import static org.fest.assertions.Assertions.assertThat; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.junit.Test; + +import com.openshift.internal.restclient.model.EnvironmentVariable; +import com.openshift.internal.restclient.model.ModelNodeBuilder; +import com.openshift.restclient.model.IEnvironmentVariable; +import com.openshift.restclient.utils.EnvironmentVariableUtils; + +/** + * @author Andre Dietisheim + */ +public class EnvironmentVariableTest { + + @Test + public void shouldBeEqualGivenEqualNameAndValue() { + // given + IEnvironmentVariable var1 = createEnvironmentVariable("foo", "bar"); + IEnvironmentVariable var2 = createEnvironmentVariable("foo", "bar"); + // when + // then + assertThat(var1).isEqualTo(var2); + } + + @Test + public void shouldBeNonEqualGivenNonEqualNameAndValue() { + // given + IEnvironmentVariable var1 = createEnvironmentVariable("foo", "bar"); + IEnvironmentVariable var2 = createEnvironmentVariable("kung", "foo"); + // when + // then + assertThat(var1).isNotEqualTo(var2); + } + + @SuppressWarnings("serial") + @Test + public void shouldReturnEmptyMapGivenEmptyEnvVars() { + // given + Collection envVars = Collections.emptyList(); + // when + Map envVarsMap = EnvironmentVariableUtils.toMapOfStrings(envVars); + // then + assertThat(envVarsMap).isEmpty(); + } + + @SuppressWarnings("serial") + @Test + public void shouldReturnMapOfStringsForEnvVariables() { + // given + Collection envVars = createEnvironmentVariables("foo", "bar", "kung", "foo", "smurfHater", "gargamel"); + // when + Map envVarsMap = EnvironmentVariableUtils.toMapOfStrings(envVars); + // then + assertThat(envVarsMap).isEqualTo( + new HashMap() {{ put("foo", "bar"); put("kung", "foo"); put("smurfHater", "gargamel"); }}); + } + + private Collection createEnvironmentVariables(String... touples) { + assertThat(touples).isNotNull(); + assertThat(touples.length % 2).isEqualTo(0); + + ArrayList envVars = new ArrayList(); + for (int i = 0; i < touples.length;) { + envVars.add(createEnvironmentVariable(touples[i++], touples[i++])); + } + return envVars; + } + + private IEnvironmentVariable createEnvironmentVariable(String name, String value) { + ModelNodeBuilder builder = new ModelNodeBuilder(); + builder + .set(EnvironmentVariable.NAME, name) + .set(EnvironmentVariable.VALUE, value); + return new EnvironmentVariable(builder.build(), null); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java new file mode 100644 index 00000000..21efdc23 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java @@ -0,0 +1,199 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.internal.restclient.model.v1; + +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; +import java.util.List; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import com.openshift.internal.restclient.model.BuildConfig; +import com.openshift.internal.restclient.model.EnvironmentVariable; +import com.openshift.internal.restclient.model.ModelNodeBuilder; +import com.openshift.internal.restclient.model.build.BuildConfigBuilder; +import com.openshift.restclient.IClient; +import com.openshift.restclient.IResourceFactory; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.IBuildConfig; +import com.openshift.restclient.model.IEnvironmentVariable; +import com.openshift.restclient.model.build.BuildStrategyType; +import com.openshift.restclient.model.build.IBuildConfigBuilder; +import com.openshift.restclient.model.build.IBuildStrategy; +import com.openshift.restclient.model.build.IJenkinsPipelineStrategy; +import com.openshift.restclient.utils.Samples; + +/** + * @author Andre Dietisheim + */ +public class PipelineBuildConfigTest { + + private static final String VERSION = "v1"; + + private IBuildConfig pipelineBc; + private IBuildConfigBuilder builder; + + @Before + public void setup() throws Exception{ + this.pipelineBc = createBuildConfig(Samples.V1_BUILDCONFIG_PIPELINE.getContentAsString()); + this.builder = createBuilder(); + } + + private IBuildConfig createBuildConfig(String content) throws MalformedURLException { + IClient client = createClient(); + BuildConfig bc = new BuildConfig(ModelNode.fromJSONString(content), client, null); + IResourceFactory factory = createResourceFactoryFor(bc); + when(client.getResourceFactory()).thenReturn(factory); + return bc; + } + + private IBuildConfigBuilder createBuilder() throws MalformedURLException { + IClient client = createClient(); + IBuildConfig bc = new BuildConfig(new ModelNode(), client, null); + IResourceFactory factory = createResourceFactoryFor(bc); + when(client.getResourceFactory()).thenReturn(factory); + + return new BuildConfigBuilder(client) + .named("foor") + .inNamespace("bar"); + } + + private IClient createClient() throws MalformedURLException { + IClient client = mock(IClient.class); + doReturn(new URL("https://localhost:8443")).when(client).getBaseURL(); + doReturn(VERSION).when(client).getOpenShiftAPIVersion(); + return client; + } + + private IResourceFactory createResourceFactoryFor(IBuildConfig bc) { + IResourceFactory factory = mock(IResourceFactory.class); + when(factory.stub(eq(ResourceKind.BUILD_CONFIG), anyString(), anyString())).thenReturn(bc); + return factory; + } + + @Test + public void shouldHaveJenkinsPipelineBuildStrategy() { + // given + // when + IBuildStrategy strategy = pipelineBc.getBuildStrategy(); + // then + assertThat(strategy).isNotNull(); + assertThat(strategy.getType()).isEqualTo(BuildStrategyType.JENKINS_PIPELINE); + } + + @Test + public void shouldHaveJenkinsfile() { + // given + // when + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // then + assertThat(strategy.getJenkinsfile()).isNotEmpty(); + } + + @Test + public void shouldHaveJenkinsfileGivenItWasSet() { + // given + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // when + strategy.setJenkinsfile("fooBar"); + // then + assertThat(strategy.getJenkinsfile()).isEqualTo("fooBar"); + } + + @Test + public void shouldHaveJenkinsfilePath() { + // given + // when + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // then + assertThat(strategy.getJenkinsfilePath()).isNotEmpty(); + } + + @Test + public void shouldHaveJenkinsfilePathGivenItWasSet() { + // given + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // when + strategy.setJenkinsfilePath("/foo/bar"); + // then + assertThat(strategy.getJenkinsfilePath()).isEqualTo("/foo/bar"); + } + + @Test + public void shouldHaveEnvVars() { + // given + // when + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // then + assertThat(strategy.getEnvVars()).containsOnly( + new EnvironmentVariable(new ModelNodeBuilder() + .set("name", "foo") + .set("value", "bar") + .build(), null), + new EnvironmentVariable(new ModelNodeBuilder() + .set("name", "kung") + .set("value", "foo") + .build(), null) + ); + } + + @Test + public void shouldHaveEnvVarsThatWereSet() { + // given + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + IEnvironmentVariable envVar = new EnvironmentVariable(new ModelNodeBuilder() + .set("name", "gargamel") + .set("value", "crazyLad") + .build(), null); + List envVars = Arrays.asList(envVar); + // when + strategy.setEnvVars(envVars); + // then + assertThat(strategy.getEnvVars()).containsOnly(envVar); + } + + @Test + public void shouldBuildJenkinsPipelineStrategyBuildConfig() { + // given + // when + IBuildConfig bc = builder + .usingJenkinsPipelineStrategy() + .end() + .build(); + // then + IBuildStrategy strategy = bc.getBuildStrategy(); + assertThat(strategy).isInstanceOf(IJenkinsPipelineStrategy.class); + } + + @Test + public void shouldBuildJenkinsPipelineStrategyWithJenkinsfileAndPath() { + // given + // when + IBuildConfig bc = builder + .usingJenkinsPipelineStrategy() + .usingJenkinsfile("node('aNode') {}") + .usingJenkinsfilePath("some/path/to/some/location") + .end() + .build(); + // then + IJenkinsPipelineStrategy strategy = bc.getBuildStrategy(); + assertThat(strategy.getJenkinsfile()).isEqualTo("node('aNode') {}"); + assertThat(strategy.getJenkinsfilePath()).isEqualTo("some/path/to/some/location"); + } +} diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 5356a799..97461049 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -64,7 +64,8 @@ public enum Samples { V1_SECRET_VOLUME_SOURCE("openshift3/v1_secret_volume_source.json"), V1_PVC_VOLUME_SOURCE("openshift3/v1_pvc_volume_source.json"), V1_LIFECYCLE("openshift3/v1_lifecycle.json"), - V1_DOCKER_IMAGE_MANIFEST("dockerregistry/v1_image_manifest.json"); + V1_DOCKER_IMAGE_MANIFEST("dockerregistry/v1_image_manifest.json"), + V1_BUILDCONFIG_PIPELINE("openshift3/v1_buildconfig_pipeline.json"); private static final String SAMPLES_FOLDER = "/samples/"; diff --git a/src/test/resources/samples/openshift3/v1_buildconfig_pipeline.json b/src/test/resources/samples/openshift3/v1_buildconfig_pipeline.json new file mode 100644 index 00000000..bc20b5e4 --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_buildconfig_pipeline.json @@ -0,0 +1,44 @@ +{ + "apiVersion": "v1", + "kind": "BuildConfig", + "metadata": { + "labels": { + "build": "mapsapp-pipeline" + }, + "name": "mapsapp-pipeline" + }, + "spec": { + "runPolicy": "Serial", + "source": { + }, + "strategy": { + "type": "JenkinsPipeline", + "jenkinsPipelineStrategy": { + "jenkinsfile": "def project = \"\"\nnode {\n project = \"${env.PROJECT_NAME}\"\n\n stage('Create NationalParks back-end') {\n def nationalParksURL = \"${NATIONALPARKS_GIT_URI}\"\n def nationalParksBranch = \"${NATIONALPARKS_GIT_REF}\"\n checkout([$class: \"GitSCM\", branches: [[name: \"*/${nationalParksBranch}\"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: \"RelativeTargetDirectory\", relativeTargetDir: \"nationalparks\"]], submoduleCfg: [], userRemoteConfigs: [[url: \"${nationalParksURL}\"]]])\n sh \"oc new-app -f nationalparks/ose3/pipeline-buildconfig-template.json -p GIT_URI=${nationalParksURL} -p GIT_REF=${nationalParksBranch} -n ${project} --dry-run -o yaml | oc apply -f - -n ${project}\"\n }\n\n stage('Create MLBParks back-end') {\n def mlbParksURL = \"${MLBPARKS_GIT_URI}\"\n def mlbParksBranch = \"${MLBPARKS_GIT_REF}\"\n checkout([$class: \"GitSCM\", branches: [[name: \"*/${mlbParksBranch}\"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: \"RelativeTargetDirectory\", relativeTargetDir: \"mlbparks\"]], submoduleCfg: [], userRemoteConfigs: [[url: \"${mlbParksURL}\"]]])\n sh \"oc new-app -f mlbparks/ose3/pipeline-buildconfig-template.json -p GIT_URI=${mlbParksURL} -p GIT_REF=${mlbParksBranch} -n ${project} --dry-run -o yaml | oc apply -f - -n ${project}\"\n }\n\n stage('Create ParksMap front-end') {\n def parksMapURL = \"${PARKSMAP_GIT_URI}\"\n def parksMapBranch = \"${PARKSMAP_GIT_REF}\"\n checkout([$class: \"GitSCM\", branches: [[name: \"*/${parksMapBranch}\"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: \"RelativeTargetDirectory\", relativeTargetDir: \"parksmap\"]], submoduleCfg: [], userRemoteConfigs: [[url: \"${parksMapURL}\"]]])\n sh \"oc new-app -f parksmap/ose3/pipeline-buildconfig-template.json -p GIT_URI=${parksMapURL} -p GIT_REF=${parksMapBranch} -n ${project} --dry-run -o yaml | oc apply -f - -n ${project}\"\n }\n}\n\nstage('Build Back-ends') {\n parallel (\n \"nationalparks\": {\n node {\n openshiftBuild buildConfig: \"nationalparks-pipeline\", namespace: project\n }\n },\n \"mlbparks\": {\n node {\n openshiftBuild buildConfig: \"mlbparks-pipeline\", namespace: project\n }\n }\n )\n}\n\nnode {\n stage('Build Front-end') {\n openshiftBuild buildConfig: \"parksmap-pipeline\", namespace: project\n }\n}", + "jenkinsfilePath": "some/repo/dir/filename", + "env": [{ + "name" : "foo", + "value" : "bar" + }, + { + "name" : "kung", + "value" : "foo" + }] + } + }, + "triggers": [ + { + "github": { + "secret": "${GITHUB_TRIGGER_SECRET}" + }, + "type": "GitHub" + }, + { + "generic": { + "secret": "${GENERIC_TRIGGER_SECRET}" + }, + "type": "Generic" + } + ] + } +} From cd02e8075219d968add0181670fe8ef43295c3ac Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 17 Apr 2017 22:38:10 +0200 Subject: [PATCH 067/258] [JBIDE-24242] display jenkins pipleline in app wizard and properties --- .../internal/restclient/model/BuildConfig.java | 11 +++++------ .../restclient/model/build/BuildConfigBuilder.java | 6 +++--- .../model/build/JenkinsPipelineStrategy.java | 2 +- .../restclient/model/build/IBuildConfigBuilder.java | 4 ++-- .../restclient/model/v1/PipelineBuildConfigTest.java | 4 ++-- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index f32b30e5..42783ba1 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -59,13 +59,12 @@ public class BuildConfig extends KubernetesResource implements IBuildConfig { public static final String BUILDCONFIG_DOCKER_BASEIMAGE = "spec.strategy.dockerStrategy.baseImage"; private static final String BUILDCONFIG_OUTPUT_REPO = "spec.output.to.name"; private static final String BUILDCONFIG_TRIGGERS = "spec.triggers"; + private static final String BUILDCONFIG_STRATEGY = "spec.strategy"; private static final String BUILD_CONFIG_WEBHOOK_GITHUB_SECRET = "github.secret"; private static final String BUILD_CONFIG_WEBHOOK_GENERIC_SECRET = "generic.secret"; private static final String BUILD_CONFIG_IMAGECHANGE_IMAGE = "imageChange.image"; private static final String BUILD_CONFIG_IMAGECHANGE_NAME = "imageChange.from.name"; private static final String BUILD_CONFIG_IMAGECHANGE_TAG = "imageChange.tag"; - private static final String BUILD_STRATEGY = "spec.strategy"; - public BuildConfig(ModelNode node, IClient client, Map overrideProperties) { super(node, client, null); @@ -201,7 +200,7 @@ public void setBuildStrategy(IBuildStrategy strategy) { break; case BuildStrategyType.SOURCE: ISourceBuildStrategy source = (ISourceBuildStrategy) strategy; - get(BUILD_STRATEGY).set(ModelNode.fromJSONString(source.toString())); + get(BUILDCONFIG_STRATEGY).set(ModelNode.fromJSONString(source.toString())); break; case BuildStrategyType.DOCKER: if ( !(strategy instanceof IDockerBuildStrategy)) { @@ -221,7 +220,7 @@ public void setBuildStrategy(IBuildStrategy strategy) { throw new IllegalArgumentException("IBuildStrategy of type Custom does not implement IJenkinsPipelineStrategy"); } IJenkinsPipelineStrategy jenkins = (IJenkinsPipelineStrategy)strategy; - get(BUILD_STRATEGY).set(ModelNode.fromJSONString(jenkins.toString())); + get(BUILDCONFIG_STRATEGY).set(ModelNode.fromJSONString(jenkins.toString())); break; } @@ -240,7 +239,7 @@ public T getBuildStrategy() { getEnvMap(BUILDCONFIG_CUSTOM_ENV) ); case BuildStrategyType.SOURCE: - return (T) new SourceBuildStrategy(get(BUILD_STRATEGY), getPropertyKeys()); + return (T) new SourceBuildStrategy(get(BUILDCONFIG_STRATEGY), getPropertyKeys()); case BuildStrategyType.DOCKER: return (T) new DockerBuildStrategy( @@ -250,7 +249,7 @@ public T getBuildStrategy() { ); case BuildStrategyType.JENKINS_PIPELINE: - return (T) new JenkinsPipelineStrategy(get(BUILD_STRATEGY), getPropertyKeys()); + return (T) new JenkinsPipelineStrategy(get(BUILDCONFIG_STRATEGY), getPropertyKeys()); default: } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java index 5f8aa54d..50a2cc27 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2017 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -268,13 +268,13 @@ class JenkinsPipelineStrategyBuilder implements IJenkinsPipelineStrategyBuilder } @Override - public IJenkinsPipelineStrategyBuilder usingJenkinsfile(String file) { + public IJenkinsPipelineStrategyBuilder usingFile(String file) { this.jenkinsFile = file; return this; } @Override - public IJenkinsPipelineStrategyBuilder usingJenkinsfilePath(String filePath) { + public IJenkinsPipelineStrategyBuilder usingFilePath(String filePath) { this.jenkinsFilePath = filePath; return this; } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java b/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java index 7a5ac19d..6e3fe82a 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2017 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java index 1a544a2d..ac8966a5 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java @@ -64,8 +64,8 @@ interface IJenkinsPipelineStrategyBuilder extends Endable { IBuildConfigBuilder end(); - IJenkinsPipelineStrategyBuilder usingJenkinsfile(String file); - IJenkinsPipelineStrategyBuilder usingJenkinsfilePath(String filePath); + IJenkinsPipelineStrategyBuilder usingFile(String file); + IJenkinsPipelineStrategyBuilder usingFilePath(String filePath); } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java index 21efdc23..a599bc41 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java @@ -187,8 +187,8 @@ public void shouldBuildJenkinsPipelineStrategyWithJenkinsfileAndPath() { // when IBuildConfig bc = builder .usingJenkinsPipelineStrategy() - .usingJenkinsfile("node('aNode') {}") - .usingJenkinsfilePath("some/path/to/some/location") + .usingFile("node('aNode') {}") + .usingFilePath("some/path/to/some/location") .end() .build(); // then From 645fbbf6956135f2d7f98014d695237e6d6dd808 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 10 May 2017 11:07:07 +0200 Subject: [PATCH 068/258] bumping to 5.7.0-SNAPSHOT after releasing 5.6.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 751de181..461fb3b7 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.6.0-SNAPSHOT + 5.7.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From cfde13e364176b6546c85534c58d740a95f4f849 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Fri, 12 May 2017 22:37:37 +0200 Subject: [PATCH 069/258] jbide-23862: fix for spaces in path to oc binary --- .../AbstractOpenShiftBinaryCapability.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index f5632dec..1da9a919 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -10,7 +10,9 @@ ******************************************************************************/ package com.openshift.internal.restclient.capability.resources; +import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -152,9 +154,11 @@ public final void start(final OpenShiftBinaryOption... options) { } private void startProcess(final String location, final OpenShiftBinaryOption... options) { - String cmdLine = new StringBuilder(location).append(' ').append(buildArgs(Arrays.asList(options))).toString(); - String[] args = StringUtils.split(cmdLine, " "); + List args = new ArrayList(); + args.add("oc"); + Arrays.stream(buildArgs(Arrays.asList(options)).split(" ")).forEach(s -> args.add(s)); ProcessBuilder builder = new ProcessBuilder(args); + builder.directory(new File(location).getParentFile()); builder.environment().remove("KUBECONFIG"); LOG.debug("OpenShift binary args: {}", builder.command()); try { @@ -217,16 +221,6 @@ protected String getOpenShiftBinaryLocation() { String.format("The OpenShift 'oc' binary location was not specified. Set the property %s", OPENSHIFT_BINARY_LOCATION)); } - - location = addQuotesIfRequired(location); - return location; - } - - private String addQuotesIfRequired(String location) { - if (!StringUtils.isEmpty(location) - && location.contains(" ")) { - location = "\"" + location + "\""; - } return location; } From 8b6477ca77bbf32e9c375cc1b03fadab4d69fdec Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Fri, 19 May 2017 17:32:20 +0200 Subject: [PATCH 070/258] jbide-23862: working fix for mac --- .../AbstractOpenShiftBinaryCapability.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 1da9a919..aeddc2cb 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -36,6 +36,10 @@ public abstract class AbstractOpenShiftBinaryCapability implements IBinaryCapability { private static final Logger LOG = LoggerFactory.getLogger(AbstractOpenShiftBinaryCapability.class); + + + private static final boolean IS_MAC = StringUtils.isNotEmpty(System.getProperty("os.name")) + && System.getProperty("os.name").toLowerCase().contains("mac"); private Process process; @@ -155,10 +159,21 @@ public final void start(final OpenShiftBinaryOption... options) { private void startProcess(final String location, final OpenShiftBinaryOption... options) { List args = new ArrayList(); - args.add("oc"); - Arrays.stream(buildArgs(Arrays.asList(options)).split(" ")).forEach(s -> args.add(s)); - ProcessBuilder builder = new ProcessBuilder(args); - builder.directory(new File(location).getParentFile()); + ProcessBuilder builder = null; + // the condition is made in order to solve mac problem + // with launching binaries containing spaces in its path + // https://issues.jboss.org/browse/JBIDE-23862 - see the latest comments + if (IS_MAC) { + args.add(location); + Arrays.stream(buildArgs(Arrays.asList(options)).split(" ")).forEach(s -> args.add(s)); + builder = new ProcessBuilder(args); + } else { + File oc = new File(location); + args.add(oc.getName()); + Arrays.stream(buildArgs(Arrays.asList(options)).split(" ")).forEach(s -> args.add(s)); + builder = new ProcessBuilder(args); + builder.directory(oc.getParentFile()); + } builder.environment().remove("KUBECONFIG"); LOG.debug("OpenShift binary args: {}", builder.command()); try { From dcb2df2398f6e4e0b56a95df73544c207e948f8b Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Mon, 22 May 2017 15:42:52 +0200 Subject: [PATCH 071/258] jbide-23862: fix pod logs --- .../AbstractOpenShiftBinaryCapability.java | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index aeddc2cb..79e45bd0 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -154,10 +154,22 @@ public final void start(final OpenShiftBinaryOption... options) { if(!validate()) { return; } - startProcess(location, options); + ProcessBuilder processBuilder = initProcessBuilder(location, options); + startProcess(processBuilder); } - private void startProcess(final String location, final OpenShiftBinaryOption... options) { + private void startProcess(ProcessBuilder builder) { + try { + process = builder.start(); + checkProcessIsAlive(); + } catch (IOException e) { + LOG.error("Could not start process for {}.", new Object[]{ getName(), e }); + throw new OpenShiftException(e, "Does your OpenShift binary location exist? Error starting process: %s", + e.getMessage()); + } + } + + private ProcessBuilder initProcessBuilder(String location, final OpenShiftBinaryOption... options) { List args = new ArrayList(); ProcessBuilder builder = null; // the condition is made in order to solve mac problem @@ -165,25 +177,18 @@ private void startProcess(final String location, final OpenShiftBinaryOption... // https://issues.jboss.org/browse/JBIDE-23862 - see the latest comments if (IS_MAC) { args.add(location); - Arrays.stream(buildArgs(Arrays.asList(options)).split(" ")).forEach(s -> args.add(s)); + Arrays.stream(StringUtils.split(buildArgs(Arrays.asList(options)))).forEach(s -> args.add(s)); builder = new ProcessBuilder(args); } else { File oc = new File(location); args.add(oc.getName()); - Arrays.stream(buildArgs(Arrays.asList(options)).split(" ")).forEach(s -> args.add(s)); + Arrays.stream(StringUtils.split(buildArgs(Arrays.asList(options)))).forEach(s -> args.add(s)); builder = new ProcessBuilder(args); builder.directory(oc.getParentFile()); } builder.environment().remove("KUBECONFIG"); LOG.debug("OpenShift binary args: {}", builder.command()); - try { - process = builder.start(); - checkProcessIsAlive(); - } catch (IOException e) { - LOG.error("Could not start process for {}.", new Object[]{ getName(), e }); - throw new OpenShiftException(e, "Does your OpenShift binary location exist? Error starting process: %s", - e.getMessage()); - } + return builder; } private void checkProcessIsAlive() throws IOException { From 57c961c3c18a6c5f9c36f41f9a448cfee40adc41 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 13 Jun 2017 19:51:36 -0400 Subject: [PATCH 072/258] support multiple certs for SSL connection --- .../openshift/restclient/ClientBuilder.java | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index a0ab34a4..a7072003 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -18,6 +18,7 @@ import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; +import java.util.Collection; import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLContext; @@ -48,6 +49,7 @@ public class ClientBuilder { private ISSLCertificateCallback sslCertificateCallback = new NoopSSLCertificateCallback(); private boolean sslCertCallbackWithDefaultHostnameVerifier = false; private X509Certificate certificate; + private Collection certificateCollection; private String certificateAlias; private IResourceFactory resourceFactory; private String userName; @@ -89,6 +91,12 @@ public ClientBuilder sslCertificate(String alias, X509Certificate cert) { return this; } + public ClientBuilder sslCertificateCollection(String alias, Collection certs) { + this.certificateAlias = alias; + this.certificateCollection = certs; + return this; + } + public ClientBuilder resourceFactory(IResourceFactory factory) { this.resourceFactory = factory; return this; @@ -176,7 +184,7 @@ public ClientBuilder withMaxRequestsPerHost(int maxRequestsPerHost) { */ public IClient build() { try { - TrustManagerFactory trustManagerFactory = initTrustManagerFactory(certificateAlias, certificate); + TrustManagerFactory trustManagerFactory = initTrustManagerFactory(certificateAlias, certificate, certificateCollection); X509TrustManager trustManager = getCurrentTrustManager(trustManagerFactory); SSLContext sslContext = SSLUtils.getSSLContext(trustManager); @@ -239,14 +247,26 @@ private X509TrustManager getCurrentTrustManager(TrustManagerFactory trustManager } - private TrustManagerFactory initTrustManagerFactory(String alias, X509Certificate cert) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { + private TrustManagerFactory initTrustManagerFactory(String alias, X509Certificate cert, Collection certs) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - if (alias != null && cert != null) { + if (alias != null && (cert != null || certs != null)) { KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); // need this load to initialize the key store, and allow for the subsequent set certificate entry ks.load(null, null); - cert.checkValidity(); - ks.setCertificateEntry(alias, cert); + if (cert != null) { + cert.checkValidity(); + ks.setCertificateEntry(alias, cert); + } + if (certs != null) { + int i = 0; + for (X509Certificate x509 : certs) { + x509.checkValidity(); + ks.setCertificateEntry(alias + i, x509); + i++; + } + } + + // testing has proven that you can only call init() once for a TrustManagerFactory wrt loading certs // from the KeyStore ... subsequent KeyStore.setCertificateEntry / TrustManagerFactory.init calls are // ignored. From 28bcd1b5d8572c26b5c2efa33593f886cc013750 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 21 Jun 2017 16:38:30 -0400 Subject: [PATCH 073/258] publish 5.7.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 461fb3b7..46639731 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.7.0-SNAPSHOT + 5.7.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From e24b9c9acbfaf71c05fc746c034682f8a7ba1540 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Wed, 21 Jun 2017 16:42:42 -0400 Subject: [PATCH 074/258] bump to 5.8.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 46639731..d1eb2db9 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.7.0.Final + 5.8.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 0f03da0549d61f62d6743e29b4541d7eb112fa06 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Fri, 7 Jul 2017 12:26:20 +0200 Subject: [PATCH 075/258] jbide-24539: User should be able to see what OpenShift version a connection is --- .../internal/restclient/DefaultClient.java | 54 +++++++++++++++++-- .../com/openshift/restclient/IClient.java | 12 +++++ .../restclient/DefaultClientTest.java | 2 +- .../restclient/TypeMapperFixture.java | 2 + .../openshift/restclient/utils/Samples.java | 3 ++ .../openshift3/api_kubernetes_version.json | 11 ++++ .../openshift3/api_openshift_version.json | 7 +++ 7 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 src/test/resources/samples/openshift3/api_kubernetes_version.json create mode 100644 src/test/resources/samples/openshift3/api_openshift_version.json diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 33947ed5..2208da7e 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -8,9 +8,8 @@ ******************************************************************************/ package com.openshift.internal.restclient; -import static java.util.stream.Collectors.joining; - import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeClientCapabilities; +import static java.util.stream.Collectors.joining; import java.io.IOException; import java.net.URL; @@ -21,9 +20,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; +import org.jboss.dmr.ModelNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -46,6 +47,8 @@ import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.JSONSerializeable; +import okhttp3.Call; +import okhttp3.Callback; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -81,8 +84,8 @@ public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory if(this.factory != null) { this.factory.setClient(this); } - openShiftVersion = System.getProperty(SYSTEM_PROP_OPENSHIFT_API_VERSION, null); - kubernetesVersion = System.getProperty(SYSTEM_PROP_K8E_API_VERSION, null); + initMasterVersion("version/openshift", new VersionCallback(version -> this.openShiftVersion = version)); + initMasterVersion("version", new VersionCallback(version -> this.kubernetesVersion = version)); this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client); this.authContext = authContext; } @@ -366,6 +369,49 @@ public String getOpenShiftAPIVersion() { return typeMapper.getPreferedVersionFor(OS_API_ENDPOINT); } + private void initMasterVersion(String versionInfoType, Callback callback) { + try { + Request request = new Request.Builder() + .url(new URL(this.baseUrl, versionInfoType)) + .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON) + .build(); + client.newCall(request).enqueue(callback); + } catch (IOException e) { + LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); + } + } + + private class VersionCallback implements Callback { + Consumer versionSetter; + public VersionCallback(Consumer versionSetter) { + this.versionSetter = versionSetter; + } + @Override + public void onFailure(Call call, IOException e) { + versionSetter.accept(""); + LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + try { + versionSetter.accept(ModelNode.fromJSONString(response.body().string()).get("gitVersion").asString()); + } finally { + response.close(); + } + } + } + + @Override + public String getOpenshiftMasterVersion() { + return this.openShiftVersion; + } + + @Override + public String getKubernetesMasterVersion() { + return this.kubernetesVersion; + } + @Override public URL getBaseURL() { return this.baseUrl; diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index 1d331903..66de4af3 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -272,6 +272,18 @@ default T adapt(Class klass) { * @throws OpenShiftException */ String getServerReadyStatus(); + + /** + * Query the server to determine the Openshift version + * @return + */ + String getOpenshiftMasterVersion(); + + /** + * Query the server to determine the Kubernetes version + * @return + */ + String getKubernetesMasterVersion(); IClient clone(); } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 0221bfe1..19212470 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -92,7 +92,7 @@ private void givenAPodList(){ private DefaultClient givenClient(URL baseUrl, String token, String user) { - DefaultClient client = new DefaultClient(baseUrl, null, null, null, new AuthorizationContext(token,user,null)); + DefaultClient client = new DefaultClient(baseUrl, getHttpClient(), null, null, new AuthorizationContext(token,user,null)); return client; } diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 078a03ba..567cf3a9 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -62,6 +62,8 @@ public void setUp() throws Exception { client.whenRequestTo(base + "/api/v1").thenReturn(responseOf(Samples.GROUP_ENDPONT_API_V1.getContentAsString())); client.whenRequestTo(base + "/oapi/v1").thenReturn(responseOf(Samples.GROUP_ENDPONT_OAPI_V1.getContentAsString())); client.whenRequestTo(base + "/apis/extensions/v1beta1").thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS_EXTENSIONS.getContentAsString())); + client.whenRequestTo(base + "/version").thenReturn(responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); + client.whenRequestTo(base + "/version/openshift").thenReturn(responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); mapper = new ApiTypeMapper(base, client); } diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 97461049..ba584543 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -19,6 +19,9 @@ * @author Jeff Cantrill */ public enum Samples { + + OPENSHIFT_VERSION("openshift3/api_openshift_version.json"), + KUBERNETES_VERSION("openshift3/api_kubernetes_version.json"), GROUP_ENDPONT_API_V1("openshift3/api_v1_endpoint.json"), GROUP_ENDPONT_OAPI_V1("openshift3/oapi_v1_endpoint.json"), diff --git a/src/test/resources/samples/openshift3/api_kubernetes_version.json b/src/test/resources/samples/openshift3/api_kubernetes_version.json new file mode 100644 index 00000000..dc24fde9 --- /dev/null +++ b/src/test/resources/samples/openshift3/api_kubernetes_version.json @@ -0,0 +1,11 @@ +{ + "major": "1", + "minor": "6", + "gitVersion": "v1.6.1+5115d708d7", + "gitCommit": "010d313", + "gitTreeState": "clean", + "buildDate": "2017-06-07T23:14:34Z", + "goVersion": "go1.7.5", + "compiler": "gc", + "platform": "linux/amd64" +} diff --git a/src/test/resources/samples/openshift3/api_openshift_version.json b/src/test/resources/samples/openshift3/api_openshift_version.json new file mode 100644 index 00000000..70ba3dfa --- /dev/null +++ b/src/test/resources/samples/openshift3/api_openshift_version.json @@ -0,0 +1,7 @@ +{ + "major": "3", + "minor": "6+", + "gitCommit": "3c221d5", + "gitVersion": "v3.6.0-alpha.2+3c221d5", + "buildDate": "2017-06-07T23:14:34Z" +} From 710499fdbd20f781b2d707312b13c1c36c060b65 Mon Sep 17 00:00:00 2001 From: Rob Stryker Date: Wed, 12 Jul 2017 12:58:41 -0400 Subject: [PATCH 076/258] JBIDE-24664 - on linux, client jar always uses oc on system path --- .../capability/resources/AbstractOpenShiftBinaryCapability.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 79e45bd0..43ad20dd 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -181,7 +181,7 @@ private ProcessBuilder initProcessBuilder(String location, final OpenShiftBinary builder = new ProcessBuilder(args); } else { File oc = new File(location); - args.add(oc.getName()); + args.add(location); Arrays.stream(StringUtils.split(buildArgs(Arrays.asList(options)))).forEach(s -> args.add(s)); builder = new ProcessBuilder(args); builder.directory(oc.getParentFile()); From 4b77261517013b1ff9e118c3f12d646a8ed4cc05 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 21 Jul 2017 11:38:34 +0200 Subject: [PATCH 077/258] [JBIDE-24745] release 5.8.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d1eb2db9..a8285320 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.8.0-SNAPSHOT + 5.8.0.FINAL jar OpenShift Java REST Client http://openshift.redhat.com From 91d29a5c3eed4643beadddcfd64d5a0534f03d5d Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 20 Jul 2017 13:13:04 -0400 Subject: [PATCH 078/258] add restclient prefix to normal okhttp setting of user-agent --- .../openshift/restclient/ClientBuilder.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index a7072003..0ce62c4f 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -26,6 +26,8 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; +import org.apache.commons.lang.StringUtils; + import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.ResourceFactory; import com.openshift.internal.restclient.authorization.AuthorizationContext; @@ -36,7 +38,11 @@ import okhttp3.Authenticator; import okhttp3.Dispatcher; +import okhttp3.Interceptor; import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.internal.Version; /** * Builder to create IClient instances. @@ -55,6 +61,7 @@ public class ClientBuilder { private String userName; private String token; private String password; + private String userAgentPrefix; private Authenticator proxyAuthenticator; private int maxRequests = 64; @@ -121,6 +128,11 @@ public ClientBuilder usingToken(String token) { this.token = token; return this; } + + public ClientBuilder usingUserAgentPrefix(String prefix) { + this.userAgentPrefix = prefix; + return this; + } public ClientBuilder withConnectTimeout(int timeout, TimeUnit unit) { this.connectTimeout = timeout; @@ -196,9 +208,18 @@ public IClient build() { //if we need to really expose them. dispatcher.setMaxRequests(maxRequests); dispatcher.setMaxRequestsPerHost(maxRequestsPerHost); + String[] pieces = {this.userAgentPrefix, "openshift-restclient-java", Version.userAgent()}; + String userAgent = StringUtils.join(pieces, "/"); OkHttpClient.Builder builder = new OkHttpClient.Builder() .addInterceptor(responseCodeInterceptor) + .addNetworkInterceptor(new Interceptor() { + @Override + public Response intercept(Chain chain) throws IOException { + Request agent = chain.request().newBuilder().header("User-Agent", userAgent).build(); + return chain.proceed(agent); + } + }) .authenticator(authenticator) .dispatcher(dispatcher) .readTimeout(readTimeout, readTimeoutUnit) From 42e959c41bf27a38f87431adfe158c5e184ac34a Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 27 Jul 2017 13:21:31 -0400 Subject: [PATCH 079/258] pod exec needs stdOut/stdErr set for 3.7 servers --- pom.xml | 2 +- .../internal/restclient/api/capabilities/PodExec.java | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a8285320..5113c396 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.8.0.FINAL + 5.9.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java index b936ff18..0adde14b 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java @@ -71,6 +71,13 @@ public IStoppable start( IPodExecOutputListener listener, Options options, Strin if ( options == null ) { options = new Options(); } + + /* + with 3.7 per https://github.com/openshift/origin/issues/15330, 3.6 was evidently broke in allowing stdErr/stdOut to not be set; need to set stdout/stderr to true + */ + options.stdErr(true); + options.stdOut(true); + Map parameters = options.getMap(); From bddec7bf04e69e51a311d150f9df527878d03d6a Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 31 Jul 2017 11:50:25 +0200 Subject: [PATCH 080/258] [JBIDE-24745] bump to 5.9.0.Final bump to 5.8.0.Final was done with an erroneous identifier "5.8.0.FINAL". Since there was a commit to master bumping it to 5.9.0-SNAPSHOT, we now have to re-release a final version, 5.9.0.Final this time --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5113c396..31b7b99a 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.0-SNAPSHOT + 5.9.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From 1b29d03c88c8b13133ad5814a11f84b87a46ef2e Mon Sep 17 00:00:00 2001 From: gabemontero Date: Tue, 15 Aug 2017 16:05:00 -0400 Subject: [PATCH 081/258] bump okhttp --- pom.xml | 4 ++-- .../com/openshift/internal/restclient/TypeMapperFixture.java | 1 + .../openshift/internal/restclient/okhttp/WatchClientTest.java | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 31b7b99a..e9a18af3 100755 --- a/pom.xml +++ b/pom.xml @@ -131,12 +131,12 @@ com.squareup.okhttp3 okhttp - 3.3.1 + 3.8.1 com.squareup.okhttp3 okhttp-ws - 3.3.1 + 3.4.2 org.yaml diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 567cf3a9..70d6cf67 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -86,6 +86,7 @@ protected static Response responseOf(String response) { .request(new Request.Builder().url("https://someurlfortesting").build()) .protocol(Protocol.HTTP_1_1) .code(IHttpConstants.STATUS_OK) + .message("foo") .body(ResponseBody.create(null, response)) .build(); } diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java index eed1f6cf..da494f22 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java @@ -59,6 +59,7 @@ public void shouldIgnoreUnsupportedFeatureResponseOnFailure() { Response.Builder responseBuilder = new Response.Builder(); responseBuilder.code(IHttpConstants.STATUS_OK) .protocol(Protocol.HTTP_2) + .message("foo") .request(new Request.Builder().url("http://localhost").build()); endpoint.onFailure(new ProtocolException(), responseBuilder.build()); verify(listener, never()).error(any()); From ebfc848d4fa82e9495e6554ab4c1602ce3c965d4 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 12 Sep 2017 11:31:16 +0200 Subject: [PATCH 082/258] bump to 5.9.1-SNAPSHOT Late bumping current master to 5.9.1-SNAPSHOT. This is a late bump since a first change was already done without bumping. The erroneous final artifact wasn't released to maven repository though so this duplication is limited to git. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9a18af3..187b8c28 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.0.Final + 5.9.1-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 5e2f4fcdd0a8e03a20ae425f1f7f97bf36d85fd1 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 29 Jun 2017 11:52:41 +0200 Subject: [PATCH 083/258] [OSJC-281] - Provide support for CPU and memory settings Signed-off-by: Jeff MAURY --- .../internal/restclient/model/Container.java | 65 ++++++++++++++++++- .../restclient/model/IContainer.java | 11 ++++ .../internal/restclient/model/v1/PodTest.java | 26 +++++++- .../resources/samples/openshift3/v1_pod.json | 11 +++- 4 files changed, 110 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Container.java b/src/main/java/com/openshift/internal/restclient/model/Container.java index 1f171526..9d529ddb 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Container.java +++ b/src/main/java/com/openshift/internal/restclient/model/Container.java @@ -20,6 +20,7 @@ import java.util.Map.Entry; import java.util.Set; +import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; @@ -42,6 +43,10 @@ public class Container extends ModelNodeAdapter implements IContainer, ResourceP private static final String COMMANDARGS = "args"; private static final String LIFECYCLE = "lifecycle"; private static final String VOLUMEMOUNTS = "volumeMounts"; + private static final String PROPERTY_REQUESTS_MEMORY = "resources.requests.memory"; + private static final String PROPERTY_REQUESTS_CPU = "resources.requests.cpu"; + private static final String PROPERTY_LIMITS_MEMORY = "resources.limits.memory"; + private static final String PROPERTY_LIMITS_CPU = "resources.limits.cpu"; private ModelNode node; private Map propertyKeys; @@ -232,9 +237,67 @@ public IVolumeMount addVolumeMount(String name) { return volume; } + @Override + public String getRequestsMemory() { + return asString(node, propertyKeys, PROPERTY_REQUESTS_MEMORY); + } + + @Override + public void setRequestsMemory(String requestsMemory) { + ModelNode child = get(getNode(), propertyKeys, PROPERTY_REQUESTS_MEMORY); + if (StringUtils.isBlank(requestsMemory)) { + child.clear(); + } else { + child.set(requestsMemory); + } + } + + @Override + public String getRequestsCPU() { + return asString(node, propertyKeys, PROPERTY_REQUESTS_CPU); + } + + @Override + public void setRequestsCPU(String requestsCPU) { + ModelNode child = get(getNode(), propertyKeys, PROPERTY_REQUESTS_CPU); + if (StringUtils.isBlank(requestsCPU)) { + child.clear(); + } else { + child.set(requestsCPU); + } + } + + @Override + public String getLimitsMemory() { + return asString(node, propertyKeys, PROPERTY_LIMITS_MEMORY); + } + + @Override + public void setLimitsMemory(String limitsMemory) { + ModelNode child = get(getNode(), propertyKeys, PROPERTY_LIMITS_MEMORY); + if (StringUtils.isBlank(limitsMemory)) { + child.clear(); + } else { + child.set(limitsMemory); + } + } + + @Override + public String getLimitsCPU() { + return asString(node, propertyKeys, PROPERTY_LIMITS_CPU); + } + + @Override + public void setLimitsCPU(String limitsCPU) { + ModelNode child = get(getNode(), propertyKeys, PROPERTY_LIMITS_CPU); + if (StringUtils.isBlank(limitsCPU)) { + child.clear(); + } else { + child.set(limitsCPU); + } + } @Override public String toJSONString() { return super.toJson(false); } - } diff --git a/src/main/java/com/openshift/restclient/model/IContainer.java b/src/main/java/com/openshift/restclient/model/IContainer.java index a9b9f194..e13aa538 100644 --- a/src/main/java/com/openshift/restclient/model/IContainer.java +++ b/src/main/java/com/openshift/restclient/model/IContainer.java @@ -78,6 +78,17 @@ public interface IContainer extends INameSetable{ */ IVolumeMount addVolumeMount(String name); + String getRequestsCPU(); + void setRequestsCPU(String requestsCPU); + String getRequestsMemory(); + void setRequestsMemory(String requestsMemory); + + String getLimitsCPU(); + void setLimitsCPU(String limitsCPU); + + String getLimitsMemory(); + void setLimitsMemory(String limitsMemory); + String toJSONString(); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index 4323b6e6..e181e9ac 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -10,6 +10,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -173,5 +174,28 @@ public void getContainerCommands() { assertEquals(cmdArgs.get(0), "-c"); assertEquals(cmdArgs.get(1), "echo 'hello'"); } - + + @Test + public void getContainerResourceRequirements() { + Collection containers = pod.getContainers(); + IContainer container = containers.iterator().next(); + assertEquals("1", container.getRequestsCPU()); + assertEquals("128Mi", container.getRequestsMemory()); + assertEquals("4", container.getLimitsCPU()); + assertEquals("1Gi", container.getLimitsMemory()); + } + + @Test + public void resetContainerResourceRequirements() { + Collection containers = pod.getContainers(); + IContainer container = containers.iterator().next(); + container.setRequestsMemory(null); + container.setRequestsCPU(null); + container.setLimitsMemory(null); + container.setLimitsCPU(null); + assertEquals("", container.getRequestsCPU()); + assertEquals("", container.getRequestsMemory()); + assertEquals("", container.getLimitsCPU()); + assertEquals("", container.getLimitsMemory()); + } } diff --git a/src/test/resources/samples/openshift3/v1_pod.json b/src/test/resources/samples/openshift3/v1_pod.json index 6c7a1e5a..f1e9f32e 100644 --- a/src/test/resources/samples/openshift3/v1_pod.json +++ b/src/test/resources/samples/openshift3/v1_pod.json @@ -62,7 +62,16 @@ "value": "test" } ], - "resources": {}, + "resources": { + "requests": { + "cpu": "1", + "memory": "128Mi" + }, + "limits": { + "cpu": "4", + "memory": "1Gi" + } + }, "volumeMounts": [ { "name": "deployer-token-22jov", From 8080a86ffbf517880730b16818c724f9ee4bdf35 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 12 Sep 2017 21:48:18 +0200 Subject: [PATCH 084/258] release 5.9.1.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 187b8c28..a269bd42 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.1-SNAPSHOT + 5.9.1.Final jar OpenShift Java REST Client http://openshift.redhat.com From 665fd74669fb4e03f8d7b479c3ff918ac54f07dd Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 12 Sep 2017 22:22:06 +0200 Subject: [PATCH 085/258] bumped to 5.9.2-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a269bd42..87257239 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.1.Final + 5.9.2-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 4fed111ba898a14fc75690e27e19849e80b4805b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 13 Sep 2017 15:34:14 +0200 Subject: [PATCH 086/258] bumping to 5.9.2.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 87257239..5f5eab68 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.2-SNAPSHOT + 5.9.2.Final jar OpenShift Java REST Client http://openshift.redhat.com From 40adef198c65efba5708fb61d7134fe9c45e02c3 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 13 Sep 2017 15:58:38 +0200 Subject: [PATCH 087/258] bump to 5.9.3-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5f5eab68..198bd43f 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.2.Final + 5.9.3-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From df4a29710fdcc6c17f780f44e120304f715975bf Mon Sep 17 00:00:00 2001 From: gabemontero Date: Wed, 27 Sep 2017 16:28:02 -0400 Subject: [PATCH 088/258] revert PR 284 --- pom.xml | 4 ++-- .../com/openshift/internal/restclient/TypeMapperFixture.java | 1 - .../openshift/internal/restclient/okhttp/WatchClientTest.java | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 198bd43f..ed48e3b3 100755 --- a/pom.xml +++ b/pom.xml @@ -131,12 +131,12 @@ com.squareup.okhttp3 okhttp - 3.8.1 + 3.3.1 com.squareup.okhttp3 okhttp-ws - 3.4.2 + 3.3.1 org.yaml diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 70d6cf67..567cf3a9 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -86,7 +86,6 @@ protected static Response responseOf(String response) { .request(new Request.Builder().url("https://someurlfortesting").build()) .protocol(Protocol.HTTP_1_1) .code(IHttpConstants.STATUS_OK) - .message("foo") .body(ResponseBody.create(null, response)) .build(); } diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java index da494f22..eed1f6cf 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java @@ -59,7 +59,6 @@ public void shouldIgnoreUnsupportedFeatureResponseOnFailure() { Response.Builder responseBuilder = new Response.Builder(); responseBuilder.code(IHttpConstants.STATUS_OK) .protocol(Protocol.HTTP_2) - .message("foo") .request(new Request.Builder().url("http://localhost").build()); endpoint.onFailure(new ProtocolException(), responseBuilder.build()); verify(listener, never()).error(any()); From 47555192ff002a20fd1b2481cf023954126969b8 Mon Sep 17 00:00:00 2001 From: Aleksi Gold Date: Tue, 24 Oct 2017 13:15:26 +0300 Subject: [PATCH 089/258] Add Insecure Edge Termination Policy to TLSConfig --- .../internal/restclient/model/Route.java | 10 ++++++++++ .../restclient/model/route/ITLSConfig.java | 15 +++++++++++++++ .../internal/restclient/model/RouteTest.java | 10 ++++++++++ 3 files changed, 35 insertions(+) diff --git a/src/main/java/com/openshift/internal/restclient/model/Route.java b/src/main/java/com/openshift/internal/restclient/model/Route.java index 7e8b53af..642db566 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Route.java +++ b/src/main/java/com/openshift/internal/restclient/model/Route.java @@ -33,6 +33,7 @@ public class Route extends KubernetesResource implements IRoute { private static final String ROUTE_TLS_KEY = "spec.tls.key"; private static final String ROUTE_TLS_CACERT = "spec.tls.caCertificate"; private static final String ROUTE_TLS_DESTINATION_CACERT = "spec.tls.destinationCACertificate"; + private static final String ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY = "spec.tls.insecureEdgeTerminationPolicy"; private static final String ROUTE_PORT = "spec.port"; private static final String ROUTE_PORT_TARGETPORT = "spec.port.targetPort"; @@ -172,6 +173,15 @@ public void setDestinationCertificate(String destinationCertificate) { get(ROUTE_TLS_DESTINATION_CACERT).set(destinationCertificate); } + @Override + public String getInsecureEdgeTerminationPolicy() { + return asString(ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY); + } + + @Override + public void setInsecureEdgeTerminationPolicy(String insecureEdgeTerminationPolicy) { + get(ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY).set(insecureEdgeTerminationPolicy); + } } private class TargetPort implements ITargetPort { diff --git a/src/main/java/com/openshift/restclient/model/route/ITLSConfig.java b/src/main/java/com/openshift/restclient/model/route/ITLSConfig.java index a9312bd1..5e54e144 100644 --- a/src/main/java/com/openshift/restclient/model/route/ITLSConfig.java +++ b/src/main/java/com/openshift/restclient/model/route/ITLSConfig.java @@ -98,4 +98,19 @@ public interface ITLSConfig { * contents of CA certificate of the final destination */ void setDestinationCertificate(String destinationCertificate); + + /** + * Retrieves InsecureEdgeTerminationPolicy + * + * @return InsecureEdgeTerminationPolicy + */ + String getInsecureEdgeTerminationPolicy(); + + /** + * Sets insecureEdgeTerminationPolicy + * + * @param insecureEdgeTerminationPolicy + * insecureEdgeTerminationPolicy + */ + void setInsecureEdgeTerminationPolicy(String insecureEdgeTerminationPolicy); } diff --git a/src/test/java/com/openshift/internal/restclient/model/RouteTest.java b/src/test/java/com/openshift/internal/restclient/model/RouteTest.java index e68ec452..9104fdbd 100644 --- a/src/test/java/com/openshift/internal/restclient/model/RouteTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/RouteTest.java @@ -53,4 +53,14 @@ public void getURLShouldBeInSecureWhenTLSConfigDoesExists() { assertEquals("http://www.host.com/abc", route.getURL()); } + @Test + public void getAndSetInsecureEdgeTerminationPolicy() { + ModelNode modelNode = new ModelNode(); + Route edgeTLSRoute = spy(new Route(modelNode, null, null)); + edgeTLSRoute.createTLSConfig().setTerminationType("edge"); + + edgeTLSRoute.getTLSConfig().setInsecureEdgeTerminationPolicy("Allow"); + assertEquals("Allow", edgeTLSRoute.getTLSConfig().getInsecureEdgeTerminationPolicy()); + } + } From f43a0d06f798d05d33b0214a7434c48043e694d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Pupier?= Date: Fri, 3 Nov 2017 14:46:16 +0100 Subject: [PATCH 090/258] Fix typos in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d0e28bb6..590ced05 100755 --- a/README.md +++ b/README.md @@ -4,14 +4,14 @@ OpenShift Java REST Client [![Travis](https://travis-ci.org/openshift/openshift-restclient-java.svg?branch=master)](https://travis-ci.org/openshift/openshift-restclient-java) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.openshift/openshift-restclient-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.openshift/openshift-restclient-java) This is the Java REST client for the version 3 architecture of [OpenShift](https://github.com/openshift/origin) based on Kubernetes. The implementation is -a work in progress to provide similiar functionality and features of the command-line interface and is used by JBoss Tools for OpenShift. For compatibility with +a work in progress to provide similar functionality and features of the command-line interface and is used by JBoss Tools for OpenShift. For compatibility with OpenShift 2.x see https://github.com/openshift/openshift-java-client/. For questions or feedback, reach us on IRC on #openshift-client on Freenode or post to our [mailing list](https://lists.openshift.redhat.com/openshiftmm/listinfo/dev) Download -------- -You may either build from source using maven (mvn clean package) which, using the master branch, will generate a snapshot build of the lastest updates. You may also retrieve final released jars from [Maven Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.openshift%22%20AND%20a%3A%22openshift-restclient-java%22). +You may either build from source using maven (mvn clean package) which, using the master branch, will generate a snapshot build of the latest updates. You may also retrieve final released jars from [Maven Central](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.openshift%22%20AND%20a%3A%22openshift-restclient-java%22). Compatibility --------- From 62d93ca9bf79b4c8e0550e4ab5c2f33110dde1a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Pupier?= Date: Fri, 3 Nov 2017 14:49:27 +0100 Subject: [PATCH 091/258] Remove unused import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Aurélien Pupier --- .../capability/resources/AssociationCapability.java | 1 - .../restclient/capability/resources/DeployCapability.java | 1 - .../capability/resources/ImageStreamImportCapability.java | 2 -- .../openshift/internal/restclient/model/ConfigMap.java | 2 -- .../openshift/internal/restclient/model/Lifecycle.java | 1 - .../java/com/openshift/internal/restclient/model/Pod.java | 1 - .../internal/restclient/model/ReplicationController.java | 1 - .../model/volume/PersistentVolumeClaimVolumeSource.java | 1 - .../internal/restclient/APIModelVersionTest.java | 1 - .../openshift/internal/restclient/DefaultClientTest.java | 8 -------- .../resources/ImageStreamImportCapabilityTest.java | 1 - .../internal/restclient/model/build/BuildRequestTest.java | 8 -------- .../restclient/model/v1/EmptyDirVolumeSourceTest.java | 1 - .../internal/restclient/model/v1/ImageStreamTest.java | 2 -- .../openshift/internal/restclient/model/v1/PodTest.java | 1 - 15 files changed, 32 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java index 90d6c8b2..0a394695 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java @@ -9,7 +9,6 @@ package com.openshift.internal.restclient.capability.resources; import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IResource; /** diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java index 068d53c6..c0261387 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java @@ -18,7 +18,6 @@ import org.slf4j.LoggerFactory; import com.openshift.restclient.IClient; -import com.openshift.restclient.NotFoundException; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.resources.IDeployCapability; diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java index c16a963a..bcd07f67 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java @@ -14,13 +14,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.openshift.internal.restclient.model.Status; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.UnsupportedEndpointException; import com.openshift.restclient.authorization.ResourceForbiddenException; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; -import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IStatus; diff --git a/src/main/java/com/openshift/internal/restclient/model/ConfigMap.java b/src/main/java/com/openshift/internal/restclient/model/ConfigMap.java index ba2be9f3..a0e2aee0 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ConfigMap.java +++ b/src/main/java/com/openshift/internal/restclient/model/ConfigMap.java @@ -6,8 +6,6 @@ import java.util.Map; -import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; - /** * @author Ulf Lilleengen */ diff --git a/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java b/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java index dbb0edab..5bd0ed00 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java +++ b/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java @@ -10,7 +10,6 @@ ******************************************************************************/ package com.openshift.internal.restclient.model; -import com.openshift.restclient.UnsupportedOperationException; import com.openshift.restclient.model.IHandler; import com.openshift.restclient.model.ILifecycle; import org.jboss.dmr.ModelNode; diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index ef32b932..109b8c89 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -13,7 +13,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; diff --git a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java index 7c449319..126b27b9 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java +++ b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java @@ -23,7 +23,6 @@ import com.openshift.internal.restclient.model.volume.EmptyDirVolumeSource; import com.openshift.restclient.model.volume.IEmptyDirVolumeSource; -import com.openshift.restclient.model.volume.IVolume; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaimVolumeSource.java b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaimVolumeSource.java index 865e9ce7..f939093d 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaimVolumeSource.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaimVolumeSource.java @@ -11,7 +11,6 @@ package com.openshift.internal.restclient.model.volume; import com.openshift.restclient.model.volume.IPersistentVolumeClaimVolumeSource; -import com.openshift.restclient.model.volume.IVolumeSource; import com.openshift.restclient.model.volume.VolumeType; import org.jboss.dmr.ModelNode; diff --git a/src/test/java/com/openshift/internal/restclient/APIModelVersionTest.java b/src/test/java/com/openshift/internal/restclient/APIModelVersionTest.java index 9f044a15..fac44c86 100644 --- a/src/test/java/com/openshift/internal/restclient/APIModelVersionTest.java +++ b/src/test/java/com/openshift/internal/restclient/APIModelVersionTest.java @@ -12,7 +12,6 @@ import static org.junit.Assert.*; -import org.junit.Before; import org.junit.Test; import com.openshift.internal.restclient.APIModelVersion.VersionComparitor; diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 19212470..f9124fea 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -11,16 +11,9 @@ package com.openshift.internal.restclient; import static org.fest.assertions.Assertions.assertThat; -import static org.junit.Assert.assertEquals; - import java.net.URL; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.jboss.dmr.ModelNode; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; @@ -29,7 +22,6 @@ import com.openshift.internal.restclient.model.Pod; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.model.IPod; /** * @author Jeff Cantrill diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java index ba8b5fff..e2b2504d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java @@ -24,7 +24,6 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.capability.resources.IImageStreamImportCapability; -import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IStatus; diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java index c18f39dc..118b1b62 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java @@ -8,21 +8,13 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.build; -import com.openshift.internal.restclient.model.BuildConfig; import com.openshift.restclient.IClient; -import com.openshift.restclient.images.DockerImageURI; -import com.openshift.restclient.model.build.BuildStrategyType; -import com.openshift.restclient.model.build.IBuildStrategy; -import com.openshift.restclient.model.build.ICustomBuildStrategy; -import com.openshift.restclient.model.build.IDockerBuildStrategy; import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; -import static com.openshift.internal.util.JBossDmrExtentions.getPath; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; public class BuildRequestTest { diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java index 7e0685a0..ea6b1695 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java @@ -11,7 +11,6 @@ package com.openshift.internal.restclient.model.v1; import com.openshift.internal.restclient.model.volume.EmptyDirVolumeSource; -import com.openshift.internal.restclient.model.volume.PersistentVolumeClaimVolumeSource; import com.openshift.restclient.model.volume.IEmptyDirVolumeSource; import com.openshift.restclient.utils.Samples; import org.jboss.dmr.ModelNode; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamTest.java index a397df59..91ad6354 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamTest.java @@ -12,7 +12,6 @@ import static org.mockito.Mockito.mock; import java.util.Collection; -import java.util.HashMap; import java.util.Optional; import java.util.stream.Collectors; @@ -22,7 +21,6 @@ import com.openshift.internal.restclient.model.ImageStream; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; -import com.openshift.internal.util.JBossDmrExtentions; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.images.DockerImageURI; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index e181e9ac..36398ea6 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -10,7 +10,6 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; From 449f92a35c29d05f1ba1e69f2e9e6c349b270642 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Pupier?= Date: Fri, 3 Nov 2017 14:52:43 +0100 Subject: [PATCH 092/258] Remove unnecessary @SuppressWarning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Aurélien Pupier --- .../java/com/openshift/internal/restclient/DefaultClient.java | 1 - .../internal/restclient/model/v1/EnvironmentVariableTest.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 2208da7e..9279b638 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -137,7 +137,6 @@ public List list(String kind, String namespace) { return list(kind, namespace, new HashMap<>()); } - @SuppressWarnings("unchecked") @Override public List list(String kind, String namespace, Map labels) { diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java index ef5485a5..36dfbe15 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java @@ -48,7 +48,6 @@ public void shouldBeNonEqualGivenNonEqualNameAndValue() { assertThat(var1).isNotEqualTo(var2); } - @SuppressWarnings("serial") @Test public void shouldReturnEmptyMapGivenEmptyEnvVars() { // given From 47f831fc502351e2c643820131cc2dbf7b3daeef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Pupier?= Date: Fri, 3 Nov 2017 14:54:16 +0100 Subject: [PATCH 093/258] Fix wrong number of argument for String.format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Aurélien Pupier --- .../java/com/openshift/internal/restclient/ApiTypeMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index 42ab9c87..a441dbf4 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -350,7 +350,7 @@ public String toString() { if(apiGroupName == null) { return String.format("%s/%s/%s", prefix, version, name); } - return String.format("%s/%s/%s/%s/%s", prefix, apiGroupName, version, name); + return String.format("%s/%s/%s/%s", prefix, apiGroupName, version, name); } @Override From 8c43df4a285f0091d821e2879ec0bf8ab17f1ecd Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 9 Nov 2017 13:54:32 +0100 Subject: [PATCH 094/258] impl'd rudimentary support for readiness- and lifeness-probes --- .../internal/restclient/model/Container.java | 24 +++- .../model/ReplicationController.java | 2 +- .../restclient/model/probe/Probe.java | 88 ++++++++++++++ .../restclient/model/IContainer.java | 4 + .../model/IReplicationController.java | 2 + .../restclient/model/probe/IProbe.java | 32 +++++ .../internal/restclient/model/v1/PodTest.java | 111 ++++++++++++++---- .../resources/samples/openshift3/v1_pod.json | 24 ++++ 8 files changed, 263 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/model/probe/Probe.java create mode 100644 src/main/java/com/openshift/restclient/model/probe/IProbe.java diff --git a/src/main/java/com/openshift/internal/restclient/model/Container.java b/src/main/java/com/openshift/internal/restclient/model/Container.java index 9d529ddb..05339331 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Container.java +++ b/src/main/java/com/openshift/internal/restclient/model/Container.java @@ -10,7 +10,10 @@ ******************************************************************************/ package com.openshift.internal.restclient.model; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asList; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.get; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.Collections; import java.util.HashMap; @@ -24,6 +27,7 @@ import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; +import com.openshift.internal.restclient.model.probe.Probe; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.internal.restclient.model.volume.EmptyDirVolume; import com.openshift.internal.restclient.model.volume.VolumeMount; @@ -31,6 +35,7 @@ import com.openshift.restclient.model.IContainer; import com.openshift.restclient.model.ILifecycle; import com.openshift.restclient.model.IPort; +import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.model.volume.IVolume; import com.openshift.restclient.model.volume.IVolumeMount; @@ -47,7 +52,9 @@ public class Container extends ModelNodeAdapter implements IContainer, ResourceP private static final String PROPERTY_REQUESTS_CPU = "resources.requests.cpu"; private static final String PROPERTY_LIMITS_MEMORY = "resources.limits.memory"; private static final String PROPERTY_LIMITS_CPU = "resources.limits.cpu"; - + private static final String LIVENESSPROBE = "livenessProbe"; + private static final String READINESSPROBE = "readinessProbe"; + private ModelNode node; private Map propertyKeys; @@ -296,6 +303,19 @@ public void setLimitsCPU(String limitsCPU) { child.set(limitsCPU); } } + + @Override + public IProbe getReadinessProbe() { + ModelNode readynessProbeNode = get(getNode(), propertyKeys, READINESSPROBE); + return new Probe(readynessProbeNode); + } + + @Override + public IProbe getLivenessProbe() { + ModelNode lifenessProbeNode = get(getNode(), propertyKeys, LIVENESSPROBE); + return new Probe(lifenessProbeNode); + } + @Override public String toJSONString() { return super.toJson(false); diff --git a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java index 126b27b9..8b2bccb3 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java +++ b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java @@ -51,7 +51,7 @@ public class ReplicationController extends KubernetesResource implements IReplic protected static final String SPEC_SELECTOR = "spec.selector"; protected static final String STATUS_REPLICA = "status.replicas"; protected static final String SERVICEACCOUNTNAME = "spec.template.spec.serviceAccountName"; - + protected static final String IMAGE = "image"; protected static final String ENV = "env"; private Map propertyKeys; diff --git a/src/main/java/com/openshift/internal/restclient/model/probe/Probe.java b/src/main/java/com/openshift/internal/restclient/model/probe/Probe.java new file mode 100644 index 00000000..84c37966 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/probe/Probe.java @@ -0,0 +1,88 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.probe; + +import static com.openshift.internal.util.JBossDmrExtentions.asInt; +import static com.openshift.internal.util.JBossDmrExtentions.set; + +import java.util.HashMap; + +import org.jboss.dmr.ModelNode; + +import com.openshift.internal.restclient.model.ModelNodeAdapter; +import com.openshift.restclient.model.probe.IProbe; + +/** + * @author Andre Dietisheim + */ +public class Probe extends ModelNodeAdapter implements IProbe { + + private static final String INITIAL_DELAY_SECONDS = "initialDelaySeconds"; + private static final String TIMEOUT_SECONDS = "timeoutSeconds"; + private static final String PERIOD_SECONDS = "periodSeconds"; + private static final String SUCCESS_THRESHOLD = "successThreshold"; + private static final String FAILURE_THRESHOLD = "failureThreshold"; + + public Probe(ModelNode node) { + super(node, new HashMap()); + } + + @Override + public void setInitialDelaySeconds(int delay) { + set(getNode(), getPropertyKeys(), INITIAL_DELAY_SECONDS, delay); + } + + @Override + public int getInitialDelaySeconds() { + return asInt(getNode(), getPropertyKeys(), INITIAL_DELAY_SECONDS); + } + + @Override + public void setPeriodSeconds(int period) { + set(getNode(), getPropertyKeys(), PERIOD_SECONDS, period); + } + + @Override + public int getPeriodSeconds() { + return asInt(getNode(), getPropertyKeys(), PERIOD_SECONDS); + } + + @Override + public void setSuccessThreshold(int threshold) { + set(getNode(), getPropertyKeys(), SUCCESS_THRESHOLD, threshold); + } + + @Override + public int getSuccessThreshold() { + return asInt(getNode(), getPropertyKeys(), SUCCESS_THRESHOLD); + } + + @Override + public void setFailureThreshold(int failureThreshold) { + set(getNode(), getPropertyKeys(), FAILURE_THRESHOLD, failureThreshold); + } + + @Override + public int getFailureThreshold() { + return asInt(getNode(), getPropertyKeys(), FAILURE_THRESHOLD); + } + + + @Override + public void setTimeoutSeconds(int timeout) { + set(getNode(), getPropertyKeys(), TIMEOUT_SECONDS, timeout); + } + + @Override + public int getTimeoutSeconds() { + return asInt(getNode(), getPropertyKeys(), TIMEOUT_SECONDS); + } +} diff --git a/src/main/java/com/openshift/restclient/model/IContainer.java b/src/main/java/com/openshift/restclient/model/IContainer.java index e13aa538..81790d31 100644 --- a/src/main/java/com/openshift/restclient/model/IContainer.java +++ b/src/main/java/com/openshift/restclient/model/IContainer.java @@ -16,6 +16,7 @@ import com.openshift.restclient.api.models.INameSetable; import com.openshift.restclient.images.DockerImageURI; +import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.model.volume.IVolume; import com.openshift.restclient.model.volume.IVolumeMount; @@ -90,5 +91,8 @@ public interface IContainer extends INameSetable{ String getLimitsMemory(); void setLimitsMemory(String limitsMemory); + IProbe getReadinessProbe(); + IProbe getLivenessProbe(); + String toJSONString(); } diff --git a/src/main/java/com/openshift/restclient/model/IReplicationController.java b/src/main/java/com/openshift/restclient/model/IReplicationController.java index ecc93a9c..d41f027a 100644 --- a/src/main/java/com/openshift/restclient/model/IReplicationController.java +++ b/src/main/java/com/openshift/restclient/model/IReplicationController.java @@ -14,6 +14,7 @@ import java.util.Set; import com.openshift.restclient.images.DockerImageURI; +import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.model.volume.IVolumeSource; /** @@ -218,4 +219,5 @@ public interface IReplicationController extends IResource{ * @return */ String getServiceAccountName(); + } diff --git a/src/main/java/com/openshift/restclient/model/probe/IProbe.java b/src/main/java/com/openshift/restclient/model/probe/IProbe.java new file mode 100644 index 00000000..8e9633f1 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/probe/IProbe.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.restclient.model.probe; + +/** + * @author Andre Dietisheim + */ +public interface IProbe { + + void setInitialDelaySeconds(int delay); + int getInitialDelaySeconds(); + + void setPeriodSeconds(int period); + int getPeriodSeconds(); + + void setSuccessThreshold(int threshold); + int getSuccessThreshold(); + + void setFailureThreshold(int failureThreshold); + int getFailureThreshold(); + + void setTimeoutSeconds(int timeout); + int getTimeoutSeconds(); +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index 36398ea6..3716d905 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -8,6 +8,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.v1; +import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -34,6 +35,7 @@ import com.openshift.restclient.model.IExecAction; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IPort; +import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.utils.Samples; /** @@ -43,12 +45,14 @@ public class PodTest { private static final String VERSION = "v1"; private IPod pod; + private IContainer container1; @Before public void setup() { IClient client = mock(IClient.class); ModelNode node = ModelNode.fromJSONString(Samples.V1_POD.getContentAsString()); - pod = new Pod(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.POD)); + this.pod = new Pod(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.POD)); + this.container1 = pod.getContainers().stream().findFirst().orElse(null); } @Test @@ -165,10 +169,8 @@ public void testAddContainer() { @Test public void getContainerCommands() { - Collection containers = pod.getContainers(); - IContainer container = containers.iterator().next(); - List cmd = container.getCommand(); - List cmdArgs = container.getCommandArgs(); + List cmd = container1.getCommand(); + List cmdArgs = container1.getCommandArgs(); assertEquals(cmd.get(0),"/bin/sh"); assertEquals(cmdArgs.get(0), "-c"); assertEquals(cmdArgs.get(1), "echo 'hello'"); @@ -176,25 +178,92 @@ public void getContainerCommands() { @Test public void getContainerResourceRequirements() { - Collection containers = pod.getContainers(); - IContainer container = containers.iterator().next(); - assertEquals("1", container.getRequestsCPU()); - assertEquals("128Mi", container.getRequestsMemory()); - assertEquals("4", container.getLimitsCPU()); - assertEquals("1Gi", container.getLimitsMemory()); + assertEquals("1", container1.getRequestsCPU()); + assertEquals("128Mi", container1.getRequestsMemory()); + assertEquals("4", container1.getLimitsCPU()); + assertEquals("1Gi", container1.getLimitsMemory()); } @Test public void resetContainerResourceRequirements() { - Collection containers = pod.getContainers(); - IContainer container = containers.iterator().next(); - container.setRequestsMemory(null); - container.setRequestsCPU(null); - container.setLimitsMemory(null); - container.setLimitsCPU(null); - assertEquals("", container.getRequestsCPU()); - assertEquals("", container.getRequestsMemory()); - assertEquals("", container.getLimitsCPU()); - assertEquals("", container.getLimitsMemory()); + container1.setRequestsMemory(null); + container1.setRequestsCPU(null); + container1.setLimitsMemory(null); + container1.setLimitsCPU(null); + assertEquals("", container1.getRequestsCPU()); + assertEquals("", container1.getRequestsMemory()); + assertEquals("", container1.getLimitsCPU()); + assertEquals("", container1.getLimitsMemory()); } + + @Test + public void shouldReturnLivenessProbe() { + // given + // when + IProbe probe = container1.getLivenessProbe(); + + // then + assertThat(probe).isNotNull(); + assertThat(probe.getInitialDelaySeconds()).isEqualTo(11); + assertThat(probe.getTimeoutSeconds()).isEqualTo(12); + assertThat(probe.getPeriodSeconds()).isEqualTo(13); + assertThat(probe.getSuccessThreshold()).isEqualTo(14); + assertThat(probe.getFailureThreshold()).isEqualTo(15); + } + + @Test + public void shouldAlterLivenessProbe() { + // given + // when + IProbe probe = container1.getLivenessProbe(); + probe.setInitialDelaySeconds(100); + probe.setTimeoutSeconds(101); + probe.setPeriodSeconds(102); + probe.setSuccessThreshold(103); + probe.setFailureThreshold(104); + + // then + assertThat(probe).isNotNull(); + assertThat(probe.getInitialDelaySeconds()).isEqualTo(100); + assertThat(probe.getTimeoutSeconds()).isEqualTo(101); + assertThat(probe.getPeriodSeconds()).isEqualTo(102); + assertThat(probe.getSuccessThreshold()).isEqualTo(103); + assertThat(probe.getFailureThreshold()).isEqualTo(104); + } + + @Test + public void shouldReturnReadynessProbe() { + // given + // when + IProbe probe = container1.getReadinessProbe(); + + // then + assertThat(probe).isNotNull(); + assertThat(probe.getInitialDelaySeconds()).isEqualTo(3); + assertThat(probe.getTimeoutSeconds()).isEqualTo(4); + assertThat(probe.getPeriodSeconds()).isEqualTo(5); + assertThat(probe.getSuccessThreshold()).isEqualTo(6); + assertThat(probe.getFailureThreshold()).isEqualTo(7); + } + + @Test + public void shouldAlterReadinessProbe() { + // given + // when + IProbe probe = container1.getReadinessProbe(); + probe.setInitialDelaySeconds(200); + probe.setTimeoutSeconds(201); + probe.setPeriodSeconds(202); + probe.setSuccessThreshold(203); + probe.setFailureThreshold(204); + + // then + assertThat(probe).isNotNull(); + assertThat(probe.getInitialDelaySeconds()).isEqualTo(200); + assertThat(probe.getTimeoutSeconds()).isEqualTo(201); + assertThat(probe.getPeriodSeconds()).isEqualTo(202); + assertThat(probe.getSuccessThreshold()).isEqualTo(203); + assertThat(probe.getFailureThreshold()).isEqualTo(204); + } + } diff --git a/src/test/resources/samples/openshift3/v1_pod.json b/src/test/resources/samples/openshift3/v1_pod.json index f1e9f32e..2ecfa419 100644 --- a/src/test/resources/samples/openshift3/v1_pod.json +++ b/src/test/resources/samples/openshift3/v1_pod.json @@ -79,6 +79,30 @@ "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount" } ], + "livenessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 11, + "timeoutSeconds" : 12, + "periodSeconds" : 13, + "successThreshold" : 14, + "failureThreshold" : 15 + }, + "readinessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 3, + "timeoutSeconds" : 4, + "periodSeconds" : 5, + "successThreshold" : 6, + "failureThreshold" : 7 + }, "terminationMessagePath": "/dev/termination-log", "imagePullPolicy": "IfNotPresent", "command" : [ From 17f5c32694f2a735812cc2eaf9094bc1d5ba6135 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 15 Nov 2017 19:25:40 +0100 Subject: [PATCH 095/258] Releasing 5.9.3.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ed48e3b3..52464b88 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.3-SNAPSHOT + 5.9.3.Final jar OpenShift Java REST Client http://openshift.redhat.com From f207c8ca853fa37181aa5ce2f5d012987a4d3a99 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 15 Nov 2017 19:37:07 +0100 Subject: [PATCH 096/258] bumping master to 5.9.4-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 52464b88..4b098fb5 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.3.Final + 5.9.4-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 7717d71bdd8e7b50ee66a064c6a54d73bd75d28b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 14 Dec 2017 12:38:05 +0100 Subject: [PATCH 097/258] #307 return null if there's no prob property (was: empty object) --- .../internal/restclient/model/Container.java | 10 +- .../model/DeploymentConfigTest.java | 46 --------- .../model/v1/DeploymentConfigTest.java | 99 ++++++++++++++++++- .../internal/restclient/model/v1/PodTest.java | 73 -------------- .../openshift3/v1_deployment_config.json | 47 ++++++++- .../resources/samples/openshift3/v1_pod.json | 24 ----- 6 files changed, 149 insertions(+), 150 deletions(-) delete mode 100644 src/test/java/com/openshift/internal/restclient/model/DeploymentConfigTest.java diff --git a/src/main/java/com/openshift/internal/restclient/model/Container.java b/src/main/java/com/openshift/internal/restclient/model/Container.java index 05339331..c0299562 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Container.java +++ b/src/main/java/com/openshift/internal/restclient/model/Container.java @@ -306,13 +306,19 @@ public void setLimitsCPU(String limitsCPU) { @Override public IProbe getReadinessProbe() { - ModelNode readynessProbeNode = get(getNode(), propertyKeys, READINESSPROBE); - return new Probe(readynessProbeNode); + ModelNode readinessProbeNode = get(getNode(), propertyKeys, READINESSPROBE); + if (!readinessProbeNode.isDefined()) { + return null; + } + return new Probe(readinessProbeNode); } @Override public IProbe getLivenessProbe() { ModelNode lifenessProbeNode = get(getNode(), propertyKeys, LIVENESSPROBE); + if (!lifenessProbeNode.isDefined()) { + return null; + } return new Probe(lifenessProbeNode); } diff --git a/src/test/java/com/openshift/internal/restclient/model/DeploymentConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/DeploymentConfigTest.java deleted file mode 100644 index 8222a3af..00000000 --- a/src/test/java/com/openshift/internal/restclient/model/DeploymentConfigTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ -package com.openshift.internal.restclient.model; - -import static org.junit.Assert.*; -import static org.mockito.Mockito.mock; - -import java.util.HashMap; - -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; - -import com.openshift.restclient.IClient; -import com.openshift.restclient.capability.resources.IDeployCapability; -import com.openshift.restclient.model.IDeploymentConfig; - -/** - * Tests unrelated to the underlying model structure and - * should api version independent - * @author jeff.cantrill - * - */ -public class DeploymentConfigTest { - - private IDeploymentConfig config; - - @Before - public void setUp() throws Exception { - config = new DeploymentConfig(new ModelNode(), mock(IClient.class), new HashMap<>()); - } - - @Test - public void testIsDeployCapable() { - assertTrue(config.supports(IDeployCapability.class)); - } - -} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java index da34bdb5..9c25d7b8 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java @@ -8,6 +8,7 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.v1; +import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -28,11 +29,14 @@ import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.resources.IDeployCapability; import com.openshift.restclient.images.DockerImageURI; +import com.openshift.restclient.model.IContainer; import com.openshift.restclient.model.IPort; import com.openshift.restclient.model.deploy.IDeploymentConfigChangeTrigger; import com.openshift.restclient.model.deploy.IDeploymentImageChangeTrigger; import com.openshift.restclient.model.deploy.IDeploymentTrigger; +import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.utils.Samples; /** @@ -40,11 +44,15 @@ */ public class DeploymentConfigTest { + private static final String CONTAINER2_NAME = "deployment"; + private static final String CONTAINER1_NAME = "ruby-helloworld-database"; private static final String VERSION = "v1"; private DeploymentConfig config; private IClient client; private ModelNode node; private Map propertyKeys; + private IContainer container1; + private IContainer container2; @Before public void setup(){ @@ -52,8 +60,15 @@ public void setup(){ node = ModelNode.fromJSONString(Samples.V1_DEPLOYMENT_CONIFIG.getContentAsString()); propertyKeys = ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.DEPLOYMENT_CONFIG); config = new DeploymentConfig(node, client, propertyKeys); + container1 = config.getContainer(CONTAINER1_NAME); + container2 = config.getContainer(CONTAINER2_NAME); } - + + @Test + public void testIsDeployCapable() { + assertThat(config.supports(IDeployCapability.class)).isTrue(); + } + @Test public void getLabels() { assertArrayEquals(new String[] {"template"},config.getLabels().keySet().toArray(new String[] {})); @@ -146,5 +161,87 @@ public void testAddContainer() { assertEquals(exp.toJSONString(false), containers.get(0).toJSONString(false)); } + @Test + public void shouldNotReturnLivenessProbe() { + IProbe livenessProbe = container1.getLivenessProbe(); + assertThat(livenessProbe).isNull(); + } + + @Test + public void shouldNotReturnReadinessProbe() { + IProbe readinessProbe = container1.getReadinessProbe(); + assertThat(readinessProbe).isNull(); + } + + @Test + public void shouldReturnLivenessProbe() { + // given + // when + IProbe probe = container2.getLivenessProbe(); + + // then + assertThat(probe).isNotNull(); + assertThat(probe.getInitialDelaySeconds()).isEqualTo(11); + assertThat(probe.getTimeoutSeconds()).isEqualTo(12); + assertThat(probe.getPeriodSeconds()).isEqualTo(13); + assertThat(probe.getSuccessThreshold()).isEqualTo(14); + assertThat(probe.getFailureThreshold()).isEqualTo(15); + } + + @Test + public void shouldAlterLivenessProbe() { + // given + // when + IProbe probe = container2.getLivenessProbe(); + probe.setInitialDelaySeconds(100); + probe.setTimeoutSeconds(101); + probe.setPeriodSeconds(102); + probe.setSuccessThreshold(103); + probe.setFailureThreshold(104); + + // then + assertThat(probe).isNotNull(); + assertThat(probe.getInitialDelaySeconds()).isEqualTo(100); + assertThat(probe.getTimeoutSeconds()).isEqualTo(101); + assertThat(probe.getPeriodSeconds()).isEqualTo(102); + assertThat(probe.getSuccessThreshold()).isEqualTo(103); + assertThat(probe.getFailureThreshold()).isEqualTo(104); + } + + @Test + public void shouldReturnReadynessProbe() { + // given + // when + IProbe probe = container2.getReadinessProbe(); + + // then + assertThat(probe).isNotNull(); + assertThat(probe.getInitialDelaySeconds()).isEqualTo(3); + assertThat(probe.getTimeoutSeconds()).isEqualTo(4); + assertThat(probe.getPeriodSeconds()).isEqualTo(5); + assertThat(probe.getSuccessThreshold()).isEqualTo(6); + assertThat(probe.getFailureThreshold()).isEqualTo(7); + } + + @Test + public void shouldAlterReadinessProbe() { + // given + // when + IProbe probe = container2.getReadinessProbe(); + probe.setInitialDelaySeconds(200); + probe.setTimeoutSeconds(201); + probe.setPeriodSeconds(202); + probe.setSuccessThreshold(203); + probe.setFailureThreshold(204); + + // then + assertThat(probe).isNotNull(); + assertThat(probe.getInitialDelaySeconds()).isEqualTo(200); + assertThat(probe.getTimeoutSeconds()).isEqualTo(201); + assertThat(probe.getPeriodSeconds()).isEqualTo(202); + assertThat(probe.getSuccessThreshold()).isEqualTo(203); + assertThat(probe.getFailureThreshold()).isEqualTo(204); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index 3716d905..46ad785f 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -8,7 +8,6 @@ ******************************************************************************/ package com.openshift.internal.restclient.model.v1; -import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -35,7 +34,6 @@ import com.openshift.restclient.model.IExecAction; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IPort; -import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.utils.Samples; /** @@ -195,75 +193,4 @@ public void resetContainerResourceRequirements() { assertEquals("", container1.getLimitsCPU()); assertEquals("", container1.getLimitsMemory()); } - - @Test - public void shouldReturnLivenessProbe() { - // given - // when - IProbe probe = container1.getLivenessProbe(); - - // then - assertThat(probe).isNotNull(); - assertThat(probe.getInitialDelaySeconds()).isEqualTo(11); - assertThat(probe.getTimeoutSeconds()).isEqualTo(12); - assertThat(probe.getPeriodSeconds()).isEqualTo(13); - assertThat(probe.getSuccessThreshold()).isEqualTo(14); - assertThat(probe.getFailureThreshold()).isEqualTo(15); - } - - @Test - public void shouldAlterLivenessProbe() { - // given - // when - IProbe probe = container1.getLivenessProbe(); - probe.setInitialDelaySeconds(100); - probe.setTimeoutSeconds(101); - probe.setPeriodSeconds(102); - probe.setSuccessThreshold(103); - probe.setFailureThreshold(104); - - // then - assertThat(probe).isNotNull(); - assertThat(probe.getInitialDelaySeconds()).isEqualTo(100); - assertThat(probe.getTimeoutSeconds()).isEqualTo(101); - assertThat(probe.getPeriodSeconds()).isEqualTo(102); - assertThat(probe.getSuccessThreshold()).isEqualTo(103); - assertThat(probe.getFailureThreshold()).isEqualTo(104); - } - - @Test - public void shouldReturnReadynessProbe() { - // given - // when - IProbe probe = container1.getReadinessProbe(); - - // then - assertThat(probe).isNotNull(); - assertThat(probe.getInitialDelaySeconds()).isEqualTo(3); - assertThat(probe.getTimeoutSeconds()).isEqualTo(4); - assertThat(probe.getPeriodSeconds()).isEqualTo(5); - assertThat(probe.getSuccessThreshold()).isEqualTo(6); - assertThat(probe.getFailureThreshold()).isEqualTo(7); - } - - @Test - public void shouldAlterReadinessProbe() { - // given - // when - IProbe probe = container1.getReadinessProbe(); - probe.setInitialDelaySeconds(200); - probe.setTimeoutSeconds(201); - probe.setPeriodSeconds(202); - probe.setSuccessThreshold(203); - probe.setFailureThreshold(204); - - // then - assertThat(probe).isNotNull(); - assertThat(probe.getInitialDelaySeconds()).isEqualTo(200); - assertThat(probe.getTimeoutSeconds()).isEqualTo(201); - assertThat(probe.getPeriodSeconds()).isEqualTo(202); - assertThat(probe.getSuccessThreshold()).isEqualTo(203); - assertThat(probe.getFailureThreshold()).isEqualTo(204); - } - } diff --git a/src/test/resources/samples/openshift3/v1_deployment_config.json b/src/test/resources/samples/openshift3/v1_deployment_config.json index 2f962862..ad360c61 100644 --- a/src/test/resources/samples/openshift3/v1_deployment_config.json +++ b/src/test/resources/samples/openshift3/v1_deployment_config.json @@ -113,10 +113,49 @@ "capabilities": {}, "privileged": false } - } - ], - "restartPolicy": "Always", - "dnsPolicy": "ClusterFirst" + }, + { + "name": "deployment", + "image": "openshift/origin-deployer:v0.6", + "ports": [ + { + "name" : "http", + "containerPort": 8080, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "OPENSHIFT_DEPLOYMENT_NAME", + "value": "database-1" + } + ], + "livenessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 11, + "timeoutSeconds" : 12, + "periodSeconds" : 13, + "successThreshold" : 14, + "failureThreshold" : 15 + }, + "readinessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 3, + "timeoutSeconds" : 4, + "periodSeconds" : 5, + "successThreshold" : 6, + "failureThreshold" : 7 + } + } + ] } } }, diff --git a/src/test/resources/samples/openshift3/v1_pod.json b/src/test/resources/samples/openshift3/v1_pod.json index 2ecfa419..f1e9f32e 100644 --- a/src/test/resources/samples/openshift3/v1_pod.json +++ b/src/test/resources/samples/openshift3/v1_pod.json @@ -79,30 +79,6 @@ "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount" } ], - "livenessProbe" : { - "httpGet" : { - "path" : "/pagecount", - "port" : 8080, - "scheme" : "HTTP" - }, - "initialDelaySeconds" : 11, - "timeoutSeconds" : 12, - "periodSeconds" : 13, - "successThreshold" : 14, - "failureThreshold" : 15 - }, - "readinessProbe" : { - "httpGet" : { - "path" : "/pagecount", - "port" : 8080, - "scheme" : "HTTP" - }, - "initialDelaySeconds" : 3, - "timeoutSeconds" : 4, - "periodSeconds" : 5, - "successThreshold" : 6, - "failureThreshold" : 7 - }, "terminationMessagePath": "/dev/termination-log", "imagePullPolicy": "IfNotPresent", "command" : [ From 1b287643fcaab29f4c9dd35b43c66a46377ca90b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 12 Jan 2018 14:48:31 +0100 Subject: [PATCH 098/258] Releasing 5.9.4.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4b098fb5..c93f8dbe 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.4-SNAPSHOT + 5.9.4.Final jar OpenShift Java REST Client http://openshift.redhat.com From a4f4f7ee79c8075dda712b92d0ecc8ac6c326c28 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Tue, 13 Feb 2018 18:55:18 +0100 Subject: [PATCH 099/258] #300 Rsync is not working when the local folder path contains a space Signed-off-by: Jeff MAURY --- pom.xml | 2 +- .../AbstractOpenShiftBinaryCapability.java | 7 +- .../internal/util/StringSplitter.java | 54 ++++++++ .../capability/resources/IRSyncable.java | 13 +- .../capabilities/PodExecIntegrationTest.java | 4 +- ...ftBinaryRSyncRetrievalIntegrationTest.java | 121 +++++++++++++++--- .../internal/util/StringSplitterTest.java | 75 +++++++++++ 7 files changed, 248 insertions(+), 28 deletions(-) create mode 100644 src/main/java/com/openshift/internal/util/StringSplitter.java create mode 100644 src/test/java/com/openshift/internal/util/StringSplitterTest.java diff --git a/pom.xml b/pom.xml index c93f8dbe..a36c4f14 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.4.Final + 5.9.5-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 43ad20dd..8244e303 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -21,6 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.openshift.internal.util.StringSplitter; import com.openshift.restclient.IClient; import com.openshift.restclient.OpenShiftContext; import com.openshift.restclient.OpenShiftException; @@ -177,12 +178,12 @@ private ProcessBuilder initProcessBuilder(String location, final OpenShiftBinary // https://issues.jboss.org/browse/JBIDE-23862 - see the latest comments if (IS_MAC) { args.add(location); - Arrays.stream(StringUtils.split(buildArgs(Arrays.asList(options)))).forEach(s -> args.add(s)); + StringSplitter.split(buildArgs(Arrays.asList(options)), args); builder = new ProcessBuilder(args); } else { File oc = new File(location); args.add(location); - Arrays.stream(StringUtils.split(buildArgs(Arrays.asList(options)))).forEach(s -> args.add(s)); + StringSplitter.split(buildArgs(Arrays.asList(options)), args); builder = new ProcessBuilder(args); builder.directory(oc.getParentFile()); } diff --git a/src/main/java/com/openshift/internal/util/StringSplitter.java b/src/main/java/com/openshift/internal/util/StringSplitter.java new file mode 100644 index 00000000..ce74b1a6 --- /dev/null +++ b/src/main/java/com/openshift/internal/util/StringSplitter.java @@ -0,0 +1,54 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.util; + +import java.util.ArrayList; +import java.util.List; + +public class StringSplitter { + private StringSplitter() {} + + public static List split(String str, List result) { + boolean inQuote = false; + StringBuilder builder = new StringBuilder(); + + for(int i=0; i < str.length();++i) { + char c = str.charAt(i); + if (inQuote) { + if (c == '"') { + inQuote = false; + } else { + builder.append(c); + } + } else if (c == '"') { + inQuote = true; + } else if (c == ' ') { + if (builder.length() > 0) { + result.add(builder.toString()); + builder = new StringBuilder(); + } + } else { + builder.append(c); + } + } + if (builder.length() > 0) { + result.add(builder.toString()); + } + return result; + } + + public static List split(String str) { + List result = new ArrayList<>(); + return split(str, result); + } + + +} diff --git a/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java b/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java index 7e84411b..bd66832c 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -51,9 +51,11 @@ public PodPeer(String location, IPod pod) { @Override public String getParameter() { return new StringBuilder() + .append('"') .append(pod.getName()) .append(POD_PATH_SEPARATOR) .append(super.getParameter()) + .append('"') .append(" -n ") .append(pod.getNamespace()) .toString(); @@ -85,6 +87,15 @@ public LocalPeer(String location) { public boolean isPod() { return false; } + + @Override + public String getParameter() { + return new StringBuilder() + .append('"') + .append(super.getParameter()) + .append('"') + .toString(); + } } public abstract class Peer { diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java index 6e3de6e0..9ec552db 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -40,7 +40,7 @@ public class PodExecIntegrationTest { private Exception ex; private IPod pod; - private static class TestExecListener implements IPodExec.IPodExecOutputListener { + public static class TestExecListener implements IPodExec.IPodExecOutputListener { private static final Logger LOG = LoggerFactory.getLogger(PodExecIntegrationTest.class); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java index 39a78f75..5f1c88cb 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java @@ -1,6 +1,6 @@ package com.openshift.internal.restclient.capability.resources; /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -16,6 +16,7 @@ import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import static org.fest.assertions.Assertions.*; import static org.junit.Assert.assertNotNull; @@ -23,20 +24,27 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; +import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.internal.restclient.api.capabilities.PodExecIntegrationTest; import com.openshift.internal.restclient.model.Pod; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability; +import com.openshift.restclient.capability.IStoppable; import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; import com.openshift.restclient.capability.resources.IRSyncable; import com.openshift.restclient.capability.resources.IRSyncable.LocalPeer; +import com.openshift.restclient.capability.resources.IRSyncable.Peer; import com.openshift.restclient.capability.resources.IRSyncable.PodPeer; import com.openshift.restclient.model.IResource; @@ -46,15 +54,24 @@ * */ public class OpenshiftBinaryRSyncRetrievalIntegrationTest { + private static final String TARGET_FOLDER_WITH_SPECIAL_CHARS = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/with sp@cé/"; + private static final String FILE_NAME_SPECIAL_CHARS = "test with spéci@l characters and spaces"; + private static final String SOURCE_FOLDER_WITH_SPECIAL_CHARS = "with sp@cé in path"; + + private static final String NORMAL_TARGET_TMP = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/withoutspace/"; + private static final String NORMAL_FILE_NAME = "normalFileName"; + private static final String NORMAL_FOLDER_NAME = "normalFolderName"; private static final Logger LOG = LoggerFactory.getLogger(OpenshiftBinaryRSyncRetrievalIntegrationTest.class); private IntegrationTestHelper helper = new IntegrationTestHelper(); private IClient client; - - private File localTempDir; - + + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); + private Pod pod; + private String podFolderToClean = null; @Before public void setUp() throws Exception { @@ -65,34 +82,97 @@ public void setUp() throws Exception { List pods = client.list(ResourceKind.POD, "default"); pod = (Pod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); assertNotNull("Did not find the registry pod to which to rsync", pod); - - localTempDir = new File(FileUtils.getTempDirectory(), helper.generateNamespace()); - localTempDir.deleteOnExit(); - assertTrue(localTempDir.mkdirs()); + } + + @After + public void tearDown() throws Exception { + if(podFolderToClean != null) { + execOnPod(new String[] {"rm", "-r",podFolderToClean}); + } + } + + @Test + public void testRSyncLogRetrieval() throws IOException, InterruptedException { + testRsyncLogRetrieval(NORMAL_FOLDER_NAME, NORMAL_FILE_NAME, NORMAL_TARGET_TMP); + } + + @Test + public void testRSyncLogRetrievalWithSpaceInFolderToSynchronize() throws Exception { + testRsyncLogRetrieval(SOURCE_FOLDER_WITH_SPECIAL_CHARS, NORMAL_FILE_NAME, NORMAL_TARGET_TMP); + } + + @Test + public void testRSyncLogRetrievalWithSpaceInFileToSynchronize() throws Exception { + testRsyncLogRetrieval(NORMAL_FOLDER_NAME, FILE_NAME_SPECIAL_CHARS, NORMAL_TARGET_TMP); + } + + @Test + public void testRSyncLogRetrievalWithSpaceInTargetDirectory() throws Exception { + testRsyncLogRetrieval(NORMAL_FOLDER_NAME, NORMAL_FILE_NAME, TARGET_FOLDER_WITH_SPECIAL_CHARS); } @Test - public void testRSyncLogRetrieval() throws IOException { + public void testRSyncLogRetrievalWithSpaceEverywhere() throws Exception { + testRsyncLogRetrieval(SOURCE_FOLDER_WITH_SPECIAL_CHARS, FILE_NAME_SPECIAL_CHARS, TARGET_FOLDER_WITH_SPECIAL_CHARS); + } + + protected void testRsyncLogRetrieval(String folderToSynchronizeName, String fileNameToSynchronize, String targetFolderPath) throws IOException, InterruptedException { + podFolderToClean = targetFolderPath; + execOnPod(new String[] {"mkdir", "-p", targetFolderPath}); + File localTempDir = tmpFolder.newFolder(folderToSynchronizeName); + // Create a dummy file locally to be sure there will be something to rsync from Local to Remote + File tmpFile = File.createTempFile(fileNameToSynchronize, ".txt", localTempDir); + final String fileName = tmpFile.getName(); + LocalPeer localPeer = new LocalPeer(localTempDir.getAbsolutePath()+File.separator); + PodPeer podPeer = new PodPeer(targetFolderPath, pod); + + // Check Local to Remote + rsyncAndCheck(fileName, localPeer, podPeer); + tmpFile.delete(); + + // Create a dummy file locally to be sure there will be something to rsync from Remote to Local + execOnPod(new String[] {"touch", targetFolderPath +"/fileToSynchronizeBackFromPodToLocal.txt"}); + + // Check Remote to Local + rsyncAndCheck("fileToSynchronizeBackFromPodToLocal", podPeer, localPeer); + assertThat(new File(localTempDir, "fileToSynchronizeBackFromPodToLocal.txt").exists()).isTrue(); + } + + protected void execOnPod(String[] commands) throws InterruptedException { + PodExecIntegrationTest.TestExecListener execListener = new PodExecIntegrationTest.TestExecListener(); + final String container = pod.getContainers().iterator().next().getName(); + IPodExec.Options options = new IPodExec.Options(); + options.container( container ); - final String targetDir = "/tmp"; - // when - // create a dummy file to be sure there will be something to rsync - final String fileName = File.createTempFile("test", ".txt", localTempDir).getName() - ; - // run the rsync and collect the logs - List logs = pod.accept(new CapabilityVisitor>() { + pod.accept(new CapabilityVisitor() { + + @Override + public IStoppable visit(IPodExec capability) { + return capability.start(execListener, options, commands); + } + + }, null); + execListener.testDone.await( 10, TimeUnit.SECONDS ); + assertTrue( execListener.openCalled.get() ); + assertTrue( execListener.closeCalled.get() ); + assertTrue( !execListener.failureCalled.get() ); + assertTrue( !execListener.execErrCalled.get() ); + } + + protected void rsyncAndCheck(final String fileName, Peer source, Peer destination) { + List logs = pod.accept(new CapabilityVisitor>() { @Override public List visit(IRSyncable cap) { try { final BufferedReader reader = new BufferedReader(new InputStreamReader( - cap.sync(new LocalPeer(localTempDir.getAbsolutePath()), new PodPeer(targetDir, pod), OpenShiftBinaryOption.SKIP_TLS_VERIFY))); + cap.sync(source, destination, OpenShiftBinaryOption.SKIP_TLS_VERIFY))); List logs = IOUtils.readLines(reader); // wait until end of 'rsync' cap.await(); return logs; } catch (Exception e) { - LOG.error("Exception rsycing to pod:",e); + LOG.error("Exception rsyncing to pod:",e); } return new ArrayList<>(); } @@ -102,9 +182,8 @@ public List visit(IRSyncable cap) { LOG.debug("**** RSync Logs ****"); logs.forEach(l->LOG.debug(l)); } - // then - // verify that the logs contain a message about the dummy file + // then verify that the logs contain a message about the dummy file assertThat(logs).isNotEmpty(); assertThat(logs.stream().anyMatch(line -> line.contains(fileName))).isTrue(); - } + } } diff --git a/src/test/java/com/openshift/internal/util/StringSplitterTest.java b/src/test/java/com/openshift/internal/util/StringSplitterTest.java new file mode 100644 index 00000000..6812ec0a --- /dev/null +++ b/src/test/java/com/openshift/internal/util/StringSplitterTest.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.internal.util; + +import static org.junit.Assert.assertThat; + +import static org.hamcrest.CoreMatchers.is; + +import java.util.Arrays; +import java.util.List; +import org.junit.Test; + +public class StringSplitterTest { + @Test + public void testSimpleUniqueParameter() { + List result = StringSplitter.split("parm1"); + List expected = Arrays.asList("parm1"); + assertThat(result, is(expected)); + } + + @Test + public void testSimpleManyParameters() { + List result = StringSplitter.split("parm1 parm2 parm3"); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } + + @Test + public void testQuotedUniqueParameter() { + List result = StringSplitter.split("\"parm1\""); + List expected = Arrays.asList("parm1"); + assertThat(result, is(expected)); + } + + @Test + public void testQuotedManyParameters() { + List result = StringSplitter.split("\"parm1\" \"parm2\" \"parm3\""); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } + + @Test + public void testQuotedManyParametersWithAdjacentValue() { + List result = StringSplitter.split("\"parm1\" \"parm2\"a \"parm3\""); + List expected = Arrays.asList("parm1", "parm2a", "parm3"); + assertThat(result, is(expected)); + } + + @Test + public void testQuotedManyParametersUnfinished() { + List result = StringSplitter.split("\"parm1\" \"parm2\" \"parm3"); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } + + @Test + public void testSimpleDoubleSpaceManyParameters() { + List result = StringSplitter.split("parm1 parm2 parm3"); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } + + @Test + public void testSimpleEndSpaceManyParameters() { + List result = StringSplitter.split("parm1 parm2 parm3 "); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } +} From 55bc2300c0aa7b980dc8292fd782813ed6307c1b Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 16 Feb 2018 11:21:44 +0100 Subject: [PATCH 100/258] [OSJC-282] - Check Java9 compatibility Signed-off-by: Jeff MAURY --- pom.xml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c93f8dbe..467257c3 100755 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ org.jboss jboss-parent - 6-beta-2 + 25 @@ -305,7 +305,7 @@ **/*IntegrationTest.java - none + @@ -329,6 +329,22 @@ + + jdk9 + + 9 + + + + + maven-surefire-plugin + + -Dfile.encoding=UTF-8 --add-modules=ALL-SYSTEM + + + + + https://github.com/openshift/openshift-restclient-java From 3940fd88a779119998fc0011779627487b336dd8 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 16 Feb 2018 15:30:20 +0100 Subject: [PATCH 101/258] [OSJC-282] - Check Java9 compatibility - Revert back to old parent but overriding the maven enforcer plugin version Signed-off-by: Jeff MAURY --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 467257c3..891dd59d 100755 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ org.jboss jboss-parent - 25 + 6-beta-2 @@ -31,6 +31,7 @@ 2.1 + 3.0.0-M1 1.8 1.8 From 3fde53e53767b02ffdd5ad13b90c74702910ce8b Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 16 Feb 2018 15:34:17 +0100 Subject: [PATCH 102/258] [OSJC-282] - Check Java9 compatibility - Add jdk9 to CircleCI Signed-off-by: Jeff MAURY --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 5374a2d0..ab39bb25 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: java jdk: - oraclejdk8 + - oraclejdk9 script: mvn clean verify From 4ce6035f5ded159d24fbec220326a27324600b4f Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 28 Feb 2018 11:55:14 +0100 Subject: [PATCH 103/258] [Issue 313] releasing 5.9.5.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ecacfcaf..7315b9a2 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.5-SNAPSHOT + 5.9.5.Final jar OpenShift Java REST Client http://openshift.redhat.com From cc8a1c8abd927b9484289f01000d900c8564b7c9 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 6 Mar 2018 15:43:15 +0100 Subject: [PATCH 104/258] bumping master to 5.9.6-SNAPSHOT after release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7315b9a2..96d50225 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.5.Final + 5.9.6-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 724252e562cdde2632895714feba6bc203393414 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 6 Mar 2018 15:40:59 +0100 Subject: [PATCH 105/258] [315] fixing git exclusion filter for OSBinaryRSync --- .../AbstractOpenShiftBinaryCapability.java | 25 ------------------ .../resources/OpenShiftBinaryRSync.java | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 8244e303..c87270db 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -121,31 +121,6 @@ protected String getSkipTlsVerifyFlag() { return "--insecure-skip-tls-verify=true "; } - /** - * @return the command-line flag to exclude some files/directories that do - * not need to be synchronized between the remote pod and the local - * deployment directory. - */ - protected String getGitFolderExclusionFlag() { - // no support for multiple exclusion, so excluding '.git' only for now - // see https://github.com/openshift/origin/issues/8223 - return "--exclude='.git' "; - } - - /** - * @return the command-line flag to avoid transferring permissions. - */ - protected String getNoPermsFlags() { - return "--no-perms=true "; - } - - /** - * @return the command-line flag to delete extraneous file from destination directories. - */ - protected String getDeleteFlags() { - return "--delete "; - } - /** * Starts the {@link Process} to run the {@code oc} command. * @param options the command line options diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java index 575e2f74..ab5746cd 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java @@ -160,4 +160,30 @@ protected String buildArgs(final List options) { return argsBuilder.toString(); } + /** + * @return the command-line flag to exclude some files/directories that do + * not need to be synchronized between the remote pod and the local + * deployment directory. + */ + protected String getGitFolderExclusionFlag() { + // no support for multiple exclusion, so excluding '.git' only for now + // see https://github.com/openshift/origin/issues/8223 + return "--exclude=.git "; + } + + /** + * @return the command-line flag to avoid transferring permissions. + */ + protected String getNoPermsFlags() { + return "--no-perms=true "; + } + + /** + * @return the command-line flag to delete extraneous file from destination directories. + */ + protected String getDeleteFlags() { + return "--delete "; + } + + } From ff9229924b8fae1d0af2a6761b0b8e87e1f63317 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 9 Mar 2018 13:35:17 +0100 Subject: [PATCH 106/258] [#286] implemented IUser#getUID --- .../restclient/model/user/OpenShiftUser.java | 5 +++++ .../com/openshift/restclient/model/user/IUser.java | 5 +++++ .../internal/restclient/model/v1/UserTest.java | 12 +++++++++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java index 172adddd..21c64e6f 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java @@ -31,4 +31,9 @@ public String getFullName() { return asString(USER_FULLNAME); } + @Override + public String getUID() { + return asString("metadata.uid"); + } + } diff --git a/src/main/java/com/openshift/restclient/model/user/IUser.java b/src/main/java/com/openshift/restclient/model/user/IUser.java index 1bf0df52..48bd0d2e 100644 --- a/src/main/java/com/openshift/restclient/model/user/IUser.java +++ b/src/main/java/com/openshift/restclient/model/user/IUser.java @@ -23,4 +23,9 @@ public interface IUser extends IResource { */ String getFullName(); + /** + * Returns the user uid as specified in the metadata + * @return + */ + String getUID(); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java index b52ed6d2..bfe5a3ae 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java @@ -29,17 +29,23 @@ public class UserTest{ private static final String VERSION = "v1"; - private IUser resource; + private IUser user; @Before public void setUp(){ IClient client = mock(IClient.class); ModelNode node = ModelNode.fromJSONString(Samples.V1_USER.getContentAsString()); - resource = new OpenShiftUser(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.USER)); + user = new OpenShiftUser(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.USER)); } @Test public void testFullName() { - assertEquals("Foo Master", resource.getFullName()); + assertEquals("Foo Master", user.getFullName()); } + + @Test + public void testUid() { + assertEquals("94b42e96-0faa-11e5-9467-080027893417", user.getUID()); + } + } From 00e4668b6251d2d88df7a6620792106ef56c0109 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 9 Mar 2018 16:09:46 +0100 Subject: [PATCH 107/258] bumping to 5.9.6.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 96d50225..173de661 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.6-SNAPSHOT + 5.9.6.Final jar OpenShift Java REST Client http://openshift.redhat.com From 96a4f534ecb68f0f7669cbae99c73d029324bf15 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 7 Mar 2018 23:31:52 +0100 Subject: [PATCH 108/258] [318] allow multiple excludes for OpenShiftBinaryRSync Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- .../AbstractOpenShiftBinaryCapability.java | 145 ++++++++++------ .../OpenShiftBinaryPodLogRetrieval.java | 91 +++++++--- .../OpenShiftBinaryPortForwarding.java | 72 ++++++-- .../resources/OpenShiftBinaryRSync.java | 97 +++++------ .../capability/IBinaryCapability.java | 25 +-- .../resources/IPodLogRetrieval.java | 2 +- .../capability/resources/IRSyncable.java | 160 +++++++++++++----- .../OpenShiftBinaryPodLogRetrievalTest.java | 107 ++++++++++++ .../OpenShiftBinaryPortForwardingTest.java | 114 +++++++++++++ .../resources/OpenShiftBinaryRSyncTest.java | 139 +++++++++++++++ ...tBinaryPodLogRetrievalIntegrationTest.java | 4 +- ...ftBinaryPortForwardingIntegrationTest.java | 4 +- ...ftBinaryRSyncRetrievalIntegrationTest.java | 13 +- .../testutils/BinaryCapabilityTestMocks.java | 61 +++++++ 15 files changed, 818 insertions(+), 218 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java diff --git a/pom.xml b/pom.xml index 173de661..80ea2b19 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 5.9.6.Final + 6.0.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index c87270db..195ad490 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -14,6 +14,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import org.apache.commons.io.IOUtils; @@ -27,25 +28,105 @@ import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.capability.resources.LocationNotFoundException; +import com.openshift.restclient.model.IResource; /** * Capability that wraps the OpenShift binary * * @author Jeff Cantrill + * @author Andre Dietisheim * */ public abstract class AbstractOpenShiftBinaryCapability implements IBinaryCapability { private static final Logger LOG = LoggerFactory.getLogger(AbstractOpenShiftBinaryCapability.class); - private static final boolean IS_MAC = StringUtils.isNotEmpty(System.getProperty("os.name")) && System.getProperty("os.name").toLowerCase().contains("mac"); + + static class Server implements OpenShiftBinaryOption { - private Process process; + private IClient client; - private IClient client; + public Server(IClient client) { + this.client = client; + } + + @Override + public void append(StringBuilder commandLine) { + commandLine + .append(" --server=") + .append(client.getBaseURL()).append(" "); + } + } + static class Token implements OpenShiftBinaryOption { + + private IClient client; + + Token(IClient client) { + this.client = client; + } + + @Override + public void append(StringBuilder commandLine) { + commandLine + .append(" --token=") + .append(client.getAuthorizationContext().getToken()); + } + } + + static class Namespace implements OpenShiftBinaryOption { + + private IResource resource; + + public Namespace(IResource resource) { + this.resource = resource; + } + + @Override + public void append(StringBuilder commandLine) { + if (resource == null) { + return; + } + commandLine.append(" -n ").append(resource.getNamespace()); + } + } + + protected static class CommandLineBuilder { + + private StringBuilder sb; + + public CommandLineBuilder(String command) { + this.sb = new StringBuilder(command); + } + + public CommandLineBuilder append(OpenShiftBinaryOption argument) { + if (argument != null) { + argument.append(sb); + } + return this; + } + + public CommandLineBuilder append(Collection arguments) { + if (arguments == null) { + return this; + } + + for (OpenShiftBinaryOption argument : arguments) { + append(argument); + } + return this; + } + + public String build() { + return sb.toString(); + } + } + + private Process process; + private IClient client; + protected AbstractOpenShiftBinaryCapability(IClient client) { this.client = client; } @@ -80,64 +161,28 @@ protected Process getProcess() { } private void addShutdownHook() { - Runnable runnable = new Runnable() { - @Override - public void run() { - stop(); - } - }; - Runtime.getRuntime().addShutdownHook(new Thread(runnable)); - } - - protected String getUserFlag() { - final StringBuilder argBuilder = new StringBuilder(); - argBuilder.append("--user=").append(client.getAuthorizationContext().getUserName()).append(" "); - return argBuilder.toString(); - } - - /** - * @return - */ - protected String getServerFlag() { - final StringBuilder argBuilder = new StringBuilder(); - argBuilder.append("--server=").append(client.getBaseURL()).append(" "); - return argBuilder.toString(); - } - - /** - * Adds the authentication token - * @return the command-line argument to use the current token - */ - protected String getTokenFlag() { - return new StringBuilder("--token=") - .append(client.getAuthorizationContext().getToken()) - .append(" ").toString(); - } - - /** - * @return the command-line flag to use insecure connection (skip TLS verification) - */ - protected String getSkipTlsVerifyFlag() { - return "--insecure-skip-tls-verify=true "; + Runtime.getRuntime().addShutdownHook(new Thread(() -> stop())); } /** * Starts the {@link Process} to run the {@code oc} command. - * @param options the command line options + * @param arguments the command line options + * @return */ - public final void start(final OpenShiftBinaryOption... options) { + public final Process start(final OpenShiftBinaryOption... arguments) { String location = getOpenShiftBinaryLocation(); if(!validate()) { - return; + return null; } - ProcessBuilder processBuilder = initProcessBuilder(location, options); - startProcess(processBuilder); + ProcessBuilder processBuilder = initProcessBuilder(location, arguments); + return startProcess(processBuilder); } - - private void startProcess(ProcessBuilder builder) { + + protected Process startProcess(ProcessBuilder builder) { try { process = builder.start(); checkProcessIsAlive(); + return process; } catch (IOException e) { LOG.error("Could not start process for {}.", new Object[]{ getName(), e }); throw new OpenShiftException(e, "Does your OpenShift binary location exist? Error starting process: %s", @@ -146,7 +191,7 @@ private void startProcess(ProcessBuilder builder) { } private ProcessBuilder initProcessBuilder(String location, final OpenShiftBinaryOption... options) { - List args = new ArrayList(); + List args = new ArrayList<>(); ProcessBuilder builder = null; // the condition is made in order to solve mac problem // with launching binaries containing spaces in its path diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrieval.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrieval.java index e6e62d83..19c7b958 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrieval.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrieval.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -29,11 +29,50 @@ public class OpenShiftBinaryPodLogRetrieval implements IPodLogRetrieval { + static class PodName implements OpenShiftBinaryOption { + + private IPod pod; + + public PodName(IPod pod) { + this.pod = pod; + } + + @Override + public void append(StringBuilder commandLine) { + if (pod == null) { + return; + } + commandLine.append(" ").append(pod.getName()); + } + } + + static class ContainerName implements OpenShiftBinaryOption { + + private String name; + + public ContainerName(String name) { + this.name = name; + } + + @Override + public void append(StringBuilder commandLine) { + commandLine.append( " -c ").append(name); + } + } + + static class Follow implements OpenShiftBinaryOption { + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" -f"); + } + } + private static final Logger LOG = LoggerFactory.getLogger(IPodLogRetrieval.class); private IPod pod; private IClient client; private Map cache = new HashMap<>(); - + public OpenShiftBinaryPodLogRetrieval(IPod pod, IClient client) { this.pod = pod; this.client = client; @@ -58,17 +97,15 @@ public InputStream getLogs(final boolean follow, final OpenShiftBinaryOption... public InputStream getLogs(final boolean follow, final String container, final OpenShiftBinaryOption... options) { final String normalizedContainer = StringUtils.defaultIfBlank(container, ""); synchronized (cache) { - if(cache.containsKey(normalizedContainer)) { + if (cache.containsKey(normalizedContainer)) { return cache.get(normalizedContainer).getLogs(); } PodLogs logs = null; try { logs = new PodLogs(client, follow, normalizedContainer, options); return logs.getLogs(); - }catch(Exception e) { - throw e; - }finally { - if(logs != null) { + } finally { + if (logs != null) { cache.put(normalizedContainer, logs); } } @@ -77,7 +114,7 @@ public InputStream getLogs(final boolean follow, final String container, final O @Override public void stop() { - new ArrayList<>(cache.keySet()).forEach(c->stop(c)); + new ArrayList<>(cache.keySet()).forEach(container -> stop(container)); } @Override @@ -92,14 +129,16 @@ public synchronized void stop(String container) { } - private class PodLogs extends AbstractOpenShiftBinaryCapability{ + protected class PodLogs extends AbstractOpenShiftBinaryCapability{ + public static final String LOGS_COMMAND = "logs"; + private String container; private boolean follow; private SequenceInputStream is; private OpenShiftBinaryOption[] options; - PodLogs(IClient client, boolean follow, String container, OpenShiftBinaryOption... options){ + protected PodLogs(IClient client, boolean follow, String container, OpenShiftBinaryOption... options){ super(client); this.follow = follow; this.container = container; @@ -107,9 +146,11 @@ private class PodLogs extends AbstractOpenShiftBinaryCapability{ } public synchronized InputStream getLogs() { - if(is == null) { - start(options); - is = new SequenceInputStream(getProcess().getInputStream(), getProcess().getErrorStream()); + if (is == null) { + Process process = start(options); + if (process != null) { + is = new SequenceInputStream(process.getInputStream(), process.getErrorStream()); + } } return is; } @@ -143,21 +184,19 @@ protected boolean validate() { @Override protected String buildArgs(final List options) { - final StringBuilder argsBuilder = new StringBuilder(); - argsBuilder.append("logs "); - if(options.contains(OpenShiftBinaryOption.SKIP_TLS_VERIFY)) { - argsBuilder.append(getSkipTlsVerifyFlag()); - } - argsBuilder.append(getServerFlag()).append(" ") - .append(pod.getName()).append(" ").append("-n ").append(pod.getNamespace()).append(" ") - .append(getTokenFlag()); - if(follow) { - argsBuilder.append(" -f "); + CommandLineBuilder builder = new CommandLineBuilder(LOGS_COMMAND) + .append(new Token(client)) + .append(new Server(client)) + .append(options) + .append(new PodName(pod)) + .append(new Namespace(pod)); + if (follow) { + builder.append(new Follow()); } - if(StringUtils.isNotBlank(container)) { - argsBuilder.append( " -c ").append(container); + if (StringUtils.isNotBlank(container)) { + builder.append(new ContainerName(container)); } - return argsBuilder.toString(); + return builder.build(); } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java index 99395aa5..3ab4ed76 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -23,13 +23,56 @@ * Port forwarding implementation that wraps the OpenShift binary * * @author Jeff Cantrill + * @author Andre Dietisheim * */ public class OpenShiftBinaryPortForwarding extends AbstractOpenShiftBinaryCapability implements IPortForwardable { + public static final String PORT_FORWARD_COMMAND = "port-forward"; private final IPod pod; private final Collection pairs = new ArrayList<>(); + static class PodName implements OpenShiftBinaryOption { + + private IPod pod; + + public PodName(IPod pod) { + this.pod = pod; + } + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" -p ").append(pod.getName()); + } + } + + static class PortPairs implements OpenShiftBinaryOption { + + private Collection pairs; + + public PortPairs(Collection pairs) { + this.pairs = pairs; + } + + @Override + public void append(StringBuilder commandLine) { + if (pairs == null) { + return; + } + for (PortPair pair : pairs) { + append(pair, commandLine); + } + } + + protected void append(PortPair pair, StringBuilder commandLine) { + commandLine + .append(" ") + .append(pair.getLocalPort()) + .append(":") + .append(pair.getRemotePort()).append(" "); + } + } + public OpenShiftBinaryPortForwarding(IPod pod, IClient client) { super(client); this.pod = pod; @@ -67,27 +110,24 @@ public Collection getPortPairs() { @Override public synchronized void forwardPorts(final Collection ports, final OpenShiftBinaryOption... options) { - if (ports != null && !ports.isEmpty()) { - this.pairs.addAll(ports); - } else { - throw new OpenShiftException("Port-forwarding was invoked but not port was specified."); + if (ports == null || ports.isEmpty()) { + throw new OpenShiftException("Port-forwarding was invoked but no ports were specified."); } + + this.pairs.addAll(ports); start(options); } @Override protected String buildArgs(final List options) { - final StringBuilder argBuilder = new StringBuilder(); - argBuilder.append("port-forward "); - if(options.contains(OpenShiftBinaryOption.SKIP_TLS_VERIFY)) { - argBuilder.append(getSkipTlsVerifyFlag()); - } - argBuilder.append(getServerFlag()).append(getTokenFlag()).append("-n ").append(pod.getNamespace()).append(" ") - .append("-p ").append(pod.getName()).append(" "); - for (PortPair pair : pairs) { - argBuilder.append(pair.getLocalPort()).append(":").append(pair.getRemotePort()).append(" "); - } - return argBuilder.toString(); + return new CommandLineBuilder(PORT_FORWARD_COMMAND) + .append( new Token(getClient())) + .append(new Server(getClient())) + .append(options) + .append(new Namespace(pod)) + .append(new PodName(pod)) + .append(new PortPairs(pairs)) + .build(); } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java index ab5746cd..d767f388 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -25,6 +25,7 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.capability.resources.IRSyncable; +import com.openshift.restclient.model.IPod; /** * Port forwarding implementation that wraps the OpenShift binary @@ -33,13 +34,14 @@ * */ public class OpenShiftBinaryRSync extends AbstractOpenShiftBinaryCapability implements IRSyncable { - - private static final Logger LOG = LoggerFactory.getLogger(OpenShiftBinaryRSync.class); + private static final Logger LOG = LoggerFactory.getLogger(OpenShiftBinaryRSync.class); + public static final String RSYNC_COMMAND = "rsync"; private static final long WAIT_FOR_EXIT_TIMEOUT = 5; // mins - + private Peer source; private Peer destination; + private IPod pod; private final Executor executor = Executors.newCachedThreadPool(); @@ -52,20 +54,41 @@ public OpenShiftBinaryRSync(final IClient client) { } @Override - public InputStream sync(final Peer source, final Peer destination, final OpenShiftBinaryOption... options) throws OpenShiftException { + public InputStream sync(final Peer source, final Peer destination, final OpenShiftBinaryOption... options) + throws OpenShiftException { this.source = source; this.destination = destination; - start(options); - // monitor the process completion in a separate thread + this.pod = getPod(source, destination); + Process process = start(options); + waitFor(process); + if (process == null) { + return null; + } + return process.getInputStream(); + } + + private IPod getPod(Peer source, Peer destination) { + if (source.isPod()) { + return source.getPod(); + } else if (destination.isPod()) { + return destination.getPod(); + } else { + return null; + } + } + + protected void waitFor(Process process) { + if (process == null) { + return; + } + this.executor.execute(() -> { try { - this.getProcess().waitFor(); + process.waitFor(); } catch (InterruptedException e) { throw new OpenShiftException("Error occurred while waiting for rsync operation to complete", e); } - }); - return getProcess().getInputStream(); } @Override @@ -138,52 +161,16 @@ public boolean isSupported() { public String getName() { return OpenShiftBinaryRSync.class.getSimpleName(); } - + @Override protected String buildArgs(final List options) { - final StringBuilder argsBuilder = new StringBuilder("rsync "); - argsBuilder.append(getTokenFlag()).append(getServerFlag()); - if(options.contains(OpenShiftBinaryOption.SKIP_TLS_VERIFY)) { - argsBuilder.append(getSkipTlsVerifyFlag()); - } - if(options.contains(OpenShiftBinaryOption.EXCLUDE_GIT_FOLDER)) { - argsBuilder.append(getGitFolderExclusionFlag()); - } - if(options.contains(OpenShiftBinaryOption.NO_PERMS)) { - argsBuilder.append(getNoPermsFlags()); - } - if(options.contains(OpenShiftBinaryOption.DELETE)) { - argsBuilder.append(getDeleteFlags()); - } - argsBuilder.append(source.getParameter()).append(" ") - .append(destination.getParameter()); - return argsBuilder.toString(); - } - - /** - * @return the command-line flag to exclude some files/directories that do - * not need to be synchronized between the remote pod and the local - * deployment directory. - */ - protected String getGitFolderExclusionFlag() { - // no support for multiple exclusion, so excluding '.git' only for now - // see https://github.com/openshift/origin/issues/8223 - return "--exclude=.git "; - } - - /** - * @return the command-line flag to avoid transferring permissions. - */ - protected String getNoPermsFlags() { - return "--no-perms=true "; + return new CommandLineBuilder(RSYNC_COMMAND) + .append( new Token(getClient())) + .append(new Server(getClient())) + .append( new Namespace(pod)) + .append(options) + .append(source) + .append(destination) + .build(); } - - /** - * @return the command-line flag to delete extraneous file from destination directories. - */ - protected String getDeleteFlags() { - return "--delete "; - } - - } diff --git a/src/main/java/com/openshift/restclient/capability/IBinaryCapability.java b/src/main/java/com/openshift/restclient/capability/IBinaryCapability.java index dcb3da98..31d33a1e 100644 --- a/src/main/java/com/openshift/restclient/capability/IBinaryCapability.java +++ b/src/main/java/com/openshift/restclient/capability/IBinaryCapability.java @@ -12,21 +12,24 @@ * @author Andre Dietisheim */ public interface IBinaryCapability extends ICapability { - + + static final OpenShiftBinaryOption SKIP_TLS_VERIFY = new SkipTlsVerify(); + /** - * Optional arguments to pass when running the {@code oc} command. + * Skips the SSL/TLS Verification when using a binary capability */ - public enum OpenShiftBinaryOption { - /** option to skip verifying the certificates during TLS connection establishment. */ - SKIP_TLS_VERIFY, - /** option to exclude the {@code .git} folder in the list of files/folders to synchronize. */ - EXCLUDE_GIT_FOLDER, - /** option to not transfer file permissions. */ - NO_PERMS, - /** option to delete delete extraneous files from destination directories**/ - DELETE + static class SkipTlsVerify implements OpenShiftBinaryOption { + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" --insecure-skip-tls-verify=true"); + } } + static interface OpenShiftBinaryOption { + void append(StringBuilder builder); + } + static final String OPENSHIFT_BINARY_LOCATION = "openshift.restclient.oc.location"; } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrieval.java b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrieval.java index 15bcb3a2..970f87ff 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrieval.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrieval.java @@ -12,8 +12,8 @@ import java.io.InputStream; -import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; +import com.openshift.restclient.capability.ICapability; /** * diff --git a/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java b/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java index bd66832c..6c2ba9ae 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java @@ -12,33 +12,86 @@ import java.io.InputStream; +import org.apache.commons.lang.ArrayUtils; + import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.model.IPod; -/** - * Defines if a pod can support port forwarding - * @author Andre Dietisheim - * - */ public interface IRSyncable extends IBinaryCapability { + + /** option to skip verifying the certificates during TLS connection establishment. */ + static final OpenShiftBinaryOption EXCLUDE_GIT_FOLDER = new GitFolderExclude(); + + /** option to exclude files/folders that match the given expressions **/ + static OpenShiftBinaryOption exclude(String... expressions) { + return new Exclude(expressions); + } + + /** option to not transfer file permissions. */ + static final OpenShiftBinaryOption NO_PERMS = new NoPerms(); + + /** option to delete delete extraneous files from destination directories**/ + static final OpenShiftBinaryOption DELETE = new Delete(); /** - * Synchronize the give {@code destination} with the given {@code source} - * @param source the source of the rsync - * @param destination the destination of the rsync - * @param options the options to pass to the underlying {@code oc rsync} command - * @return the underlying {@link Process} streams to be displayed in a console. + * Excludes some files/directories that match the given patterns when rsync'ing + * the remote pod and the local deployment directory. + * + * @see {@link https://github.com/openshift/origin/issues/8223} */ - InputStream sync(Peer source, Peer destination, OpenShiftBinaryOption... options); + static class Exclude implements OpenShiftBinaryOption { + + private String[] expressions; + + public Exclude(String... expressions) { + this.expressions = expressions; + } + @Override + public void append(StringBuilder arguments) { + if (ArrayUtils.isEmpty(expressions)) { + return; + } + for (String expression : expressions) { + arguments.append(" --exclude=").append(expression); + } + } + } + /** - * Stop rsync'ing, forcibly if necessary. + * Does not sync .git folders when rsync'ing */ - void stop(); + static class GitFolderExclude extends Exclude { + + public GitFolderExclude() { + super(".git"); + } + } + + /** + * Avoids transferring file permissions when rsync'ing + */ + static class NoPerms implements OpenShiftBinaryOption { + + @Override + public void append(StringBuilder arguments) { + arguments.append(" --no-perms=true"); + } + } + + /** + * Deletes extraneous files from destination directories when rsync'ing. + */ + static class Delete implements OpenShiftBinaryOption { + + @Override + public void append(StringBuilder arguments) { + arguments.append(" --delete"); + } + } - public class PodPeer extends Peer { + static class PodPeer extends Peer { - private static final char NAMESPACE_POD_SEPARATOR = '/'; private static final char POD_PATH_SEPARATOR = ':'; private IPod pod; @@ -49,74 +102,89 @@ public PodPeer(String location, IPod pod) { } @Override - public String getParameter() { - return new StringBuilder() - .append('"') - .append(pod.getName()) - .append(POD_PATH_SEPARATOR) - .append(super.getParameter()) - .append('"') - .append(" -n ") - .append(pod.getNamespace()) - .toString(); + public boolean isPod() { + return true; + } + + public IPod getPod() { + return pod; } @Override - public String getLocation() { + protected String getParameter() { return new StringBuilder() - .append(pod.getNamespace()) - .append(NAMESPACE_POD_SEPARATOR) + .append('"') .append(pod.getName()) .append(POD_PATH_SEPARATOR) - .append(super.getParameter()) + .append(getLocation()) + .append('"') .toString(); } - - @Override - public boolean isPod() { - return true; - } } - public class LocalPeer extends Peer { + static class LocalPeer extends Peer { public LocalPeer(String location) { super(location); } + @Override public boolean isPod() { return false; } - + @Override - public String getParameter() { + public IPod getPod() { + return null; + } + + protected String getParameter() { return new StringBuilder() .append('"') - .append(super.getParameter()) + .append(getLocation()) .append('"') .toString(); } } - public abstract class Peer { + abstract static class Peer implements OpenShiftBinaryOption { private String location; - private Peer(String location) { - this.location = location; + private Peer(String path) { + this.location = path; } - public String getParameter() { + protected String getLocation() { return location; } - public String getLocation() { - return getParameter(); - } + protected abstract String getParameter(); public abstract boolean isPod(); + + public abstract IPod getPod(); + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" ").append(getParameter()); + } } + /** + * Synchronizes the give {@code destination} with the given {@code source} + * @param source the source of the rsync + * @param destination the destination of the rsync + * @param options the options to pass to the underlying {@code oc rsync} command + * @return the underlying {@link Process} streams to be displayed in a console. + */ + InputStream sync(Peer source, Peer destination, OpenShiftBinaryOption... options); + + /** + * Stops rsync'ing, forcibly if necessary. + */ + void stop(); + /** * Indicates if the {@link Process} completed or not * @@ -138,6 +206,4 @@ public String getLocation() { * if the current thread is interrupted while waiting */ void await() throws InterruptedException; - - } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java new file mode 100644 index 00000000..2289377c --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java @@ -0,0 +1,107 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.OC_LOCATION; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.POD_NAME; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.POD_NAMESPACE; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.SERVER_URL; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.TOKEN; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockClient; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockPod; +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import java.net.MalformedURLException; +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPodLogRetrieval.PodLogs; +import com.openshift.restclient.IClient; +import com.openshift.restclient.capability.IBinaryCapability; +import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; +import com.openshift.restclient.model.IPod; + +public class OpenShiftBinaryPodLogRetrievalTest { + + private static final String CONTAINER_NAME = "smurfland"; + + private IClient client; + private IPod pod; + + @Before + public void before() throws MalformedURLException { + this.client = mockClient(); + this.pod = mockPod(); + } + + private OpenShiftBinaryPodLogRetrieval.PodLogs createPodLogs(boolean follow, IPod pod, IClient client, OpenShiftBinaryOption... options) { + OpenShiftBinaryPodLogRetrieval.PodLogs podLogs = spy( + new OpenShiftBinaryPodLogRetrieval(pod, client).new PodLogs(client, true, CONTAINER_NAME, options)); + doReturn(OC_LOCATION).when(podLogs).getOpenShiftBinaryLocation(); + doReturn(null).when(podLogs).startProcess(any(ProcessBuilder.class)); + return podLogs; + } + + @Test + public void shouldBuildCommandLineWithoutSkipTlsVerify() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + PodLogs podLogs = createPodLogs(false, pod, client); + // when + podLogs.getLogs(); + // then + verify(podLogs).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList( + OC_LOCATION, + PodLogs.LOGS_COMMAND, + "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), + POD_NAME, + "-n", + POD_NAMESPACE, + "-f", + "-c", + CONTAINER_NAME)); + } + + @Test + public void shouldBuildCommandLineWithSkipTlsVerify() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + PodLogs podLogs = createPodLogs(false, pod, client, IBinaryCapability.SKIP_TLS_VERIFY); + // when + podLogs.getLogs(); + // then + verify(podLogs).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList( + OC_LOCATION, + PodLogs.LOGS_COMMAND, + "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), + "--insecure-skip-tls-verify=true", + POD_NAME, + "-n", + POD_NAMESPACE, + "-f", + "-c", + CONTAINER_NAME)); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java new file mode 100644 index 00000000..32982895 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java @@ -0,0 +1,114 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.OC_LOCATION; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.POD_NAME; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.POD_NAMESPACE; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.SERVER_URL; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.TOKEN; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockClient; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockPod; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockPortPair; +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import java.net.MalformedURLException; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; +import com.openshift.restclient.capability.resources.IPortForwardable.PortPair; +import com.openshift.restclient.model.IPod; + +public class OpenShiftBinaryPortForwardingTest { + + private static final int LOCAL_PORT1 = 8080; + private static final int REMOTE_PORT1 = 80; + + private static final int LOCAL_PORT2 = 8443; + private static final int REMOTE_PORT2 = 43; + + private IPod pod; + + private OpenShiftBinaryPortForwarding binaryPortForwarding; + + @Before + public void before() throws MalformedURLException { + IClient client = mockClient(); + this.pod = mockPod(); + this.binaryPortForwarding = createBinaryPortForwarding(pod, client); + } + + private OpenShiftBinaryPortForwarding createBinaryPortForwarding(IPod pod, IClient client) { + OpenShiftBinaryPortForwarding portForwarding = spy(new OpenShiftBinaryPortForwarding(pod, client)); + doReturn(OC_LOCATION).when(portForwarding).getOpenShiftBinaryLocation(); + doReturn(null).when(portForwarding).startProcess(any(ProcessBuilder.class)); + return portForwarding; + } + + @Test + public void shouldBuildCommandLineWithoutSkipSSL() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + List ports = Arrays.asList( + mockPortPair(LOCAL_PORT2, REMOTE_PORT2)); + // when + binaryPortForwarding.forwardPorts(ports); + // then + verify(binaryPortForwarding).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList( + OC_LOCATION, + OpenShiftBinaryPortForwarding.PORT_FORWARD_COMMAND, + "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), + "-n", + POD_NAMESPACE, + "-p", + POD_NAME, + LOCAL_PORT2 + ":" + REMOTE_PORT2)); + } + + @Test + public void shouldBuildCommandLineWith2PortsSkipSSL() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + List ports = Arrays.asList( + mockPortPair(LOCAL_PORT1, REMOTE_PORT1), + mockPortPair(LOCAL_PORT2, REMOTE_PORT2)); + // when + binaryPortForwarding.forwardPorts(ports, new SkipTlsVerify()); + // then + verify(binaryPortForwarding).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList( + OC_LOCATION, + OpenShiftBinaryPortForwarding.PORT_FORWARD_COMMAND, + "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), + "--insecure-skip-tls-verify=true", + "-n", + POD_NAMESPACE, + "-p", + POD_NAME, + LOCAL_PORT1 + ":" + REMOTE_PORT1, + LOCAL_PORT2 + ":" + REMOTE_PORT2)); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java new file mode 100644 index 00000000..be9ffa44 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java @@ -0,0 +1,139 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.OC_LOCATION; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.POD_NAME; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.POD_NAMESPACE; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.SERVER_URL; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.TOKEN; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockClient; +import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockPod; +import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +import java.net.MalformedURLException; +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; +import com.openshift.restclient.capability.resources.IRSyncable.Exclude; +import com.openshift.restclient.capability.resources.IRSyncable.GitFolderExclude; +import com.openshift.restclient.capability.resources.IRSyncable.LocalPeer; +import com.openshift.restclient.capability.resources.IRSyncable.NoPerms; +import com.openshift.restclient.capability.resources.IRSyncable.Peer; +import com.openshift.restclient.capability.resources.IRSyncable.PodPeer; +import com.openshift.restclient.model.IPod; + +public class OpenShiftBinaryRSyncTest { + + private static final String LOCAL_PATH = "/local/42"; + private static final String POD_PATH = "/deployment/42"; + + private IPod pod; + + private OpenShiftBinaryRSync binaryRsync; + + @Before + public void before() throws MalformedURLException { + IClient client = mockClient(); + this.pod = mockPod(); + this.binaryRsync = createBinaryRSync(client); + } + + private OpenShiftBinaryRSync createBinaryRSync(IClient client) { + OpenShiftBinaryRSync binaryRsync = spy(new OpenShiftBinaryRSync(client)); + doReturn(OC_LOCATION).when(binaryRsync).getOpenShiftBinaryLocation(); + doReturn(null).when(binaryRsync).startProcess(any(ProcessBuilder.class)); + return binaryRsync; + } + + + @Test + public void shouldBuildCommandLineWithoutSkipSSL() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + Peer localPeer = new LocalPeer(LOCAL_PATH); + PodPeer podPeer = new PodPeer(POD_PATH, pod); + // when + binaryRsync.sync(localPeer, podPeer); + // then + verify(binaryRsync).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList( + OC_LOCATION, + OpenShiftBinaryRSync.RSYNC_COMMAND, + "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), + "-n", + POD_NAMESPACE, + LOCAL_PATH, + POD_NAME + ":" + POD_PATH)); + } + + @Test + public void shouldBuildCommandLineWithSkipSSLNoPermsGitExclude() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + Peer localPeer = new LocalPeer(LOCAL_PATH); + PodPeer podPeer = new PodPeer(POD_PATH, pod); + // when + binaryRsync.sync(localPeer, podPeer, + new SkipTlsVerify(), new NoPerms(), new GitFolderExclude()); + // then + verify(binaryRsync).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList( + OC_LOCATION, + OpenShiftBinaryRSync.RSYNC_COMMAND, + "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), + "-n", + POD_NAMESPACE, + "--insecure-skip-tls-verify=true", + "--no-perms=true", + "--exclude=.git", + LOCAL_PATH, + POD_NAME + ":" + POD_PATH)); + } + + @Test + public void shouldBuildCommandLineWithExcludeDotGitDotNpm() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + Peer localPeer = new LocalPeer(LOCAL_PATH); + PodPeer podPeer = new PodPeer(POD_PATH, pod); + // when + binaryRsync.sync(localPeer, podPeer, + new Exclude(".git", ".npm")); + // then + verify(binaryRsync).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList( + OC_LOCATION, + OpenShiftBinaryRSync.RSYNC_COMMAND, + "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), + "-n", + POD_NAMESPACE, + "--exclude=.git", + "--exclude=.npm", + LOCAL_PATH, + POD_NAME + ":" + POD_PATH)); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java index 6e0876b2..92e4e74f 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java @@ -25,7 +25,7 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability; -import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; +import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; import com.openshift.restclient.capability.resources.IPodLogRetrieval; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IResource; @@ -54,7 +54,7 @@ public void testLogRetrieval() { public Exception visit(IPodLogRetrieval cap) { StringBuilder builder = new StringBuilder(); try { - BufferedInputStream os = new BufferedInputStream(cap.getLogs(false, OpenShiftBinaryOption.SKIP_TLS_VERIFY)); + BufferedInputStream os = new BufferedInputStream(cap.getLogs(false, new SkipTlsVerify())); int c; while((c = os.read()) != -1) { builder.append((char)c); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java index c7455561..bb57bf6e 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java @@ -30,7 +30,7 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability; -import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; +import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; import com.openshift.restclient.capability.resources.IPortForwardable; import com.openshift.restclient.capability.resources.IPortForwardable.PortPair; import com.openshift.restclient.model.IProject; @@ -76,7 +76,7 @@ public void testPortForwarding() { @Override public Object visit(IPortForwardable capability) { - capability.forwardPorts(Arrays.asList(new PortPair(8181, port)), OpenShiftBinaryOption.SKIP_TLS_VERIFY); + capability.forwardPorts(Arrays.asList(new PortPair(8181, port)), new SkipTlsVerify()); try { Thread.sleep(5 * IntegrationTestHelper.MILLISECONDS_PER_SECOND); curl(); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java index 5f1c88cb..c92a65fb 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java @@ -10,6 +10,10 @@ * Red Hat, Inc. - initial API and implementation ******************************************************************************/ +import static org.fest.assertions.Assertions.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + import java.io.BufferedReader; import java.io.File; import java.io.IOException; @@ -18,11 +22,6 @@ import java.util.List; import java.util.concurrent.TimeUnit; -import static org.fest.assertions.Assertions.*; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.junit.After; import org.junit.Before; @@ -40,8 +39,8 @@ import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability; +import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; import com.openshift.restclient.capability.IStoppable; -import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; import com.openshift.restclient.capability.resources.IRSyncable; import com.openshift.restclient.capability.resources.IRSyncable.LocalPeer; import com.openshift.restclient.capability.resources.IRSyncable.Peer; @@ -166,7 +165,7 @@ protected void rsyncAndCheck(final String fileName, Peer source, Peer destinatio public List visit(IRSyncable cap) { try { final BufferedReader reader = new BufferedReader(new InputStreamReader( - cap.sync(source, destination, OpenShiftBinaryOption.SKIP_TLS_VERIFY))); + cap.sync(source, destination, new SkipTlsVerify()))); List logs = IOUtils.readLines(reader); // wait until end of 'rsync' cap.await(); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java b/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java new file mode 100644 index 00000000..b5fbf97f --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java @@ -0,0 +1,61 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources.testutils; + +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +import java.net.MalformedURLException; +import java.net.URL; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.authorization.IAuthorizationContext; +import com.openshift.restclient.capability.resources.IPortForwardable.PortPair; +import com.openshift.restclient.model.IPod; + +public class BinaryCapabilityTestMocks { + + public static final String SERVER_URL = "https://localhost:8443"; + public static final String TOKEN = "phWDXIqSspYBZARPQIzqaevHGDIxduQGbhcZuwj48EI"; + + public static final String OC_LOCATION = "/path/to/oc"; + + public static final String POD_NAME = "papa-smurf"; + public static final String POD_NAMESPACE = "the-smurfs"; + + public static IClient mockClient() throws MalformedURLException { + IClient client = mock(IClient.class); + doReturn(new URL(SERVER_URL)).when(client).getBaseURL(); + IAuthorizationContext context = mockAuthorizationContext(); + doReturn(context).when(client).getAuthorizationContext(); + return client; + } + + private static IAuthorizationContext mockAuthorizationContext() { + IAuthorizationContext context = mock(IAuthorizationContext.class); + doReturn(TOKEN).when(context).getToken(); + return context; + } + + public static IPod mockPod() { + IPod pod = mock(IPod.class); + doReturn(POD_NAME).when(pod).getName(); + doReturn(POD_NAMESPACE).when(pod).getNamespace(); + return pod; + } + + public static PortPair mockPortPair(int localPort, int remotePort) { + PortPair ports = mock(PortPair.class); + doReturn(localPort).when(ports).getLocalPort(); + doReturn(remotePort).when(ports).getRemotePort(); + return ports; + } +} From 14e2269e9fd637019ca1d8a5f771f77946171308 Mon Sep 17 00:00:00 2001 From: Thomas Krause Date: Mon, 12 Mar 2018 15:56:17 +0100 Subject: [PATCH 109/258] #314 created INamespace, implemented Namespace model with test; created ResourceKind for Namespace and registered it in the ResourceFactory. --- .../internal/restclient/DefaultClient.java | 6 +- .../internal/restclient/ResourceFactory.java | 19 +----- .../internal/restclient/URLBuilder.java | 2 +- .../api/capabilities/ScaleCapability.java | 4 +- .../AbstractOpenShiftBinaryCapability.java | 2 +- .../resources/AssociationCapability.java | 2 +- .../capability/resources/BuildTrigger.java | 4 +- .../resources/DeployCapability.java | 2 +- .../resources/DeploymentTrigger.java | 4 +- .../resources/PodLogRetrievalAsync.java | 2 +- .../ProjectTemplateListCapability.java | 2 +- .../resources/ProjectTemplateProcessing.java | 2 +- .../restclient/model/BuildConfig.java | 2 +- .../restclient/model/KubernetesResource.java | 24 +++++-- .../internal/restclient/model/Namespace.java | 68 +++++++++++++++++++ .../internal/restclient/model/Project.java | 7 +- .../internal/restclient/model/Service.java | 2 +- .../openshift/restclient/ResourceKind.java | 1 + .../restclient/model/INamespace.java | 36 ++++++++++ .../openshift/restclient/model/IResource.java | 11 ++- .../DefaultClientFilterIntegrationTest.java | 14 ++-- .../DefaultClientIntegrationTest.java | 10 +-- .../restclient/ResourceFactoryTest.java | 2 +- .../internal/restclient/URLBuilderTest.java | 2 +- .../resources/DeployCapabilityTest.java | 2 +- .../DeploymentConfigTraceabilityTest.java | 3 +- .../resources/DeploymentTraceabilityTest.java | 3 +- ...ftBinaryPortForwardingIntegrationTest.java | 2 +- .../ProjectTemplateProcessingTest.java | 2 +- .../resources/TemplateTraceabilityTest.java | 3 +- .../testutils/BinaryCapabilityTestMocks.java | 2 +- .../restclient/model/NamespaceTest.java | 42 ++++++++++++ .../restclient/model/v1/ResourceTest.java | 4 +- .../restclient/model/v1/ServiceTest.java | 4 +- .../model/v1/UnrecognizedResourceTest.java | 2 +- .../restclient/model/MocksFactory.java | 4 +- .../openshift/restclient/utils/Samples.java | 3 +- .../samples/openshift3/v1_namespace.json | 28 ++++++++ 38 files changed, 253 insertions(+), 81 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/model/Namespace.java create mode 100644 src/main/java/com/openshift/restclient/model/INamespace.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/NamespaceTest.java create mode 100644 src/test/resources/samples/openshift3/v1_namespace.json diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 9279b638..15ad0cb2 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -184,7 +184,7 @@ public Collection create(IList list, String namespace){ @Override public T create(T resource) { - return create(resource, resource.getNamespace()); + return create(resource, resource.getNamespaceName()); } @@ -312,12 +312,12 @@ public Request.Builder newRequestBuilderTo(String endpoint,String acceptMediaTyp @Override public T update(T resource) { - return execute(HttpMethod.PUT, resource.getKind(), resource.getNamespace(), resource.getName(), null, resource); + return execute(HttpMethod.PUT, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, resource); } @Override public void delete(T resource) { - execute(HttpMethod.DELETE, resource.getKind(), resource.getNamespace(), resource.getName(), null, resource); + execute(HttpMethod.DELETE, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, resource); } diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 2fdba9b6..bbabd12d 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -19,28 +19,12 @@ import java.util.Map; import java.util.Optional; +import com.openshift.internal.restclient.model.*; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; -import com.openshift.internal.restclient.model.Build; -import com.openshift.internal.restclient.model.BuildConfig; -import com.openshift.internal.restclient.model.ConfigMap; -import com.openshift.internal.restclient.model.DeploymentConfig; -import com.openshift.internal.restclient.model.ImageStream; -import com.openshift.internal.restclient.model.KubernetesEvent; -import com.openshift.internal.restclient.model.KubernetesResource; -import com.openshift.internal.restclient.model.LimitRange; import com.openshift.internal.restclient.model.volume.PersistentVolume; -import com.openshift.internal.restclient.model.Pod; -import com.openshift.internal.restclient.model.Project; -import com.openshift.internal.restclient.model.ReplicationController; -import com.openshift.internal.restclient.model.ResourceQuota; -import com.openshift.internal.restclient.model.Route; -import com.openshift.internal.restclient.model.Secret; -import com.openshift.internal.restclient.model.Service; -import com.openshift.internal.restclient.model.ServiceAccount; -import com.openshift.internal.restclient.model.Status; import com.openshift.internal.restclient.model.authorization.OpenshiftPolicy; import com.openshift.internal.restclient.model.authorization.OpenshiftRole; import com.openshift.internal.restclient.model.authorization.PolicyBinding; @@ -84,6 +68,7 @@ public class ResourceFactory implements IResourceFactory{ IMPL_MAP.put(ResourceKind.IMAGE_STREAM, ImageStream.class); IMPL_MAP.put(ResourceKind.IMAGE_STREAM_IMPORT, ImageStreamImport.class); IMPL_MAP.put(ResourceKind.LIST, com.openshift.internal.restclient.model.List.class); + IMPL_MAP.put(ResourceKind.NAMESPACE, Namespace.class); IMPL_MAP.put(ResourceKind.OAUTH_ACCESS_TOKEN, OAuthAccessToken.class); IMPL_MAP.put(ResourceKind.OAUTH_AUTHORIZE_TOKEN, OAuthAuthorizeToken.class); IMPL_MAP.put(ResourceKind.OAUTH_CLIENT, OAuthClient.class); diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index 4045fd97..5058e6fe 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -99,7 +99,7 @@ public URLBuilder resource(IResource resource) { if (resource == null) return this; this.name = resource.getName(); kind(resource.getKind()); - namespace(resource.getNamespace()); + namespace(resource.getNamespaceName()); return this; } diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java index bc021707..3f06d748 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java @@ -59,9 +59,9 @@ public String getName() { @Override public IScale scaleTo(int replicas) { replicas = replicas >= MIN_VALUE ? replicas : MIN_VALUE; - IScale arg = (IScale) factory.stubKind(ARG_KINDS.get(rc.getKind()), Optional.of(rc.getName()), Optional.of(rc.getNamespace())); + IScale arg = (IScale) factory.stubKind(ARG_KINDS.get(rc.getKind()), Optional.of(rc.getName()), Optional.of(rc.getNamespaceName())); arg.setSpecReplicas(replicas); - return (IScale) client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespace(), rc.getName(), CAPABILITY, null, arg, + return (IScale) client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespaceName(), rc.getName(), CAPABILITY, null, arg, Collections.emptyMap()); } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 195ad490..2e911c82 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -89,7 +89,7 @@ public void append(StringBuilder commandLine) { if (resource == null) { return; } - commandLine.append(" -n ").append(resource.getNamespace()); + commandLine.append(" -n ").append(resource.getNamespaceName()); } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java index 0a394695..ae41c99d 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java @@ -45,6 +45,6 @@ public boolean isSupported() { protected T getAssociatedResource(String kind){ if(!isSupported()) return null; String name = getResource().getAnnotation(getAnnotationKey()); - return getClient().get(kind, name, getResource().getNamespace()); + return getClient().get(kind, name, getResource().getNamespaceName()); } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java index ebb76878..182f5a38 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java @@ -71,14 +71,14 @@ public IBuild trigger() { request.setCommitId(commitId); causes.forEach(c->request.addBuildCause(c)); envVars.forEach((name, value)->request.setEnvironmentVariable(name, value)); - return client.create(resource.getKind(), resource.getNamespace(), resource.getName(), subresource, request); + return client.create(resource.getKind(), resource.getNamespaceName(), resource.getName(), subresource, request); } @Override @Deprecated public IBuild trigger(String commitId) { IBuildRequest request = client.getResourceFactory().stub(ResourceKind.BUILD_REQUEST, resource.getName()); request.setCommitId(commitId); - return client.create(resource.getKind(), resource.getNamespace(), resource.getName(), subresource, request); + return client.create(resource.getKind(), resource.getNamespaceName(), resource.getName(), subresource, request); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java index c0261387..b456cc81 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java @@ -55,7 +55,7 @@ public void deploy() { try { final String deploymentName = getLatestDeploymentName(); LOG.debug("Attempting to deploy latest deployment for config %s. Loading deployment: %s", config.getName(), deploymentName); - IReplicationController deployment = client.get(ResourceKind.REPLICATION_CONTROLLER, deploymentName, config.getNamespace()); + IReplicationController deployment = client.get(ResourceKind.REPLICATION_CONTROLLER, deploymentName, config.getNamespaceName()); final String status = getStatusFor(deployment); if(!COMPLETED_STATES.contains(status)) { LOG.debug("Skipping deployment because deployment status %s for %s is not in %s", new Object [] {status, deploymentName, COMPLETED_STATES}); diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java index 26bb7c98..b1e070ec 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java @@ -65,12 +65,12 @@ public IDeploymentConfig trigger() { request.setForce(force); request.setLatest(latest); request.setName(resourceName); - return (IDeploymentConfig) client.execute(client.getResourceFactory(), IHttpConstants.POST, config.getKind(), config.getNamespace(), config.getName(), DEPLOYMENT_ENDPOINT, null, request, + return (IDeploymentConfig) client.execute(client.getResourceFactory(), IHttpConstants.POST, config.getKind(), config.getNamespaceName(), config.getName(), DEPLOYMENT_ENDPOINT, null, request, Collections.emptyMap()); } else { IDeployCapability deployer = config.getCapability(IDeployCapability.class); deployer.deploy(); - return client.get(ResourceKind.DEPLOYMENT_CONFIG, config.getName(), config.getNamespace()); + return client.get(ResourceKind.DEPLOYMENT_CONFIG, config.getName(), config.getNamespaceName()); } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java index 78ca230f..8aa2cba8 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java @@ -84,7 +84,7 @@ public IStoppable start(IPodLogListener listener, Options options) { OkHttpClient okClient = client.adapt(OkHttpClient.class); final String endpoint = new URLBuilder(client.getBaseURL(), mapper) .kind(pod.getKind()) - .namespace(pod.getNamespace()) + .namespace(pod.getNamespaceName()) .name(pod.getName()) .subresource(CAPABILITY) .addParameters(parameters) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java index 6cef47f8..7f8d0738 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java @@ -39,7 +39,7 @@ public String getName() { @Override public Collection getTemplates() { - return client.list(ResourceKind.TEMPLATE, project.getNamespace()); + return client.list(ResourceKind.TEMPLATE, project.getNamespaceName()); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java index db3fdcdb..c2d8876c 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java @@ -33,7 +33,7 @@ public ProjectTemplateProcessing(IProject project, IClient client) { if(client != null && client.supports(ITemplateProcessing.class)) { serverCapability = client.getCapability(ITemplateProcessing.class); this.client = client; - this.namespace = project.getNamespace(); + this.namespace = project.getNamespaceName(); } } diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index 42783ba1..dd18faa9 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -81,7 +81,7 @@ public List getBuildTriggers() { List triggers = new ArrayList(); if (has(BUILDCONFIG_TRIGGERS)) { List list = get(BUILDCONFIG_TRIGGERS).asList(); - final String url = getClient() != null && StringUtils.isNotEmpty(getNamespace()) ? getClient().getResourceURI(this) : ""; + final String url = getClient() != null && StringUtils.isNotEmpty(getNamespaceName()) ? getClient().getResourceURI(this) : ""; for (ModelNode node : list) { String type = node.get(TYPE).asString(); switch (type) { diff --git a/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java b/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java index 242cf34d..7a4a16b2 100644 --- a/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java +++ b/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java @@ -13,6 +13,7 @@ import java.util.Map; import java.util.Set; +import com.openshift.restclient.model.INamespace; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; @@ -39,6 +40,7 @@ public class KubernetesResource implements IResource, ResourcePropertyKeys { private Map, ICapability> capabilities = new HashMap, ICapability>(); private Map propertyKeys; private IProject project; + private INamespace namespace; /** * @@ -96,11 +98,19 @@ public R accept(CapabilityVisitor visitor, R un @Override public IProject getProject() { if(this.project == null) { - this.project = client.get(ResourceKind.PROJECT, getNamespace(), ""); + this.project = client.get(ResourceKind.PROJECT, getNamespaceName(), ""); } return this.project; } + @Override + public INamespace getNamespace() { + if (this.namespace == null) { + this.namespace = client.get(ResourceKind.NAMESPACE, getNamespaceName(), ""); + } + return this.namespace; + } + @Override public Map getAnnotations() { return asMap(ANNOTATIONS); @@ -148,7 +158,7 @@ public ModelNode getNode(){ public void refresh(){ //TODO find better way to bypass serialization/deserialization - this.node = ModelNode.fromJSONString(client.get(getKind(), getName(), getNamespace()).toString()); + this.node = ModelNode.fromJSONString(client.get(getKind(), getName(), getNamespaceName()).toString()); } @Override @@ -175,7 +185,7 @@ public void setName(String name) { } @Override - public String getNamespace(){ + public String getNamespaceName(){ return asString(METADATA_NAMESPACE); } @@ -310,7 +320,7 @@ public String toPrettyString(){ @Override public int hashCode() { - String namespace = getNamespace(); + String namespace = getNamespaceName(); String name = getName(); String kind = getKind(); final int prime = 31; @@ -336,12 +346,12 @@ else if (getClass() != obj.getClass()) return false; } } - if (getNamespace() != null) { - if(!getNamespace().equals(other.getNamespace())) { + if (getNamespaceName() != null) { + if(!getNamespaceName().equals(other.getNamespaceName())) { return false; } } else { - if (other.getNamespace() != null) { + if (other.getNamespaceName() != null) { return false; } } diff --git a/src/main/java/com/openshift/internal/restclient/model/Namespace.java b/src/main/java/com/openshift/internal/restclient/model/Namespace.java new file mode 100644 index 00000000..3311b9c4 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/Namespace.java @@ -0,0 +1,68 @@ +package com.openshift.internal.restclient.model; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.INamespace; +import com.openshift.restclient.model.IResource; +import org.jboss.dmr.ModelNode; + +import java.util.List; +import java.util.Map; + +import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; + +public class Namespace extends KubernetesResource implements INamespace { + + private static final String ANNOTATION_DISPLAY_NAME = "openshift.io/display-name"; + private static final String ANNOTATION_DESCRIPTION = "openshift.io/description"; + private static final String ANNOTATION_REQUESTER = "openshift.io/requester"; + + public Namespace(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + initializeCapabilities(getModifiableCapabilities(), this, getClient()); + } + + @Override + public List getResources(String kind) { + return null; + } + + @Override + public Namespace getNamespace() { + return this; + } + + @Override + public String getNamespaceName() { + return this.getName(); + } + + @Override + public String getDisplayName() { + return getAnnotation(ANNOTATION_DISPLAY_NAME); + } + + @Override + public void setDisplayName(String displayName) { + setAnnotation(ANNOTATION_DISPLAY_NAME, displayName); + } + + @Override + public String getDescription() { + return getAnnotation(ANNOTATION_DESCRIPTION); + } + + @Override + public void setDescription(String description) { + setAnnotation(ANNOTATION_DESCRIPTION, description); + } + + @Override + public String getRequester() { + return getAnnotation(ANNOTATION_REQUESTER); + } + + @Override + public void setRequest(String requester) { + setAnnotation(ANNOTATION_REQUESTER, requester); + } +} diff --git a/src/main/java/com/openshift/internal/restclient/model/Project.java b/src/main/java/com/openshift/internal/restclient/model/Project.java index 7d28ae79..9e200a09 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Project.java +++ b/src/main/java/com/openshift/internal/restclient/model/Project.java @@ -35,17 +35,16 @@ public Project(ModelNode node, IClient client, Map propertyKe initializeCapabilities(getModifiableCapabilities(), this, getClient()); } - @Override public IProject getProject() { return this; } @Override - public String getNamespace() { - if(StringUtils.isEmpty(super.getNamespace())) + public String getNamespaceName() { + if(StringUtils.isEmpty(super.getNamespaceName())) return getName(); - return super.getNamespace(); + return super.getNamespaceName(); } diff --git a/src/main/java/com/openshift/internal/restclient/model/Service.java b/src/main/java/com/openshift/internal/restclient/model/Service.java index af3b1224..6b28240b 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Service.java +++ b/src/main/java/com/openshift/internal/restclient/model/Service.java @@ -152,7 +152,7 @@ public String getClusterIP() { @Override public List getPods() { if(getClient() == null) return new ArrayList(); - return getClient().list(ResourceKind.POD, getNamespace(), getSelector()); + return getClient().list(ResourceKind.POD, getNamespaceName(), getSelector()); } @Override diff --git a/src/main/java/com/openshift/restclient/ResourceKind.java b/src/main/java/com/openshift/restclient/ResourceKind.java index 390f9a8a..17d7a392 100644 --- a/src/main/java/com/openshift/restclient/ResourceKind.java +++ b/src/main/java/com/openshift/restclient/ResourceKind.java @@ -29,6 +29,7 @@ public final class ResourceKind { public static final String IMAGE_STREAM = "ImageStream"; public static final String IMAGE_STREAM_TAG = "ImageStreamTag"; public static final String IMAGE_STREAM_IMPORT = "ImageStreamImport"; + public static final String NAMESPACE = "Namespace"; public static final String OAUTH_ACCESS_TOKEN = "OAuthAccessToken"; public static final String OAUTH_AUTHORIZE_TOKEN = "OAuthAuthorizeToken"; public static final String OAUTH_CLIENT = "OAuthClient"; diff --git a/src/main/java/com/openshift/restclient/model/INamespace.java b/src/main/java/com/openshift/restclient/model/INamespace.java new file mode 100644 index 00000000..abcb90a6 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/INamespace.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ +package com.openshift.restclient.model; + +import java.util.List; + +/** + * @author Thomas Krause + */ +public interface INamespace extends IResource { + + /** + * Retrieves resource of the given kind that are scoped to this project + * @param kind the resource kind to retrieve + * @return a list of {@link INamespace}s + */ + List getResources(String kind); + + String getDisplayName(); + + void setDisplayName(String displayName); + + String getDescription(); + + void setDescription(String description); + + String getRequester(); + + void setRequest(String requester); +} diff --git a/src/main/java/com/openshift/restclient/model/IResource.java b/src/main/java/com/openshift/restclient/model/IResource.java index 304d7e4b..9743945a 100644 --- a/src/main/java/com/openshift/restclient/model/IResource.java +++ b/src/main/java/com/openshift/restclient/model/IResource.java @@ -47,14 +47,19 @@ public interface IResource extends ICapable, Annotatable, IAnnotatable, JSONSeri * Returns the scope of this resource * @return */ - String getNamespace(); + String getNamespaceName(); /** - * Return the project of the resource which - * corresponds to the namespace + * Return the project of the resource * @return */ IProject getProject(); + + /** + * Return the namespace of the resource + * @return + */ + INamespace getNamespace(); /** * Retrieves the labels associated with the resource diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java index 2ba36f6c..5410df7f 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java @@ -70,7 +70,7 @@ public static void cleanup() { @Test public void testFilteringWithOneLabel() { - List list = client.list(BUILD_CONFIG, project.getNamespace(), new HashMap() {{ + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), new HashMap() {{ put("foo", "yes"); }}); @@ -83,7 +83,7 @@ public void testFilteringWithOneLabel() { @Test public void testFilteringWithTwoLabel() { - List list = client.list(BUILD_CONFIG, project.getNamespace(), new HashMap() {{ + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), new HashMap() {{ put("foo", "yes"); put("bar", "no"); }}); @@ -95,7 +95,7 @@ public void testFilteringWithTwoLabel() { @Test public void testFilteringWithLabelExist() { - List list = client.list(BUILD_CONFIG, project.getNamespace(), "baz"); + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "baz"); assertEquals(1, list.size()); IBuildConfig bc = list.get(0); @@ -105,7 +105,7 @@ public void testFilteringWithLabelExist() { @Test public void testFilteringWithLabelNotExist() { List list = - client.list(BUILD_CONFIG, project.getNamespace(), "!baz"); + client.list(BUILD_CONFIG, project.getNamespaceName(), "!baz"); Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); @@ -118,7 +118,7 @@ public void testFilteringWithLabelNotExist() { @Test public void testFilteringWithLabelNotEqualTo() { - List list = client.list(BUILD_CONFIG, project.getNamespace(), "foo != yes"); + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "foo != yes"); Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); @@ -129,7 +129,7 @@ public void testFilteringWithLabelNotEqualTo() { @Test public void testFilteringWithLabelCombinedLabelQuery() { - List list = client.list(BUILD_CONFIG, project.getNamespace(), "foo,bar=no"); + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "foo,bar=no"); assertEquals(1, list.size()); IBuildConfig bc = list.get(0); @@ -142,7 +142,7 @@ private static IBuildConfig createBuildConfigWithLabels(IProject project, String IBuildConfig bc = new BuildConfigBuilder(client) .named(name) - .inNamespace(project.getNamespace()) + .inNamespace(project.getNamespaceName()) .usingSourceStrategy() .fromDockerImage("centos/ruby-22-centos7:latest") .end() diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index 74c35479..8ba8f1fb 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -88,7 +88,7 @@ public void testListTemplates(){ template = factory.stub(ResourceKind.TEMPLATE, "mytemplate"); project = (IProject) client.create(projectRequest); - template = client.create(template, project.getNamespace()); + template = client.create(template, project.getNamespaceName()); assertNotNull("Exp. the template to be found but was not", waitForResource(client, ResourceKind.TEMPLATE, project.getName(), template.getName(), 5 * MILLISECONDS_PER_SECOND)); @@ -153,12 +153,12 @@ public void testResourceLifeCycle() { List projects = client.list(ResourceKind.PROJECT); LOG.debug(String.format("Listed projects: %s", projects)); - LOG.debug(String.format("Listing services with namespace: %s", project.getNamespace())); - List services = client.list(ResourceKind.SERVICE, project.getNamespace()); + LOG.debug(String.format("Listing services with namespace: %s", project.getNamespaceName())); + List services = client.list(ResourceKind.SERVICE, project.getNamespaceName()); LOG.debug(String.format("Listed services: %s", services)); LOG.debug(String.format("Getting service: %s", otherService.getName())); - Service s = client.get(ResourceKind.SERVICE, otherService.getName(), otherService.getNamespace()); + Service s = client.get(ResourceKind.SERVICE, otherService.getName(), otherService.getNamespaceName()); LOG.debug(String.format("Retrieved service: %s", s.getName())); assertEquals("Expected there to be only one service returned", 1, services.size()); @@ -175,7 +175,7 @@ public void testResourceLifeCycle() { .end() .toImageStreamTag("foo/bar:latest") .build(); - bc = client.create(bc, project.getNamespace()); + bc = client.create(bc, project.getNamespaceName()); LOG.debug(String.format("Created bc: %s", bc.getName())); LOG.debug(String.format("Trying to delete bc: %s", bc.getName())); client.delete(bc); diff --git a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java index 064307a8..a3afe045 100644 --- a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java +++ b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java @@ -58,7 +58,7 @@ public void testV1Beta3Implementations() { public void testStubWithNamespace() { IService service = factory.stub(ResourceKind.SERVICE, "foo", "bar"); assertEquals("foo", service.getName()); - assertEquals("bar", service.getNamespace()); + assertEquals("bar", service.getNamespaceName()); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java index 0d1e84dd..b16b4c94 100644 --- a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java @@ -124,7 +124,7 @@ private IResource givenAResource(String kind, KubernetesAPIVersion version, Stri IResource resource = mock(IResource.class); when(resource.getApiVersion()).thenReturn(version.toString()); when(resource.getKind()).thenReturn(kind); - when(resource.getNamespace()).thenReturn(namespace); + when(resource.getNamespaceName()).thenReturn(namespace); return resource; } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java index 378b564b..37dd74a1 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java @@ -44,7 +44,7 @@ public class DeployCapabilityTest { @Before public void setUp() throws Exception { cap = new DeployCapability(config, client); - when(config.getNamespace()).thenReturn(NAMESPACE); + when(config.getNamespaceName()).thenReturn(NAMESPACE); when(config.getName()).thenReturn(NAME); givenDeployConfigIsVersion(config, VERSION); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java index 471a07a7..66578460 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java @@ -18,7 +18,6 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import com.openshift.internal.restclient.capability.resources.DeploymentConfigTraceability; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IDeploymentConfig; @@ -40,7 +39,7 @@ public class DeploymentConfigTraceabilityTest { public void setUp(){ capability = new DeploymentConfigTraceability(resource, client); - when(resource.getNamespace()).thenReturn("mynamespace"); + when(resource.getNamespaceName()).thenReturn("mynamespace"); when(client.get(eq(ResourceKind.DEPLOYMENT_CONFIG), eq("foobar"), eq("mynamespace"))) .thenReturn(config); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java index 8da71f80..4461f1cf 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java @@ -17,7 +17,6 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import com.openshift.internal.restclient.capability.resources.DeploymentTraceability; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IPod; @@ -39,7 +38,7 @@ public class DeploymentTraceabilityTest { public void setUp(){ capability = new DeploymentTraceability(resource, client); - when(resource.getNamespace()).thenReturn("mynamespace"); + when(resource.getNamespaceName()).thenReturn("mynamespace"); when(client.get(eq(ResourceKind.REPLICATION_CONTROLLER), eq("foobar"), eq("mynamespace"))) .thenReturn(deployment); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java index bb57bf6e..5f6e6e52 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java @@ -64,7 +64,7 @@ public void testPortForwarding() { pod = (Pod) client.create(pod); pod = (Pod) IntegrationTestHelper.waitForResource(client, pod.getKind(), - pod.getNamespace(), + pod.getNamespaceName(), pod.getName(), 5 * IntegrationTestHelper.MILLISECONDS_PER_MIN, new PodStatusRunningConditional()); assertNotNull("The test timed out before the pod was in a running state", pod); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java index e810df6b..39fb548b 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java @@ -45,7 +45,7 @@ public class ProjectTemplateProcessingTest { @Before public void setUp() throws Exception { - when(project.getNamespace()).thenReturn(NAMESPACE); + when(project.getNamespaceName()).thenReturn(NAMESPACE); when(client.supports(eq(ITemplateProcessing.class))).thenReturn(true); when(client.getCapability(eq(ITemplateProcessing.class))).thenReturn(serverCapability); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java index b18373d3..dc4065f9 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java @@ -17,7 +17,6 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import com.openshift.internal.restclient.capability.resources.TemplateTraceability; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IResource; @@ -35,7 +34,7 @@ public class TemplateTraceabilityTest { @Before public void setUp(){ capability = new TemplateTraceability(resource); - when(resource.getNamespace()).thenReturn("mynamespace"); + when(resource.getNamespaceName()).thenReturn("mynamespace"); when(resource.getKind()).thenReturn(ResourceKind.TEMPLATE); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java b/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java index b5fbf97f..9ffc5cfc 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java @@ -48,7 +48,7 @@ private static IAuthorizationContext mockAuthorizationContext() { public static IPod mockPod() { IPod pod = mock(IPod.class); doReturn(POD_NAME).when(pod).getName(); - doReturn(POD_NAMESPACE).when(pod).getNamespace(); + doReturn(POD_NAMESPACE).when(pod).getNamespaceName(); return pod; } diff --git a/src/test/java/com/openshift/internal/restclient/model/NamespaceTest.java b/src/test/java/com/openshift/internal/restclient/model/NamespaceTest.java new file mode 100644 index 00000000..9713a437 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/NamespaceTest.java @@ -0,0 +1,42 @@ +package com.openshift.internal.restclient.model; + +import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.INamespace; +import com.openshift.restclient.utils.Samples; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +public class NamespaceTest { + + private static final String VERSION = "v1"; + private INamespace namespace; + + @Before + public void setUp(){ + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_NAMESPACE.getContentAsString()); + namespace = new Namespace(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, + ResourceKind.NAMESPACE)); + } + + @Test + public void testGetDisplayName() { + assertEquals("OpenShift 3 Sample", namespace.getDisplayName()); + } + + @Test + public void testGetDescription() { + assertEquals("This is an example namespace to demonstrate OpenShift v3", namespace.getDescription()); + } + + @Test + public void testGetRequester() { + assertEquals("admin", namespace.getRequester()); + } +} \ No newline at end of file diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ResourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ResourceTest.java index 6a5f3a28..6ccf4eea 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ResourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ResourceTest.java @@ -40,7 +40,7 @@ public void setup(){ @Test public void getNamespace(){ - assertEquals("test", resource.getNamespace()); + assertEquals("test", resource.getNamespaceName()); } @Test @@ -49,7 +49,7 @@ public void getNamespaceWhenUndefinedShouldReturnEmptyString(){ ModelNode node = ModelNode.fromJSONString(Samples.V1_SERVICE.getContentAsString()); node.get("metadata").remove("namespace"); resource = new Build(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PROJECT)); - assertEquals("", resource.getNamespace()); + assertEquals("", resource.getNamespaceName()); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java index 460ccb7a..ba99169f 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java @@ -104,7 +104,7 @@ public void testSetName() { @Test public void testGetNamespace() { - assertEquals("test", service.getNamespace()); + assertEquals("test", service.getNamespaceName()); } @Test @@ -113,7 +113,7 @@ public void testSetNamespace() { // operation ((Service) service).setNamespace("foo"); // verification - assertEquals("foo", service.getNamespace()); + assertEquals("foo", service.getNamespaceName()); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java index a56ca701..1c590a9d 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java @@ -40,7 +40,7 @@ public void testGetName() { @Test public void testGetNamespace() { - assertEquals("test", service.getNamespace()); + assertEquals("test", service.getNamespaceName()); } @Test diff --git a/src/test/java/com/openshift/restclient/model/MocksFactory.java b/src/test/java/com/openshift/restclient/model/MocksFactory.java index 2285c29f..d4da4827 100644 --- a/src/test/java/com/openshift/restclient/model/MocksFactory.java +++ b/src/test/java/com/openshift/restclient/model/MocksFactory.java @@ -48,7 +48,7 @@ public IClient getClient() { public T mock(Class klass, String namespace, String name) { T mock = mock(klass); - when(mock.getNamespace()).thenReturn(namespace); + when(mock.getNamespaceName()).thenReturn(namespace); when(mock.getName()).thenReturn(name); return mock; } @@ -63,7 +63,7 @@ public T mock(Class klass) { T mock = Mockito.mock(klass); when(mock.getName()).thenReturn("a" + klass.getSimpleName()); when(mock.getApiVersion()).thenReturn(version); - when(mock.getNamespace()).thenReturn("aNamespace"); + when(mock.getNamespaceName()).thenReturn("aNamespace"); when(mock.getKind()).thenReturn(klass.getSimpleName().substring(1)); return mock; } diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index ba584543..13613969 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -42,7 +42,8 @@ public enum Samples { V1_IMAGE_STREAM("openshift3/v1_image_stream.json"), V1_IMAGE_STREAM_IMPORT("openshift3/v1_image_stream_import.json"), V1_BUILD("openshift3/v1_build.json"), - V1_OBJECT_REF("openshift3/v1_objectref.json"), + V1_OBJECT_REF("openshift3/v1_objectref.json"), + V1_NAMESPACE("openshift3/v1_namespace.json"), V1_POD("openshift3/v1_pod.json"), V1_PROJECT("openshift3/v1_project.json"), V1_PROJECT_REQUEST("openshift3/v1_project_request.json"), diff --git a/src/test/resources/samples/openshift3/v1_namespace.json b/src/test/resources/samples/openshift3/v1_namespace.json new file mode 100644 index 00000000..ced5a5d0 --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_namespace.json @@ -0,0 +1,28 @@ +{ + "kind": "Namespace", + "apiVersion": "v1", + "metadata": { + "annotations": { + "openshift.io/description": "This is an example namespace to demonstrate OpenShift v3", + "openshift.io/display-name": "OpenShift 3 Sample", + "openshift.io/requester": "admin", + "openshift.io/sa.scc.mcs": "s0:c8,c2", + "openshift.io/sa.scc.supplemental-groups": "1000060000/10000", + "openshift.io/sa.scc.uid-range": "1000060000/10000" + }, + "creationTimestamp": "2018-03-09T21:19:53Z", + "name": "test", + "resourceVersion": "292005", + "selfLink": "/osapi/v1beta3/namespaces/test", + "uid": "9bf521ab-23df-11e8-ba22-e2a386cca5ea" + }, + "spec": { + "finalizers": [ + "openshift.io/origin", + "kubernetes" + ] + }, + "status": { + "phase": "Active" + } +} \ No newline at end of file From 59058ddd4606ef0c6b2aa760887137fc5b20eeb7 Mon Sep 17 00:00:00 2001 From: Thomas Krause Date: Mon, 12 Mar 2018 15:58:13 +0100 Subject: [PATCH 110/258] #314 implemented missing method --- .../com/openshift/internal/restclient/model/Namespace.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Namespace.java b/src/main/java/com/openshift/internal/restclient/model/Namespace.java index 3311b9c4..6ac5f7ed 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Namespace.java +++ b/src/main/java/com/openshift/internal/restclient/model/Namespace.java @@ -5,6 +5,7 @@ import com.openshift.restclient.model.IResource; import org.jboss.dmr.ModelNode; +import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -23,7 +24,8 @@ public Namespace(ModelNode node, IClient client, Map property @Override public List getResources(String kind) { - return null; + if(getClient() == null) return new ArrayList<>(); + return getClient().list(kind, getName()); } @Override From ad5c7c73ed2b0ad86d67e3e9efbd8cd4ae03b07c Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 19 Mar 2018 14:38:19 +0100 Subject: [PATCH 111/258] bumping to 6.0.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 80ea2b19..fc0cea5e 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.0.0-SNAPSHOT + 6.0.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From bfb232b457b802add321f6124f03a4708769f3fc Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 19 Mar 2018 14:59:27 +0100 Subject: [PATCH 112/258] bump to 6.0.1-SNAPSHOT after release of 6.0.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fc0cea5e..49ee68f3 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.0.0.Final + 6.0.1-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 0588113acfa8147a082f8a29fc98be5da12ed522 Mon Sep 17 00:00:00 2001 From: Jeff Cantrill Date: Fri, 20 Apr 2018 12:16:20 -0400 Subject: [PATCH 113/258] Add checkstyle and fix violations --- .gitignore | 1 + checkstyle.xml | 260 ++++++ pom.xml | 701 +++++++------- .../internal/restclient/APIModelVersion.java | 34 +- .../internal/restclient/ApiTypeMapper.java | 712 +++++++------- .../internal/restclient/DefaultClient.java | 867 +++++++++--------- .../restclient/KubernetesAPIVersion.java | 33 +- .../restclient/OpenShiftAPIVersion.java | 30 +- .../internal/restclient/ResourceFactory.java | 413 +++++---- .../internal/restclient/URLBuilder.java | 389 ++++---- .../restclient/api/capabilities/PodExec.java | 303 +++--- .../api/capabilities/ScaleCapability.java | 66 +- .../restclient/api/models/Endpoints.java | 18 +- .../restclient/api/models/TypeMeta.java | 40 +- .../restclient/apis/TypeMetaFactory.java | 135 +-- .../apis/autoscaling/models/Scale.java | 190 ++-- .../authorization/AuthorizationContext.java | 214 +++-- .../authorization/AuthorizationDetails.java | 156 ++-- .../capability/AbstractCapability.java | 44 +- .../capability/CapabilityInitializer.java | 175 ++-- .../AbstractOpenShiftBinaryCapability.java | 459 +++++----- .../resources/AnnotationCapability.java | 76 +- .../resources/AssociationCapability.java | 70 +- .../capability/resources/BuildCanceller.java | 52 +- .../capability/resources/BuildTrigger.java | 158 ++-- .../resources/ClientCapability.java | 44 +- .../resources/DeployCapability.java | 125 +-- .../DeploymentConfigTraceability.java | 29 +- .../resources/DeploymentTraceability.java | 40 +- .../resources/DeploymentTrigger.java | 21 +- ...erRegistryImageStreamImportCapability.java | 504 +++++----- .../ImageStreamImportCapability.java | 82 +- .../OpenShiftBinaryPodLogRetrieval.java | 342 ++++--- .../OpenShiftBinaryPortForwarding.java | 201 ++-- .../resources/OpenShiftBinaryRSync.java | 268 +++--- .../resources/PodLogRetrievalAsync.java | 227 +++-- .../ProjectTemplateListCapability.java | 59 +- .../resources/ProjectTemplateProcessing.java | 69 +- .../resources/PropertyAccessCapability.java | 215 ++--- .../capability/resources/TagCapability.java | 28 +- .../resources/TemplateTraceability.java | 56 +- .../resources/UpdateableCapability.java | 54 +- .../server/ServerTemplateProcessing.java | 56 +- .../internal/restclient/model/Build.java | 211 +++-- .../restclient/model/BuildConfig.java | 358 ++++---- .../internal/restclient/model/ConfigMap.java | 7 +- .../internal/restclient/model/Container.java | 546 +++++------ .../restclient/model/DeploymentConfig.java | 324 ++++--- .../restclient/model/EnvironmentVariable.java | 200 ++-- .../internal/restclient/model/ExecAction.java | 8 +- .../restclient/model/ImageStream.java | 230 ++--- .../restclient/model/KubernetesEvent.java | 126 ++- .../restclient/model/KubernetesResource.java | 694 +++++++------- .../internal/restclient/model/Lifecycle.java | 14 +- .../internal/restclient/model/LimitRange.java | 8 +- .../internal/restclient/model/List.java | 105 ++- .../restclient/model/ModelNodeAdapter.java | 54 +- .../restclient/model/ModelNodeBuilder.java | 75 +- .../internal/restclient/model/Namespace.java | 15 +- .../restclient/model/ObjectReference.java | 193 ++-- .../internal/restclient/model/Pod.java | 234 ++--- .../internal/restclient/model/Port.java | 203 ++-- .../internal/restclient/model/Project.java | 85 +- .../model/ReplicationController.java | 683 +++++++------- .../restclient/model/ResourceQuota.java | 8 +- .../internal/restclient/model/Route.java | 291 +++--- .../internal/restclient/model/Secret.java | 69 +- .../internal/restclient/model/Service.java | 270 +++--- .../restclient/model/ServiceAccount.java | 88 +- .../restclient/model/ServicePort.java | 263 +++--- .../internal/restclient/model/Status.java | 78 +- .../model/authorization/OpenshiftPolicy.java | 8 +- .../model/authorization/OpenshiftRole.java | 8 +- .../model/authorization/PolicyBinding.java | 8 +- .../model/authorization/RoleBinding.java | 165 ++-- .../model/build/BuildConfigBuilder.java | 520 ++++++----- .../restclient/model/build/BuildRequest.java | 120 ++- .../restclient/model/build/BuildStatus.java | 62 +- .../model/build/CustomBuildStrategy.java | 61 +- .../model/build/DockerBuildStrategy.java | 63 +- .../model/build/GitBuildSource.java | 86 +- .../model/build/ImageChangeTrigger.java | 146 +-- .../model/build/JenkinsPipelineStrategy.java | 96 +- .../model/build/STIBuildStrategy.java | 90 +- .../model/build/SourceBuildStrategy.java | 245 +++-- .../model/build/WebhookTrigger.java | 117 +-- .../model/deploy/ConfigChangeTrigger.java | 7 +- .../model/deploy/DeploymentRequest.java | 5 +- .../model/deploy/DeploymentTrigger.java | 51 +- .../model/deploy/ImageChangeTrigger.java | 167 ++-- .../model/image/ImageStreamImport.java | 111 ++- .../restclient/model/image/TagReference.java | 122 +-- .../restclient/model/kubeclient/Cluster.java | 64 +- .../restclient/model/kubeclient/Context.java | 72 +- .../model/kubeclient/KubeClientConfig.java | 89 +- .../KubeClientConfigConstructor.java | 33 +- .../restclient/model/kubeclient/User.java | 43 +- .../model/oauth/OAuthAccessToken.java | 13 +- .../model/oauth/OAuthAuthorizeToken.java | 13 +- .../restclient/model/oauth/OAuthClient.java | 13 +- .../model/oauth/OAuthClientAuthorization.java | 8 +- .../restclient/model/probe/Probe.java | 122 +-- .../project/OpenshiftProjectRequest.java | 43 +- .../ResourcePropertiesRegistry.java | 240 ++--- .../properties/ResourcePropertyKeys.java | 41 +- .../restclient/model/template/Parameter.java | 245 +++-- .../restclient/model/template/Template.java | 196 ++-- .../restclient/model/user/OpenShiftUser.java | 33 +- .../model/volume/AbstractVolume.java | 126 ++- .../model/volume/EmptyDirVolume.java | 31 +- .../model/volume/EmptyDirVolumeSource.java | 10 +- .../model/volume/HostPathVolumeSource.java | 31 +- .../model/volume/PersistentVolume.java | 439 ++++----- .../model/volume/PersistentVolumeClaim.java | 86 +- .../PersistentVolumeClaimVolumeSource.java | 10 +- .../model/volume/SecretVolumeSource.java | 10 +- .../restclient/model/volume/VolumeMount.java | 144 ++- .../restclient/model/volume/VolumeSource.java | 34 +- .../AbstractPersistentVolumeProperties.java | 4 +- .../property/HostPathVolumeProperties.java | 78 +- .../volume/property/NfsVolumeProperties.java | 144 +-- .../okhttp/BasicChallangeHandler.java | 58 +- .../restclient/okhttp/IChallangeHandler.java | 37 +- .../okhttp/OpenShiftAuthenticator.java | 192 ++-- .../okhttp/ResponseCodeInterceptor.java | 219 ++--- .../restclient/okhttp/WatchClient.java | 334 ++++--- .../restclient/okhttp/WebSocketAdapter.java | 36 +- .../com/openshift/internal/util/Assert.java | 57 +- .../internal/util/JBossDmrExtentions.java | 489 +++++----- .../internal/util/StringSplitter.java | 71 +- .../com/openshift/internal/util/URIUtils.java | 83 +- .../com/openshift/internal/util/URLUtils.java | 95 +- .../util/UnregisteredPropertyException.java | 12 +- .../restclient/BadRequestException.java | 22 +- .../openshift/restclient/ClientBuilder.java | 561 ++++++------ .../openshift/restclient/IApiTypeMapper.java | 270 +++--- .../com/openshift/restclient/IClient.java | 555 +++++------ .../restclient/IOpenShiftWatchListener.java | 197 ++-- .../restclient/IResourceFactory.java | 142 +-- .../restclient/ISSLCertificateCallback.java | 15 +- .../com/openshift/restclient/IWatcher.java | 5 +- .../IncompatibleApiVersionsException.java | 24 +- .../NoopSSLCertificateCallback.java | 17 +- .../restclient/NotFoundException.java | 34 +- .../restclient/OpenShiftContext.java | 81 +- .../restclient/OpenShiftException.java | 67 +- .../restclient/ResourceFactoryException.java | 12 +- .../openshift/restclient/ResourceKind.java | 262 +++--- .../UnsupportedEndpointException.java | 23 +- .../UnsupportedOperationException.java | 14 +- .../UnsupportedVersionException.java | 20 +- .../restclient/api/ITypeFactory.java | 45 +- .../restclient/api/capabilities/IPodExec.java | 257 +++--- .../api/capabilities/IScalable.java | 16 +- .../restclient/api/models/IAnnotatable.java | 56 +- .../api/models/IApiVersionable.java | 13 +- .../restclient/api/models/IEndpoints.java | 31 +- .../restclient/api/models/IKindable.java | 16 +- .../restclient/api/models/ILabelable.java | 27 +- .../restclient/api/models/INameSetable.java | 17 +- .../api/models/INamespaceSetable.java | 17 +- .../restclient/api/models/IObjectMeta.java | 46 +- .../restclient/api/models/ITypeMeta.java | 3 +- .../apis/autoscaling/models/IScale.java | 24 +- .../authorization/IAuthorizationContext.java | 156 ++-- .../authorization/IAuthorizationDetails.java | 51 +- .../ResourceForbiddenException.java | 20 +- .../authorization/UnauthorizedException.java | 83 +- .../capability/CapabilityVisitor.java | 58 +- .../capability/IBinaryCapability.java | 31 +- .../restclient/capability/ICapability.java | 33 +- .../restclient/capability/ICapable.java | 59 +- .../restclient/capability/IStoppable.java | 15 +- .../resources/IBuildCancelable.java | 14 +- .../resources/IBuildTriggerable.java | 112 +-- .../resources/IClientCapability.java | 6 +- .../resources/IDeployCapability.java | 20 +- .../IDeploymentConfigTraceability.java | 16 +- .../resources/IDeploymentTraceability.java | 19 +- .../resources/IDeploymentTriggerable.java | 6 +- .../IImageStreamImportCapability.java | 16 +- .../resources/IPodLogRetrieval.java | 81 +- .../resources/IPodLogRetrievalAsync.java | 259 +++--- .../resources/IPortForwardable.java | 218 ++--- .../resources/IProjectTemplateList.java | 31 +- .../resources/IProjectTemplateProcessing.java | 32 +- .../resources/IPropertyAccessCapability.java | 74 +- .../capability/resources/IRSyncable.java | 375 ++++---- .../capability/resources/ITags.java | 15 +- .../resources/ITemplateTraceability.java | 13 +- .../capability/resources/IUpdatable.java | 6 +- .../resources/LocationNotFoundException.java | 12 +- .../server/IImageRegistryHosting.java | 22 +- .../server/ITemplateProcessing.java | 23 +- .../restclient/http/IHttpConstants.java | 83 +- .../images/DockerImageDescriptor.java | 36 +- .../restclient/images/DockerImageURI.java | 367 ++++---- .../restclient/model/Annotatable.java | 1 + .../openshift/restclient/model/IBuild.java | 78 +- .../restclient/model/IBuildConfig.java | 120 ++- .../openshift/restclient/model/IConfig.java | 2 +- .../model/IConfigMapKeySelector.java | 9 +- .../restclient/model/IContainer.java | 147 +-- .../restclient/model/IDeploymentConfig.java | 145 ++- .../model/IEnvironmentVariable.java | 75 +- .../openshift/restclient/model/IEvent.java | 143 ++- .../restclient/model/IExecAction.java | 2 + .../openshift/restclient/model/IHandler.java | 1 + .../restclient/model/IImageStream.java | 132 ++- .../restclient/model/ILifecycle.java | 4 + .../restclient/model/ILimitRange.java | 4 +- .../com/openshift/restclient/model/IList.java | 24 +- .../restclient/model/INamespace.java | 5 +- .../model/IObjectFieldSelector.java | 9 +- .../restclient/model/IObjectReference.java | 99 +- .../com/openshift/restclient/model/IPod.java | 94 +- .../com/openshift/restclient/model/IPort.java | 24 +- .../openshift/restclient/model/IProject.java | 36 +- .../model/IReplicationController.java | 394 ++++---- .../openshift/restclient/model/IResource.java | 174 ++-- .../restclient/model/IResourceBuilder.java | 28 +- .../restclient/model/IResourceQuota.java | 4 +- .../restclient/model/ISecretKeySelector.java | 7 +- .../openshift/restclient/model/IService.java | 185 ++-- .../restclient/model/IServicePort.java | 66 +- .../openshift/restclient/model/IStatus.java | 72 +- .../restclient/model/JSONSerializeable.java | 33 +- .../model/authorization/IPolicy.java | 4 +- .../model/authorization/IPolicyBinding.java | 5 +- .../restclient/model/authorization/IRole.java | 4 +- .../model/authorization/IRoleBinding.java | 36 +- .../model/build/BuildSourceType.java | 10 +- .../model/build/BuildStrategyType.java | 22 +- .../model/build/BuildTriggerType.java | 30 +- .../model/build/IBuildConfigBuilder.java | 107 ++- .../restclient/model/build/IBuildRequest.java | 77 +- .../restclient/model/build/IBuildSource.java | 43 +- .../restclient/model/build/IBuildStatus.java | 25 +- .../model/build/IBuildStrategy.java | 17 +- .../restclient/model/build/IBuildTrigger.java | 8 +- .../model/build/ICustomBuildStrategy.java | 16 +- .../model/build/IDockerBuildStrategy.java | 16 +- .../model/build/IGitBuildSource.java | 16 +- .../model/build/IImageChangeTrigger.java | 35 +- .../model/build/IJenkinsPipelineStrategy.java | 24 +- .../model/build/ISTIBuildStrategy.java | 35 +- .../model/build/ISourceBuildStrategy.java | 74 +- .../model/build/IWebhookTrigger.java | 21 +- .../model/deploy/DeploymentTriggerType.java | 10 +- .../IDeploymentConfigChangeTrigger.java | 6 +- .../deploy/IDeploymentImageChangeTrigger.java | 89 +- .../model/deploy/IDeploymentRequest.java | 6 +- .../model/deploy/IDeploymentTrigger.java | 18 +- .../model/image/IImageStreamImport.java | 92 +- .../restclient/model/image/ITagReference.java | 31 +- .../restclient/model/kubeclient/ICluster.java | 22 +- .../restclient/model/kubeclient/IContext.java | 50 +- .../model/kubeclient/IKubeClientConfig.java | 38 +- .../restclient/model/kubeclient/IUser.java | 9 +- .../KubeClientConfigSerializer.java | 38 +- .../model/oauth/IOAuthAccessToken.java | 4 +- .../model/oauth/IOAuthAuthorizeToken.java | 4 +- .../restclient/model/oauth/IOAuthClient.java | 4 +- .../oauth/IOAuthClientAuthorization.java | 4 +- .../restclient/model/probe/IProbe.java | 26 +- .../model/project/IProjectRequest.java | 20 +- .../restclient/model/route/IRoute.java | 137 ++- .../restclient/model/route/ITLSConfig.java | 177 ++-- .../restclient/model/route/ITargetPort.java | 36 +- .../model/route/TLSTerminationType.java | 12 +- .../restclient/model/secret/ISecret.java | 69 +- .../model/serviceaccount/IServiceAccount.java | 54 +- .../restclient/model/template/IParameter.java | 94 +- .../restclient/model/template/ITemplate.java | 103 +-- .../restclient/model/user/IUser.java | 24 +- .../model/volume/IEmptyDirVolumeSource.java | 1 + .../model/volume/IHostPathVolumeSource.java | 17 +- .../model/volume/IPersistentVolume.java | 154 ++-- .../model/volume/IPersistentVolumeClaim.java | 74 +- .../IPersistentVolumeClaimVolumeSource.java | 3 + .../model/volume/ISecretVolumeSource.java | 1 + .../restclient/model/volume/IVolume.java | 21 +- .../restclient/model/volume/IVolumeMount.java | 24 +- .../model/volume/IVolumeSource.java | 8 +- .../model/volume/PVCAccessModes.java | 7 +- .../restclient/model/volume/VolumeType.java | 40 +- .../property/IHostPathVolumeProperties.java | 7 +- .../volume/property/INfsVolumeProperties.java | 18 +- .../property/IPersistentVolumeProperties.java | 1 + .../restclient/utils/Base64Coder.java | 127 ++- .../openshift/restclient/utils/BeanUtils.java | 32 +- .../utils/EnvironmentVariableUtils.java | 29 +- .../restclient/utils/MemoryUnit.java | 3 +- .../openshift/restclient/utils/SSLUtils.java | 121 ++- .../restclient/APIModelVersionTest.java | 20 +- .../restclient/ApiTypeMapperTest.java | 110 +-- .../DefaultClientFilterIntegrationTest.java | 238 ++--- .../DefaultClientIntegrationTest.java | 316 ++++--- .../restclient/DefaultClientTest.java | 180 ++-- .../restclient/IntegrationTestHelper.java | 436 +++++---- .../PodStatusRunningConditional.java | 20 +- .../restclient/ResourceFactoryTest.java | 79 +- .../restclient/TypeMapperFixture.java | 158 ++-- .../internal/restclient/URLBuilderTest.java | 200 ++-- .../capabilities/PodExecIntegrationTest.java | 367 ++++---- .../api/capabilities/PodExecTest.java | 182 ++-- .../ScaleCapabilityIntegrationTest.java | 185 ++-- .../restclient/apis/TypeMetaFactoryTest.java | 62 +- .../extensions/model/v1beta1/ScaleTest.java | 81 +- .../AuthorizationDetailsTest.java | 85 +- .../AuthorizationKindsIntegrationTest.java | 66 +- .../resources/AnnotationCapabilityTest.java | 69 +- .../resources/AssociationCapabilityTest.java | 28 +- .../BuildCapabilitiesIntegrationTest.java | 183 ++-- .../resources/DeployCapabilityTest.java | 201 ++-- .../DeploymentConfigTraceabilityTest.java | 72 +- .../resources/DeploymentTraceabilityTest.java | 76 +- .../DockerManifestComparatorTest.java | 39 +- .../IPodLogRetrievalAsyncOptionsTest.java | 90 +- ...StreamImportCapabilityIntegrationTest.java | 74 +- .../ImageStreamImportCapabilityTest.java | 80 +- .../OpenShiftBinaryPodLogRetrievalTest.java | 104 +-- .../OpenShiftBinaryPortForwardingTest.java | 115 +-- .../resources/OpenShiftBinaryRSyncTest.java | 150 ++- ...tBinaryPodLogRetrievalIntegrationTest.java | 68 +- ...ftBinaryPortForwardingIntegrationTest.java | 114 ++- ...ftBinaryRSyncRetrievalIntegrationTest.java | 268 +++--- .../PodLogRetrievalAsyncIntegrationTest.java | 136 ++- .../resources/PodLogRetrievalAsyncTest.java | 145 +-- .../ProjectTemplateProcessingTest.java | 132 +-- .../PropertyAccessCapabilityTest.java | 98 +- .../resources/TagCapabilityTest.java | 36 +- .../resources/TemplateTraceabilityTest.java | 72 +- .../resources/UpdateableCapabilityTest.java | 66 +- .../testutils/BinaryCapabilityTestMocks.java | 71 +- ...rverTemplateProcessingIntegrationTest.java | 99 +- .../server/ServerTemplateProcessingTest.java | 79 +- .../restclient/model/BuildConfigTest.java | 24 +- .../model/KubernetesResourceTest.java | 390 ++++---- .../restclient/model/NamespaceTest.java | 13 +- .../restclient/model/PortFactory.java | 29 +- .../restclient/model/ProjectTest.java | 51 +- .../internal/restclient/model/RouteTest.java | 73 +- .../restclient/model/ServiceTest.java | 92 +- .../internal/restclient/model/StatusTest.java | 52 +- .../model/build/BuildConfigBuilderTest.java | 111 ++- .../model/build/BuildConfigTest.java | 98 +- .../model/build/BuildRequestTest.java | 67 +- .../model/build/WebhookTriggerTest.java | 42 +- .../model/deploy/DeployRequestTest.java | 52 +- .../kubeconfig/KubeClientConfigTest.java | 71 +- .../ResourcePropertiesRegistryTest.java | 121 +-- .../model/template/ParameterTest.java | 253 ++--- .../model/template/TemplateTest.java | 135 +-- .../restclient/model/v1/BuildConfigTest.java | 270 +++--- .../restclient/model/v1/BuildTest.java | 83 +- .../restclient/model/v1/ConfigMapTest.java | 57 +- .../model/v1/DeploymentConfigTest.java | 307 ++++--- .../model/v1/EmptyDirVolumeSourceTest.java | 12 +- .../restclient/model/v1/EndpointsTest.java | 41 +- .../model/v1/EnvironmentVariableTest.java | 113 +-- .../restclient/model/v1/EventTest.java | 114 +-- .../model/v1/HostPathVolumeSourceTest.java | 49 +- .../model/v1/ImageStreamImportTest.java | 71 +- .../restclient/model/v1/ImageStreamTest.java | 101 +- .../restclient/model/v1/LifecycleTest.java | 14 +- .../restclient/model/v1/ListTest.java | 66 +- .../restclient/model/v1/ObjectRefTest.java | 118 +-- .../internal/restclient/model/v1/PVCTest.java | 88 +- .../model/v1/PVCVolumeSourceTest.java | 14 +- .../model/v1/PersistentVolumeTest.java | 223 ++--- .../model/v1/PipelineBuildConfigTest.java | 287 +++--- .../internal/restclient/model/v1/PodTest.java | 278 +++--- .../model/v1/ProjectRequestTest.java | 70 +- .../restclient/model/v1/ProjectTest.java | 46 +- .../model/v1/ReplicationControllerTest.java | 581 ++++++------ .../restclient/model/v1/ResourceTest.java | 57 +- .../restclient/model/v1/RoleBindingTest.java | 112 +-- .../restclient/model/v1/RouteTest.java | 158 ++-- .../restclient/model/v1/SecretTest.java | 55 +- .../model/v1/SecretVolumeSourceTest.java | 12 +- .../model/v1/ServiceAccountTest.java | 110 +-- .../restclient/model/v1/ServiceTest.java | 221 ++--- .../restclient/model/v1/StatusTest.java | 58 +- .../restclient/model/v1/TemplateTest.java | 95 +- .../model/v1/UnrecognizedResourceTest.java | 50 +- .../restclient/model/v1/UserTest.java | 49 +- .../okhttp/BasicChallangeHandlerTest.java | 92 +- .../restclient/okhttp/WatchClientTest.java | 79 +- .../internal/util/JBossDmrExtentionsTest.java | 206 +++-- .../internal/util/StringSplitterTest.java | 111 +-- .../openshift/internal/util/TestTimer.java | 57 +- .../openshift/internal/util/URIUtilsTest.java | 76 +- .../restclient/OpenShiftContextTest.java | 117 +-- .../restclient/ResourceKindTest.java | 84 +- .../WatchClientIntegrationTest.java | 162 ++-- .../restclient/images/DockerImageURITest.java | 189 ++-- .../restclient/model/MocksFactory.java | 171 ++-- .../restclient/server/HttpServerFake.java | 320 +++---- .../restclient/server/HttpsServerFake.java | 109 +-- .../server/WaitingHttpServerFake.java | 1 + .../utils/ExceptionCauseMatcher.java | 26 +- .../restclient/utils/ResourceTestHelper.java | 46 +- .../openshift/restclient/utils/Samples.java | 136 +-- 404 files changed, 21539 insertions(+), 21217 deletions(-) create mode 100644 checkstyle.xml diff --git a/.gitignore b/.gitignore index 9b89fc9d..be2b3174 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ bin *.iml **/integrationTest.properties /target/ +.checkstyle diff --git a/checkstyle.xml b/checkstyle.xml new file mode 100644 index 00000000..5da71ec9 --- /dev/null +++ b/checkstyle.xml @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 49ee68f3..3408b3c8 100755 --- a/pom.xml +++ b/pom.xml @@ -1,357 +1,388 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - - - org.jboss - jboss-parent - 6-beta-2 - - + + + org.jboss + jboss-parent + 6-beta-2 + + - - 4.0.0 + + 4.0.0 - - com.openshift - openshift-restclient-java - 6.0.1-SNAPSHOT - jar - OpenShift Java REST Client - http://openshift.redhat.com - OpenShift Java Client + + com.openshift + openshift-restclient-java + 6.0.1-SNAPSHOT + jar + OpenShift Java REST Client + http://openshift.redhat.com + OpenShift Java Client - + - - + + UTF-8 - - 2.1 - 3.0.0-M1 - 1.8 - 1.8 + + 2.1 + 3.0.0-M1 + 1.8 + 1.8 - - 1.0.0-beta-6 - 1.0.0-beta-5 - 1.1.0-beta-1 + + 1.0.0-beta-6 + 1.0.0-beta-5 + 1.1.0-beta-1 - - ${basedir}/src/test/resources/integrationTest.properties - ${project.build.directory} - + + ${basedir}/src/test/resources/openshiftv3IntegrationTest.properties + ${project.build.directory} + - - - jira - https://issues.jboss.org/browse/OSJC - + + + jira + https://issues.jboss.org/browse/OSJC + - - - - Eclipse Public License v1.0 - http://www.eclipse.org/legal/epl-v10.html - - + + + + Eclipse Public License v1.0 + http://www.eclipse.org/legal/epl-v10.html + + - - - - src/main/resources - true - - - - - - - org.codehaus.mojo - properties-maven-plugin - 1.0-alpha-1 - - - initialize - - read-project-properties - - - - ${integrationtest.properties} - - - - - - - maven-surefire-plugin - 2.12 - - -Dfile.encoding=UTF-8 - - **/*IntegrationTest.java - - - - - maven-jar-plugin - 2.4 - - ${jar.outputDir} - - - - maven-source-plugin - - - package-sources - package - - jar - - - - - ${jar.outputDir} - - - - maven-deploy-plugin - 2.8.2 - - - - + + + + src/main/resources + true + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 2.16 + + + com.puppycrawl.tools + checkstyle + 6.19 + + + + + + ${project.basedir}/checkstyle.xml + UTF-8 + license.txt + true + true + false + true + warning + + + check + + + + + + + org.codehaus.mojo + properties-maven-plugin + 1.0-alpha-1 + + + initialize + + read-project-properties + + + + ${integrationtest.properties} + + + + + + + maven-surefire-plugin + 2.12 + + -Dfile.encoding=UTF-8 + + **/*IntegrationTest.java + + + + + maven-jar-plugin + 2.4 + + ${jar.outputDir} + + + + maven-source-plugin + + + package-sources + package + + jar + + + + + ${jar.outputDir} + + + + maven-deploy-plugin + 2.8.2 + + + - - - com.squareup.okhttp3 - okhttp - 3.3.1 - - - com.squareup.okhttp3 - okhttp-ws - 3.3.1 - - - org.yaml - snakeyaml - 1.14 - - - org.jboss - jboss-dmr - 1.3.0.Final - - - org.apache.commons - commons-io - 1.3.2 - - - org.apache.commons - commons-compress - 1.8.1 - - - junit - junit - 4.8.2 - test - - - org.mockito - mockito-core - 1.9.0-rc1 - test - - - org.easytesting - fest-assert - 1.4 - test - - - commons-io - commons-io - 2.1 - - - org.slf4j - slf4j-api - 1.6.4 - - - org.slf4j - slf4j-log4j12 - 1.6.4 - - - log4j - log4j - 1.2.16 - - - commons-codec - commons-codec - 1.6 - - - commons-lang - commons-lang - 2.6 - - - org.skyscreamer - jsonassert - 1.2.3 - test - - + + + com.squareup.okhttp3 + okhttp + 3.3.1 + + + com.squareup.okhttp3 + okhttp-ws + 3.3.1 + + + org.yaml + snakeyaml + 1.14 + + + org.jboss + jboss-dmr + 1.3.0.Final + + + org.apache.commons + commons-io + 1.3.2 + + + org.apache.commons + commons-compress + 1.8.1 + + + junit + junit + 4.8.2 + test + + + org.mockito + mockito-core + 1.9.0-rc1 + test + + + org.easytesting + fest-assert + 1.4 + test + + + commons-io + commons-io + 2.1 + + + org.slf4j + slf4j-api + 1.6.4 + + + org.slf4j + slf4j-log4j12 + 1.6.4 + + + log4j + log4j + 1.2.16 + + + commons-codec + commons-codec + 1.6 + + + commons-lang + commons-lang + 2.6 + + + org.skyscreamer + jsonassert + 1.2.3 + test + + - - - release - - - - maven-release-plugin - - true - false - true - - - - maven-javadoc-plugin - - org.jboss.apiviz.APIviz - - org.jboss.apiviz - apiviz - 1.3.1.GA - - true - UTF-8 - UTF-8 - UTF-8 - true - true - true - true - -sourceclasspath - ${project.build.outputDirectory} - ${project.parent.parent.basedir}/javadoc/stylesheet.css - ${project.parent.parent.basedir}/javadoc - - - - attach-javadocs - - jar - - - - - - - + + + release + + + + maven-release-plugin + + true + false + true + + + + maven-javadoc-plugin + + org.jboss.apiviz.APIviz + + org.jboss.apiviz + apiviz + 1.3.1.GA + + true + UTF-8 + UTF-8 + UTF-8 + true + true + true + true + -sourceclasspath + ${project.build.outputDirectory} + ${project.parent.parent.basedir}/javadoc/stylesheet.css + ${project.parent.parent.basedir}/javadoc + + + + attach-javadocs + + jar + + + + - - - defaultprofile - - - axis - defaultprofile - - - - true - - + + + - - - integration-tests - - - axis - integration-tests - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.12 - - - ${libra_server} - ${default_rhlogin} - ${rhpassword} - ${openshift.binary.location} - - - none - - - **/*IntegrationTest.java - - - - - - integration-tests - integration-test - - test - - - false - - none - - - **/*IntegrationTest.java - - - - - - - - - - jdk9 - - 9 - - - - - maven-surefire-plugin - - -Dfile.encoding=UTF-8 --add-modules=ALL-SYSTEM - - - - - - - - https://github.com/openshift/openshift-restclient-java - - - Red Hat, Inc - http://www.redhat.com - + + + defaultprofile + + + axis + defaultprofile + + + + true + + + + + + integration-tests + + + axis + integration-tests + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12 + + + ${libra_server} + ${default_rhlogin} + ${rhpassword} + ${openshift.binary.location} + + + none + + + **/*IntegrationTest.java + + + + + + integration-tests + integration-test + + test + + + false + + none + + + **/*IntegrationTest.java + + + + + + + + + + jdk9 + + 9 + + + + + maven-surefire-plugin + + -Dfile.encoding=UTF-8 + --add-modules=ALL-SYSTEM + + + + + + + + https://github.com/openshift/openshift-restclient-java + + + Red Hat, Inc + http://www.redhat.com + diff --git a/src/main/java/com/openshift/internal/restclient/APIModelVersion.java b/src/main/java/com/openshift/internal/restclient/APIModelVersion.java index d672677f..b9cc6af6 100644 --- a/src/main/java/com/openshift/internal/restclient/APIModelVersion.java +++ b/src/main/java/com/openshift/internal/restclient/APIModelVersion.java @@ -6,25 +6,31 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient; import java.util.Comparator; -/** - * @author Jeff Cantrill - */ public interface APIModelVersion { - int getOrder(); + int getOrder(); - static class VersionComparitor implements Comparator { - @Override - public int compare(APIModelVersion v1, APIModelVersion v2) { - if(v2 == null) return 1; - if(v1 == null) return -1; - if(v1.getOrder() < v2.getOrder()) return -1; - if(v1.getOrder() > v2.getOrder()) return 1; - return 0; - } - }; + static class VersionComparitor implements Comparator { + @Override + public int compare(APIModelVersion v1, APIModelVersion v2) { + if (v2 == null) { + return 1; + } + if (v1 == null) { + return -1; + } + if (v1.getOrder() < v2.getOrder()) { + return -1; + } + if (v1.getOrder() > v2.getOrder()) { + return 1; + } + return 0; + } + } } diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index a441dbf4..9bea7335 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient; import java.io.IOException; @@ -40,361 +41,364 @@ import okhttp3.Response; /** - * Typemapper to determine the endpoints for - * various openshift resources + * Typemapper to determine the endpoints for various openshift resources + * * @author jeff.cantrill * */ -public class ApiTypeMapper implements IApiTypeMapper, ResourcePropertyKeys{ - - private static final Logger LOGGER = LoggerFactory.getLogger(ApiTypeMapper.class); - private final String baseUrl; - private final OkHttpClient client; - private List resourceEndpoints; - private final Map preferedVersion = new HashMap<>(2); - private boolean initialized = false; - - public ApiTypeMapper(String baseUrl, OkHttpClient client) { - this.baseUrl = baseUrl; - this.client = client; - preferedVersion.put(KUBE_API, KubernetesAPIVersion.v1.toString()); - preferedVersion.put(OS_API, OpenShiftAPIVersion.v1.toString()); - } - - @Override - public String getPreferedVersionFor(String endpoint) { - return preferedVersion.get(endpoint); - } - - @Override - public boolean isSupported(IResource resource) { - return isSupported(resource.getApiVersion(), resource.getKind()); - } - - @Override - public IVersionedApiResource getEndpointFor(String apiVersion, String kind) { - init(); - IVersionedApiResource apiresource = endpointFor(apiVersion, kind); - if(apiresource == null) { - throw new UnsupportedEndpointException("No endpoint found for %s, version %s", kind, apiVersion); - } - return apiresource; - } - - private IVersionedApiResource endpointFor(String version, String kind) { - String[] split = StringUtils.isBlank(version) ? new String [] {} : version.split(FWD_SLASH); - Optional result = null; - if(split.length <=1) { - result = Stream.of(KUBE_API, OS_API) - .map(api->formatEndpointFor(api, (split.length == 0 ? preferedVersion.get(api) : split[0]), kind)) - .filter(e->resourceEndpoints.contains(e)) - .findFirst(); - }else{ - result = Optional.of(formatEndpointFor(API_GROUPS_API, version, ResourceKind.pluralize(kind, true, true))); - } - if(result.isPresent()) { - int index = resourceEndpoints.indexOf(result.get()); - if(index > -1) { - return resourceEndpoints.get(index); - } - } - return null; - } - - @Override - public boolean isSupported(String kind) { - return isSupported(null, kind); - } - - @Override - public boolean isSupported(String version, String kind) { - init(); - return endpointFor(version, kind) != null; - } - - private IVersionedApiResource formatEndpointFor(String prefix, String version, String kind) { - return new VersionedApiResource(prefix, version, ResourceKind.pluralize(kind, true, true)); - } - - private synchronized void init() { - if(!this.initialized) { - List resourceEndpoints = new ArrayList<>(); - Collection groups = getLegacyGroups(); - groups.addAll(getApiGroups()); - groups.forEach(g->{ - Collection versions = g.getVersions(); - versions.forEach(v->{ - Collection resources = getResources(g, v); - addEndpoints(resourceEndpoints, g.getPrefix(), g.getName(), v, resources); - }); - }); - this.resourceEndpoints = resourceEndpoints; - this.initialized = true; - } - } - - private void addEndpoints(List endpoints, final String prefix, final String apiGroupName, final String version, final Collection nodes) { - for (ModelNode node : nodes) { - String name = node.get(NAME).asString(); - String capability = null; - if(name.contains(FWD_SLASH)) { - int first = name.indexOf(FWD_SLASH); - capability = name.substring(first+1); - name = name.substring(0, first); - } - boolean namespaced = node.get("namespaced").asBoolean(); - VersionedApiResource resource = new VersionedApiResource(prefix, apiGroupName, version, name, node.get(KIND).asString(), namespaced); - if(!endpoints.contains(resource)) { - endpoints.add(resource); - } - if(capability != null) { - int index = endpoints.indexOf(resource); - endpoints.get(index).addCapability(capability); - } - } - } - - private Collection getApiGroups(){ - String json = readEndpoint(API_GROUPS_API); - return ModelNode.fromJSONString(json) - .get("groups") - .asList() - .stream() - .map(n->new ApiGroup(API_GROUPS_API, n)) - .collect(Collectors.toList()); - } - - private Collection getResources(IApiGroup group, String version){ - String json = readEndpoint(group.pathFor(version)); - if(StringUtils.isBlank(json)) { - return new ArrayList<>(); - } - ModelNode node = ModelNode.fromJSONString(json); - return node.get("resources").asList(); - } - - private Collection getLegacyGroups(){ - Collection groups = new ArrayList<>(); - for(String e: Arrays.asList(KUBE_API,OS_API)) { - String json = readEndpoint(e); - ModelNode n = ModelNode.fromJSONString(json); - groups.add(new LegacyApiGroup(e,n)); - } - return groups; - } - - private String readEndpoint(final String endpoint) { - try { - final URL url = new URL(new URL(this.baseUrl), endpoint); - LOGGER.debug(url.toString()); - Request request = new Request.Builder() - .url(url) - .build(); - Response response = client.newCall(request).execute(); - return response.body().string(); - } catch (IOException e) { - throw new OpenShiftException(e,"Unable to read endpoint %s/%s", this.baseUrl, endpoint); - } - } - - static class ApiGroup implements IApiGroup{ - private final ModelNode node; - private final String prefix; - private final String path; - - ApiGroup(String prefix, ModelNode node) { - this.prefix = prefix; - this.node = node; - StringBuilder builder = new StringBuilder(prefix); - if(getName() != null) { //null name for k8e or openshift - builder - .append(FWD_SLASH) - .append(getName()); - } - path = builder.toString(); - } - - protected ModelNode getNode() { - return node; - } - - @Override - public String getPrefix() { - return prefix; - } - - @Override - public String getName() { - return JBossDmrExtentions.asString(node, new HashMap<>(), NAME); - } - - @Override - public Collection getVersions() { - return JBossDmrExtentions.get(node, new HashMap<>(), "versions").asList() - .stream().map(n->n.get("version").asString()) - .collect(Collectors.toList()); - } - - @Override - public String getPreferedVersion() { - return JBossDmrExtentions.asString(node, new HashMap<>(), "preferedVersion.version"); - } - - @Override - public String pathFor(String version) { - //add check for supported version? - return String.format("%s/%s", path, version); - } - } - - static class LegacyApiGroup extends ApiGroup{ - - LegacyApiGroup(String prefix, ModelNode node) { - super(prefix, node); - } - - @Override - public String getName() { - return null; - } - - @Override - public Collection getVersions() { - return JBossDmrExtentions.get(getNode(), new HashMap<>(), "versions").asList() - .stream().map(n->n.asString()) - .collect(Collectors.toList()); - } - - @Override - public String getPreferedVersion() { - return OpenShiftAPIVersion.v1.toString(); - } - - - } - - static class VersionedApiResource implements IVersionedApiResource { - - private final String prefix; - private final String name; - private final boolean namespaced; - private final Collection capabilities = new ArrayList<>(); - private final String version; - private String apiGroupName; - private String kind; - - VersionedApiResource(String prefix, String version, String name){ - if(version == null) throw new IllegalArgumentException("version can not be null when creating a VersionedApiResource "); - if(version.contains(FWD_SLASH)) { - int last = version.lastIndexOf(FWD_SLASH); - this.apiGroupName = version.substring(0, last); - version = version.substring(last + 1); - } - this.prefix = prefix; - this.name = name; - this.version = version; - this.namespaced = false; - } - - VersionedApiResource(String prefix, String apiGroupName, String version, String name, String kind, boolean namespaced){ - this.prefix = prefix; - this.name = name; - this.namespaced = namespaced; - this.version = version; - this.apiGroupName = apiGroupName; - this.kind = kind; - } - - public void addCapability(String capability) { - capabilities.add(capability); - } - - @Override - public String getApiGroupName() { - return apiGroupName; - } - - @Override - public String getVersion() { - return this.version; - } - - @Override - public String getPrefix() { - return prefix; - } - - @Override - public String getName() { - return name; - } - - - @Override - public String getKind() { - return kind; - } - - @Override - public boolean isNamespaced() { - return namespaced; - } - - @Override - public boolean isSupported(String capability) { - return capabilities.contains(capability); - } - - @Override - public String toString() { - if(apiGroupName == null) { - return String.format("%s/%s/%s", prefix, version, name); - } - return String.format("%s/%s/%s/%s", prefix, apiGroupName, version, name); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((apiGroupName == null) ? 0 : apiGroupName.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); - result = prime * result + ((version == null) ? 0 : version.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - VersionedApiResource other = (VersionedApiResource) obj; - if (apiGroupName == null) { - if (other.apiGroupName != null) - return false; - } else if (!apiGroupName.equals(other.apiGroupName)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (prefix == null) { - if (other.prefix != null) - return false; - } else if (!prefix.equals(other.prefix)) - return false; - if (version == null) { - if (other.version != null) - return false; - } else if (!version.equals(other.version)) - return false; - return true; - } - - } +public class ApiTypeMapper implements IApiTypeMapper, ResourcePropertyKeys { + + private static final Logger LOGGER = LoggerFactory.getLogger(ApiTypeMapper.class); + private final String baseUrl; + private final OkHttpClient client; + private List resourceEndpoints; + private final Map preferedVersion = new HashMap<>(2); + private boolean initialized = false; + + public ApiTypeMapper(String baseUrl, OkHttpClient client) { + this.baseUrl = baseUrl; + this.client = client; + preferedVersion.put(KUBE_API, KubernetesAPIVersion.v1.toString()); + preferedVersion.put(OS_API, OpenShiftAPIVersion.v1.toString()); + } + + @Override + public String getPreferedVersionFor(String endpoint) { + return preferedVersion.get(endpoint); + } + + @Override + public boolean isSupported(IResource resource) { + return isSupported(resource.getApiVersion(), resource.getKind()); + } + + @Override + public boolean isSupported(String kind) { + return isSupported(null, kind); + } + + @Override + public boolean isSupported(String version, String kind) { + init(); + return endpointFor(version, kind) != null; + } + + @Override + public IVersionedApiResource getEndpointFor(String apiVersion, String kind) { + init(); + IVersionedApiResource apiresource = endpointFor(apiVersion, kind); + if (apiresource == null) { + throw new UnsupportedEndpointException("No endpoint found for %s, version %s", kind, apiVersion); + } + return apiresource; + } + + private IVersionedApiResource endpointFor(String version, String kind) { + String[] split = StringUtils.isBlank(version) ? new String[] {} : version.split(FWD_SLASH); + Optional result = null; + if (split.length <= 1) { + result = Stream.of(KUBE_API, OS_API) + .map(api -> formatEndpointFor(api, (split.length == 0 ? preferedVersion.get(api) : split[0]), kind)) + .filter(e -> resourceEndpoints.contains(e)).findFirst(); + } else { + result = Optional.of(formatEndpointFor(API_GROUPS_API, version, ResourceKind.pluralize(kind, true, true))); + } + if (result.isPresent()) { + int index = resourceEndpoints.indexOf(result.get()); + if (index > -1) { + return resourceEndpoints.get(index); + } + } + return null; + } + + private IVersionedApiResource formatEndpointFor(String prefix, String version, String kind) { + return new VersionedApiResource(prefix, version, ResourceKind.pluralize(kind, true, true)); + } + + private synchronized void init() { + if (!this.initialized) { + List resourceEndpoints = new ArrayList<>(); + Collection groups = getLegacyGroups(); + groups.addAll(getApiGroups()); + groups.forEach(g -> { + Collection versions = g.getVersions(); + versions.forEach(v -> { + Collection resources = getResources(g, v); + addEndpoints(resourceEndpoints, g.getPrefix(), g.getName(), v, resources); + }); + }); + this.resourceEndpoints = resourceEndpoints; + this.initialized = true; + } + } + + private void addEndpoints(List endpoints, final String prefix, final String apiGroupName, + final String version, final Collection nodes) { + for (ModelNode node : nodes) { + String name = node.get(NAME).asString(); + String capability = null; + if (name.contains(FWD_SLASH)) { + int first = name.indexOf(FWD_SLASH); + capability = name.substring(first + 1); + name = name.substring(0, first); + } + boolean namespaced = node.get("namespaced").asBoolean(); + VersionedApiResource resource = new VersionedApiResource(prefix, apiGroupName, version, name, + node.get(KIND).asString(), namespaced); + if (!endpoints.contains(resource)) { + endpoints.add(resource); + } + if (capability != null) { + int index = endpoints.indexOf(resource); + endpoints.get(index).addCapability(capability); + } + } + } + + private Collection getApiGroups() { + String json = readEndpoint(API_GROUPS_API); + return ModelNode.fromJSONString(json).get("groups").asList().stream().map(n -> new ApiGroup(API_GROUPS_API, n)) + .collect(Collectors.toList()); + } + + private Collection getResources(IApiGroup group, String version) { + String json = readEndpoint(group.pathFor(version)); + if (StringUtils.isBlank(json)) { + return new ArrayList<>(); + } + ModelNode node = ModelNode.fromJSONString(json); + return node.get("resources").asList(); + } + + private Collection getLegacyGroups() { + Collection groups = new ArrayList<>(); + for (String e : Arrays.asList(KUBE_API, OS_API)) { + String json = readEndpoint(e); + ModelNode n = ModelNode.fromJSONString(json); + groups.add(new LegacyApiGroup(e, n)); + } + return groups; + } + + private String readEndpoint(final String endpoint) { + try { + final URL url = new URL(new URL(this.baseUrl), endpoint); + LOGGER.debug(url.toString()); + Request request = new Request.Builder().url(url).build(); + Response response = client.newCall(request).execute(); + return response.body().string(); + } catch (IOException e) { + throw new OpenShiftException(e, "Unable to read endpoint %s/%s", this.baseUrl, endpoint); + } + } + + static class ApiGroup implements IApiGroup { + private final ModelNode node; + private final String prefix; + private final String path; + + ApiGroup(String prefix, ModelNode node) { + this.prefix = prefix; + this.node = node; + StringBuilder builder = new StringBuilder(prefix); + if (getName() != null) { // null name for k8e or openshift + builder.append(FWD_SLASH).append(getName()); + } + path = builder.toString(); + } + + protected ModelNode getNode() { + return node; + } + + @Override + public String getPrefix() { + return prefix; + } + + @Override + public String getName() { + return JBossDmrExtentions.asString(node, new HashMap<>(), NAME); + } + + @Override + public Collection getVersions() { + return JBossDmrExtentions.get(node, new HashMap<>(), "versions").asList().stream() + .map(n -> n.get("version").asString()).collect(Collectors.toList()); + } + + @Override + public String getPreferedVersion() { + return JBossDmrExtentions.asString(node, new HashMap<>(), "preferedVersion.version"); + } + + @Override + public String pathFor(String version) { + // add check for supported version? + return String.format("%s/%s", path, version); + } + } + + static class LegacyApiGroup extends ApiGroup { + + LegacyApiGroup(String prefix, ModelNode node) { + super(prefix, node); + } + + @Override + public String getName() { + return null; + } + + @Override + public Collection getVersions() { + return JBossDmrExtentions.get(getNode(), new HashMap<>(), "versions").asList().stream() + .map(n -> n.asString()).collect(Collectors.toList()); + } + + @Override + public String getPreferedVersion() { + return OpenShiftAPIVersion.v1.toString(); + } + + } + + static class VersionedApiResource implements IVersionedApiResource { + + private final String prefix; + private final String name; + private final boolean namespaced; + private final Collection capabilities = new ArrayList<>(); + private final String version; + private String apiGroupName; + private String kind; + + VersionedApiResource(String prefix, String version, String name) { + if (version == null) { + throw new IllegalArgumentException("version can not be null when creating a VersionedApiResource "); + } + if (version.contains(FWD_SLASH)) { + int last = version.lastIndexOf(FWD_SLASH); + this.apiGroupName = version.substring(0, last); + version = version.substring(last + 1); + } + this.prefix = prefix; + this.name = name; + this.version = version; + this.namespaced = false; + } + + VersionedApiResource(String prefix, String apiGroupName, String version, String name, String kind, + boolean namespaced) { + this.prefix = prefix; + this.name = name; + this.namespaced = namespaced; + this.version = version; + this.apiGroupName = apiGroupName; + this.kind = kind; + } + + public void addCapability(String capability) { + capabilities.add(capability); + } + + @Override + public String getApiGroupName() { + return apiGroupName; + } + + @Override + public String getVersion() { + return this.version; + } + + @Override + public String getPrefix() { + return prefix; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getKind() { + return kind; + } + + @Override + public boolean isNamespaced() { + return namespaced; + } + + @Override + public boolean isSupported(String capability) { + return capabilities.contains(capability); + } + + @Override + public String toString() { + if (apiGroupName == null) { + return String.format("%s/%s/%s", prefix, version, name); + } + return String.format("%s/%s/%s/%s", prefix, apiGroupName, version, name); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((apiGroupName == null) ? 0 : apiGroupName.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((prefix == null) ? 0 : prefix.hashCode()); + result = prime * result + ((version == null) ? 0 : version.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + VersionedApiResource other = (VersionedApiResource) obj; + if (apiGroupName == null) { + if (other.apiGroupName != null) { + return false; + } + } else if (!apiGroupName.equals(other.apiGroupName)) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (prefix == null) { + if (other.prefix != null) { + return false; + } + } else if (!prefix.equals(other.prefix)) { + return false; + } + if (version == null) { + if (other.version != null) { + return false; + } + } else if (!version.equals(other.version)) { + return false; + } + return true; + } + + } } diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 15ad0cb2..58114a74 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient; import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeClientCapabilities; @@ -58,441 +59,439 @@ /** * @author Jeff Cantrill */ -public class DefaultClient implements IClient, IHttpConstants{ - - public static final String SYSTEM_PROP_K8E_API_VERSION = "osjc.k8e.apiversion"; - public static final String SYSTEM_PROP_OPENSHIFT_API_VERSION = "osjc.openshift.apiversion"; - - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); - private URL baseUrl; - private OkHttpClient client; - private IResourceFactory factory; - private Map, ICapability> capabilities = new HashMap, ICapability>(); - private boolean capabilitiesInitialized = false; - - private static final String OS_API_ENDPOINT = "oapi"; - - private String openShiftVersion; - private String kubernetesVersion; - private AuthorizationContext authContext; - private IApiTypeMapper typeMapper; - - public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, IApiTypeMapper typeMapper, AuthorizationContext authContext){ - this.baseUrl = baseUrl; - this.client = client; - this.factory = factory; - if(this.factory != null) { - this.factory.setClient(this); - } - initMasterVersion("version/openshift", new VersionCallback(version -> this.openShiftVersion = version)); - initMasterVersion("version", new VersionCallback(version -> this.kubernetesVersion = version)); - this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client); - this.authContext = authContext; - } - - - @Override - public IClient clone() { - AuthorizationContext context = authContext.clone(); - DefaultClient clone = new DefaultClient(baseUrl, client, factory, typeMapper, context); - context.setClient(clone); - return clone; - } - - - @Override - public IResourceFactory getResourceFactory() { - return factory; - }; - - @Override - public IWatcher watch(String namespace, IOpenShiftWatchListener listener, String...kinds) { - WatchClient watcher = new WatchClient(this, this.typeMapper, this.client); - return watcher.watch(Arrays.asList(kinds), namespace, listener); - } - - @Override - public IWatcher watch(IOpenShiftWatchListener listener, String...kinds) { - return this.watch("", listener, kinds); - } - - @Override - public String getResourceURI(IResource resource) { - return new URLBuilder(getBaseURL(), typeMapper, resource).build().toString(); - } - - @Override - public List list(String kind) { - return list(kind,""); - } - - @Override - public List list(String kind, Map labels) { - return list(kind,"", labels); - } - - - @Override - public List list(String kind, String namespace) { - return list(kind, namespace, new HashMap<>()); - } - - @Override - public List list(String kind, String namespace, Map labels) { - - String labelQuery=""; - if(labels != null && !labels.isEmpty()){ - labelQuery = labels.entrySet().stream() - .map(e -> e.getKey() + "=" + e.getValue()) - .collect(joining(",")); - } - return list(kind, namespace, labelQuery); - } - - @SuppressWarnings("unchecked") - @Override - public List list(String kind, String namespace, String labelQuery) { - - Map params = new HashMap<>(); - if(labelQuery != null && !labelQuery.isEmpty()){ - params.put("labelSelector", labelQuery); - } - - IList resources = execute(HttpMethod.GET.toString(), kind, namespace, null, null, null, params); - List items = new ArrayList<>(); - items.addAll((Collection) resources.getItems()); - return items; - } - - - @Override - public Collection create(IList list, String namespace){ - List results = new ArrayList(list.getItems().size()); - for (IResource resource : list.getItems()) { - try{ - results.add(create(resource, namespace)); - }catch(OpenShiftException e){ - if(e.getStatus() != null){ - results.add(e.getStatus()); - }else{ - throw e; - } - } - } - return results; - } - - @Override - public T create(T resource) { - return create(resource, resource.getNamespaceName()); - } - - - @Override - public T create(T resource, String namespace) { - return execute(HttpMethod.POST, resource.getKind(), namespace, null, null, resource); - } - - @Override - public T create(String kind, String namespace, String name, String subresource, IResource payload) { - return execute(HttpMethod.POST, kind, namespace, name, subresource, payload); - } - - enum HttpMethod{ - GET, - PUT, - POST, - DELETE - } - - private T execute(HttpMethod method, String kind, String namespace, String name, String subresource, IResource payload) { - return execute(method.toString(), kind, namespace, name, subresource, payload); - } - - @SuppressWarnings("unchecked") - public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, String subContext) { - return (T) execute(this.factory, method, kind, namespace, name, subresource, subContext, payload, - Collections.emptyMap()); - } - - @Override - @SuppressWarnings("unchecked") - public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload) { - return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload, - Collections.emptyMap()); - } +public class DefaultClient implements IClient, IHttpConstants { + + public static final String SYSTEM_PROP_K8E_API_VERSION = "osjc.k8e.apiversion"; + public static final String SYSTEM_PROP_OPENSHIFT_API_VERSION = "osjc.openshift.apiversion"; + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); + private URL baseUrl; + private OkHttpClient client; + private IResourceFactory factory; + private Map, ICapability> capabilities = new HashMap, ICapability>(); + private boolean capabilitiesInitialized = false; + + private static final String OS_API_ENDPOINT = "oapi"; + + private String openShiftVersion; + private String kubernetesVersion; + private AuthorizationContext authContext; + private IApiTypeMapper typeMapper; + + public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, IApiTypeMapper typeMapper, + AuthorizationContext authContext) { + this.baseUrl = baseUrl; + this.client = client; + this.factory = factory; + if (this.factory != null) { + this.factory.setClient(this); + } + initMasterVersion("version/openshift", new VersionCallback(version -> this.openShiftVersion = version)); + initMasterVersion("version", new VersionCallback(version -> this.kubernetesVersion = version)); + this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client); + this.authContext = authContext; + } + + @Override + public IClient clone() { + AuthorizationContext context = authContext.clone(); + DefaultClient clone = new DefaultClient(baseUrl, client, factory, typeMapper, context); + context.setClient(clone); + return clone; + } + + @Override + public IResourceFactory getResourceFactory() { + return factory; + } + + @Override + public IWatcher watch(String namespace, IOpenShiftWatchListener listener, String... kinds) { + WatchClient watcher = new WatchClient(this, this.typeMapper, this.client); + return watcher.watch(Arrays.asList(kinds), namespace, listener); + } + + @Override + public IWatcher watch(IOpenShiftWatchListener listener, String... kinds) { + return this.watch("", listener, kinds); + } + + @Override + public String getResourceURI(IResource resource) { + return new URLBuilder(getBaseURL(), typeMapper, resource).build().toString(); + } + + @Override + public List list(String kind) { + return list(kind, ""); + } + + @Override + public List list(String kind, Map labels) { + return list(kind, "", labels); + } + + @Override + public List list(String kind, String namespace) { + return list(kind, namespace, new HashMap<>()); + } + + @Override + public List list(String kind, String namespace, Map labels) { + + String labelQuery = ""; + if (labels != null && !labels.isEmpty()) { + labelQuery = labels.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(joining(",")); + } + return list(kind, namespace, labelQuery); + } + + @SuppressWarnings("unchecked") + @Override + public List list(String kind, String namespace, String labelQuery) { + + Map params = new HashMap<>(); + if (labelQuery != null && !labelQuery.isEmpty()) { + params.put("labelSelector", labelQuery); + } + + IList resources = execute(HttpMethod.GET.toString(), kind, namespace, null, null, null, params); + List items = new ArrayList<>(); + items.addAll((Collection) resources.getItems()); + return items; + } + + @Override + public Collection create(IList list, String namespace) { + List results = new ArrayList(list.getItems().size()); + for (IResource resource : list.getItems()) { + try { + results.add(create(resource, namespace)); + } catch (OpenShiftException e) { + if (e.getStatus() != null) { + results.add(e.getStatus()); + } else { + throw e; + } + } + } + return results; + } + + @Override + public T create(T resource) { + return create(resource, resource.getNamespaceName()); + } @Override + public T create(T resource, String namespace) { + return execute(HttpMethod.POST, resource.getKind(), namespace, null, null, resource); + } + + @Override + public T create(String kind, String namespace, String name, String subresource, + IResource payload) { + return execute(HttpMethod.POST, kind, namespace, name, subresource, payload); + } + + enum HttpMethod { + GET, PUT, POST, DELETE + } + + private T execute(HttpMethod method, String kind, String namespace, String name, + String subresource, IResource payload) { + return execute(method.toString(), kind, namespace, name, subresource, payload); + } + + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String namespace, String name, + String subresource, IResource payload, String subContext) { + return (T) execute(this.factory, method, kind, namespace, name, subresource, subContext, payload, + Collections.emptyMap()); + } + + @Override + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String namespace, String name, + String subresource, IResource payload) { + return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload, + Collections.emptyMap()); + } + + @Override + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String namespace, String name, + String subresource, IResource payload, Map params) { + return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload, params); + } + @SuppressWarnings("unchecked") - public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, Map params) { - return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload,params); - } - @SuppressWarnings("unchecked") - public T execute(ITypeFactory factory, String method, String kind, String namespace, String name, - String subresource, String subContext, JSONSerializeable payload, Map params) { - if(factory == null) { - throw new OpenShiftException("ITypeFactory is null while trying to call IClient#execute"); - } - - if(params == null){ - params = Collections.emptyMap(); - } - - if(ResourceKind.LIST.equals(kind)) - throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) - .kind(kind) - .name(name) - .namespace(namespace) - .subresource(subresource) - .subContext(subContext) - .addParameters(params) - .build(); - - try { - Request request = newRequestBuilderTo(endpoint.toString()) - .method(method, getPayload(method, payload)) - .build(); - LOGGER.debug("About to make {} request: {}", request.method(), request); - try(Response result = client.newCall(request).execute()){ - String response = result.body().string(); - LOGGER.debug("Response: {}", response); - return (T) factory.createInstanceFrom(response); - } - } catch (IOException e){ - throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); - } - } - - private RequestBody getPayload(String method, JSONSerializeable payload) { - switch(method.toUpperCase()){ - case "GET": - case "DELETE": - return null; - default: - String json = payload == null ? "" : payload.toJson(true); - LOGGER.debug("About to send payload: {}", json); - return RequestBody.create(MediaType.parse(MEDIATYPE_APPLICATION_JSON), json); - } - } - - - @Override - public String getServerReadyStatus() { - try { - Request request = new Request.Builder() - .url(new URL(this.baseUrl, "healthz/ready")) - .header(PROPERTY_ACCEPT, "*/*") - .build(); - try(Response response = client.newCall(request).execute()){ - return response.body().string(); - } - } catch (IOException e) { - throw new OpenShiftException(e, "Exception while trying to determine the health/ready response of the server"); - } - } - - public Request.Builder newRequestBuilderTo(String endpoint){ - return newRequestBuilderTo(endpoint, MEDIATYPE_APPLICATION_JSON); - } - - public Request.Builder newRequestBuilderTo(String endpoint,String acceptMediaType){ - Request.Builder builder = new Request.Builder() - .url(endpoint.toString()) - .header(PROPERTY_ACCEPT, acceptMediaType); - - String token = null; - if(this.authContext != null && StringUtils.isNotBlank(this.authContext.getToken())){ - token = this.authContext.getToken(); - } - builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)); - return builder; - } - - - @Override - public T update(T resource) { - return execute(HttpMethod.PUT, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, resource); - } - - @Override - public void delete(T resource) { - execute(HttpMethod.DELETE, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, resource); - } - - - @Override - public IList get(String kind, String namespace) { - return execute(HttpMethod.GET, kind, namespace, null, null, null); - } - - - @Override - public T get(String kind, String name, String namespace) { - return execute(HttpMethod.GET, kind, namespace, name, null, null); - } - - public synchronized void initializeCapabilities(){ - if(capabilitiesInitialized) return; - initializeClientCapabilities(capabilities, this); - capabilitiesInitialized = true; - } - - @SuppressWarnings("unchecked") - @Override - public T getCapability(Class capability) { - return (T) capabilities.get(capability); - } - - @Override - public boolean supports(Class capability) { - if(!capabilitiesInitialized ){ - initializeCapabilities(); - } - return capabilities.containsKey(capability); - } - - @SuppressWarnings("unchecked") - @Override - public R accept(CapabilityVisitor visitor, R unsupportedCapabililityValue){ - if(!capabilitiesInitialized) initializeCapabilities(); - if(capabilities.containsKey(visitor.getCapabilityType())){ - T capability = (T) capabilities.get(visitor.getCapabilityType()); - return (R) visitor.visit(capability); - } - return unsupportedCapabililityValue; - } - - @Override - public String getOpenShiftAPIVersion() { - return typeMapper.getPreferedVersionFor(OS_API_ENDPOINT); - } - - private void initMasterVersion(String versionInfoType, Callback callback) { - try { - Request request = new Request.Builder() - .url(new URL(this.baseUrl, versionInfoType)) - .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON) - .build(); - client.newCall(request).enqueue(callback); - } catch (IOException e) { - LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); - } - } - - private class VersionCallback implements Callback { - Consumer versionSetter; - public VersionCallback(Consumer versionSetter) { - this.versionSetter = versionSetter; - } - @Override - public void onFailure(Call call, IOException e) { - versionSetter.accept(""); - LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); - } - - @Override - public void onResponse(Call call, Response response) throws IOException { - try { - versionSetter.accept(ModelNode.fromJSONString(response.body().string()).get("gitVersion").asString()); - } finally { - response.close(); - } - } - } - - @Override - public String getOpenshiftMasterVersion() { - return this.openShiftVersion; - } - - @Override - public String getKubernetesMasterVersion() { - return this.kubernetesVersion; - } - - @Override - public URL getBaseURL() { - return this.baseUrl; - } - - @Override - public IAuthorizationContext getAuthorizationContext() { - return this.authContext; - } - - public void setToken(String token) { - this.authContext.setToken(token); - } - - public String getToken() { - return getAuthorizationContext().getToken(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((baseUrl == null) ? 0 : baseUrl.toString().hashCode()); - result = prime * result + ((kubernetesVersion == null) ? 0 : kubernetesVersion.hashCode()); - result = prime * result + ((openShiftVersion == null) ? 0 : openShiftVersion.hashCode()); - result = prime * result + ((authContext == null || authContext.getToken() == null) ? 0 : authContext.getToken().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof DefaultClient)) - return false; - DefaultClient other = (DefaultClient) obj; - if (baseUrl == null) { - if (other.baseUrl != null) - return false; - } else if (!baseUrl.toString().equals(other.baseUrl.toString())) - return false; - if (kubernetesVersion == null) { - if (other.kubernetesVersion != null) - return false; - } else if (!kubernetesVersion.equals(other.kubernetesVersion)) - return false; - if (openShiftVersion == null) { - if (other.openShiftVersion != null) - return false; - } else if (!openShiftVersion.equals(other.openShiftVersion)) { - return false; - } - if (authContext == null) { - return other.authContext == null; - } else { - if (other.authContext == null) { - return false; - } - return ObjectUtils.equals(authContext.getUserName(), other.authContext.getUserName()); - } - } - - @SuppressWarnings("unchecked") - @Override - public T adapt(Class klass) { - if(DefaultClient.class.equals(klass)){ - return (T) this; - } - if(OkHttpClient.class.equals(klass)) { - return (T) this.client; - } - if(IApiTypeMapper.class.equals(klass)) { - return (T)this.typeMapper; - } - if(ICapability.class.isAssignableFrom(klass) && this.supports((Class) klass)) { - return (T) getCapability((Class)klass); - } - return null; - } - - - + public T execute(ITypeFactory factory, String method, String kind, String namespace, String name, + String subresource, String subContext, JSONSerializeable payload, Map params) { + if (factory == null) { + throw new OpenShiftException("ITypeFactory is null while trying to call IClient#execute"); + } + + if (params == null) { + params = Collections.emptyMap(); + } + + if (ResourceKind.LIST.equals(kind)) { + throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); + } + final URL endpoint = new URLBuilder(this.baseUrl, typeMapper).kind(kind).name(name).namespace(namespace) + .subresource(subresource).subContext(subContext).addParameters(params).build(); + + try { + Request request = newRequestBuilderTo(endpoint.toString()).method(method, getPayload(method, payload)) + .build(); + LOGGER.debug("About to make {} request: {}", request.method(), request); + try (Response result = client.newCall(request).execute()) { + String response = result.body().string(); + LOGGER.debug("Response: {}", response); + return (T) factory.createInstanceFrom(response); + } + } catch (IOException e) { + throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); + } + } + + private RequestBody getPayload(String method, JSONSerializeable payload) { + switch (method.toUpperCase()) { + case "GET": + case "DELETE": + return null; + default: + String json = payload == null ? "" : payload.toJson(true); + LOGGER.debug("About to send payload: {}", json); + return RequestBody.create(MediaType.parse(MEDIATYPE_APPLICATION_JSON), json); + } + } + + @Override + public String getServerReadyStatus() { + try { + Request request = new Request.Builder().url(new URL(this.baseUrl, "healthz/ready")) + .header(PROPERTY_ACCEPT, "*/*").build(); + try (Response response = client.newCall(request).execute()) { + return response.body().string(); + } + } catch (IOException e) { + throw new OpenShiftException(e, + "Exception while trying to determine the health/ready response of the server"); + } + } + + public Request.Builder newRequestBuilderTo(String endpoint) { + return newRequestBuilderTo(endpoint, MEDIATYPE_APPLICATION_JSON); + } + + public Request.Builder newRequestBuilderTo(String endpoint, String acceptMediaType) { + Request.Builder builder = new Request.Builder().url(endpoint.toString()).header(PROPERTY_ACCEPT, + acceptMediaType); + + String token = null; + if (this.authContext != null && StringUtils.isNotBlank(this.authContext.getToken())) { + token = this.authContext.getToken(); + } + builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, + String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)); + return builder; + } + + @Override + public T update(T resource) { + return execute(HttpMethod.PUT, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, + resource); + } + + @Override + public void delete(T resource) { + execute(HttpMethod.DELETE, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, resource); + } + + @Override + public IList get(String kind, String namespace) { + return execute(HttpMethod.GET, kind, namespace, null, null, null); + } + + @Override + public T get(String kind, String name, String namespace) { + return execute(HttpMethod.GET, kind, namespace, name, null, null); + } + + public synchronized void initializeCapabilities() { + if (capabilitiesInitialized) { + return; + } + initializeClientCapabilities(capabilities, this); + capabilitiesInitialized = true; + } + + @SuppressWarnings("unchecked") + @Override + public T getCapability(Class capability) { + return (T) capabilities.get(capability); + } + + @Override + public boolean supports(Class capability) { + if (!capabilitiesInitialized) { + initializeCapabilities(); + } + return capabilities.containsKey(capability); + } + + @SuppressWarnings("unchecked") + @Override + public R accept(CapabilityVisitor visitor, R unsupportedCapabililityValue) { + if (!capabilitiesInitialized) { + initializeCapabilities(); + } + if (capabilities.containsKey(visitor.getCapabilityType())) { + T capability = (T) capabilities.get(visitor.getCapabilityType()); + return (R) visitor.visit(capability); + } + return unsupportedCapabililityValue; + } + + @Override + public String getOpenShiftAPIVersion() { + return typeMapper.getPreferedVersionFor(OS_API_ENDPOINT); + } + + private void initMasterVersion(String versionInfoType, Callback callback) { + try { + Request request = new Request.Builder().url(new URL(this.baseUrl, versionInfoType)) + .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON).build(); + client.newCall(request).enqueue(callback); + } catch (IOException e) { + LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); + } + } + + private class VersionCallback implements Callback { + Consumer versionSetter; + + public VersionCallback(Consumer versionSetter) { + this.versionSetter = versionSetter; + } + + @Override + public void onFailure(Call call, IOException e) { + versionSetter.accept(""); + LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + try { + versionSetter.accept(ModelNode.fromJSONString(response.body().string()).get("gitVersion").asString()); + } finally { + response.close(); + } + } + } + + @Override + public String getOpenshiftMasterVersion() { + return this.openShiftVersion; + } + + @Override + public String getKubernetesMasterVersion() { + return this.kubernetesVersion; + } + + @Override + public URL getBaseURL() { + return this.baseUrl; + } + + @Override + public IAuthorizationContext getAuthorizationContext() { + return this.authContext; + } + + public void setToken(String token) { + this.authContext.setToken(token); + } + + public String getToken() { + return getAuthorizationContext().getToken(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((baseUrl == null) ? 0 : baseUrl.toString().hashCode()); + result = prime * result + ((kubernetesVersion == null) ? 0 : kubernetesVersion.hashCode()); + result = prime * result + ((openShiftVersion == null) ? 0 : openShiftVersion.hashCode()); + result = prime * result + + ((authContext == null || authContext.getToken() == null) ? 0 : authContext.getToken().hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof DefaultClient)) { + return false; + } + DefaultClient other = (DefaultClient) obj; + if (baseUrl == null) { + if (other.baseUrl != null) { + return false; + } + } else if (!baseUrl.toString().equals(other.baseUrl.toString())) { + return false; + } + if (kubernetesVersion == null) { + if (other.kubernetesVersion != null) { + return false; + } + } else if (!kubernetesVersion.equals(other.kubernetesVersion)) { + return false; + } + if (openShiftVersion == null) { + if (other.openShiftVersion != null) { + return false; + } + } else if (!openShiftVersion.equals(other.openShiftVersion)) { + return false; + } + if (authContext == null) { + return other.authContext == null; + } else { + if (other.authContext == null) { + return false; + } + return ObjectUtils.equals(authContext.getUserName(), other.authContext.getUserName()); + } + } + + @SuppressWarnings("unchecked") + @Override + public T adapt(Class klass) { + if (DefaultClient.class.equals(klass)) { + return (T) this; + } + if (OkHttpClient.class.equals(klass)) { + return (T) this.client; + } + if (IApiTypeMapper.class.equals(klass)) { + return (T) this.typeMapper; + } + if (ICapability.class.isAssignableFrom(klass) && this.supports((Class) klass)) { + return (T) getCapability((Class) klass); + } + return null; + } + } diff --git a/src/main/java/com/openshift/internal/restclient/KubernetesAPIVersion.java b/src/main/java/com/openshift/internal/restclient/KubernetesAPIVersion.java index 80efcb7b..3310dd2e 100644 --- a/src/main/java/com/openshift/internal/restclient/KubernetesAPIVersion.java +++ b/src/main/java/com/openshift/internal/restclient/KubernetesAPIVersion.java @@ -6,27 +6,26 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient; /** - * This list of supported Kubernetes API Models - * by this client + * This list of supported Kubernetes API Models by this client * * @author Jeff Cantrill */ -public enum KubernetesAPIVersion implements APIModelVersion{ - @Deprecated - v1beta3(2), - v1(3); - - private int order; - - KubernetesAPIVersion( int order){ - this.order = order; - } - - @Override - public int getOrder(){ - return order; - } +public enum KubernetesAPIVersion implements APIModelVersion { + @Deprecated + v1beta3(2), v1(3); + + private int order; + + KubernetesAPIVersion(int order) { + this.order = order; + } + + @Override + public int getOrder() { + return order; + } } diff --git a/src/main/java/com/openshift/internal/restclient/OpenShiftAPIVersion.java b/src/main/java/com/openshift/internal/restclient/OpenShiftAPIVersion.java index 57193bf0..d3da3bcf 100644 --- a/src/main/java/com/openshift/internal/restclient/OpenShiftAPIVersion.java +++ b/src/main/java/com/openshift/internal/restclient/OpenShiftAPIVersion.java @@ -6,27 +6,25 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient; /** - * This list of supported OpenShift API Models - * by this client + * This list of supported OpenShift API Models by this client * - * @author Jeff Cantrill */ -public enum OpenShiftAPIVersion implements APIModelVersion{ - @Deprecated - v1beta3(2), - v1(3); +public enum OpenShiftAPIVersion implements APIModelVersion { + @Deprecated + v1beta3(2), v1(3); + + private int order; - private int order; + OpenShiftAPIVersion(int order) { + this.order = order; + } - OpenShiftAPIVersion(int order){ - this.order = order; - } - - @Override - public int getOrder(){ - return order; - } + @Override + public int getOrder() { + return order; + } } diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index bbabd12d..1246f204 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient; import java.io.IOException; @@ -19,12 +20,28 @@ import java.util.Map; import java.util.Optional; -import com.openshift.internal.restclient.model.*; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; -import com.openshift.internal.restclient.model.volume.PersistentVolume; +import com.openshift.internal.restclient.model.Build; +import com.openshift.internal.restclient.model.BuildConfig; +import com.openshift.internal.restclient.model.ConfigMap; +import com.openshift.internal.restclient.model.DeploymentConfig; +import com.openshift.internal.restclient.model.ImageStream; +import com.openshift.internal.restclient.model.KubernetesEvent; +import com.openshift.internal.restclient.model.KubernetesResource; +import com.openshift.internal.restclient.model.LimitRange; +import com.openshift.internal.restclient.model.Namespace; +import com.openshift.internal.restclient.model.Pod; +import com.openshift.internal.restclient.model.Project; +import com.openshift.internal.restclient.model.ReplicationController; +import com.openshift.internal.restclient.model.ResourceQuota; +import com.openshift.internal.restclient.model.Route; +import com.openshift.internal.restclient.model.Secret; +import com.openshift.internal.restclient.model.Service; +import com.openshift.internal.restclient.model.ServiceAccount; +import com.openshift.internal.restclient.model.Status; import com.openshift.internal.restclient.model.authorization.OpenshiftPolicy; import com.openshift.internal.restclient.model.authorization.OpenshiftRole; import com.openshift.internal.restclient.model.authorization.PolicyBinding; @@ -39,6 +56,7 @@ import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.internal.restclient.model.template.Template; import com.openshift.internal.restclient.model.user.OpenShiftUser; +import com.openshift.internal.restclient.model.volume.PersistentVolume; import com.openshift.internal.restclient.model.volume.PersistentVolumeClaim; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; @@ -50,213 +68,218 @@ import com.openshift.restclient.model.IResource; /** - * ResourceFactory creates a list of resources from a json string + * ResourceFactory creates a list of resources from a json string * - * @author Jeff Cantrill */ -public class ResourceFactory implements IResourceFactory{ - - private static final String KIND = "kind"; - private static final String APIVERSION = "apiVersion"; - private static final Map> IMPL_MAP = new HashMap<>(); - static { - //OpenShift kinds - IMPL_MAP.put(ResourceKind.BUILD, Build.class); - IMPL_MAP.put(ResourceKind.BUILD_CONFIG, BuildConfig.class); - IMPL_MAP.put(ResourceKind.BUILD_REQUEST, BuildRequest.class); - IMPL_MAP.put(ResourceKind.DEPLOYMENT_CONFIG, DeploymentConfig.class); - IMPL_MAP.put(ResourceKind.IMAGE_STREAM, ImageStream.class); - IMPL_MAP.put(ResourceKind.IMAGE_STREAM_IMPORT, ImageStreamImport.class); - IMPL_MAP.put(ResourceKind.LIST, com.openshift.internal.restclient.model.List.class); - IMPL_MAP.put(ResourceKind.NAMESPACE, Namespace.class); - IMPL_MAP.put(ResourceKind.OAUTH_ACCESS_TOKEN, OAuthAccessToken.class); - IMPL_MAP.put(ResourceKind.OAUTH_AUTHORIZE_TOKEN, OAuthAuthorizeToken.class); - IMPL_MAP.put(ResourceKind.OAUTH_CLIENT, OAuthClient.class); - IMPL_MAP.put(ResourceKind.OAUTH_CLIENT_AUTHORIZATION, OAuthClientAuthorization.class); - IMPL_MAP.put(ResourceKind.PROJECT, Project.class); - IMPL_MAP.put(ResourceKind.PROJECT_REQUEST, OpenshiftProjectRequest.class); - IMPL_MAP.put(ResourceKind.POLICY, OpenshiftPolicy.class); - IMPL_MAP.put(ResourceKind.POLICY_BINDING, PolicyBinding.class); - IMPL_MAP.put(ResourceKind.ROLE, OpenshiftRole.class); - IMPL_MAP.put(ResourceKind.ROLE_BINDING, RoleBinding.class); - IMPL_MAP.put(ResourceKind.ROUTE, Route.class); - IMPL_MAP.put(ResourceKind.TEMPLATE, Template.class); - IMPL_MAP.put(ResourceKind.USER, OpenShiftUser.class); - - //Kubernetes Kinds - IMPL_MAP.put(ResourceKind.EVENT, KubernetesEvent.class); - IMPL_MAP.put(ResourceKind.LIMIT_RANGE, LimitRange.class); - IMPL_MAP.put(ResourceKind.POD, Pod.class); - IMPL_MAP.put(ResourceKind.PVC, PersistentVolumeClaim.class); - IMPL_MAP.put(ResourceKind.PERSISTENT_VOLUME, PersistentVolume.class); - IMPL_MAP.put(ResourceKind.RESOURCE_QUOTA, ResourceQuota.class); - IMPL_MAP.put(ResourceKind.REPLICATION_CONTROLLER, ReplicationController.class); - IMPL_MAP.put(ResourceKind.STATUS, Status.class); - IMPL_MAP.put(ResourceKind.SERVICE, Service.class); - IMPL_MAP.put(ResourceKind.SECRET, Secret.class); - IMPL_MAP.put(ResourceKind.SERVICE_ACCOUNT, ServiceAccount.class); - IMPL_MAP.put(ResourceKind.CONFIG_MAP, ConfigMap.class); - - //fallback - IMPL_MAP.put(ResourceKind.UNRECOGNIZED, KubernetesResource.class); - - } - private IClient client; - - public ResourceFactory(IClient client) { - this.client = client; - } - - public static Map> getImplMap(){ - return Collections.unmodifiableMap(IMPL_MAP); - } +public class ResourceFactory implements IResourceFactory { + + private static final String KIND = "kind"; + private static final String APIVERSION = "apiVersion"; + private static final Map> IMPL_MAP = new HashMap<>(); + + static { + // OpenShift kinds + IMPL_MAP.put(ResourceKind.BUILD, Build.class); + IMPL_MAP.put(ResourceKind.BUILD_CONFIG, BuildConfig.class); + IMPL_MAP.put(ResourceKind.BUILD_REQUEST, BuildRequest.class); + IMPL_MAP.put(ResourceKind.DEPLOYMENT_CONFIG, DeploymentConfig.class); + IMPL_MAP.put(ResourceKind.IMAGE_STREAM, ImageStream.class); + IMPL_MAP.put(ResourceKind.IMAGE_STREAM_IMPORT, ImageStreamImport.class); + IMPL_MAP.put(ResourceKind.LIST, com.openshift.internal.restclient.model.List.class); + IMPL_MAP.put(ResourceKind.NAMESPACE, Namespace.class); + IMPL_MAP.put(ResourceKind.OAUTH_ACCESS_TOKEN, OAuthAccessToken.class); + IMPL_MAP.put(ResourceKind.OAUTH_AUTHORIZE_TOKEN, OAuthAuthorizeToken.class); + IMPL_MAP.put(ResourceKind.OAUTH_CLIENT, OAuthClient.class); + IMPL_MAP.put(ResourceKind.OAUTH_CLIENT_AUTHORIZATION, OAuthClientAuthorization.class); + IMPL_MAP.put(ResourceKind.PROJECT, Project.class); + IMPL_MAP.put(ResourceKind.PROJECT_REQUEST, OpenshiftProjectRequest.class); + IMPL_MAP.put(ResourceKind.POLICY, OpenshiftPolicy.class); + IMPL_MAP.put(ResourceKind.POLICY_BINDING, PolicyBinding.class); + IMPL_MAP.put(ResourceKind.ROLE, OpenshiftRole.class); + IMPL_MAP.put(ResourceKind.ROLE_BINDING, RoleBinding.class); + IMPL_MAP.put(ResourceKind.ROUTE, Route.class); + IMPL_MAP.put(ResourceKind.TEMPLATE, Template.class); + IMPL_MAP.put(ResourceKind.USER, OpenShiftUser.class); + + // Kubernetes Kinds + IMPL_MAP.put(ResourceKind.EVENT, KubernetesEvent.class); + IMPL_MAP.put(ResourceKind.LIMIT_RANGE, LimitRange.class); + IMPL_MAP.put(ResourceKind.POD, Pod.class); + IMPL_MAP.put(ResourceKind.PVC, PersistentVolumeClaim.class); + IMPL_MAP.put(ResourceKind.PERSISTENT_VOLUME, PersistentVolume.class); + IMPL_MAP.put(ResourceKind.RESOURCE_QUOTA, ResourceQuota.class); + IMPL_MAP.put(ResourceKind.REPLICATION_CONTROLLER, ReplicationController.class); + IMPL_MAP.put(ResourceKind.STATUS, Status.class); + IMPL_MAP.put(ResourceKind.SERVICE, Service.class); + IMPL_MAP.put(ResourceKind.SECRET, Secret.class); + IMPL_MAP.put(ResourceKind.SERVICE_ACCOUNT, ServiceAccount.class); + IMPL_MAP.put(ResourceKind.CONFIG_MAP, ConfigMap.class); + + // fallback + IMPL_MAP.put(ResourceKind.UNRECOGNIZED, KubernetesResource.class); + + } + + private IClient client; + + public ResourceFactory(IClient client) { + this.client = client; + } + + public static Map> getImplMap() { + return Collections.unmodifiableMap(IMPL_MAP); + } + + public List createList(String json, String kind) { + ModelNode data = ModelNode.fromJSONString(json); + final String dataKind = data.get(KIND).asString(); + if (!(kind.toString() + "List").equals(dataKind)) { + throw new RuntimeException( + String.format("Unexpected container type '%s' for desired kind: %s", dataKind, kind)); + } + + try { + final String version = data.get(APIVERSION).asString(); + return buildList(version, data.get("items").asList(), kind); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - public List createList(String json, String kind){ - ModelNode data = ModelNode.fromJSONString(json); - final String dataKind = data.get(KIND).asString(); - if(!(kind.toString() + "List").equals(dataKind)){ - throw new RuntimeException(String.format("Unexpected container type '%s' for desired kind: %s", dataKind, kind)); - } - - try{ - final String version = data.get(APIVERSION).asString(); - return buildList(version, data.get("items").asList(), kind); - }catch(Exception e){ - throw new RuntimeException(e); - } - } + private List buildList(final String version, List items, String kind) + throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException { + List resources = new ArrayList(items.size()); + for (ModelNode item : items) { + resources.add(create(item, version, kind)); + } + return resources; + } - private List buildList(final String version, List items, String kind) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - List resources = new ArrayList(items.size()); - for (ModelNode item : items) { - resources.add(create(item, version, kind)); - } - return resources; - } - - @Override - @SuppressWarnings("unchecked") - public IResource create(InputStream input) { - try { - String resource = IOUtils.toString(input, "UTF-8"); - return create(resource); - } catch (IOException e) { - throw new ResourceFactoryException(e, "There was an exception creating the resource from the InputStream"); - } - } - - - @Override - public Object createInstanceFrom(String response) { - return create(response); - } + @Override + @SuppressWarnings("unchecked") + public IResource create(InputStream input) { + try { + String resource = IOUtils.toString(input, "UTF-8"); + return create(resource); + } catch (IOException e) { + throw new ResourceFactoryException(e, "There was an exception creating the resource from the InputStream"); + } + } - @Override - @SuppressWarnings("unchecked") - public T create(String response) { - try { - ModelNode node = ModelNode.fromJSONString(response); - String version = node.get(APIVERSION).asString(); - String kind = node.get(KIND).asString(); - return (T) create(node, version, kind); - } catch (UnsupportedVersionException e) { - throw e; - }catch(Exception e) { - throw new ResourceFactoryException(e, "There was an exception creating the resource from: %s", response); - } - } - - - @Override - @SuppressWarnings("unchecked") - public T create(String version, String kind) { - return (T) create(new ModelNode(), version, kind); - } - @Override - @SuppressWarnings("unchecked") - public T create(String version, String kind, String name) { - T resource = (T) create(new ModelNode(), version, kind); - ((KubernetesResource)resource).setName(name); - return resource; - } + @Override + @SuppressWarnings("unchecked") + public T create(String response) { + try { + ModelNode node = ModelNode.fromJSONString(response); + String version = node.get(APIVERSION).asString(); + String kind = node.get(KIND).asString(); + return (T) create(node, version, kind); + } catch (UnsupportedVersionException e) { + throw e; + } catch (Exception e) { + throw new ResourceFactoryException(e, "There was an exception creating the resource from: %s", response); + } + } - private IResource create(ModelNode node, String version, String kind) { - try { - node.get(APIVERSION).set(version); - node.get(KIND).set(kind.toString()); - Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); - if(kind.endsWith("List")) { - return new com.openshift.internal.restclient.model.List(node, client, properyKeyMap); - } - Class klass = getResourceClass(version, kind); - if(klass != null) { - Constructor constructor = klass.getConstructor(ModelNode.class, IClient.class, Map.class); - return constructor.newInstance(node, client, properyKeyMap); - } - return new KubernetesResource(node, client, properyKeyMap); - } catch (UnsupportedVersionException e) { - throw e; - } catch (Exception e) { - throw new ResourceFactoryException(e,"Unable to create %s resource kind %s from %s", version, kind, node); - } - } - - @SuppressWarnings("unchecked") - private Class getResourceClass(String version, String kind){ - if(IMPL_MAP.containsKey(kind)) { + @Override + @SuppressWarnings("unchecked") + public T create(String version, String kind) { + return (T) create(new ModelNode(), version, kind); + } + + @Override + @SuppressWarnings("unchecked") + public T create(String version, String kind, String name) { + T resource = (T) create(new ModelNode(), version, kind); + ((KubernetesResource) resource).setName(name); + return resource; + } + + private IResource create(ModelNode node, String version, String kind) { + try { + node.get(APIVERSION).set(version); + node.get(KIND).set(kind.toString()); + Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); + if (kind.endsWith("List")) { + return new com.openshift.internal.restclient.model.List(node, client, properyKeyMap); + } + Class klass = getResourceClass(version, kind); + if (klass != null) { + Constructor constructor = klass.getConstructor(ModelNode.class, IClient.class, + Map.class); + return constructor.newInstance(node, client, properyKeyMap); + } + return new KubernetesResource(node, client, properyKeyMap); + } catch (UnsupportedVersionException e) { + throw e; + } catch (Exception e) { + throw new ResourceFactoryException(e, "Unable to create %s resource kind %s from %s", version, kind, node); + } + } + + @Override + public Object createInstanceFrom(String response) { + return create(response); + } + + @SuppressWarnings("unchecked") + private Class getResourceClass(String version, String kind) { + if (IMPL_MAP.containsKey(kind)) { return IMPL_MAP.get(kind); } - IApiTypeMapper mapper = this.client.adapt(IApiTypeMapper.class); - if(mapper != null) { - IVersionedApiResource endpoint = mapper.getEndpointFor(version, kind); - String extension = ""; - switch(endpoint.getPrefix()) { - case IApiTypeMapper.KUBE_API: - case IApiTypeMapper.OS_API: - break; + IApiTypeMapper mapper = this.client.adapt(IApiTypeMapper.class); + if (mapper != null) { + IVersionedApiResource endpoint = mapper.getEndpointFor(version, kind); + String extension = ""; + switch (endpoint.getPrefix()) { + case IApiTypeMapper.KUBE_API: + case IApiTypeMapper.OS_API: + break; default: String extPlusVersion = endpoint.getApiGroupName(); extension = StringUtils.split(extPlusVersion, IApiTypeMapper.FWD_SLASH)[0]; - } - try { - String classname = String.format("com.openshift.internal.restclient.%s%s.models.%s", endpoint.getPrefix(), extension, endpoint.getKind()); - return (Class)Class.forName(classname); - }catch(ClassNotFoundException e) { - //class doesnt exist in the exp location. - //fallback to an explicit registration - } - } - return null; - } + } + try { + String classname = String.format("com.openshift.internal.restclient.%s%s.models.%s", + endpoint.getPrefix(), extension, endpoint.getKind()); + return (Class) Class.forName(classname); + } catch (ClassNotFoundException e) { + // class doesnt exist in the exp location. + // fallback to an explicit registration + } + } + return null; + } - @SuppressWarnings("unchecked") - @Override - public T stub(String kind, String name, String namespace) { - //TODO get k8e or os - String version = client.getOpenShiftAPIVersion(); - KubernetesResource resource = (KubernetesResource) create(version, kind); - resource.setName(name); - resource.setNamespace(namespace); - if(StringUtils.isNotEmpty(namespace)) { - resource.setNamespace(namespace); - } - return (T) resource; - } + @SuppressWarnings("unchecked") + @Override + public T stub(String kind, String name, String namespace) { + // TODO get k8e or os + String version = client.getOpenShiftAPIVersion(); + KubernetesResource resource = (KubernetesResource) create(version, kind); + resource.setName(name); + resource.setNamespace(namespace); + if (StringUtils.isNotEmpty(namespace)) { + resource.setNamespace(namespace); + } + return (T) resource; + } - @Override - public Object stubKind(String kind, Optional name, Optional namespace) { - return stub(kind, name.get(), namespace.get()); - } + @Override + public T stub(String kind, String name) { + return stub(kind, name, null); + } + + @Override + public Object stubKind(String kind, Optional name, Optional namespace) { + return stub(kind, name.get(), namespace.get()); + } - @Override - public T stub(String kind, String name) { - return stub(kind, name, null); - } + @Override + public void setClient(IClient client) { + this.client = client; + } - @Override - public void setClient(IClient client) { - this.client = client; - } - } diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index 5058e6fe..f32fa06a 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -6,18 +6,8 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ -package com.openshift.internal.restclient; -import com.openshift.restclient.IApiTypeMapper; -import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; -import com.openshift.restclient.OpenShiftException; -import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.UnsupportedEndpointException; -import com.openshift.restclient.http.IHttpConstants; -import com.openshift.restclient.model.IResource; -import org.apache.commons.lang.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +package com.openshift.internal.restclient; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; @@ -28,190 +18,205 @@ import java.util.Iterator; import java.util.Map; +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; +import com.openshift.restclient.OpenShiftException; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.UnsupportedEndpointException; +import com.openshift.restclient.http.IHttpConstants; +import com.openshift.restclient.model.IResource; + /** - * Helper class to build the URL connection string in the proper - * format + * Helper class to build the URL connection string in the proper format * - * @author Jeff Cantrill */ public class URLBuilder { - - private static final Logger LOG = LoggerFactory.getLogger(URLBuilder.class); - - private String baseUrl; - private String kind; - private String name; - private ArrayList> params = new ArrayList<>(); - private final IApiTypeMapper typeMappings; - - private String apiVersion; - private String namespace; - private String subResource; - private String subContext; - - - /** - * - * @param baseUrl - * @param typeMappings the map of kinds to endpoint - * @param resource - */ - URLBuilder(URL baseUrl, IApiTypeMapper typeMappings, IResource resource) { - this(baseUrl, typeMappings); - resource(resource); - } - - /** - * - * @param baseUrl - * @param typeMappings the map of kinds to endpoint - */ - public URLBuilder(URL baseUrl, IApiTypeMapper typeMappings) { - this.baseUrl = baseUrl.toString().replaceAll("/*$", ""); - this.typeMappings = typeMappings; - } - - public URLBuilder apiVersion(String apiVersion){ - this.apiVersion = apiVersion; - return this; - } - - public URLBuilder namespace(String namespace){ - if(StringUtils.isBlank(namespace)) return this; - this.namespace = namespace; - return this; - } - - public URLBuilder name(String name) { - this.name = name; - return this; - } - - public URLBuilder kind(String kind) { - if(!ResourceKind.values().contains(kind)) { - LOG.warn(String.format("There kind '%s' is not recognized by this client; this operation may fail.", kind)); - } - this.kind = kind; - return this; - } - - public URLBuilder resource(IResource resource) { - if (resource == null) return this; - this.name = resource.getName(); - kind(resource.getKind()); - namespace(resource.getNamespaceName()); - return this; - } - - public URLBuilder addParmeter(String key, String value) { - params.add(new AbstractMap.SimpleEntry<>( key, value )); - return this; - } - - - public URLBuilder subresource(String value) { - this.subResource = value; - return this; - } - - public URLBuilder subContext(String value) { - this.subContext = value; - return this; - } - - /** - * Builds a URL based on the information provided. Either a resource or - * a resource kind must be provided - * @return - */ - public URL build() { - StringBuilder url = new StringBuilder(baseUrl); - if (kind == null) - throw new RuntimeException( - "Unable to build a URL because the ResourceKind is unknown"); - buildWithNamespaceInPath(url); - - try { - if(LOG.isDebugEnabled()) { - LOG.debug(String.format("Built url: %s", url.toString())); - } - return new URL(url.toString()); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - } - - private void buildWithNamespaceInPath(StringBuilder url) { - if(!typeMappings.isSupported(apiVersion, kind)) { - throw new UnsupportedEndpointException("Unable to determine the api endpoint for kind '%s'", kind); - } - url.append("/"); - IVersionedApiResource apiResource = typeMappings.getEndpointFor(apiVersion, kind); - url.append(apiResource.getPrefix()).append("/").append(apiResource.getVersion()); - if(namespace == null && apiResource.isNamespaced()) { - LOG.debug("The api endpoint for kind '{}' requires a namespace but none was provided. Will only work for priviledged user.", kind); - } - if(!ResourceKind.PROJECT.equals(kind) && namespace != null) { - url.append("/namespaces/") - .append(namespace); - } - url.append("/").append(apiResource.getName()); - if (name != null) { - url.append("/").append(name); - } - if(StringUtils.isNotBlank(subResource) && !apiResource.isSupported(subResource)){ - throw new OpenShiftException("The api endpoint for kind '%s' && subresource '%s' is not supported by the cluster", kind, subResource); - } - if(StringUtils.isNotBlank(subResource)) { - url.append("/").append(subResource); - } - if (StringUtils.isNotBlank(subContext)){ - url.append("/").append(subContext); - } - url = appendParameters(url); - } - - private StringBuilder appendParameters(StringBuilder url) { - if (!params.isEmpty()) { - url.append(IHttpConstants.QUESTION_MARK); - for ( Iterator> iterator = params.iterator(); iterator.hasNext(); ) { - AbstractMap.SimpleEntry entry = iterator.next(); - try { - if(StringUtils.isNotBlank(entry.getValue())) { - url.append(entry.getKey()) - .append(IHttpConstants.EQUALS) - .append(URLEncoder.encode(entry.getValue(), "UTF-8")); - }else { - LOG.error("Unable to append parameter: {} since it is blank", entry.getKey()); - } - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - if (iterator.hasNext()) { - url.append(IHttpConstants.AMPERSAND); - } - } - } - return url; - } - - public URLBuilder watch() { - addParmeter("watch", "true"); - return this; - } - - public String websocket() { - String url = build().toString(); - url = "wss" + url.substring(url.indexOf(":")); - if(LOG.isDebugEnabled()) { - LOG.debug(String.format("Built url: %s", url)); - } - return url; - } - - public URLBuilder addParameters(Map params) { - params.forEach((k,v)->addParmeter(k, v)); - return this; - } + + private static final Logger LOG = LoggerFactory.getLogger(URLBuilder.class); + + private String baseUrl; + private String kind; + private String name; + private ArrayList> params = new ArrayList<>(); + private final IApiTypeMapper typeMappings; + + private String apiVersion; + private String namespace; + private String subResource; + private String subContext; + + /** + * + * @param baseUrl the base url + * @param typeMappings + * the map of kinds to endpoint + * @param resource the resource to use for building + */ + URLBuilder(URL baseUrl, IApiTypeMapper typeMappings, IResource resource) { + this(baseUrl, typeMappings); + resource(resource); + } + + /** + * + * @param typeMappings + * the map of kinds to endpoint + */ + public URLBuilder(URL baseUrl, IApiTypeMapper typeMappings) { + this.baseUrl = baseUrl.toString().replaceAll("/*$", ""); + this.typeMappings = typeMappings; + } + + public URLBuilder apiVersion(String apiVersion) { + this.apiVersion = apiVersion; + return this; + } + + public URLBuilder namespace(String namespace) { + if (StringUtils.isBlank(namespace)) { + return this; + } + this.namespace = namespace; + return this; + } + + public URLBuilder name(String name) { + this.name = name; + return this; + } + + public URLBuilder kind(String kind) { + if (!ResourceKind.values().contains(kind)) { + LOG.warn(String.format("There kind '%s' is not recognized by this client; this operation may fail.", kind)); + } + this.kind = kind; + return this; + } + + public URLBuilder resource(IResource resource) { + if (resource == null) { + return this; + } + this.name = resource.getName(); + kind(resource.getKind()); + namespace(resource.getNamespaceName()); + return this; + } + + public URLBuilder addParmeter(String key, String value) { + params.add(new AbstractMap.SimpleEntry<>(key, value)); + return this; + } + + public URLBuilder subresource(String value) { + this.subResource = value; + return this; + } + + public URLBuilder subContext(String value) { + this.subContext = value; + return this; + } + + /** + * Builds a URL based on the information provided. Either a resource or a + * resource kind must be provided + * + */ + public URL build() { + StringBuilder url = new StringBuilder(baseUrl); + if (kind == null) { + throw new RuntimeException("Unable to build a URL because the ResourceKind is unknown"); + } + buildWithNamespaceInPath(url); + + try { + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Built url: %s", url.toString())); + } + return new URL(url.toString()); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + private void buildWithNamespaceInPath(StringBuilder url) { + if (!typeMappings.isSupported(apiVersion, kind)) { + throw new UnsupportedEndpointException("Unable to determine the api endpoint for kind '%s'", kind); + } + url.append("/"); + IVersionedApiResource apiResource = typeMappings.getEndpointFor(apiVersion, kind); + url.append(apiResource.getPrefix()).append("/").append(apiResource.getVersion()); + if (namespace == null && apiResource.isNamespaced()) { + LOG.debug( + "The api endpoint for kind '{}' requires a namespace but none was provided. Will only work for priviledged user.", + kind); + } + if (!ResourceKind.PROJECT.equals(kind) && namespace != null) { + url.append("/namespaces/").append(namespace); + } + url.append("/").append(apiResource.getName()); + if (name != null) { + url.append("/").append(name); + } + if (StringUtils.isNotBlank(subResource) && !apiResource.isSupported(subResource)) { + throw new OpenShiftException( + "The api endpoint for kind '%s' && subresource '%s' is not supported by the cluster", kind, + subResource); + } + if (StringUtils.isNotBlank(subResource)) { + url.append("/").append(subResource); + } + if (StringUtils.isNotBlank(subContext)) { + url.append("/").append(subContext); + } + url = appendParameters(url); + } + + private StringBuilder appendParameters(StringBuilder url) { + if (!params.isEmpty()) { + url.append(IHttpConstants.QUESTION_MARK); + for (Iterator> iterator = params.iterator(); iterator.hasNext();) { + AbstractMap.SimpleEntry entry = iterator.next(); + try { + if (StringUtils.isNotBlank(entry.getValue())) { + url.append(entry.getKey()).append(IHttpConstants.EQUALS) + .append(URLEncoder.encode(entry.getValue(), "UTF-8")); + } else { + LOG.error("Unable to append parameter: {} since it is blank", entry.getKey()); + } + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + if (iterator.hasNext()) { + url.append(IHttpConstants.AMPERSAND); + } + } + } + return url; + } + + public URLBuilder watch() { + addParmeter("watch", "true"); + return this; + } + + public String websocket() { + String url = build().toString(); + url = "wss" + url.substring(url.indexOf(":")); + if (LOG.isDebugEnabled()) { + LOG.debug(String.format("Built url: %s", url)); + } + return url; + } + + public URLBuilder addParameters(Map params) { + params.forEach((k, v) -> addParmeter(k, v)); + return this; + } } diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java index 0adde14b..df2be371 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java @@ -8,8 +8,16 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.api.capabilities; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.URLBuilder; import com.openshift.internal.restclient.capability.AbstractCapability; @@ -17,168 +25,161 @@ import com.openshift.internal.restclient.okhttp.WebSocketAdapter; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; -import com.openshift.restclient.capability.IStoppable; import com.openshift.restclient.api.capabilities.IPodExec; +import com.openshift.restclient.capability.IStoppable; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IPod; + import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; import okhttp3.ws.WebSocket; import okhttp3.ws.WebSocketCall; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; public class PodExec extends AbstractCapability implements IPodExec { - private static final Logger LOG = LoggerFactory.getLogger(IPodExec.class); - private static final String CAPABILITY = "exec"; - - private static final String COMMAND = "command"; - - private static final String K8S_PROTOCOL_HEADER = "X-Stream-Protocol-Version"; - - private static final String K8S_PROTOCOL = "channel.k8s.io"; - - public static final int CHANNEL_STDOUT = 1; - public static final int CHANNEL_STDERR = 2; - public static final int CHANNEL_EXECERR = 3; - - private final IPod pod; - private final DefaultClient client; - private final IApiTypeMapper mapper; - - public PodExec(IPod pod, IClient client) { - super( pod, client, CAPABILITY ); - this.pod = pod; - this.client = client.adapt(DefaultClient.class); - this.mapper = client.adapt(IApiTypeMapper.class); - } - - @Override - public String getName() { - return PodExec.class.getSimpleName(); - } - - @Override - public IStoppable start( IPodExecOutputListener listener, Options options, String... commands ) { - - if ( options == null ) { - options = new Options(); - } - - /* - with 3.7 per https://github.com/openshift/origin/issues/15330, 3.6 was evidently broke in allowing stdErr/stdOut to not be set; need to set stdout/stderr to true - */ - options.stdErr(true); - options.stdOut(true); - - - Map parameters = options.getMap(); - - OkHttpClient okClient = client.adapt(OkHttpClient.class); - - URLBuilder urlBuilder = new URLBuilder(client.getBaseURL(), mapper) - .resource(pod) - .subresource(CAPABILITY) - .addParameters(parameters); - - // The main command and all arguments are specified as 'command' parameters - for ( String command : commands ) { - urlBuilder.addParmeter( COMMAND, command ); - } - - final String endpoint = urlBuilder.websocket(); - - Request request = client.newRequestBuilderTo(endpoint, IHttpConstants.MEDIATYPE_ANY) - .method( "GET", null ) - .addHeader(K8S_PROTOCOL_HEADER, K8S_PROTOCOL ) - // Unless we mark this as ignored, exceptions triggered by interceptor would be lost in dispatcher thread - .tag( new ResponseCodeInterceptor.Ignore() {} ) - .build(); - - WebSocketCall call = WebSocketCall.create(okClient, request); - ExecOutputListenerAdapter adapter = new ExecOutputListenerAdapter(call, listener); - call.enqueue(adapter); - return adapter; - } - - static class ExecOutputListenerAdapter extends WebSocketAdapter implements IStoppable{ - - private final IPodExecOutputListener listener; - private final WebSocketCall call; - private AtomicBoolean open = new AtomicBoolean(false); - - public ExecOutputListenerAdapter(WebSocketCall call, IPodExecOutputListener listener) { - this.call = call; - this.listener = listener; - } - - @Override - public void stop() { - call.cancel(); - } - - @Override - public void onOpen(WebSocket webSocket, Response response) { - if(open.compareAndSet(false, true)) { - listener.onOpen(); - } - } - - @Override - public void onClose(int code, String reason) { - if( open.compareAndSet(true, false) ) { - listener.onClose(code, reason); - } - } - - @Override - public void onFailure(IOException e, Response response) { - listener.onFailure(e); - } - - public void deliver( int channel, String msg ) { - switch ( channel ) { - case CHANNEL_STDOUT: - listener.onStdOut(msg); - break; - case CHANNEL_STDERR: - listener.onStdErr(msg); - break; - case CHANNEL_EXECERR: - listener.onExecErr(msg); - break; - default: - LOG.warn("Unable to deliver exec message of type [%d]: %s", channel, msg ); - } - } - - @Override - public void onMessage(ResponseBody message) throws IOException { - - /** - * https://godoc.org/k8s.io/kubernetes/pkg/util/wsstream - * The Websocket subprotocol "channel.k8s.io" prepends each binary message - * with a byte indicating the channel number (zero indexed) the message was - * sent on. Messages in both directions should prefix their messages with - * this channel byte. When used for remote execution, the channel numbers - * are by convention defined to match the POSIX file-descriptors assigned - * to STDIN, STDOUT, and STDERR (0, 1, and 2). No other conversion is - * performed on the raw subprotocol - writes are sent as they are received - * by the server. - */ - - int channel = message.byteStream().read(); - String msg = message.string(); - deliver( channel, msg ); - } - - } + private static final Logger LOG = LoggerFactory.getLogger(IPodExec.class); + private static final String CAPABILITY = "exec"; + + private static final String COMMAND = "command"; + + private static final String K8S_PROTOCOL_HEADER = "X-Stream-Protocol-Version"; + + private static final String K8S_PROTOCOL = "channel.k8s.io"; + + public static final int CHANNEL_STDOUT = 1; + public static final int CHANNEL_STDERR = 2; + public static final int CHANNEL_EXECERR = 3; + + private final IPod pod; + private final DefaultClient client; + private final IApiTypeMapper mapper; + + public PodExec(IPod pod, IClient client) { + super(pod, client, CAPABILITY); + this.pod = pod; + this.client = client.adapt(DefaultClient.class); + this.mapper = client.adapt(IApiTypeMapper.class); + } + + @Override + public String getName() { + return PodExec.class.getSimpleName(); + } + + @Override + public IStoppable start(IPodExecOutputListener listener, Options options, String... commands) { + + if (options == null) { + options = new Options(); + } + + /* + * with 3.7 per https://github.com/openshift/origin/issues/15330, 3.6 was + * evidently broke in allowing stdErr/stdOut to not be set; need to set + * stdout/stderr to true + */ + options.stdErr(true); + options.stdOut(true); + + Map parameters = options.getMap(); + + OkHttpClient okClient = client.adapt(OkHttpClient.class); + + URLBuilder urlBuilder = new URLBuilder(client.getBaseURL(), mapper).resource(pod).subresource(CAPABILITY) + .addParameters(parameters); + + // The main command and all arguments are specified as 'command' parameters + for (String command : commands) { + urlBuilder.addParmeter(COMMAND, command); + } + + final String endpoint = urlBuilder.websocket(); + + Request request = client.newRequestBuilderTo(endpoint, IHttpConstants.MEDIATYPE_ANY).method("GET", null) + .addHeader(K8S_PROTOCOL_HEADER, K8S_PROTOCOL) + // Unless we mark this as ignored, exceptions triggered by interceptor would be + // lost in dispatcher thread + .tag(new ResponseCodeInterceptor.Ignore() { + }).build(); + + WebSocketCall call = WebSocketCall.create(okClient, request); + ExecOutputListenerAdapter adapter = new ExecOutputListenerAdapter(call, listener); + call.enqueue(adapter); + return adapter; + } + + static class ExecOutputListenerAdapter extends WebSocketAdapter implements IStoppable { + + private final IPodExecOutputListener listener; + private final WebSocketCall call; + private AtomicBoolean open = new AtomicBoolean(false); + + public ExecOutputListenerAdapter(WebSocketCall call, IPodExecOutputListener listener) { + this.call = call; + this.listener = listener; + } + + @Override + public void stop() { + call.cancel(); + } + + @Override + public void onOpen(WebSocket webSocket, Response response) { + if (open.compareAndSet(false, true)) { + listener.onOpen(); + } + } + + @Override + public void onClose(int code, String reason) { + if (open.compareAndSet(true, false)) { + listener.onClose(code, reason); + } + } + + @Override + public void onFailure(IOException e, Response response) { + listener.onFailure(e); + } + + public void deliver(int channel, String msg) { + switch (channel) { + case CHANNEL_STDOUT: + listener.onStdOut(msg); + break; + case CHANNEL_STDERR: + listener.onStdErr(msg); + break; + case CHANNEL_EXECERR: + listener.onExecErr(msg); + break; + default: + LOG.warn("Unable to deliver exec message of type [%d]: %s", channel, msg); + } + } + + @Override + public void onMessage(ResponseBody message) throws IOException { + + /** + * https://godoc.org/k8s.io/kubernetes/pkg/util/wsstream The Websocket + * subprotocol "channel.k8s.io" prepends each binary message with a byte + * indicating the channel number (zero indexed) the message was sent on. + * Messages in both directions should prefix their messages with this channel + * byte. When used for remote execution, the channel numbers are by convention + * defined to match the POSIX file-descriptors assigned to STDIN, STDOUT, and + * STDERR (0, 1, and 2). No other conversion is performed on the raw subprotocol + * - writes are sent as they are received by the server. + */ + + int channel = message.byteStream().read(); + String msg = message.string(); + deliver(channel, msg); + } + + } } diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java index 3f06d748..6cca3f02 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.api.capabilities; import java.util.Collections; @@ -25,44 +26,45 @@ import com.openshift.restclient.model.IReplicationController; /** - * Implementation of the scalable interface. Applies - * to a deploymentconfig for the moment - * @author jeff.cantrill + * Implementation of the scalable interface. Applies to a deploymentconfig for + * the moment * */ public class ScaleCapability extends AbstractCapability implements IScalable { - - private static final Map ARG_KINDS = new HashMap<>(); - static { - ARG_KINDS.put(ResourceKind.DEPLOYMENT_CONFIG, "extensions/v1beta1.Scale"); - ARG_KINDS.put(ResourceKind.REPLICATION_CONTROLLER, "autoscaling/v1.Scale"); - } - private static final int MIN_VALUE = 0; - private static final String CAPABILITY = "scale"; - private final IClient client; - private IReplicationController rc; - private final ITypeFactory factory; + private static final Map ARG_KINDS = new HashMap<>(); + + static { + ARG_KINDS.put(ResourceKind.DEPLOYMENT_CONFIG, "extensions/v1beta1.Scale"); + ARG_KINDS.put(ResourceKind.REPLICATION_CONTROLLER, "autoscaling/v1.Scale"); + } + + private static final int MIN_VALUE = 0; + private static final String CAPABILITY = "scale"; + private final IClient client; + private IReplicationController rc; + private final ITypeFactory factory; - public ScaleCapability(IReplicationController rc, IClient client, ITypeFactory factory) { - super(rc, client, CAPABILITY); - this.client = client; - this.rc = rc; - this.factory = factory; - } + public ScaleCapability(IReplicationController rc, IClient client, ITypeFactory factory) { + super(rc, client, CAPABILITY); + this.client = client; + this.rc = rc; + this.factory = factory; + } - @Override - public String getName() { - return ScaleCapability.class.getSimpleName(); - } + @Override + public String getName() { + return ScaleCapability.class.getSimpleName(); + } - @Override - public IScale scaleTo(int replicas) { - replicas = replicas >= MIN_VALUE ? replicas : MIN_VALUE; - IScale arg = (IScale) factory.stubKind(ARG_KINDS.get(rc.getKind()), Optional.of(rc.getName()), Optional.of(rc.getNamespaceName())); - arg.setSpecReplicas(replicas); - return (IScale) client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespaceName(), rc.getName(), CAPABILITY, null, arg, - Collections.emptyMap()); - } + @Override + public IScale scaleTo(int replicas) { + replicas = replicas >= MIN_VALUE ? replicas : MIN_VALUE; + IScale arg = (IScale) factory.stubKind(ARG_KINDS.get(rc.getKind()), Optional.of(rc.getName()), + Optional.of(rc.getNamespaceName())); + arg.setSpecReplicas(replicas); + return (IScale) client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespaceName(), rc.getName(), + CAPABILITY, null, arg, Collections.emptyMap()); + } } diff --git a/src/main/java/com/openshift/internal/restclient/api/models/Endpoints.java b/src/main/java/com/openshift/internal/restclient/api/models/Endpoints.java index 4df412c5..5a527dde 100644 --- a/src/main/java/com/openshift/internal/restclient/api/models/Endpoints.java +++ b/src/main/java/com/openshift/internal/restclient/api/models/Endpoints.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.api.models; import java.util.ArrayList; @@ -75,10 +76,10 @@ public List getPorts() { } return ports; } - + } - - private static class EndpointAddress extends ModelNodeAdapter implements IEndpointAddress{ + + private static class EndpointAddress extends ModelNodeAdapter implements IEndpointAddress { private static final String TARGET_REF = "targetRef"; @@ -95,7 +96,7 @@ public String getIP() { public String getHostName() { return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "hostname"); } - + @Override public String getNodeName() { return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "nodeName"); @@ -108,15 +109,15 @@ public String getName() { @Override public IObjectReference getTargetRef() { - if(getNode().has(JBossDmrExtentions.getPath(getPropertyKeys(), TARGET_REF))) { + if (getNode().has(JBossDmrExtentions.getPath(getPropertyKeys(), TARGET_REF))) { ModelNode node = JBossDmrExtentions.get(getNode(), getPropertyKeys(), TARGET_REF); return new ObjectReference(node); } return null; } - + } - + private static class EndpointPort extends ModelNodeAdapter implements IEndpointPort { protected EndpointPort(ModelNode node, Map propertyKeys) { @@ -137,7 +138,6 @@ public int getPort() { public String getProtocol() { return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), PROTOCOL); } - + } } - diff --git a/src/main/java/com/openshift/internal/restclient/api/models/TypeMeta.java b/src/main/java/com/openshift/internal/restclient/api/models/TypeMeta.java index ec539ebb..c70d9168 100644 --- a/src/main/java/com/openshift/internal/restclient/api/models/TypeMeta.java +++ b/src/main/java/com/openshift/internal/restclient/api/models/TypeMeta.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.api.models; import static com.openshift.internal.util.JBossDmrExtentions.asString; @@ -22,25 +23,24 @@ public class TypeMeta extends ModelNodeAdapter implements ITypeMeta, ResourcePropertyKeys { - /** - * - * @param node - * @param propertyKeys overrides based on version - */ - public TypeMeta(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - } - - @Override - public String getApiVersion() { - return asString(getNode(), getPropertyKeys(), APIVERSION ); - } - - @Override - public String getKind() { - return asString(getNode(), getPropertyKeys(), KIND); - } - - + /** + * + * @param node the node + * @param propertyKeys + * overrides based on version + */ + public TypeMeta(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public String getApiVersion() { + return asString(getNode(), getPropertyKeys(), APIVERSION); + } + + @Override + public String getKind() { + return asString(getNode(), getPropertyKeys(), KIND); + } } diff --git a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java index 7990a735..b0251d08 100644 --- a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java +++ b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.apis; import java.lang.reflect.Constructor; @@ -33,77 +34,77 @@ import com.openshift.restclient.api.models.ITypeMeta; public class TypeMetaFactory implements ITypeFactory, ResourcePropertyKeys { - - private static final String DELIMITER = "."; - private static final Map> IMPL_MAP = new HashMap<>(); - static { - IMPL_MAP.put("Scale", Scale.class); - //its own factory? - IMPL_MAP.put("DeploymentRequest", DeploymentRequest.class); - } - - @Override - public Object stubKind(String kind, Optional name, Optional namespace) { - if(StringUtils.isEmpty(kind)) { - throw new OpenShiftException("Unable to stub a kind when the kind passed in is empty"); - } - try { - String version = ""; - if(kind.contains(DELIMITER)) { - int delimeter = kind.indexOf(DELIMITER); - version = StringUtils.left(kind, delimeter); - kind = StringUtils.right(kind, kind.length() - delimeter - DELIMITER.length()); - } - Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); - ModelNode node = new ModelNode(); - JBossDmrExtentions.set(node, properyKeyMap, APIVERSION, version); - JBossDmrExtentions.set(node, properyKeyMap, KIND, kind); - - ITypeMeta instance = null; - if(IMPL_MAP.containsKey(kind)) { - Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, Map.class); - instance = constructor.newInstance(node, properyKeyMap); - }else { - instance = new TypeMeta(node, properyKeyMap); - } - - if(name.isPresent() && instance instanceof INameSetable) { - ((INameSetable) instance).setName(name.get()); - } - if(namespace.isPresent() && instance instanceof INamespaceSetable) { - ((INamespaceSetable) instance).setNamespace(namespace.get()); - } - - return instance; - } catch (UnsupportedVersionException e) { - throw e; - } catch (Exception e) { - throw new ResourceFactoryException(e,"Unable to stub instance from %s", kind); - } - } + private static final String DELIMITER = "."; + private static final Map> IMPL_MAP = new HashMap<>(); + + static { + IMPL_MAP.put("Scale", Scale.class); + // its own factory? + IMPL_MAP.put("DeploymentRequest", DeploymentRequest.class); + } + + @Override + public Object stubKind(String kind, Optional name, Optional namespace) { + if (StringUtils.isEmpty(kind)) { + throw new OpenShiftException("Unable to stub a kind when the kind passed in is empty"); + } + try { + String version = ""; + if (kind.contains(DELIMITER)) { + int delimeter = kind.indexOf(DELIMITER); + version = StringUtils.left(kind, delimeter); + kind = StringUtils.right(kind, kind.length() - delimeter - DELIMITER.length()); + } + Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); + ModelNode node = new ModelNode(); + JBossDmrExtentions.set(node, properyKeyMap, APIVERSION, version); + JBossDmrExtentions.set(node, properyKeyMap, KIND, kind); + + ITypeMeta instance = null; + if (IMPL_MAP.containsKey(kind)) { + Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, + Map.class); + instance = constructor.newInstance(node, properyKeyMap); + } else { + instance = new TypeMeta(node, properyKeyMap); + } + + if (name.isPresent() && instance instanceof INameSetable) { + ((INameSetable) instance).setName(name.get()); + } + if (namespace.isPresent() && instance instanceof INamespaceSetable) { + ((INamespaceSetable) instance).setNamespace(namespace.get()); + } + return instance; + } catch (UnsupportedVersionException e) { + throw e; + } catch (Exception e) { + throw new ResourceFactoryException(e, "Unable to stub instance from %s", kind); + } + } + @Override + public Object createInstanceFrom(String response) { + try { + ModelNode node = ModelNode.fromJSONString(response); + String version = node.get(APIVERSION).asString(); + String kind = node.get(KIND).asString(); - @Override - public Object createInstanceFrom(String response) { - try { - ModelNode node = ModelNode.fromJSONString(response); - String version = node.get(APIVERSION).asString(); - String kind = node.get(KIND).asString(); + Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); + if (IMPL_MAP.containsKey(kind)) { + Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, + Map.class); + return constructor.newInstance(node, properyKeyMap); + } + return new TypeMeta(node, properyKeyMap); - Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); - if(IMPL_MAP.containsKey(kind)) { - Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, Map.class); - return constructor.newInstance(node, properyKeyMap); - } - return new TypeMeta(node, properyKeyMap); - - } catch (UnsupportedVersionException e) { - throw e; - } catch (Exception e) { - throw new ResourceFactoryException(e,"Unable to create from %s", response); - } - } + } catch (UnsupportedVersionException e) { + throw e; + } catch (Exception e) { + throw new ResourceFactoryException(e, "Unable to create from %s", response); + } + } } diff --git a/src/main/java/com/openshift/internal/restclient/apis/autoscaling/models/Scale.java b/src/main/java/com/openshift/internal/restclient/apis/autoscaling/models/Scale.java index b462d8d1..66799cb0 100644 --- a/src/main/java/com/openshift/internal/restclient/apis/autoscaling/models/Scale.java +++ b/src/main/java/com/openshift/internal/restclient/apis/autoscaling/models/Scale.java @@ -8,9 +8,15 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.apis.autoscaling.models; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asInt; +import static com.openshift.internal.util.JBossDmrExtentions.asMap; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.get; +import static com.openshift.internal.util.JBossDmrExtentions.getPath; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.Collections; import java.util.Map; @@ -22,97 +28,95 @@ public class Scale extends TypeMeta implements IScale { - private static final String SPEC_REPLICAS = "spec.replicas"; - - public Scale() { - super(new ModelNode(), Collections.emptyMap()); - } - - /** - * - * @param node - * @param propertyKeys overrides based on version - */ - public Scale(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - } - - @Override - public int getSpecReplicas() { - return asInt(getNode(), getPropertyKeys(), SPEC_REPLICAS); - } - - @Override - public void setSpecReplicas(int replicas) { - set(getNode(), getPropertyKeys(), SPEC_REPLICAS, replicas); - } - - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), METADATA_NAME); - } - - @Override - public void setName(String name) { - set(getNode(), getPropertyKeys(), METADATA_NAME, name); - } - - @Override - public String getCreationTimeStamp() { - return asString(getNode(), getPropertyKeys(), CREATION_TIMESTAMP); - } - - @Override - public String getNamespace() { - return asString(getNode(), getPropertyKeys(), METADATA_NAMESPACE); - } - - @Override - public void setNamespace(String namespace) { - set(getNode(), getPropertyKeys(), METADATA_NAMESPACE, namespace); - } - - - @Override - public String getResourceVersion() { - return asString(getNode(), getPropertyKeys(), METADATA_RESOURCE_VERSION); - } - - @Override - public Map getLabels() { - return asMap(getNode(), getPropertyKeys(), LABELS); - } - - @Override - public void addLabel(String key, String value) { - ModelNode labels = getNode().get(getPath(LABELS)); - labels.get(key).set(value); - } - - @Override - public Map getAnnotations() { - return asMap(getNode(), getPropertyKeys(), ANNOTATIONS); - } - - @Override - public String getAnnotation(String key) { - return getAnnotations().get(key); - } - - @Override - public void setAnnotation(String name, String value) { - if(value == null) return; - ModelNode annotations = get(getNode(), getPropertyKeys(), ANNOTATIONS); - annotations.get(name).set(value); - } - - @Override - public boolean isAnnotatedWith(String key) { - Map annotations = getAnnotations(); - return annotations.containsKey(key); - } - - - + private static final String SPEC_REPLICAS = "spec.replicas"; + + public Scale() { + super(new ModelNode(), Collections.emptyMap()); + } + + /** + * + * @param propertyKeys + * overrides based on version + */ + public Scale(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public int getSpecReplicas() { + return asInt(getNode(), getPropertyKeys(), SPEC_REPLICAS); + } + + @Override + public void setSpecReplicas(int replicas) { + set(getNode(), getPropertyKeys(), SPEC_REPLICAS, replicas); + } + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), METADATA_NAME); + } + + @Override + public void setName(String name) { + set(getNode(), getPropertyKeys(), METADATA_NAME, name); + } + + @Override + public String getCreationTimeStamp() { + return asString(getNode(), getPropertyKeys(), CREATION_TIMESTAMP); + } + + @Override + public String getNamespace() { + return asString(getNode(), getPropertyKeys(), METADATA_NAMESPACE); + } + + @Override + public void setNamespace(String namespace) { + set(getNode(), getPropertyKeys(), METADATA_NAMESPACE, namespace); + } + + @Override + public String getResourceVersion() { + return asString(getNode(), getPropertyKeys(), METADATA_RESOURCE_VERSION); + } + + @Override + public Map getLabels() { + return asMap(getNode(), getPropertyKeys(), LABELS); + } + + @Override + public void addLabel(String key, String value) { + ModelNode labels = getNode().get(getPath(LABELS)); + labels.get(key).set(value); + } + + @Override + public Map getAnnotations() { + return asMap(getNode(), getPropertyKeys(), ANNOTATIONS); + } + + @Override + public String getAnnotation(String key) { + return getAnnotations().get(key); + } + + @Override + public void setAnnotation(String name, String value) { + if (value == null) { + return; + } + ModelNode annotations = get(getNode(), getPropertyKeys(), ANNOTATIONS); + annotations.get(name).set(value); + } + + @Override + public boolean isAnnotatedWith(String key) { + Map annotations = getAnnotations(); + return annotations.containsKey(key); + } } diff --git a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java index 2bbc0775..6062c74f 100644 --- a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java +++ b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.authorization; import org.apache.commons.lang.StringUtils; @@ -16,116 +17,107 @@ import com.openshift.restclient.authorization.IAuthorizationDetails; import com.openshift.restclient.model.user.IUser; -/** - * @author Jeff Cantrill - */ public class AuthorizationContext implements IAuthorizationContext { - - private String token; - private String expires; - private String scheme; - private IUser user; - private String userName; - private String password; - private IClient client; - - public AuthorizationContext(String scope){ - this.scheme = scope; - } - - public AuthorizationContext(String token, String userName, String password){ - this.token = token; - this.userName = userName; - this.password = password; - } - - public AuthorizationContext(String token, String expires, IUser user, String scheme){ - this.token = token; - this.expires = expires; - this.user = user; - this.scheme = scheme; - } - - public AuthorizationContext clone() { - AuthorizationContext context = new AuthorizationContext(this.token, this.expires, this.user, this.scheme); - context.setUserName(this.userName); - context.setPassword(this.password); - context.setClient(this.client); - return context; - } - - public void setClient(IClient client){ - this.client = client; - } - - @Override - public boolean isAuthorized() { - if(user == null) { - synchronized (this) { - user = client.get(ResourceKind.USER, "~", ""); - } - } - return StringUtils.isNotEmpty(token); - } - - @Override - public IAuthorizationDetails getAuthorizationDetails() { - return new AuthorizationDetails(String.format("%s/oauth/token/request", client.getBaseURL())); - } - - @Override - public String getToken(){ - return this.token; - } - - @Override - public String getExpiresIn(){ - return expires; - } - - @Override - public String getAuthScheme() { - return scheme; - } - - @Override - public IUser getUser() { - return user; - } - - public void setUser(IUser user) { - this.user = user; - } - - - @Override - public void setToken(String token) { - this.token = token; - } - - - @Override - public void setUserName(String userName) { - this.userName = userName; - } - - - @Override - public String getUserName() { - return this.userName; - } - - - @Override - public void setPassword(String password) { - this.password = password; - } - - - @Override - public String getPassword() { - return this.password; - } - - + + private String token; + private String expires; + private String scheme; + private IUser user; + private String userName; + private String password; + private IClient client; + + public AuthorizationContext(String scope) { + this.scheme = scope; + } + + public AuthorizationContext(String token, String userName, String password) { + this.token = token; + this.userName = userName; + this.password = password; + } + + public AuthorizationContext(String token, String expires, IUser user, String scheme) { + this.token = token; + this.expires = expires; + this.user = user; + this.scheme = scheme; + } + + public AuthorizationContext clone() { + AuthorizationContext context = new AuthorizationContext(this.token, this.expires, this.user, this.scheme); + context.setUserName(this.userName); + context.setPassword(this.password); + context.setClient(this.client); + return context; + } + + public void setClient(IClient client) { + this.client = client; + } + + @Override + public boolean isAuthorized() { + if (user == null) { + synchronized (this) { + user = client.get(ResourceKind.USER, "~", ""); + } + } + return StringUtils.isNotEmpty(token); + } + + @Override + public IAuthorizationDetails getAuthorizationDetails() { + return new AuthorizationDetails(String.format("%s/oauth/token/request", client.getBaseURL())); + } + + @Override + public String getToken() { + return this.token; + } + + @Override + public String getExpiresIn() { + return expires; + } + + @Override + public String getAuthScheme() { + return scheme; + } + + @Override + public IUser getUser() { + return user; + } + + public void setUser(IUser user) { + this.user = user; + } + + @Override + public void setToken(String token) { + this.token = token; + } + + @Override + public void setUserName(String userName) { + this.userName = userName; + } + + @Override + public String getUserName() { + return this.userName; + } + + @Override + public void setPassword(String password) { + this.password = password; + } + + @Override + public String getPassword() { + return this.password; + } + } diff --git a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationDetails.java b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationDetails.java index 30935def..fd90f496 100644 --- a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationDetails.java +++ b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationDetails.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.authorization; import java.util.regex.Matcher; @@ -17,87 +18,82 @@ import okhttp3.Headers; -/** - * @author Jeff Cantrill - */ public class AuthorizationDetails implements IAuthorizationDetails { - private static final String LINK = "Link"; - private static final String WARNING = "Warning"; - private static final String WWW_AUTHENTICATE = "WWW-Authenticate"; - - private static final Pattern LINK_RE = Pattern.compile(".*?((?:http|https)(?::\\/{2}[\\w]+)(?:[\\/|\\.]?)(?:[^\\s\"<>]*))",Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - private static final Pattern WARNING_RE = Pattern.compile(".*?(\".*?\")",Pattern.CASE_INSENSITIVE | Pattern.DOTALL); - - private String message = ""; - private String link = ""; - private String scheme = ""; - - public AuthorizationDetails(String link) { - this.link = link; - } - - public AuthorizationDetails(String error, String errorDetails) { - this.message = "Unknown authorization error"; - if (error != null) { - this.message = error; - } - if (errorDetails != null) { - this.message = this.message + ": " + errorDetails; - } - } - - public AuthorizationDetails(Headers headers) { - for (String name : headers.names()) { - if(LINK.equalsIgnoreCase(name)) { - Matcher matcher = LINK_RE.matcher(headers.get(name)); - if(matcher.find()) { - link = matcher.group(1); - } - }else if(WARNING.equalsIgnoreCase(name)) { - Matcher matcher = WARNING_RE.matcher(headers.get(name)); - if(matcher.find()) { - message = matcher.group(1); - } - }else if(WWW_AUTHENTICATE.equalsIgnoreCase(name)) { - scheme = headers.get(name); - if(scheme.contains("realm")) { - scheme = scheme.split(" ")[0]; - } - } - } - } - - - public AuthorizationDetails(Headers headers, String link) { - this(headers); - if(link != null) { - this.link = link; - } - } - - @Override - public String getScheme() { - return scheme ; - } - - - - @Override - public String getMessage() { - return message; - } - - @Override - public String getRequestTokenLink() { - return link; - } - - - @Override - public String toString() { - return message; - } - + private static final String LINK = "Link"; + private static final String WARNING = "Warning"; + private static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + + private static final Pattern LINK_RE = Pattern.compile( + ".*?((?:http|https)(?::\\/{2}[\\w]+)(?:[\\/|\\.]?)(?:[^\\s\"<>]*))", + Pattern.CASE_INSENSITIVE | Pattern.DOTALL); + private static final Pattern WARNING_RE = Pattern.compile(".*?(\".*?\")", + Pattern.CASE_INSENSITIVE | Pattern.DOTALL); + + private String message = ""; + private String link = ""; + private String scheme = ""; + + public AuthorizationDetails(String link) { + this.link = link; + } + + public AuthorizationDetails(String error, String errorDetails) { + this.message = "Unknown authorization error"; + if (error != null) { + this.message = error; + } + if (errorDetails != null) { + this.message = this.message + ": " + errorDetails; + } + } + + public AuthorizationDetails(Headers headers) { + for (String name : headers.names()) { + if (LINK.equalsIgnoreCase(name)) { + Matcher matcher = LINK_RE.matcher(headers.get(name)); + if (matcher.find()) { + link = matcher.group(1); + } + } else if (WARNING.equalsIgnoreCase(name)) { + Matcher matcher = WARNING_RE.matcher(headers.get(name)); + if (matcher.find()) { + message = matcher.group(1); + } + } else if (WWW_AUTHENTICATE.equalsIgnoreCase(name)) { + scheme = headers.get(name); + if (scheme.contains("realm")) { + scheme = scheme.split(" ")[0]; + } + } + } + } + + public AuthorizationDetails(Headers headers, String link) { + this(headers); + if (link != null) { + this.link = link; + } + } + + @Override + public String getScheme() { + return scheme; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public String getRequestTokenLink() { + return link; + } + + @Override + public String toString() { + return message; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/AbstractCapability.java b/src/main/java/com/openshift/internal/restclient/capability/AbstractCapability.java index 0c5dfe7d..4aeaa979 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/AbstractCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/AbstractCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability; import com.openshift.restclient.IApiTypeMapper; @@ -17,32 +18,31 @@ import com.openshift.restclient.model.IResource; /** - * Capability base - * @author jeff.cantrill + * Capability base * */ public abstract class AbstractCapability implements ICapability { - private IApiTypeMapper mapper; - private IResource resource; - private final String capability; + private IApiTypeMapper mapper; + private IResource resource; + private final String capability; + + protected AbstractCapability(IResource resource, IClient client, String capability) { + this.capability = capability; + this.resource = resource; + this.mapper = client.adapt(IApiTypeMapper.class); + } - protected AbstractCapability(IResource resource, IClient client, String capability) { - this.capability = capability; - this.resource = resource; - this.mapper = client.adapt(IApiTypeMapper.class); - } - - @Override - public boolean isSupported() { - if(mapper != null) { - try { - return mapper.getEndpointFor(resource.getApiVersion(), resource.getKind()).isSupported(capability); - }catch(UnsupportedEndpointException e) { - //endpoint not found for version/kind - } - } - return false; - } + @Override + public boolean isSupported() { + if (mapper != null) { + try { + return mapper.getEndpointFor(resource.getApiVersion(), resource.getKind()).isSupported(capability); + } catch (UnsupportedEndpointException e) { + // endpoint not found for version/kind + } + } + return false; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index 6f6e1710..052168d0 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -6,10 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability; import java.util.Map; +import com.openshift.internal.restclient.api.capabilities.PodExec; import com.openshift.internal.restclient.api.capabilities.ScaleCapability; import com.openshift.internal.restclient.apis.TypeMetaFactory; import com.openshift.internal.restclient.capability.resources.BuildCanceller; @@ -23,7 +25,6 @@ import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPodLogRetrieval; import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPortForwarding; import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryRSync; -import com.openshift.internal.restclient.api.capabilities.PodExec; import com.openshift.internal.restclient.capability.resources.PodLogRetrievalAsync; import com.openshift.internal.restclient.capability.resources.ProjectTemplateListCapability; import com.openshift.internal.restclient.capability.resources.ProjectTemplateProcessing; @@ -35,6 +36,7 @@ import com.openshift.internal.restclient.model.Service; import com.openshift.internal.restclient.model.build.BuildConfigBuilder; import com.openshift.restclient.IClient; +import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.api.capabilities.IScalable; import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.capability.resources.IBuildCancelable; @@ -43,9 +45,8 @@ import com.openshift.restclient.capability.resources.IDeployCapability; import com.openshift.restclient.capability.resources.IDeploymentConfigTraceability; import com.openshift.restclient.capability.resources.IDeploymentTraceability; -import com.openshift.restclient.capability.resources.IImageStreamImportCapability; -import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.capability.resources.IDeploymentTriggerable; +import com.openshift.restclient.capability.resources.IImageStreamImportCapability; import com.openshift.restclient.capability.resources.IPodLogRetrieval; import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; import com.openshift.restclient.capability.resources.IPortForwardable; @@ -67,92 +68,100 @@ import com.openshift.restclient.model.build.IBuildConfigBuilder; /** - * Convenience class to initialize capabilies. Only adds entry - * to underlying map if the capability is supported + * Convenience class to initialize capabilies. Only adds entry to underlying map + * if the capability is supported * - * @author Jeff Cantrill */ public class CapabilityInitializer { - /** - * Registers the capability if it is supported - * @param capabilities - * @param capability - * @param impl - */ - private static void initializeCapability(Map, ICapability> capabilities, Class capability, ICapability impl){ - if(impl.isSupported()){ - capabilities.put(capability, impl); - } - } - - /** - * Initialize Build specific capabilities - * @param capabilities - * @param resource - */ - public static void initializeCapabilities(Map, ICapability> capabilities, IBuild build, IClient client){ - initializeCapability(capabilities, IBuildTriggerable.class, new BuildTrigger(build, client)); - initializeCapability(capabilities, IBuildCancelable.class, new BuildCanceller(build, client)); - } + /** + * Registers the capability if it is supported + * + */ + private static void initializeCapability(Map, ICapability> capabilities, + Class capability, ICapability impl) { + if (impl.isSupported()) { + capabilities.put(capability, impl); + } + } + + /** + * Initialize Build specific capabilities + * + */ + public static void initializeCapabilities(Map, ICapability> capabilities, IBuild build, + IClient client) { + initializeCapability(capabilities, IBuildTriggerable.class, new BuildTrigger(build, client)); + initializeCapability(capabilities, IBuildCancelable.class, new BuildCanceller(build, client)); + } + + /** + * Initialize BuildConfig specific capabilities + * + */ + public static void initializeCapabilities(Map, ICapability> capabilities, + IBuildConfig buildConfig, IClient client) { + initializeCapability(capabilities, IBuildTriggerable.class, new BuildTrigger(buildConfig, client)); + } + + /** + * Initialize Pod specific capabilities + * + */ + public static void initializeCapabilities(Map, ICapability> capabilities, IPod pod, + IClient client) { + initializeCapability(capabilities, IPortForwardable.class, new OpenShiftBinaryPortForwarding(pod, client)); + initializeCapability(capabilities, IPodLogRetrieval.class, new OpenShiftBinaryPodLogRetrieval(pod, client)); + initializeCapability(capabilities, IPodLogRetrievalAsync.class, new PodLogRetrievalAsync(pod, client)); + initializeCapability(capabilities, IPodExec.class, new PodExec(pod, client)); + initializeCapability(capabilities, IRSyncable.class, new OpenShiftBinaryRSync(client)); + } + + /** + * Initialize Project specific capabilities + * + */ + public static void initializeCapabilities(Map, ICapability> capabilities, + IProject project, IClient client) { + initializeCapability(capabilities, IProjectTemplateProcessing.class, + new ProjectTemplateProcessing(project, client)); + initializeCapability(capabilities, IProjectTemplateList.class, + new ProjectTemplateListCapability(project, client)); + initializeCapability(capabilities, IImageStreamImportCapability.class, + new ImageStreamImportCapability(project, client)); + } + + public static void initializeCapabilities(Map, ICapability> capabilities, + Service service, IClient client) { + } - /** - * Initialize BuildConfig specific capabilities - * @param capabilities - * @param resource - */ - public static void initializeCapabilities(Map, ICapability> capabilities, IBuildConfig buildConfig, IClient client){ - initializeCapability(capabilities, IBuildTriggerable.class, new BuildTrigger(buildConfig, client)); - } - - /** - * Initialize Pod specific capabilities - * @param capabilities - * @param resource - */ - public static void initializeCapabilities(Map, ICapability> capabilities, IPod pod, IClient client){ - initializeCapability(capabilities, IPortForwardable.class, new OpenShiftBinaryPortForwarding(pod, client)); - initializeCapability(capabilities, IPodLogRetrieval.class, new OpenShiftBinaryPodLogRetrieval(pod, client)); - initializeCapability(capabilities, IPodLogRetrievalAsync.class, new PodLogRetrievalAsync(pod, client)); - initializeCapability(capabilities, IPodExec.class, new PodExec(pod, client)); - initializeCapability(capabilities, IRSyncable.class, new OpenShiftBinaryRSync(client)); - } + public static void initializeCapabilities(Map, ICapability> capabilities, + IDeploymentConfig config, IClient client) { + initializeCapability(capabilities, IDeployCapability.class, new DeployCapability(config, client)); + initializeCapability(capabilities, IDeploymentTriggerable.class, + new DeploymentTrigger(config, client, new TypeMetaFactory())); + } - /** - * Initialize Project specific capabilities - * @param capabilities - * @param resource - */ - public static void initializeCapabilities(Map, ICapability> capabilities, IProject project, IClient client){ - initializeCapability(capabilities, IProjectTemplateProcessing.class, new ProjectTemplateProcessing(project, client)); - initializeCapability(capabilities, IProjectTemplateList.class, new ProjectTemplateListCapability(project, client)); - initializeCapability(capabilities, IImageStreamImportCapability.class, new ImageStreamImportCapability(project, client)); - } - - public static void initializeCapabilities(Map, ICapability> capabilities, Service service, IClient client){ - } - - public static void initializeCapabilities(Map, ICapability> capabilities, IDeploymentConfig config, IClient client){ - initializeCapability(capabilities, IDeployCapability.class, new DeployCapability(config, client)); - initializeCapability(capabilities, IDeploymentTriggerable.class, new DeploymentTrigger(config, client, new TypeMetaFactory())); - } + public static void initializeCapabilities(Map, ICapability> capabilities, + IReplicationController rc, IClient client) { + initializeCapability(capabilities, IScalable.class, new ScaleCapability(rc, client, new TypeMetaFactory())); + } - public static void initializeCapabilities(Map, ICapability> capabilities, IReplicationController rc, IClient client){ - initializeCapability(capabilities, IScalable.class, new ScaleCapability(rc, client, new TypeMetaFactory())); - } + public static void initializeCapabilities(Map, ICapability> capabilities, + IResource resource, IClient client) { + initializeCapability(capabilities, ITemplateTraceability.class, new TemplateTraceability(resource)); + initializeCapability(capabilities, IDeploymentConfigTraceability.class, + new DeploymentConfigTraceability(resource, client)); + initializeCapability(capabilities, IDeploymentTraceability.class, new DeploymentTraceability(resource, client)); + initializeCapability(capabilities, ITags.class, new TagCapability(resource)); + initializeCapability(capabilities, IClientCapability.class, new ClientCapability(client)); + initializeCapability(capabilities, IUpdatable.class, new UpdateableCapability(resource)); + initializeCapability(capabilities, IPropertyAccessCapability.class, new PropertyAccessCapability(resource)); + } - public static void initializeCapabilities(Map, ICapability> capabilities, IResource resource, IClient client){ - initializeCapability(capabilities, ITemplateTraceability.class, new TemplateTraceability(resource)); - initializeCapability(capabilities, IDeploymentConfigTraceability.class, new DeploymentConfigTraceability(resource, client)); - initializeCapability(capabilities, IDeploymentTraceability.class, new DeploymentTraceability(resource, client)); - initializeCapability(capabilities, ITags.class, new TagCapability(resource)); - initializeCapability(capabilities, IClientCapability.class, new ClientCapability(client)); - initializeCapability(capabilities, IUpdatable.class, new UpdateableCapability(resource)); - initializeCapability(capabilities, IPropertyAccessCapability.class, new PropertyAccessCapability(resource)); - } - - public static void initializeClientCapabilities(Map, ICapability> capabilities, IClient client){ - initializeCapability(capabilities, ITemplateProcessing.class, new ServerTemplateProcessing(client)); - initializeCapability(capabilities, IBuildConfigBuilder.class, new BuildConfigBuilder(client)); - } + public static void initializeClientCapabilities(Map, ICapability> capabilities, + IClient client) { + initializeCapability(capabilities, ITemplateProcessing.class, new ServerTemplateProcessing(client)); + initializeCapability(capabilities, IBuildConfigBuilder.class, new BuildConfigBuilder(client)); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 2e911c82..79c7ea7f 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.io.File; @@ -33,236 +34,236 @@ /** * Capability that wraps the OpenShift binary * - * @author Jeff Cantrill - * @author Andre Dietisheim - * */ public abstract class AbstractOpenShiftBinaryCapability implements IBinaryCapability { - - private static final Logger LOG = LoggerFactory.getLogger(AbstractOpenShiftBinaryCapability.class); - - private static final boolean IS_MAC = StringUtils.isNotEmpty(System.getProperty("os.name")) - && System.getProperty("os.name").toLowerCase().contains("mac"); - - static class Server implements OpenShiftBinaryOption { - - private IClient client; - - public Server(IClient client) { - this.client = client; - } - - @Override - public void append(StringBuilder commandLine) { - commandLine - .append(" --server=") - .append(client.getBaseURL()).append(" "); - } - } - - static class Token implements OpenShiftBinaryOption { - - private IClient client; - - Token(IClient client) { - this.client = client; - } - - @Override - public void append(StringBuilder commandLine) { - commandLine - .append(" --token=") - .append(client.getAuthorizationContext().getToken()); - } - } - - static class Namespace implements OpenShiftBinaryOption { - - private IResource resource; - - public Namespace(IResource resource) { - this.resource = resource; - } - - @Override - public void append(StringBuilder commandLine) { - if (resource == null) { - return; - } - commandLine.append(" -n ").append(resource.getNamespaceName()); - } - } - - protected static class CommandLineBuilder { - - private StringBuilder sb; - - public CommandLineBuilder(String command) { - this.sb = new StringBuilder(command); - } - - public CommandLineBuilder append(OpenShiftBinaryOption argument) { - if (argument != null) { - argument.append(sb); - } - return this; - } - - public CommandLineBuilder append(Collection arguments) { - if (arguments == null) { - return this; - } - - for (OpenShiftBinaryOption argument : arguments) { - append(argument); - } - return this; - } - - public String build() { - return sb.toString(); - } - } - - private Process process; - private IClient client; - - protected AbstractOpenShiftBinaryCapability(IClient client) { - this.client = client; - } - - /** - * Cleanup required when stopping the process - */ - protected abstract void cleanup(); - - /** - * Validate arguments before starting process - * @return true if start should continue; false otherwise; - */ - protected abstract boolean validate(); - - /** - * Callback for building args to be sent to the {@code oc} command. - * @return the String representation of all the arguments to use when running the {@code oc} command. - */ - protected abstract String buildArgs(final List options); - - protected IClient getClient() { - return client; - } - - protected AbstractOpenShiftBinaryCapability() { - addShutdownHook(); - } - - protected Process getProcess() { - return process; - } - - private void addShutdownHook() { - Runtime.getRuntime().addShutdownHook(new Thread(() -> stop())); - } - - /** - * Starts the {@link Process} to run the {@code oc} command. - * @param arguments the command line options - * @return - */ - public final Process start(final OpenShiftBinaryOption... arguments) { - String location = getOpenShiftBinaryLocation(); - if(!validate()) { - return null; - } - ProcessBuilder processBuilder = initProcessBuilder(location, arguments); - return startProcess(processBuilder); - } - - protected Process startProcess(ProcessBuilder builder) { - try { - process = builder.start(); - checkProcessIsAlive(); - return process; - } catch (IOException e) { - LOG.error("Could not start process for {}.", new Object[]{ getName(), e }); - throw new OpenShiftException(e, "Does your OpenShift binary location exist? Error starting process: %s", - e.getMessage()); - } - } - - private ProcessBuilder initProcessBuilder(String location, final OpenShiftBinaryOption... options) { - List args = new ArrayList<>(); - ProcessBuilder builder = null; - // the condition is made in order to solve mac problem - // with launching binaries containing spaces in its path - // https://issues.jboss.org/browse/JBIDE-23862 - see the latest comments - if (IS_MAC) { - args.add(location); - StringSplitter.split(buildArgs(Arrays.asList(options)), args); - builder = new ProcessBuilder(args); - } else { - File oc = new File(location); - args.add(location); - StringSplitter.split(buildArgs(Arrays.asList(options)), args); - builder = new ProcessBuilder(args); - builder.directory(oc.getParentFile()); - } - builder.environment().remove("KUBECONFIG"); - LOG.debug("OpenShift binary args: {}", builder.command()); - return builder; - } - - private void checkProcessIsAlive() throws IOException { - try { - // TODO: replace fixed wait with wait for process to be running - Thread.sleep(1000); - if(!process.isAlive() && process.exitValue() != 0) { - throw new OpenShiftException("OpenShiftBinaryCapability process exited: %s", - IOUtils.toString(process.getErrorStream())); - } - } catch (InterruptedException e) { - if(!process.isAlive() && process.exitValue() != 0) { - throw new OpenShiftException("OpenShiftBinaryCapability process exited: %s", - IOUtils.toString(process.getErrorStream())); - } - } - } - - /** - * Stops the {@link Process} running the {@code oc} command. - */ - public final synchronized void stop() { - if(process == null) return; - cleanup(); - if(!process.isAlive()) { - final int exitValue = process.exitValue(); - LOG.debug("OpenShiftBinaryCapability process exit code {}", exitValue); - if(exitValue != 0) { - try { - LOG.debug("OpenShiftBinaryCapability process error stream", IOUtils.toString(process.getErrorStream())); - } catch (IOException e) { - LOG.debug("IOException trying to debug the process error stream", e); - } - } - process = null; - return; - } - process.destroyForcibly(); - } - - protected String getOpenShiftBinaryLocation() { - //Check the ThreadLocal for oc binary - String location = OpenShiftContext.get().get(OPENSHIFT_BINARY_LOCATION); - if (StringUtils.isBlank(location)) { - //Fall back to System property - location = System.getProperty(OPENSHIFT_BINARY_LOCATION); - } - if(StringUtils.isBlank(location)) { - throw new LocationNotFoundException( - String.format("The OpenShift 'oc' binary location was not specified. Set the property %s", - OPENSHIFT_BINARY_LOCATION)); - } - return location; - } + + private static final Logger LOG = LoggerFactory.getLogger(AbstractOpenShiftBinaryCapability.class); + + private static final boolean IS_MAC = StringUtils.isNotEmpty(System.getProperty("os.name")) + && System.getProperty("os.name").toLowerCase().contains("mac"); + + static class Server implements OpenShiftBinaryOption { + + private IClient client; + + public Server(IClient client) { + this.client = client; + } + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" --server=").append(client.getBaseURL()).append(" "); + } + } + + static class Token implements OpenShiftBinaryOption { + + private IClient client; + + Token(IClient client) { + this.client = client; + } + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" --token=").append(client.getAuthorizationContext().getToken()); + } + } + + static class Namespace implements OpenShiftBinaryOption { + + private IResource resource; + + public Namespace(IResource resource) { + this.resource = resource; + } + + @Override + public void append(StringBuilder commandLine) { + if (resource == null) { + return; + } + commandLine.append(" -n ").append(resource.getNamespaceName()); + } + } + + protected static class CommandLineBuilder { + + private StringBuilder sb; + + public CommandLineBuilder(String command) { + this.sb = new StringBuilder(command); + } + + public CommandLineBuilder append(OpenShiftBinaryOption argument) { + if (argument != null) { + argument.append(sb); + } + return this; + } + + public CommandLineBuilder append(Collection arguments) { + if (arguments == null) { + return this; + } + + for (OpenShiftBinaryOption argument : arguments) { + append(argument); + } + return this; + } + + public String build() { + return sb.toString(); + } + } + + private Process process; + private IClient client; + + protected AbstractOpenShiftBinaryCapability(IClient client) { + this.client = client; + } + + /** + * Cleanup required when stopping the process + */ + protected abstract void cleanup(); + + /** + * Validate arguments before starting process + * + * @return true if start should continue; false otherwise; + */ + protected abstract boolean validate(); + + /** + * Callback for building args to be sent to the {@code oc} command. + * + * @return the String representation of all the arguments to use when running + * the {@code oc} command. + */ + protected abstract String buildArgs(final List options); + + protected IClient getClient() { + return client; + } + + protected AbstractOpenShiftBinaryCapability() { + addShutdownHook(); + } + + protected Process getProcess() { + return process; + } + + private void addShutdownHook() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> stop())); + } + + /** + * Starts the {@link Process} to run the {@code oc} command. + * + * @param arguments + * the command line options + */ + public final Process start(final OpenShiftBinaryOption... arguments) { + String location = getOpenShiftBinaryLocation(); + if (!validate()) { + return null; + } + ProcessBuilder processBuilder = initProcessBuilder(location, arguments); + return startProcess(processBuilder); + } + + protected Process startProcess(ProcessBuilder builder) { + try { + process = builder.start(); + checkProcessIsAlive(); + return process; + } catch (IOException e) { + LOG.error("Could not start process for {}.", new Object[] { getName(), e }); + throw new OpenShiftException(e, "Does your OpenShift binary location exist? Error starting process: %s", + e.getMessage()); + } + } + + private ProcessBuilder initProcessBuilder(String location, final OpenShiftBinaryOption... options) { + List args = new ArrayList<>(); + ProcessBuilder builder = null; + // the condition is made in order to solve mac problem + // with launching binaries containing spaces in its path + // https://issues.jboss.org/browse/JBIDE-23862 - see the latest comments + if (IS_MAC) { + args.add(location); + StringSplitter.split(buildArgs(Arrays.asList(options)), args); + builder = new ProcessBuilder(args); + } else { + args.add(location); + StringSplitter.split(buildArgs(Arrays.asList(options)), args); + File oc = new File(location); + builder = new ProcessBuilder(args); + builder.directory(oc.getParentFile()); + } + builder.environment().remove("KUBECONFIG"); + LOG.debug("OpenShift binary args: {}", builder.command()); + return builder; + } + + private void checkProcessIsAlive() throws IOException { + try { + // TODO: replace fixed wait with wait for process to be running + Thread.sleep(1000); + if (!process.isAlive() && process.exitValue() != 0) { + throw new OpenShiftException("OpenShiftBinaryCapability process exited: %s", + IOUtils.toString(process.getErrorStream())); + } + } catch (InterruptedException e) { + if (!process.isAlive() && process.exitValue() != 0) { + throw new OpenShiftException("OpenShiftBinaryCapability process exited: %s", + IOUtils.toString(process.getErrorStream())); + } + } + } + + /** + * Stops the {@link Process} running the {@code oc} command. + */ + public final synchronized void stop() { + if (process == null) { + return; + } + cleanup(); + if (!process.isAlive()) { + final int exitValue = process.exitValue(); + LOG.debug("OpenShiftBinaryCapability process exit code {}", exitValue); + if (exitValue != 0) { + try { + LOG.debug("OpenShiftBinaryCapability process error stream", + IOUtils.toString(process.getErrorStream())); + } catch (IOException e) { + LOG.debug("IOException trying to debug the process error stream", e); + } + } + process = null; + return; + } + process.destroyForcibly(); + } + + protected String getOpenShiftBinaryLocation() { + // Check the ThreadLocal for oc binary + String location = OpenShiftContext.get().get(OPENSHIFT_BINARY_LOCATION); + if (StringUtils.isBlank(location)) { + // Fall back to System property + location = System.getProperty(OPENSHIFT_BINARY_LOCATION); + } + if (StringUtils.isBlank(location)) { + throw new LocationNotFoundException( + String.format("The OpenShift 'oc' binary location was not specified. Set the property %s", + OPENSHIFT_BINARY_LOCATION)); + } + return location; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AnnotationCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AnnotationCapability.java index a364ebbf..782426e2 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AnnotationCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AnnotationCapability.java @@ -6,53 +6,51 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.model.IResource; /** - * Determine if a resource has a capability if it - * has the given annotation + * Determine if a resource has a capability if it has the given annotation * - * @author Jeff Cantrill */ public abstract class AnnotationCapability implements ICapability { - private final IResource resource; - private final String name; - - public AnnotationCapability(String name, IResource resource) { - this.resource = resource; - this.name = name; - } - - @Override - public boolean isSupported() { - return resource.isAnnotatedWith(getAnnotationKey()); - } - - @Override - public String getName() { - return this.name; - } - - protected IResource getResource(){ - return this.resource; - } - - - /** - * The annotation key - * @return - */ - protected abstract String getAnnotationKey(); - - /** - * The annotations value - * @return - */ - public String getAnnotationValue(){ - return getResource().getAnnotation(getAnnotationKey()); - } + private final IResource resource; + private final String name; + + public AnnotationCapability(String name, IResource resource) { + this.resource = resource; + this.name = name; + } + + @Override + public boolean isSupported() { + return resource.isAnnotatedWith(getAnnotationKey()); + } + + @Override + public String getName() { + return this.name; + } + + protected IResource getResource() { + return this.resource; + } + + /** + * The annotation key + * + */ + protected abstract String getAnnotationKey(); + + /** + * The annotations value + * + */ + public String getAnnotationValue() { + return getResource().getAnnotation(getAnnotationKey()); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java index ae41c99d..6741eaa9 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AssociationCapability.java @@ -6,45 +6,49 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import com.openshift.restclient.IClient; import com.openshift.restclient.model.IResource; /** - * Retrieve the associated resource from the given - * resource's annotation + * Retrieve the associated resource from the given resource's annotation * - * @author Jeff Cantrill */ -public abstract class AssociationCapability extends AnnotationCapability{ - - private IClient client; - - public AssociationCapability(String name, IResource resource, IClient client) { - super(name, resource); - this.client = client; - } - - protected IClient getClient(){ - return client; - } - - @Override - public boolean isSupported() { - if(client == null) return false; - return super.isSupported(); - } - - /** - * Get the associated resource of the given kind using the - * name from the annotation key; - * @param kind - * @return - */ - protected T getAssociatedResource(String kind){ - if(!isSupported()) return null; - String name = getResource().getAnnotation(getAnnotationKey()); - return getClient().get(kind, name, getResource().getNamespaceName()); - } +public abstract class AssociationCapability extends AnnotationCapability { + + private IClient client; + + public AssociationCapability(String name, IResource resource, IClient client) { + super(name, resource); + this.client = client; + } + + protected IClient getClient() { + return client; + } + + @Override + public boolean isSupported() { + if (client == null) { + return false; + } + return super.isSupported(); + } + + /** + * Get the associated resource of the given kind using the name from the + * annotation key; + * + * @param kind The kind + * @return the resource + */ + protected T getAssociatedResource(String kind) { + if (!isSupported()) { + return null; + } + String name = getResource().getAnnotation(getAnnotationKey()); + return getClient().get(kind, name, getResource().getNamespaceName()); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildCanceller.java b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildCanceller.java index 4192f756..18d62f2f 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildCanceller.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildCanceller.java @@ -7,31 +7,31 @@ public class BuildCanceller implements IBuildCancelable { - private IBuild build; - private IClient client; - - public BuildCanceller(IBuild build, IClient client) { - this.build = build; - this.client = client; - } - - @Override - public boolean isSupported() { - return build != null && client != null && ResourceKind.BUILD.equals(build.getKind()); - } - - @Override - public String getName() { - return BuildCanceller.class.getSimpleName(); - } - - @Override - public IBuild cancel() { - boolean cancelled = build.cancel(); - if (cancelled) { - build = client.update(build); - } - return build; - } + private IBuild build; + private IClient client; + + public BuildCanceller(IBuild build, IClient client) { + this.build = build; + this.client = client; + } + + @Override + public boolean isSupported() { + return build != null && client != null && ResourceKind.BUILD.equals(build.getKind()); + } + + @Override + public String getName() { + return BuildCanceller.class.getSimpleName(); + } + + @Override + public IBuild cancel() { + boolean cancelled = build.cancel(); + if (cancelled) { + build = client.update(build); + } + return build; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java index 182f5a38..08562018 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.util.ArrayList; @@ -24,87 +25,84 @@ import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.build.IBuildRequest; -/** - * - * @author Jeff Cantrill - * - */ public class BuildTrigger implements IBuildTriggerable { - private static final String BUILDCONFIG_SUBRESOURCE = "instantiate"; - private static final String BUILD_SUBRESOURCE = "clone"; - private IResource resource; - private IClient client; - private final String subresource; - private String commitId; - private List causes; - private HashMap envVars = new HashMap(); - - public BuildTrigger(IBuildConfig buildConfig, IClient client) { - this.resource = buildConfig; - this.client = client; - this.subresource = BUILDCONFIG_SUBRESOURCE; - this.causes = new ArrayList<>(); - } - - public BuildTrigger(IBuild build, IClient client) { - this.resource = build; - this.client = client; - this.subresource = BUILD_SUBRESOURCE; - this.causes = new ArrayList<>(); - } - - @Override - public boolean isSupported() { - return resource != null && client != null && (ResourceKind.BUILD.equals(resource.getKind()) || ResourceKind.BUILD_CONFIG.equals(resource.getKind())); - } - - @Override - public String getName() { - return BuildTrigger.class.getSimpleName(); - } - - @Override - public IBuild trigger() { - IBuildRequest request = client.getResourceFactory().stub(ResourceKind.BUILD_REQUEST, resource.getName()); - if(StringUtils.isNotEmpty(commitId)) - request.setCommitId(commitId); - causes.forEach(c->request.addBuildCause(c)); - envVars.forEach((name, value)->request.setEnvironmentVariable(name, value)); - return client.create(resource.getKind(), resource.getNamespaceName(), resource.getName(), subresource, request); - } - - @Override @Deprecated - public IBuild trigger(String commitId) { - IBuildRequest request = client.getResourceFactory().stub(ResourceKind.BUILD_REQUEST, resource.getName()); - request.setCommitId(commitId); - return client.create(resource.getKind(), resource.getNamespaceName(), resource.getName(), subresource, request); - } - - @Override - public void setCommitId(String commitId) { - this.commitId = commitId; - } - - @Override - public String getCommitId() { - return commitId; - } - - @Override - public void addBuildCause(String cause) { - causes.add(cause); - } - - @Override - public List getBuildCauses() { - return new ArrayList<>(causes); - } - - @Override - public void setEnvironmentVariable(String name, String value) { - envVars.put(name, value); - } - + private static final String BUILDCONFIG_SUBRESOURCE = "instantiate"; + private static final String BUILD_SUBRESOURCE = "clone"; + private IResource resource; + private IClient client; + private final String subresource; + private String commitId; + private List causes; + private HashMap envVars = new HashMap(); + + public BuildTrigger(IBuildConfig buildConfig, IClient client) { + this.resource = buildConfig; + this.client = client; + this.subresource = BUILDCONFIG_SUBRESOURCE; + this.causes = new ArrayList<>(); + } + + public BuildTrigger(IBuild build, IClient client) { + this.resource = build; + this.client = client; + this.subresource = BUILD_SUBRESOURCE; + this.causes = new ArrayList<>(); + } + + @Override + public boolean isSupported() { + return resource != null && client != null && (ResourceKind.BUILD.equals(resource.getKind()) + || ResourceKind.BUILD_CONFIG.equals(resource.getKind())); + } + + @Override + public String getName() { + return BuildTrigger.class.getSimpleName(); + } + + @Override + public IBuild trigger() { + IBuildRequest request = client.getResourceFactory().stub(ResourceKind.BUILD_REQUEST, resource.getName()); + if (StringUtils.isNotEmpty(commitId)) { + request.setCommitId(commitId); + } + causes.forEach(c -> request.addBuildCause(c)); + envVars.forEach((name, value) -> request.setEnvironmentVariable(name, value)); + return client.create(resource.getKind(), resource.getNamespaceName(), resource.getName(), subresource, request); + } + + @Override + @Deprecated + public IBuild trigger(String commitId) { + IBuildRequest request = client.getResourceFactory().stub(ResourceKind.BUILD_REQUEST, resource.getName()); + request.setCommitId(commitId); + return client.create(resource.getKind(), resource.getNamespaceName(), resource.getName(), subresource, request); + } + + @Override + public void setCommitId(String commitId) { + this.commitId = commitId; + } + + @Override + public String getCommitId() { + return commitId; + } + + @Override + public void addBuildCause(String cause) { + causes.add(cause); + } + + @Override + public List getBuildCauses() { + return new ArrayList<>(causes); + } + + @Override + public void setEnvironmentVariable(String name, String value) { + envVars.put(name, value); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ClientCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ClientCapability.java index 28779c71..a76a4407 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ClientCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ClientCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import com.openshift.restclient.IClient; @@ -15,29 +16,28 @@ /** * Implementation to retrieve the client from a resource - * @author Jeff Cantrill */ public class ClientCapability implements IClientCapability { - - private IClient client; - - public ClientCapability(IClient client) { - this.client = client; - } - - @Override - public boolean isSupported() { - return client != null; - } - - @Override - public String getName() { - return getClass().getSimpleName(); - } - - @Override - public IClient getClient() { - return client; - } + + private IClient client; + + public ClientCapability(IClient client) { + this.client = client; + } + + @Override + public boolean isSupported() { + return client != null; + } + + @Override + public String getName() { + return getClass().getSimpleName(); + } + + @Override + public IClient getClient() { + return client; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java index b456cc81..29c57bd3 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java @@ -8,8 +8,8 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.capability.resources; +package com.openshift.internal.restclient.capability.resources; import java.util.Arrays; import java.util.List; @@ -25,65 +25,66 @@ import com.openshift.restclient.model.IDeploymentConfig; import com.openshift.restclient.model.IReplicationController; -public class DeployCapability implements IDeployCapability{ - - private static final List COMPLETED_STATES = Arrays.asList("Complete", "Failed"); - private static final Logger LOG = LoggerFactory.getLogger(IDeployCapability.class); - - - private final IClient client; - private final IDeploymentConfig config; - - public DeployCapability(IDeploymentConfig config, IClient client) { - this.config = config; - this.client = client; - - } - - @Override - public boolean isSupported() { - return true; - } - - @Override - public String getName() { - return DeployCapability.class.getSimpleName(); - } - - @Override - public void deploy() { - try { - final String deploymentName = getLatestDeploymentName(); - LOG.debug("Attempting to deploy latest deployment for config %s. Loading deployment: %s", config.getName(), deploymentName); - IReplicationController deployment = client.get(ResourceKind.REPLICATION_CONTROLLER, deploymentName, config.getNamespaceName()); - final String status = getStatusFor(deployment); - if(!COMPLETED_STATES.contains(status)) { - LOG.debug("Skipping deployment because deployment status %s for %s is not in %s", new Object [] {status, deploymentName, COMPLETED_STATES}); - return; - } - } catch(OpenShiftException e) { - if (e.getStatus() == null || e.getStatus().getCode() != IHttpConstants.STATUS_NOT_FOUND) { - //swallow exception like cli - throw e; - } - } - - //bumping as currently not supporting 'retry' - int version = config.getLatestVersionNumber(); - config.setLatestVersionNumber(++version); - client.update(config); - - } - - - private String getLatestDeploymentName() { - return String.format("%s-%d", config.getName(), config.getLatestVersionNumber()); - } - - private String getStatusFor(IReplicationController rc) { - if (rc.isAnnotatedWith(IReplicationController.DEPLOYMENT_PHASE)) { - return rc.getAnnotation(IReplicationController.DEPLOYMENT_PHASE); - } - return ""; - } +public class DeployCapability implements IDeployCapability { + + private static final List COMPLETED_STATES = Arrays.asList("Complete", "Failed"); + private static final Logger LOG = LoggerFactory.getLogger(IDeployCapability.class); + + private final IClient client; + private final IDeploymentConfig config; + + public DeployCapability(IDeploymentConfig config, IClient client) { + this.config = config; + this.client = client; + + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return DeployCapability.class.getSimpleName(); + } + + @Override + public void deploy() { + try { + final String deploymentName = getLatestDeploymentName(); + LOG.debug("Attempting to deploy latest deployment for config %s. Loading deployment: %s", config.getName(), + deploymentName); + IReplicationController deployment = client.get(ResourceKind.REPLICATION_CONTROLLER, deploymentName, + config.getNamespaceName()); + final String status = getStatusFor(deployment); + if (!COMPLETED_STATES.contains(status)) { + LOG.debug("Skipping deployment because deployment status %s for %s is not in %s", + new Object[] { status, deploymentName, COMPLETED_STATES }); + return; + } + } catch (OpenShiftException e) { + if (e.getStatus() == null || e.getStatus().getCode() != IHttpConstants.STATUS_NOT_FOUND) { + // swallow exception like cli + throw e; + } + } + + // bumping as currently not supporting 'retry' + int version = config.getLatestVersionNumber(); + config.setLatestVersionNumber(++version); + client.update(config); + + } + + private String getLatestDeploymentName() { + return String.format("%s-%d", config.getName(), config.getLatestVersionNumber()); + } + + private String getStatusFor(IReplicationController rc) { + if (rc.isAnnotatedWith(IReplicationController.DEPLOYMENT_PHASE)) { + return rc.getAnnotation(IReplicationController.DEPLOYMENT_PHASE); + } + return ""; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceability.java index f7b0c630..7861be65 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceability.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import com.openshift.restclient.IClient; @@ -15,25 +16,23 @@ import com.openshift.restclient.model.IResource; /** - * Capability for a resource to determine - * to which deploymentconfig it is associated - * - * @author Jeff Cantrill + * Capability for a resource to determine to which deploymentconfig it is + * associated */ public class DeploymentConfigTraceability extends AssociationCapability implements IDeploymentConfigTraceability { - public DeploymentConfigTraceability(IResource resource, IClient client) { - super(DeploymentConfigTraceability.class.getSimpleName(), resource, client); - } + public DeploymentConfigTraceability(IResource resource, IClient client) { + super(DeploymentConfigTraceability.class.getSimpleName(), resource, client); + } - @Override - public IDeploymentConfig getDeploymentConfig() { - return getAssociatedResource(ResourceKind.DEPLOYMENT_CONFIG); - } + @Override + public IDeploymentConfig getDeploymentConfig() { + return getAssociatedResource(ResourceKind.DEPLOYMENT_CONFIG); + } - @Override - protected String getAnnotationKey() { - return "deploymentconfig"; - } + @Override + protected String getAnnotationKey() { + return "deploymentconfig"; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceability.java index 9fe28294..eeca998f 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceability.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import com.openshift.restclient.IClient; @@ -15,28 +16,25 @@ import com.openshift.restclient.model.IResource; /** - * Determine which deployment caused a resource to - * be deployed based on the information found in its - * annotations - * - * @author Jeff Cantrill + * Determine which deployment caused a resource to be deployed based on the + * information found in its annotations */ public class DeploymentTraceability extends AssociationCapability implements IDeploymentTraceability { - - private static final String DEPLOYMENT_ANNOTATION = "deployment"; - - public DeploymentTraceability(IResource resource, IClient client) { - super(DeploymentTraceability.class.getSimpleName(), resource, client); - } - - @Override - public IReplicationController getDeployment() { - return getAssociatedResource(ResourceKind.REPLICATION_CONTROLLER); - } - - @Override - protected String getAnnotationKey() { - return DEPLOYMENT_ANNOTATION; - } + + private static final String DEPLOYMENT_ANNOTATION = "deployment"; + + public DeploymentTraceability(IResource resource, IClient client) { + super(DeploymentTraceability.class.getSimpleName(), resource, client); + } + + @Override + public IReplicationController getDeployment() { + return getAssociatedResource(ResourceKind.REPLICATION_CONTROLLER); + } + + @Override + protected String getAnnotationKey() { + return DEPLOYMENT_ANNOTATION; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java index b1e070ec..893ff791 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.util.Collections; @@ -30,9 +31,8 @@ */ public class DeploymentTrigger extends AbstractCapability implements IDeploymentTriggerable { private static final String DEPLOYMENT_ENDPOINT = "instantiate"; - private static final String DEPLOYMENT_REQUEST = "DeploymentRequest"; + private static final String DEPLOYMENT_REQUEST = "DeploymentRequest"; - private IClient client; private IDeploymentConfig config; private ITypeFactory factory; @@ -40,7 +40,6 @@ public class DeploymentTrigger extends AbstractCapability implements IDeployment private boolean force; private String resourceName; - public DeploymentTrigger(IDeploymentConfig resource, IClient client, ITypeFactory factory) { super(resource, client, DEPLOYMENT_ENDPOINT); this.client = client; @@ -54,19 +53,21 @@ public String getName() { } @Override - public boolean isSupported() { - return true; - } + public boolean isSupported() { + return true; + } - @Override + @Override public IDeploymentConfig trigger() { if (super.isSupported()) { - IDeploymentRequest request = (IDeploymentRequest) factory.stubKind(DEPLOYMENT_REQUEST, Optional.of(config.getName()), Optional.empty()); + IDeploymentRequest request = (IDeploymentRequest) factory.stubKind(DEPLOYMENT_REQUEST, + Optional.of(config.getName()), Optional.empty()); request.setForce(force); request.setLatest(latest); request.setName(resourceName); - return (IDeploymentConfig) client.execute(client.getResourceFactory(), IHttpConstants.POST, config.getKind(), config.getNamespaceName(), config.getName(), DEPLOYMENT_ENDPOINT, null, request, - Collections.emptyMap()); + return (IDeploymentConfig) client.execute(client.getResourceFactory(), IHttpConstants.POST, + config.getKind(), config.getNamespaceName(), config.getName(), DEPLOYMENT_ENDPOINT, null, request, + Collections.emptyMap()); } else { IDeployCapability deployer = config.getCapability(IDeployCapability.class); deployer.deploy(); diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java index 0e1b4d59..fd46998f 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.util.Comparator; @@ -43,259 +44,254 @@ /** * Retrieve metadata directly from docker. - * @author jeff.cantrill - * */ -public class DockerRegistryImageStreamImportCapability implements IImageStreamImportCapability, IHttpConstants, ResourcePropertyKeys { - - private static final String TOKEN = "token"; - private static final String STATUS_STATUS = "status.status"; - private static final String ID = "id"; - private static final String PARENT = "parent"; - private static final String REALM = "realm"; - private static final Logger LOG = LoggerFactory.getLogger(IImageStreamImportCapability.class); - private static final String DEFAULT_DOCKER_REGISTRY = "https://registry-1.docker.io/v2"; - private IResourceFactory factory; - private IProject project; - private OkHttpClient okClient; - - public DockerRegistryImageStreamImportCapability(IProject project, IResourceFactory factory, IClient client) { - this.factory = factory; - this.project = project; - this.okClient = client.adapt(OkHttpClient.class); - if(okClient != null) { - okClient = okClient.newBuilder() - .followRedirects(true) - .build(); - } - } - - @Override - public boolean isSupported() { - return true; - } - - @Override - public String getName() { - return DockerRegistryImageStreamImportCapability.class.getSimpleName(); - } - - private boolean registryExists(OkHttpClient client) throws Exception{ - Request req = new Request.Builder() - .url(DEFAULT_DOCKER_REGISTRY) - .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true") - .build(); - Response response = client.newCall(req).execute(); - if(response == null) return false; - return (response.code() == STATUS_UNAUTHORIZED || response.code() == STATUS_OK); - } - - /** - * @return the token required to pull docker metadata - */ - private String retrieveAuthToken(OkHttpClient client, String details) throws Exception { - if(StringUtils.isNotBlank(details)) { - Map auth = parseAuthDetails(details); - if(auth.containsKey(REALM)) { - Request request = createAuthRequest(auth); - Response response = client.newCall(request).execute(); - LOG.debug("Auth response: " + response.toString()); - if(response.code() == STATUS_OK && MEDIATYPE_APPLICATION_JSON.equals(response.headers().get(PROPERTY_CONTENT_TYPE))) { - ModelNode tokenNode = ModelNode.fromJSONString(response.body().string()); - if(tokenNode.hasDefined(TOKEN)) { - return tokenNode.get(TOKEN).asString(); - }else { - LOG.debug("No auth token was found on auth response: " + tokenNode.toJSONString(false)); - } - } else { - LOG.info("Unable to retrieve authentication token as response was not OK and/or unexpected content type"); - } - }else { - LOG.info("Unable to retrieve authentication token - 'realm' was not found in the authenticate header: " + auth.toString()); - } - } - return null; - } - - private Request createAuthRequest(Map authParams) { - HttpUrl.Builder builder = HttpUrl.parse(StringUtils.strip(authParams.get(REALM),"\"")) - .newBuilder(); - for (Entry e: authParams.entrySet()) { - if(!REALM.equals(e.getKey())) { - builder.addQueryParameter(StringUtils.strip(e.getKey(),"\""), StringUtils.strip(e.getValue(),"\"")); - } - } - Request request = new Request.Builder() - .url(builder.build()) - .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true") - .build(); - LOG.debug("Auth request uri: " + request.url()); - return request; - } - - private Map parseAuthDetails(String auth){ - LOG.debug("Auth details header: " + auth); - Map map = new HashMap<>(); - String [] authAndValues = auth.split(" "); - if(authAndValues.length == 2 && AUTHORIZATION_BEARER.equals(authAndValues[0])) { - String [] params = authAndValues[1].split(","); - for (String p : params) { - String[] knv = p.split("="); - if(knv.length >= 2 ) { - map.put(knv[0], knv[1]); - } - } - } - return map; - } - - private DockerResponse retrieveMetaData(OkHttpClient client, String token, DockerImageURI uri) throws Exception { - String regUri = String.format("%s/%s/%s/manifests/%s", - DEFAULT_DOCKER_REGISTRY, - StringUtils.defaultIfBlank(uri.getUserName(),"library"), - uri.getName(), - uri.getTag()); - Request.Builder builder = new Request.Builder() - .url(regUri) - .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true"); - if(token != null) { - builder.header(PROPERTY_AUTHORIZATION, String.format("%s %s", AUTHORIZATION_BEARER, token)); - - } - LOG.debug("retrieveMetaData uri: " + regUri); - Response response = client.newCall(builder.build()).execute(); - LOG.debug("retrieveMetaData response: " + response.toString()); - switch(response.code()) { - case STATUS_OK: - return new DockerResponse(DockerResponse.DATA, response.body().string()); - case STATUS_UNAUTHORIZED: - return new DockerResponse(DockerResponse.AUTH, response.headers().get(IHttpConstants.PROPERTY_WWW_AUTHENTICATE)); - } - LOG.info("Unable to retrieve docker meta data: " + response.toString()); - return null; - } - - private static class DockerResponse { - public static final String DATA = "data"; - public static final String AUTH = "auth"; - String responseType; - String data; - DockerResponse(String responseType, String data){ - this.responseType = responseType; - this.data = data; - } - public Object getResponseType() { - return responseType; - } - public String getData() { - return data; - } - } - - @Override - public IImageStreamImport importImageMetadata(DockerImageURI uri) { - if(okClient != null) { - try { - if(registryExists(okClient)) { - String token = null; - DockerResponse response = retrieveMetaData(okClient, token, uri); - if(DockerResponse.AUTH.equals(response.getResponseType())){ - LOG.debug("Unauthorized. Trying to retrieve token..."); - token = retrieveAuthToken(okClient, response.getData()); - response = retrieveMetaData(okClient, token, uri); - } - if(DockerResponse.DATA.equals(response.getResponseType())) { - String meta = response.getData(); - LOG.debug("Raw Docker image metadata: " + meta); - return buildResponse(meta, uri); - }else { - LOG.info("Unable to retrieve image metadata from docker registry"); - return buildErrorResponse(uri); - } - } - } catch (Exception e) { - LOG.error("Exception while trying to retrieve image metadata from docker", e); - } - } - return buildErrorResponse(uri); - } - - private IImageStreamImport buildErrorResponse(DockerImageURI uri) { - ModelNodeBuilder builder = new ModelNodeBuilder() - .set(STATUS_STATUS, "Failure") - .set("status.message", String.format("you may not have access to the Docker image \"%s\"", uri.getUriWithoutHost())) - .set("status.reason", "Unauthorized") - .set("status.code", IHttpConstants.STATUS_UNAUTHORIZED); - - return buildImageStreamImport(uri, builder.build()); - } - - private IImageStreamImport buildResponse(String meta, DockerImageURI uri) { - ModelNode raw = ModelNode.fromJSONString(meta); - ModelNode last = findNewestHistoryEntry(raw); - ModelNode containerConfig = last.remove("container_config"); - last.get("ContainerConfig").set(containerConfig); - - ModelNodeBuilder builder = new ModelNodeBuilder() - .set(STATUS_STATUS, "Success") - .set("tag", uri.getTag()) - .set("image.metadata.name", uri.getName()) - .set(ImageStreamImport.IMAGE_DOCKER_IMAGE_REFERENCE,uri.getUriUserNameAndName()) - .set("image.dockerImageMetadata", last) - .set("status.code", IHttpConstants.STATUS_OK); - - return buildImageStreamImport(uri, builder.build()); - } - - private ImageStreamImport buildImageStreamImport(DockerImageURI uri, ModelNode node) { - ImageStreamImport isImport = (ImageStreamImport) factory.stub(ResourceKind.IMAGE_STREAM_IMPORT, uri.getName(), this.project.getName()); - ModelNode root = isImport.getNode(); - ModelNode images = JBossDmrExtentions.get(root,null, ImageStreamImport.STATUS_IMAGES); - images.add(node); - - return isImport; - } - - private ModelNode findNewestHistoryEntry(ModelNode root) { - ModelNode history = root.get("history"); - List entries = history.asList().stream().map(n->ModelNode.fromJSONString(n.get("v1Compatibility").asString())).collect(Collectors.toList()); - entries.sort(new ManifestComparator()); - - - ModelNode last = entries.get(entries.size() - 1); - LOG.debug("newest history: " + last.toJSONString(false)); - return last; - } - - /** - * Sorts history entries ordering from oldest to newest - * by comparing the entry id to its referenced parent - * @author jeff.cantrill - * - */ - static class ManifestComparator implements Comparator { - - @Override - public int compare(ModelNode one, ModelNode two) { - String parent1 = one.has(PARENT) ? one.get(PARENT).asString() : null; - String parent2 = two.has(PARENT) ? one.get(PARENT).asString() : null; - if(parent1 == null && parent2 != null) { - return -1; - }else if(parent1 != null && parent2 == null) { - return 1; - }else if(parent1 == null && parent2 == null) { - return 0; //we should never get here - } - String id1 = one.get(ID).asString(); - String id2 = two.get(ID).asString(); - - if(parent2.equals(id1)) { - return -1; - }else if(parent1.equals(id2)) { - return 1; - } - - return 0; //we should never get here - } - } +public class DockerRegistryImageStreamImportCapability + implements IImageStreamImportCapability, IHttpConstants, ResourcePropertyKeys { + + private static final String TOKEN = "token"; + private static final String STATUS_STATUS = "status.status"; + private static final String ID = "id"; + private static final String PARENT = "parent"; + private static final String REALM = "realm"; + private static final Logger LOG = LoggerFactory.getLogger(IImageStreamImportCapability.class); + private static final String DEFAULT_DOCKER_REGISTRY = "https://registry-1.docker.io/v2"; + private IResourceFactory factory; + private IProject project; + private OkHttpClient okClient; + + public DockerRegistryImageStreamImportCapability(IProject project, IResourceFactory factory, IClient client) { + this.factory = factory; + this.project = project; + this.okClient = client.adapt(OkHttpClient.class); + if (okClient != null) { + okClient = okClient.newBuilder().followRedirects(true).build(); + } + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return DockerRegistryImageStreamImportCapability.class.getSimpleName(); + } + + private boolean registryExists(OkHttpClient client) throws Exception { + Request req = new Request.Builder().url(DEFAULT_DOCKER_REGISTRY) + .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true").build(); + Response response = client.newCall(req).execute(); + if (response == null) { + return false; + } + return (response.code() == STATUS_UNAUTHORIZED || response.code() == STATUS_OK); + } + + /** + * @return the token required to pull docker metadata + */ + private String retrieveAuthToken(OkHttpClient client, String details) throws Exception { + if (StringUtils.isNotBlank(details)) { + Map auth = parseAuthDetails(details); + if (auth.containsKey(REALM)) { + Request request = createAuthRequest(auth); + Response response = client.newCall(request).execute(); + LOG.debug("Auth response: " + response.toString()); + if (response.code() == STATUS_OK + && MEDIATYPE_APPLICATION_JSON.equals(response.headers().get(PROPERTY_CONTENT_TYPE))) { + ModelNode tokenNode = ModelNode.fromJSONString(response.body().string()); + if (tokenNode.hasDefined(TOKEN)) { + return tokenNode.get(TOKEN).asString(); + } else { + LOG.debug("No auth token was found on auth response: " + tokenNode.toJSONString(false)); + } + } else { + LOG.info( + "Unable to retrieve authentication token as response was not OK and/or unexpected content type"); + } + } else { + LOG.info("Unable to retrieve authentication token - 'realm' was not found in the authenticate header: " + + auth.toString()); + } + } + return null; + } + + private Request createAuthRequest(Map authParams) { + HttpUrl.Builder builder = HttpUrl.parse(StringUtils.strip(authParams.get(REALM), "\"")).newBuilder(); + for (Entry e : authParams.entrySet()) { + if (!REALM.equals(e.getKey())) { + builder.addQueryParameter(StringUtils.strip(e.getKey(), "\""), StringUtils.strip(e.getValue(), "\"")); + } + } + Request request = new Request.Builder().url(builder.build()) + .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true").build(); + LOG.debug("Auth request uri: " + request.url()); + return request; + } + + private Map parseAuthDetails(String auth) { + LOG.debug("Auth details header: " + auth); + Map map = new HashMap<>(); + String[] authAndValues = auth.split(" "); + if (authAndValues.length == 2 && AUTHORIZATION_BEARER.equals(authAndValues[0])) { + String[] params = authAndValues[1].split(","); + for (String p : params) { + String[] knv = p.split("="); + if (knv.length >= 2) { + map.put(knv[0], knv[1]); + } + } + } + return map; + } + + private DockerResponse retrieveMetaData(OkHttpClient client, String token, DockerImageURI uri) throws Exception { + String regUri = String.format("%s/%s/%s/manifests/%s", DEFAULT_DOCKER_REGISTRY, + StringUtils.defaultIfBlank(uri.getUserName(), "library"), uri.getName(), uri.getTag()); + Request.Builder builder = new Request.Builder().url(regUri) + .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true"); + if (token != null) { + builder.header(PROPERTY_AUTHORIZATION, String.format("%s %s", AUTHORIZATION_BEARER, token)); + + } + LOG.debug("retrieveMetaData uri: " + regUri); + Response response = client.newCall(builder.build()).execute(); + LOG.debug("retrieveMetaData response: " + response.toString()); + switch (response.code()) { + case STATUS_OK: + return new DockerResponse(DockerResponse.DATA, response.body().string()); + case STATUS_UNAUTHORIZED: + return new DockerResponse(DockerResponse.AUTH, + response.headers().get(IHttpConstants.PROPERTY_WWW_AUTHENTICATE)); + } + LOG.info("Unable to retrieve docker meta data: " + response.toString()); + return null; + } + + private static class DockerResponse { + public static final String DATA = "data"; + public static final String AUTH = "auth"; + String responseType; + String data; + + DockerResponse(String responseType, String data) { + this.responseType = responseType; + this.data = data; + } + + public Object getResponseType() { + return responseType; + } + + public String getData() { + return data; + } + } + + @Override + public IImageStreamImport importImageMetadata(DockerImageURI uri) { + if (okClient != null) { + try { + if (registryExists(okClient)) { + String token = null; + DockerResponse response = retrieveMetaData(okClient, token, uri); + if (DockerResponse.AUTH.equals(response.getResponseType())) { + LOG.debug("Unauthorized. Trying to retrieve token..."); + token = retrieveAuthToken(okClient, response.getData()); + response = retrieveMetaData(okClient, token, uri); + } + if (DockerResponse.DATA.equals(response.getResponseType())) { + String meta = response.getData(); + LOG.debug("Raw Docker image metadata: " + meta); + return buildResponse(meta, uri); + } else { + LOG.info("Unable to retrieve image metadata from docker registry"); + return buildErrorResponse(uri); + } + } + } catch (Exception e) { + LOG.error("Exception while trying to retrieve image metadata from docker", e); + } + } + return buildErrorResponse(uri); + } + + private IImageStreamImport buildErrorResponse(DockerImageURI uri) { + ModelNodeBuilder builder = new ModelNodeBuilder().set(STATUS_STATUS, "Failure") + .set("status.message", + String.format("you may not have access to the Docker image \"%s\"", uri.getUriWithoutHost())) + .set("status.reason", "Unauthorized").set("status.code", IHttpConstants.STATUS_UNAUTHORIZED); + + return buildImageStreamImport(uri, builder.build()); + } + + private IImageStreamImport buildResponse(String meta, DockerImageURI uri) { + ModelNode raw = ModelNode.fromJSONString(meta); + ModelNode last = findNewestHistoryEntry(raw); + ModelNode containerConfig = last.remove("container_config"); + last.get("ContainerConfig").set(containerConfig); + + ModelNodeBuilder builder = new ModelNodeBuilder().set(STATUS_STATUS, "Success").set("tag", uri.getTag()) + .set("image.metadata.name", uri.getName()) + .set(ImageStreamImport.IMAGE_DOCKER_IMAGE_REFERENCE, uri.getUriUserNameAndName()) + .set("image.dockerImageMetadata", last).set("status.code", IHttpConstants.STATUS_OK); + + return buildImageStreamImport(uri, builder.build()); + } + + private ImageStreamImport buildImageStreamImport(DockerImageURI uri, ModelNode node) { + ImageStreamImport isImport = (ImageStreamImport) factory.stub(ResourceKind.IMAGE_STREAM_IMPORT, uri.getName(), + this.project.getName()); + ModelNode root = isImport.getNode(); + ModelNode images = JBossDmrExtentions.get(root, null, ImageStreamImport.STATUS_IMAGES); + images.add(node); + + return isImport; + } + + private ModelNode findNewestHistoryEntry(ModelNode root) { + ModelNode history = root.get("history"); + List entries = history.asList().stream() + .map(n -> ModelNode.fromJSONString(n.get("v1Compatibility").asString())).collect(Collectors.toList()); + entries.sort(new ManifestComparator()); + + ModelNode last = entries.get(entries.size() - 1); + LOG.debug("newest history: " + last.toJSONString(false)); + return last; + } + + /** + * Sorts history entries ordering from oldest to newest by comparing the entry + * id to its referenced parent + * + * @author jeff.cantrill + * + */ + static class ManifestComparator implements Comparator { + + @Override + public int compare(ModelNode one, ModelNode two) { + String parent1 = one.has(PARENT) ? one.get(PARENT).asString() : null; + String parent2 = two.has(PARENT) ? one.get(PARENT).asString() : null; + if (parent1 == null && parent2 != null) { + return -1; + } else if (parent1 != null && parent2 == null) { + return 1; + } else if (parent1 == null && parent2 == null) { + return 0; // we should never get here + } + String id1 = one.get(ID).asString(); + String id2 = two.get(ID).asString(); + + if (parent2.equals(id1)) { + return -1; + } else if (parent1.equals(id2)) { + return 1; + } + + return 0; // we should never get here + } + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java index bcd07f67..85a631a4 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapability.java @@ -8,8 +8,8 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.capability.resources; +package com.openshift.internal.restclient.capability.resources; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,53 +24,49 @@ import com.openshift.restclient.model.IStatus; import com.openshift.restclient.model.image.IImageStreamImport; -/** - * - * @author jeff.cantrill - * - */ public class ImageStreamImportCapability implements IImageStreamImportCapability { - private static final Logger LOG = LoggerFactory.getLogger(IImageStreamImportCapability.class); - private IClient client; - private IProject project; + private static final Logger LOG = LoggerFactory.getLogger(IImageStreamImportCapability.class); + private IClient client; + private IProject project; + + public ImageStreamImportCapability(IProject project, IClient client) { + this.project = project; + this.client = client; + } - public ImageStreamImportCapability(IProject project, IClient client) { - this.project = project; - this.client = client; - } - - @Override - public IImageStreamImport importImageMetadata(DockerImageURI uri) { - - LOG.debug("first trying imagestreamimport against OpenShift server..."); - IImageStreamImport streamImport = client.getResourceFactory().stub(ResourceKind.IMAGE_STREAM_IMPORT, "jbosstools-openshift-deployimage", project.getName()); - streamImport.setImport(false); - streamImport.addImage("DockerImage", uri); - try { - IImageStreamImport result = client.create(streamImport); - for (IStatus status : result.getImageStatus()) { - if(IStatus.SUCCESS.equalsIgnoreCase(status.getStatus())) { - return result; - } - } - }catch(ResourceForbiddenException | UnsupportedEndpointException e) { - LOG.info("Unsuccessful in trying OpenShift server. ImageStreamImport is not supported."); - } - LOG.debug("Unsuccessful in trying OpenShift server. Trying dockerhub v2 registry..."); - DockerRegistryImageStreamImportCapability reg = new DockerRegistryImageStreamImportCapability(this.project, client.getResourceFactory(), client); - return reg.importImageMetadata(uri); - } + @Override + public IImageStreamImport importImageMetadata(DockerImageURI uri) { + LOG.debug("first trying imagestreamimport against OpenShift server..."); + IImageStreamImport streamImport = client.getResourceFactory().stub(ResourceKind.IMAGE_STREAM_IMPORT, + "jbosstools-openshift-deployimage", project.getName()); + streamImport.setImport(false); + streamImport.addImage("DockerImage", uri); + try { + IImageStreamImport result = client.create(streamImport); + for (IStatus status : result.getImageStatus()) { + if (IStatus.SUCCESS.equalsIgnoreCase(status.getStatus())) { + return result; + } + } + } catch (ResourceForbiddenException | UnsupportedEndpointException e) { + LOG.info("Unsuccessful in trying OpenShift server. ImageStreamImport is not supported."); + } + LOG.debug("Unsuccessful in trying OpenShift server. Trying dockerhub v2 registry..."); + DockerRegistryImageStreamImportCapability reg = new DockerRegistryImageStreamImportCapability(this.project, + client.getResourceFactory(), client); + return reg.importImageMetadata(uri); + } - @Override - public boolean isSupported() { - return true; - } + @Override + public boolean isSupported() { + return true; + } - @Override - public String getName() { - return ImageStreamImportCapability.class.getSimpleName(); - } + @Override + public String getName() { + return ImageStreamImportCapability.class.getSimpleName(); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrieval.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrieval.java index 19c7b958..980d0a5c 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrieval.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrieval.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.io.InputStream; @@ -28,176 +29,173 @@ import com.openshift.restclient.model.IPod; public class OpenShiftBinaryPodLogRetrieval implements IPodLogRetrieval { - - static class PodName implements OpenShiftBinaryOption { - - private IPod pod; - - public PodName(IPod pod) { - this.pod = pod; - } - - @Override - public void append(StringBuilder commandLine) { - if (pod == null) { - return; - } - commandLine.append(" ").append(pod.getName()); - } - } - - static class ContainerName implements OpenShiftBinaryOption { - - private String name; - - public ContainerName(String name) { - this.name = name; - } - - @Override - public void append(StringBuilder commandLine) { - commandLine.append( " -c ").append(name); - } - } - - static class Follow implements OpenShiftBinaryOption { - - @Override - public void append(StringBuilder commandLine) { - commandLine.append(" -f"); - } - } - - private static final Logger LOG = LoggerFactory.getLogger(IPodLogRetrieval.class); - private IPod pod; - private IClient client; - private Map cache = new HashMap<>(); - - public OpenShiftBinaryPodLogRetrieval(IPod pod, IClient client) { - this.pod = pod; - this.client = client; - } - - @Override - public boolean isSupported() { - return true; - } - - @Override - public String getName() { - return OpenShiftBinaryPodLogRetrieval.class.getSimpleName(); - } - - @Override - public InputStream getLogs(final boolean follow, final OpenShiftBinaryOption... options) { - return getLogs(follow, null, options); - } - - @Override - public InputStream getLogs(final boolean follow, final String container, final OpenShiftBinaryOption... options) { - final String normalizedContainer = StringUtils.defaultIfBlank(container, ""); - synchronized (cache) { - if (cache.containsKey(normalizedContainer)) { - return cache.get(normalizedContainer).getLogs(); - } - PodLogs logs = null; - try { - logs = new PodLogs(client, follow, normalizedContainer, options); - return logs.getLogs(); - } finally { - if (logs != null) { - cache.put(normalizedContainer, logs); - } - } - } - } - - @Override - public void stop() { - new ArrayList<>(cache.keySet()).forEach(container -> stop(container)); - } - - @Override - public synchronized void stop(String container) { - if(!cache.containsKey(container)) return; - try { - PodLogs logs = cache.remove(container); - logs.stop(); - }catch(Exception e) { - LOG.warn("Unable to stop pod logs",e); - } - } - - - protected class PodLogs extends AbstractOpenShiftBinaryCapability{ - - public static final String LOGS_COMMAND = "logs"; - - private String container; - private boolean follow; - private SequenceInputStream is; - private OpenShiftBinaryOption[] options; - - protected PodLogs(IClient client, boolean follow, String container, OpenShiftBinaryOption... options){ - super(client); - this.follow = follow; - this.container = container; - this.options = options; - } - - public synchronized InputStream getLogs() { - if (is == null) { - Process process = start(options); - if (process != null) { - is = new SequenceInputStream(process.getInputStream(), process.getErrorStream()); - } - } - return is; - } - - @Override - public boolean isSupported() { - return true; - } - - @Override - public String getName() { - return ""; - } - - @Override - protected void cleanup() { - follow = false; - if(getProcess() != null) { - IOUtils.closeQuietly(getProcess().getInputStream()); - IOUtils.closeQuietly(getProcess().getErrorStream()); - } - synchronized (cache) { - cache.remove(this.container); - } - } - - @Override - protected boolean validate() { - return true; - } - - @Override - protected String buildArgs(final List options) { - CommandLineBuilder builder = new CommandLineBuilder(LOGS_COMMAND) - .append(new Token(client)) - .append(new Server(client)) - .append(options) - .append(new PodName(pod)) - .append(new Namespace(pod)); - if (follow) { - builder.append(new Follow()); - } - if (StringUtils.isNotBlank(container)) { - builder.append(new ContainerName(container)); - } - return builder.build(); - } - } - + + static class PodName implements OpenShiftBinaryOption { + + private IPod pod; + + public PodName(IPod pod) { + this.pod = pod; + } + + @Override + public void append(StringBuilder commandLine) { + if (pod == null) { + return; + } + commandLine.append(" ").append(pod.getName()); + } + } + + static class ContainerName implements OpenShiftBinaryOption { + + private String name; + + public ContainerName(String name) { + this.name = name; + } + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" -c ").append(name); + } + } + + static class Follow implements OpenShiftBinaryOption { + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" -f"); + } + } + + private static final Logger LOG = LoggerFactory.getLogger(IPodLogRetrieval.class); + private IPod pod; + private IClient client; + private Map cache = new HashMap<>(); + + public OpenShiftBinaryPodLogRetrieval(IPod pod, IClient client) { + this.pod = pod; + this.client = client; + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return OpenShiftBinaryPodLogRetrieval.class.getSimpleName(); + } + + @Override + public InputStream getLogs(final boolean follow, final OpenShiftBinaryOption... options) { + return getLogs(follow, null, options); + } + + @Override + public InputStream getLogs(final boolean follow, final String container, final OpenShiftBinaryOption... options) { + final String normalizedContainer = StringUtils.defaultIfBlank(container, ""); + synchronized (cache) { + if (cache.containsKey(normalizedContainer)) { + return cache.get(normalizedContainer).getLogs(); + } + PodLogs logs = null; + try { + logs = new PodLogs(client, follow, normalizedContainer, options); + return logs.getLogs(); + } finally { + if (logs != null) { + cache.put(normalizedContainer, logs); + } + } + } + } + + @Override + public void stop() { + new ArrayList<>(cache.keySet()).forEach(container -> stop(container)); + } + + @Override + public synchronized void stop(String container) { + if (!cache.containsKey(container)) { + return; + } + try { + PodLogs logs = cache.remove(container); + logs.stop(); + } catch (Exception e) { + LOG.warn("Unable to stop pod logs", e); + } + } + + protected class PodLogs extends AbstractOpenShiftBinaryCapability { + + public static final String LOGS_COMMAND = "logs"; + + private String container; + private boolean follow; + private SequenceInputStream is; + private OpenShiftBinaryOption[] options; + + protected PodLogs(IClient client, boolean follow, String container, OpenShiftBinaryOption... options) { + super(client); + this.follow = follow; + this.container = container; + this.options = options; + } + + public synchronized InputStream getLogs() { + if (is == null) { + Process process = start(options); + if (process != null) { + is = new SequenceInputStream(process.getInputStream(), process.getErrorStream()); + } + } + return is; + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return ""; + } + + @Override + protected void cleanup() { + follow = false; + if (getProcess() != null) { + IOUtils.closeQuietly(getProcess().getInputStream()); + IOUtils.closeQuietly(getProcess().getErrorStream()); + } + synchronized (cache) { + cache.remove(this.container); + } + } + + @Override + protected boolean validate() { + return true; + } + + @Override + protected String buildArgs(final List options) { + CommandLineBuilder builder = new CommandLineBuilder(LOGS_COMMAND).append(new Token(client)) + .append(new Server(client)).append(options).append(new PodName(pod)).append(new Namespace(pod)); + if (follow) { + builder.append(new Follow()); + } + if (StringUtils.isNotBlank(container)) { + builder.append(new ContainerName(container)); + } + return builder.build(); + } + } + } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java index 3ab4ed76..74207e9b 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.util.ArrayList; @@ -22,112 +23,100 @@ /** * Port forwarding implementation that wraps the OpenShift binary * - * @author Jeff Cantrill - * @author Andre Dietisheim - * */ public class OpenShiftBinaryPortForwarding extends AbstractOpenShiftBinaryCapability implements IPortForwardable { - - public static final String PORT_FORWARD_COMMAND = "port-forward"; - private final IPod pod; - private final Collection pairs = new ArrayList<>(); - - static class PodName implements OpenShiftBinaryOption { - - private IPod pod; - - public PodName(IPod pod) { - this.pod = pod; - } - - @Override - public void append(StringBuilder commandLine) { - commandLine.append(" -p ").append(pod.getName()); - } - } - - static class PortPairs implements OpenShiftBinaryOption { - - private Collection pairs; - - public PortPairs(Collection pairs) { - this.pairs = pairs; - } - - @Override - public void append(StringBuilder commandLine) { - if (pairs == null) { - return; - } - for (PortPair pair : pairs) { - append(pair, commandLine); - } - } - - protected void append(PortPair pair, StringBuilder commandLine) { - commandLine - .append(" ") - .append(pair.getLocalPort()) - .append(":") - .append(pair.getRemotePort()).append(" "); - } - } - - public OpenShiftBinaryPortForwarding(IPod pod, IClient client) { - super(client); - this.pod = pod; - } - - @Override - protected void cleanup() { - this.pairs.clear(); - } - - @Override - protected boolean validate() { - return !pairs.isEmpty(); - } - - @Override - public boolean isForwarding() { - return getProcess() != null && getProcess().isAlive(); - } - - @Override - public boolean isSupported() { - return true; - } - - @Override - public String getName() { - return OpenShiftBinaryPortForwarding.class.getSimpleName(); - } - - @Override - public Collection getPortPairs() { - return pairs; - } - - @Override - public synchronized void forwardPorts(final Collection ports, final OpenShiftBinaryOption... options) { - if (ports == null || ports.isEmpty()) { - throw new OpenShiftException("Port-forwarding was invoked but no ports were specified."); - } - - this.pairs.addAll(ports); - start(options); - } - - @Override - protected String buildArgs(final List options) { - return new CommandLineBuilder(PORT_FORWARD_COMMAND) - .append( new Token(getClient())) - .append(new Server(getClient())) - .append(options) - .append(new Namespace(pod)) - .append(new PodName(pod)) - .append(new PortPairs(pairs)) - .build(); - } - + + public static final String PORT_FORWARD_COMMAND = "port-forward"; + private final IPod pod; + private final Collection pairs = new ArrayList<>(); + + static class PodName implements OpenShiftBinaryOption { + + private IPod pod; + + public PodName(IPod pod) { + this.pod = pod; + } + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" -p ").append(pod.getName()); + } + } + + static class PortPairs implements OpenShiftBinaryOption { + + private Collection pairs; + + public PortPairs(Collection pairs) { + this.pairs = pairs; + } + + @Override + public void append(StringBuilder commandLine) { + if (pairs == null) { + return; + } + for (PortPair pair : pairs) { + append(pair, commandLine); + } + } + + protected void append(PortPair pair, StringBuilder commandLine) { + commandLine.append(" ").append(pair.getLocalPort()).append(":").append(pair.getRemotePort()).append(" "); + } + } + + public OpenShiftBinaryPortForwarding(IPod pod, IClient client) { + super(client); + this.pod = pod; + } + + @Override + protected void cleanup() { + this.pairs.clear(); + } + + @Override + protected boolean validate() { + return !pairs.isEmpty(); + } + + @Override + public boolean isForwarding() { + return getProcess() != null && getProcess().isAlive(); + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return OpenShiftBinaryPortForwarding.class.getSimpleName(); + } + + @Override + public Collection getPortPairs() { + return pairs; + } + + @Override + public synchronized void forwardPorts(final Collection ports, final OpenShiftBinaryOption... options) { + if (ports == null || ports.isEmpty()) { + throw new OpenShiftException("Port-forwarding was invoked but no ports were specified."); + } + + this.pairs.addAll(ports); + start(options); + } + + @Override + protected String buildArgs(final List options) { + return new CommandLineBuilder(PORT_FORWARD_COMMAND).append(new Token(getClient())) + .append(new Server(getClient())).append(options).append(new Namespace(pod)).append(new PodName(pod)) + .append(new PortPairs(pairs)).build(); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java index d767f388..234d3b16 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.io.IOException; @@ -35,142 +36,133 @@ */ public class OpenShiftBinaryRSync extends AbstractOpenShiftBinaryCapability implements IRSyncable { - private static final Logger LOG = LoggerFactory.getLogger(OpenShiftBinaryRSync.class); - public static final String RSYNC_COMMAND = "rsync"; - private static final long WAIT_FOR_EXIT_TIMEOUT = 5; // mins - - private Peer source; - private Peer destination; - private IPod pod; - - private final Executor executor = Executors.newCachedThreadPool(); - - /** - * Constructor. - * @param client the client to connect to OpenShift. - */ - public OpenShiftBinaryRSync(final IClient client) { - super(client); - } - - @Override - public InputStream sync(final Peer source, final Peer destination, final OpenShiftBinaryOption... options) - throws OpenShiftException { - this.source = source; - this.destination = destination; - this.pod = getPod(source, destination); - Process process = start(options); - waitFor(process); - if (process == null) { - return null; - } - return process.getInputStream(); - } - - private IPod getPod(Peer source, Peer destination) { - if (source.isPod()) { - return source.getPod(); - } else if (destination.isPod()) { - return destination.getPod(); - } else { - return null; - } - } - - protected void waitFor(Process process) { - if (process == null) { - return; - } - - this.executor.execute(() -> { - try { - process.waitFor(); - } catch (InterruptedException e) { - throw new OpenShiftException("Error occurred while waiting for rsync operation to complete", e); - } - }); - } - - @Override - public boolean isDone() { - return !getProcess().isAlive(); - } - - @Override - public int exitValue() { - return getProcess().exitValue(); - } - - @Override - public void await() throws InterruptedException { - try { - if (getProcess() == null) { - throw new OpenShiftException("Could not sync %s to %s, no process was launched.", - destination); - } - if (!getProcess().waitFor(WAIT_FOR_EXIT_TIMEOUT, TimeUnit.MINUTES)) { - throw new OpenShiftException("Syncing %s to %s did not terminate within %d minutes.", - source, destination, WAIT_FOR_EXIT_TIMEOUT); - } - - if (getProcess().exitValue() != 0) { - String errorMessage = getErrorMessage(getProcess().getErrorStream()); - throw new OpenShiftException("Syncing %s to %s failed" - + (StringUtils.isBlank(errorMessage) ? "" : ": %s"), - source, destination, errorMessage); - } - } catch (InterruptedException e) { - throw new OpenShiftException(e, "Syncing %s to %s was interrupted.", - source, destination); - } - } - - private static String getErrorMessage(InputStream errorStream) { - try { - return IOUtils.toString(errorStream); - } catch (IOException e) { - LOG.error("Could not retrieve error message from process", e); - return null; - } - } - - @Override - protected void cleanup() { - this.source = null; - this.destination = null; - } - - @Override - protected boolean validate() { - return source != null - && destination != null - && hasPodPeer(source, destination); - } - - private static boolean hasPodPeer(Peer source, Peer destination) { - return source.isPod() - || destination.isPod(); - } - - @Override - public boolean isSupported() { - return true; - } - - @Override - public String getName() { - return OpenShiftBinaryRSync.class.getSimpleName(); - } - - @Override - protected String buildArgs(final List options) { - return new CommandLineBuilder(RSYNC_COMMAND) - .append( new Token(getClient())) - .append(new Server(getClient())) - .append( new Namespace(pod)) - .append(options) - .append(source) - .append(destination) - .build(); - } + private static final Logger LOG = LoggerFactory.getLogger(OpenShiftBinaryRSync.class); + public static final String RSYNC_COMMAND = "rsync"; + private static final long WAIT_FOR_EXIT_TIMEOUT = 5; // mins + + private Peer source; + private Peer destination; + private IPod pod; + + private final Executor executor = Executors.newCachedThreadPool(); + + /** + * Constructor. + * + * @param client + * the client to connect to OpenShift. + */ + public OpenShiftBinaryRSync(final IClient client) { + super(client); + } + + @Override + public InputStream sync(final Peer source, final Peer destination, final OpenShiftBinaryOption... options) + throws OpenShiftException { + this.source = source; + this.destination = destination; + this.pod = getPod(source, destination); + Process process = start(options); + waitFor(process); + if (process == null) { + return null; + } + return process.getInputStream(); + } + + private IPod getPod(Peer source, Peer destination) { + if (source.isPod()) { + return source.getPod(); + } else if (destination.isPod()) { + return destination.getPod(); + } else { + return null; + } + } + + protected void waitFor(Process process) { + if (process == null) { + return; + } + + this.executor.execute(() -> { + try { + process.waitFor(); + } catch (InterruptedException e) { + throw new OpenShiftException("Error occurred while waiting for rsync operation to complete", e); + } + }); + } + + @Override + public boolean isDone() { + return !getProcess().isAlive(); + } + + @Override + public int exitValue() { + return getProcess().exitValue(); + } + + @Override + public void await() throws InterruptedException { + try { + if (getProcess() == null) { + throw new OpenShiftException("Could not sync %s to %s, no process was launched.", destination); + } + if (!getProcess().waitFor(WAIT_FOR_EXIT_TIMEOUT, TimeUnit.MINUTES)) { + throw new OpenShiftException("Syncing %s to %s did not terminate within %d minutes.", source, + destination, WAIT_FOR_EXIT_TIMEOUT); + } + + if (getProcess().exitValue() != 0) { + String errorMessage = getErrorMessage(getProcess().getErrorStream()); + throw new OpenShiftException( + "Syncing %s to %s failed" + (StringUtils.isBlank(errorMessage) ? "" : ": %s"), source, + destination, errorMessage); + } + } catch (InterruptedException e) { + throw new OpenShiftException(e, "Syncing %s to %s was interrupted.", source, destination); + } + } + + private static String getErrorMessage(InputStream errorStream) { + try { + return IOUtils.toString(errorStream); + } catch (IOException e) { + LOG.error("Could not retrieve error message from process", e); + return null; + } + } + + @Override + protected void cleanup() { + this.source = null; + this.destination = null; + } + + @Override + protected boolean validate() { + return source != null && destination != null && hasPodPeer(source, destination); + } + + private static boolean hasPodPeer(Peer source, Peer destination) { + return source.isPod() || destination.isPod(); + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return OpenShiftBinaryRSync.class.getSimpleName(); + } + + @Override + protected String buildArgs(final List options) { + return new CommandLineBuilder(RSYNC_COMMAND).append(new Token(getClient())).append(new Server(getClient())) + .append(new Namespace(pod)).append(options).append(source).append(destination).build(); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java index 8aa2cba8..af435cdd 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java @@ -8,8 +8,17 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.URLBuilder; import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; @@ -21,130 +30,118 @@ import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IPod; + import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; import okhttp3.ws.WebSocket; import okhttp3.ws.WebSocketCall; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; /** * Impl of Pod log retrieval using websocket - * @author jeff.cantrill * */ -public class PodLogRetrievalAsync implements IPodLogRetrievalAsync{ - - private static final Logger LOG = LoggerFactory.getLogger(PodLogRetrievalAsync.class); - private static final String CAPABILITY = "log"; - private final IPod pod; - private final DefaultClient client; - private final IApiTypeMapper mapper; - - public PodLogRetrievalAsync(IPod pod, IClient client) { - this.pod = pod; - this.client = client.adapt(DefaultClient.class); - this.mapper = client.adapt(IApiTypeMapper.class); - } - - @Override - public boolean isSupported() { - if(client != null && mapper != null) { - try { - return mapper.getEndpointFor(pod.getApiVersion(), pod.getKind()).isSupported(CAPABILITY); - }catch(UnsupportedEndpointException e) { - //endpoint not found for version/kind - } - } - return false; - } - - @Override - public String getName() { - return PodLogRetrievalAsync.class.getSimpleName(); - } - - @Override - public IStoppable start(IPodLogListener listener) { - return start(listener, null); - } - - @Override - public IStoppable start(IPodLogListener listener, Options options) { - Map parameters = options != null ? options.getMap() : new HashMap<>(); - PodLogListenerAdapter adapter = new PodLogListenerAdapter(listener); - - OkHttpClient okClient = client.adapt(OkHttpClient.class); - final String endpoint = new URLBuilder(client.getBaseURL(), mapper) - .kind(pod.getKind()) - .namespace(pod.getNamespaceName()) - .name(pod.getName()) - .subresource(CAPABILITY) - .addParameters(parameters) - .websocket(); - Request request = client.newRequestBuilderTo(endpoint) - .tag( new ResponseCodeInterceptor.Ignore(){} ) - .build(); - WebSocketCall call = WebSocketCall.create(okClient, request); - call.enqueue(adapter); - - return adapter; - } - - static class PodLogListenerAdapter extends WebSocketAdapter implements IStoppable{ - - private final IPodLogListener listener; - private WebSocket wsClient; - private AtomicBoolean open = new AtomicBoolean(false); - - public PodLogListenerAdapter(IPodLogListener listener) { - this.listener = listener; - } - - @Override - public void stop() { - try { - if(open.get()) { - wsClient.close(IHttpConstants.STATUS_NORMAL_STOP, "Client asking to stop."); - } - } catch (Exception e) { - LOG.debug("Unable to stop the watch client",e); - }finally { - wsClient = null; - } - } - - @Override - public void onOpen(WebSocket webSocket, Response response) { - if(open.compareAndSet(false, true)) { - wsClient = webSocket; - listener.onOpen(); - } - } - - @Override - public void onClose(int code, String reason) { - if(open.compareAndSet(true, false)) { - listener.onClose(code, reason); - } - } - - @Override - public void onMessage(ResponseBody message) throws IOException { - listener.onMessage(message.string()); - } - - @Override - public void onFailure(IOException e, Response response) { - listener.onFailure(e); - } - - } +public class PodLogRetrievalAsync implements IPodLogRetrievalAsync { + + private static final Logger LOG = LoggerFactory.getLogger(PodLogRetrievalAsync.class); + private static final String CAPABILITY = "log"; + private final IPod pod; + private final DefaultClient client; + private final IApiTypeMapper mapper; + + public PodLogRetrievalAsync(IPod pod, IClient client) { + this.pod = pod; + this.client = client.adapt(DefaultClient.class); + this.mapper = client.adapt(IApiTypeMapper.class); + } + + @Override + public boolean isSupported() { + if (client != null && mapper != null) { + try { + return mapper.getEndpointFor(pod.getApiVersion(), pod.getKind()).isSupported(CAPABILITY); + } catch (UnsupportedEndpointException e) { + // endpoint not found for version/kind + } + } + return false; + } + + @Override + public String getName() { + return PodLogRetrievalAsync.class.getSimpleName(); + } + + @Override + public IStoppable start(IPodLogListener listener) { + return start(listener, null); + } + + @Override + public IStoppable start(IPodLogListener listener, Options options) { + Map parameters = options != null ? options.getMap() : new HashMap<>(); + PodLogListenerAdapter adapter = new PodLogListenerAdapter(listener); + + OkHttpClient okClient = client.adapt(OkHttpClient.class); + final String endpoint = new URLBuilder(client.getBaseURL(), mapper).kind(pod.getKind()) + .namespace(pod.getNamespaceName()).name(pod.getName()).subresource(CAPABILITY).addParameters(parameters) + .websocket(); + Request request = client.newRequestBuilderTo(endpoint).tag(new ResponseCodeInterceptor.Ignore() { + }).build(); + WebSocketCall call = WebSocketCall.create(okClient, request); + call.enqueue(adapter); + + return adapter; + } + + static class PodLogListenerAdapter extends WebSocketAdapter implements IStoppable { + + private final IPodLogListener listener; + private WebSocket wsClient; + private AtomicBoolean open = new AtomicBoolean(false); + + public PodLogListenerAdapter(IPodLogListener listener) { + this.listener = listener; + } + + @Override + public void stop() { + try { + if (open.get()) { + wsClient.close(IHttpConstants.STATUS_NORMAL_STOP, "Client asking to stop."); + } + } catch (Exception e) { + LOG.debug("Unable to stop the watch client", e); + } finally { + wsClient = null; + } + } + + @Override + public void onOpen(WebSocket webSocket, Response response) { + if (open.compareAndSet(false, true)) { + wsClient = webSocket; + listener.onOpen(); + } + } + + @Override + public void onClose(int code, String reason) { + if (open.compareAndSet(true, false)) { + listener.onClose(code, reason); + } + } + + @Override + public void onMessage(ResponseBody message) throws IOException { + listener.onMessage(message.string()); + } + + @Override + public void onFailure(IOException e, Response response) { + listener.onFailure(e); + } + + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java index 7f8d0738..6695dc27 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateListCapability.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.util.Collection; @@ -17,30 +18,30 @@ import com.openshift.restclient.model.template.ITemplate; public class ProjectTemplateListCapability implements IProjectTemplateList { - - private static final String COMMON_NAMESPACE = "openshift"; //eventually configurable - private IProject project; - private IClient client; - - public ProjectTemplateListCapability(IProject project, IClient client) { - this.project = project; - this.client = client; - } - - @Override - public boolean isSupported() { - return client != null && project != null; - } - - @Override - public String getName() { - return this.getClass().getSimpleName(); - } - - @Override - public Collection getTemplates() { - return client.list(ResourceKind.TEMPLATE, project.getNamespaceName()); - } + + private static final String COMMON_NAMESPACE = "openshift"; // eventually configurable + private IProject project; + private IClient client; + + public ProjectTemplateListCapability(IProject project, IClient client) { + this.project = project; + this.client = client; + } + + @Override + public boolean isSupported() { + return client != null && project != null; + } + + @Override + public String getName() { + return this.getClass().getSimpleName(); + } + + @Override + public Collection getTemplates() { + return client.list(ResourceKind.TEMPLATE, project.getNamespaceName()); + } @Override public Collection getCommonTemplates() { @@ -48,9 +49,9 @@ public Collection getCommonTemplates() { } @Override - public Collection getCommonTemplates(String clusterNamespace) { - return client.list(ResourceKind.TEMPLATE,clusterNamespace==null?COMMON_NAMESPACE:clusterNamespace); - } - - + public Collection getCommonTemplates(String clusterNamespace) { + return client.list(ResourceKind.TEMPLATE, + clusterNamespace == null ? COMMON_NAMESPACE : clusterNamespace); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java index c2d8876c..8e892f88 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessing.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.util.Collection; @@ -24,39 +25,39 @@ * */ public class ProjectTemplateProcessing implements IProjectTemplateProcessing { - - private String namespace; - private IClient client; - private ITemplateProcessing serverCapability; - - public ProjectTemplateProcessing(IProject project, IClient client) { - if(client != null && client.supports(ITemplateProcessing.class)) { - serverCapability = client.getCapability(ITemplateProcessing.class); - this.client = client; - this.namespace = project.getNamespaceName(); - } - } - - @Override - public boolean isSupported() { - return serverCapability != null; - } - - @Override - public String getName() { - return ProjectTemplateProcessing.class.getSimpleName(); - } - - @Override - public ITemplate process(ITemplate template) { - return serverCapability.process(template, namespace); - } - - @Override - public Collection apply(ITemplate template) { - IList resources = client.getResourceFactory().create(template.getApiVersion(), ResourceKind.LIST); - resources.addAll(template.getObjects()); - return client.create(resources, this.namespace); - } + + private String namespace; + private IClient client; + private ITemplateProcessing serverCapability; + + public ProjectTemplateProcessing(IProject project, IClient client) { + if (client != null && client.supports(ITemplateProcessing.class)) { + serverCapability = client.getCapability(ITemplateProcessing.class); + this.client = client; + this.namespace = project.getNamespaceName(); + } + } + + @Override + public boolean isSupported() { + return serverCapability != null; + } + + @Override + public String getName() { + return ProjectTemplateProcessing.class.getSimpleName(); + } + + @Override + public ITemplate process(ITemplate template) { + return serverCapability.process(template, namespace); + } + + @Override + public Collection apply(ITemplate template) { + IList resources = client.getResourceFactory().create(template.getApiVersion(), ResourceKind.LIST); + resources.addAll(template.getObjects()); + return client.create(resources, this.namespace); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/PropertyAccessCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/PropertyAccessCapability.java index d05eecda..9fcc749c 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/PropertyAccessCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/PropertyAccessCapability.java @@ -8,15 +8,16 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; +import static com.openshift.internal.util.JBossDmrExtentions.get; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import static com.openshift.internal.util.JBossDmrExtentions.*; - import org.jboss.dmr.ModelNode; import com.openshift.internal.restclient.model.KubernetesResource; @@ -25,109 +26,111 @@ public class PropertyAccessCapability implements IPropertyAccessCapability { - private KubernetesResource resource; - - public PropertyAccessCapability(IResource resource) { - if(resource instanceof KubernetesResource) { - this.resource = (KubernetesResource) resource; - } - } - - @Override - public String asString(String path) { - ModelNode node = get(resource.getNode(), null, path); - if(!node.isDefined()) { - throw new UnresolvablePathException(); - } - return node.asString(); - } - - @Override - public Map asMap(String path) { - return asMap(get(resource.getNode(), null, path)); - } - - private Map asMap(ModelNode node) { - if(!node.isDefined()) { - throw new UnresolvablePathException(); - } - Map result = new HashMap<>(); - for (String key : node.keys()) { - ModelNode value = node.get(key); - switch(value.getType()) { - case OBJECT: - result.put(key, asMap(value)); - break; - case LIST: - result.put(key, asList(value)); - case STRING: - result.put(key, value.asString()); - break; - case INT: - result.put(key, value.asInt()); - break; - case BIG_INTEGER: - result.put(key, value.asBigInteger()); - break; - case BIG_DECIMAL: - result.put(key, value.asBigDecimal()); - break; - case LONG: - result.put(key, value.asBigDecimal()); - break; - case BOOLEAN: - result.put(key, value.asBoolean()); - break; - default: - result.put(key, value.asString()); - } - } - return result; - } - - private List asList(ModelNode node) { - List list = new ArrayList<>(); - for (ModelNode entry : node.asList()) { - switch(entry.getType()) { - case OBJECT: - list.add(asMap(entry)); - break; - case LIST: - list.add(asList(entry)); - case STRING: - list.add(entry.asString()); - break; - case INT: - list.add(entry.asInt()); - break; - case BIG_INTEGER: - list.add(entry.asBigInteger()); - break; - case BIG_DECIMAL: - list.add(entry.asBigDecimal()); - break; - case LONG: - list.add(entry.asBigDecimal()); - break; - case BOOLEAN: - list.add(entry.asBoolean()); - break; - default: - list.add(entry.asString()); - } - - } - return list; - } - - @Override - public boolean isSupported() { - return resource != null; - } - - @Override - public String getName() { - return this.getClass().getSimpleName(); - } + private KubernetesResource resource; + + public PropertyAccessCapability(IResource resource) { + if (resource instanceof KubernetesResource) { + this.resource = (KubernetesResource) resource; + } + } + + @Override + public String asString(String path) { + ModelNode node = get(resource.getNode(), null, path); + if (!node.isDefined()) { + throw new UnresolvablePathException(); + } + return node.asString(); + } + + @Override + public Map asMap(String path) { + return asMap(get(resource.getNode(), null, path)); + } + + private Map asMap(ModelNode node) { + if (!node.isDefined()) { + throw new UnresolvablePathException(); + } + Map result = new HashMap<>(); + for (String key : node.keys()) { + ModelNode value = node.get(key); + switch (value.getType()) { + case OBJECT: + result.put(key, asMap(value)); + break; + case LIST: + result.put(key, asList(value)); + break; + case STRING: + result.put(key, value.asString()); + break; + case INT: + result.put(key, value.asInt()); + break; + case BIG_INTEGER: + result.put(key, value.asBigInteger()); + break; + case BIG_DECIMAL: + result.put(key, value.asBigDecimal()); + break; + case LONG: + result.put(key, value.asBigDecimal()); + break; + case BOOLEAN: + result.put(key, value.asBoolean()); + break; + default: + result.put(key, value.asString()); + } + } + return result; + } + + private List asList(ModelNode node) { + List list = new ArrayList<>(); + for (ModelNode entry : node.asList()) { + switch (entry.getType()) { + case OBJECT: + list.add(asMap(entry)); + break; + case LIST: + list.add(asList(entry)); + break; + case STRING: + list.add(entry.asString()); + break; + case INT: + list.add(entry.asInt()); + break; + case BIG_INTEGER: + list.add(entry.asBigInteger()); + break; + case BIG_DECIMAL: + list.add(entry.asBigDecimal()); + break; + case LONG: + list.add(entry.asBigDecimal()); + break; + case BOOLEAN: + list.add(entry.asBoolean()); + break; + default: + list.add(entry.asString()); + } + + } + return list; + } + + @Override + public boolean isSupported() { + return resource != null; + } + + @Override + public String getName() { + return this.getClass().getSimpleName(); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/TagCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/TagCapability.java index c2ff5bab..a1b9b469 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/TagCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/TagCapability.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import java.util.Arrays; @@ -14,24 +15,21 @@ import com.openshift.restclient.capability.resources.ITags; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public class TagCapability extends AnnotationCapability implements ITags { - public TagCapability(IResource resource) { - super(TagCapability.class.getSimpleName(), resource); - } + public TagCapability(IResource resource) { + super(TagCapability.class.getSimpleName(), resource); + } - @Override - public Collection getTags() { - String value = getAnnotationValue(); - return Arrays.asList(value.split(",")); - } + @Override + public Collection getTags() { + String value = getAnnotationValue(); + return Arrays.asList(value.split(",")); + } - @Override - protected String getAnnotationKey() { - return "tags"; - } + @Override + protected String getAnnotationKey() { + return "tags"; + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/TemplateTraceability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/TemplateTraceability.java index 047bc2b5..c93a9658 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/TemplateTraceability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/TemplateTraceability.java @@ -6,40 +6,40 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import com.openshift.restclient.capability.resources.ITemplateTraceability; import com.openshift.restclient.model.IResource; /** - * Capability of resource tracing the template from which - * it was generated - * - * @author Jeff Cantrill + * Capability of resource tracing the template from which it was generated */ -public class TemplateTraceability implements ITemplateTraceability { - - private static final String TEMPLATE_ANNOTATION = "template"; - private IResource resource; - - public TemplateTraceability(IResource resource) { - this.resource = resource; - } - - @Override - public String getTemplateName() { - if(!isSupported()) return ""; - return resource.getAnnotation(TEMPLATE_ANNOTATION); - } - - @Override - public boolean isSupported() { - return resource.isAnnotatedWith(TEMPLATE_ANNOTATION); - } - - @Override - public String getName() { - return TemplateTraceability.class.getSimpleName(); - } +public class TemplateTraceability implements ITemplateTraceability { + + private static final String TEMPLATE_ANNOTATION = "template"; + private IResource resource; + + public TemplateTraceability(IResource resource) { + this.resource = resource; + } + + @Override + public String getTemplateName() { + if (!isSupported()) { + return ""; + } + return resource.getAnnotation(TEMPLATE_ANNOTATION); + } + + @Override + public boolean isSupported() { + return resource.isAnnotatedWith(TEMPLATE_ANNOTATION); + } + + @Override + public String getName() { + return TemplateTraceability.class.getSimpleName(); + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/UpdateableCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/UpdateableCapability.java index 567ed0e6..3a97333d 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/UpdateableCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/UpdateableCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import com.openshift.internal.restclient.model.KubernetesResource; @@ -16,31 +17,32 @@ public class UpdateableCapability implements IUpdatable { - private boolean isSupported; - private KubernetesResource resource; - public UpdateableCapability(IResource resource) { - if(resource instanceof KubernetesResource) { - isSupported = true; - this.resource = (KubernetesResource) resource; - } - } - - @Override - public boolean isSupported() { - return isSupported; - } - - @Override - public String getName() { - return UpdateableCapability.class.getSimpleName(); - } - - @Override - public void updateFrom(IResource source) { - if(source instanceof KubernetesResource) { - KubernetesResource from = (KubernetesResource) source; - resource.setNode(from.getNode()); - } - } + private boolean isSupported; + private KubernetesResource resource; + + public UpdateableCapability(IResource resource) { + if (resource instanceof KubernetesResource) { + isSupported = true; + this.resource = (KubernetesResource) resource; + } + } + + @Override + public boolean isSupported() { + return isSupported; + } + + @Override + public String getName() { + return UpdateableCapability.class.getSimpleName(); + } + + @Override + public void updateFrom(IResource source) { + if (source instanceof KubernetesResource) { + KubernetesResource from = (KubernetesResource) source; + resource.setNode(from.getNode()); + } + } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessing.java b/src/main/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessing.java index acab0c3d..a3768b85 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessing.java +++ b/src/main/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessing.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.server; import com.openshift.restclient.IApiTypeMapper; @@ -14,35 +15,32 @@ import com.openshift.restclient.capability.server.ITemplateProcessing; import com.openshift.restclient.model.template.ITemplate; -/** - * @author Jeff Cantrill - */ public class ServerTemplateProcessing implements ITemplateProcessing { - private IClient client; - - public ServerTemplateProcessing(IClient client){ - this.client = client; - } - - @Override - public boolean isSupported() { - IApiTypeMapper mapper = client.adapt(IApiTypeMapper.class); - if(mapper != null) { - return mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES); - } - return false; - } - - @Override - public String getName() { - return this.getClass().getSimpleName(); - } - - @Override - public ITemplate process(ITemplate template, String namespace) { - return client.execute("POST", ResourceKind.PROCESSED_TEMPLATES, namespace, null, null, template); - - } - + private IClient client; + + public ServerTemplateProcessing(IClient client) { + this.client = client; + } + + @Override + public boolean isSupported() { + IApiTypeMapper mapper = client.adapt(IApiTypeMapper.class); + if (mapper != null) { + return mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES); + } + return false; + } + + @Override + public String getName() { + return this.getClass().getSimpleName(); + } + + @Override + public ITemplate process(ITemplate template, String namespace) { + return client.execute("POST", ResourceKind.PROCESSED_TEMPLATES, namespace, null, null, template); + + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/Build.java b/src/main/java/com/openshift/internal/restclient/model/Build.java index 312b699e..a3c2754a 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Build.java +++ b/src/main/java/com/openshift/internal/restclient/model/Build.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.Map; @@ -28,112 +29,106 @@ import com.openshift.restclient.model.build.IBuildStatus; import com.openshift.restclient.model.build.IBuildStrategy; -/** - * @author Jeff Cantrill - */ -public class Build extends KubernetesResource implements IBuild{ - - private static final String BUILD_MESSAGE = "status.message"; - private static final String BUILD_PODNAME = "podName"; - private static final String BUILD_STATUS = "status.phase"; - private static final String BUILD_STATUS_CANCELLED = "status.cancelled"; - private static final String OUTPUT_KIND = "spec.output.to.kind"; - private static final String OUTPUT_NAME = "spec.output.to.name"; - - private static final String COMPLETE = "Complete"; - private static final String FAILED = "Failed"; - private static final String CANCELLED = "Cancelled"; - private Map propertyKeys; - - - public Build(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - this.propertyKeys = propertyKeys; - CapabilityInitializer.initializeCapabilities(getModifiableCapabilities(), this, client); - } - - @Override - public String getStatus() { - return asString(BUILD_STATUS); - } - - @Override - public String getMessage() { - return asString(BUILD_MESSAGE); - } - - @Override - public String getPodName() { - return asString(BUILD_PODNAME); - } - - @Override - public boolean cancel() { - String currentStatus = getStatus(); - if (!currentStatus.equalsIgnoreCase(COMPLETE) && !currentStatus.equalsIgnoreCase(FAILED) && !currentStatus.equalsIgnoreCase(CANCELLED)) { - set(BUILD_STATUS_CANCELLED, true); - return true; - } - return false; - } - - @Override - public DockerImageURI getOutputTo() { - return new DockerImageURI(asString(OUTPUT_NAME)); - } - - @Override - public String getOutputKind() { - return asString(OUTPUT_KIND); - } - - @SuppressWarnings("unchecked") - @Override - public T getBuildSource() { - switch(asString("spec.source.type")){ - case BuildSourceType.GIT: - return (T) new GitBuildSource(asString("spec.source.git.uri"), asString("spec.source.git.ref"), asString("spec.source.git.contextDir")); - default: - } - return null; - } - - @SuppressWarnings("unchecked") - public T getBuildStrategy() { - switch(asString("spec.strategy.type")){ - - case BuildStrategyType.CUSTOM: - return (T) new CustomBuildStrategy( - asString("spec.strategy.customStrategy.image"), - asBoolean("spec.strategy.customStrategy.exposeDockerSocket"), - getEnvMap("spec.strategy.customStrategy.env") - ); - case BuildStrategyType.SOURCE: - return (T) new SourceBuildStrategy(get("spec.strategy"), getPropertyKeys()); - - case BuildStrategyType.DOCKER: - return (T) new DockerBuildStrategy( - asString("spec.strategy.dockerStrategy.contextDir"), - asBoolean("spec.strategy.dockerStrategy.noCache"), - asString("spec.strategy.dockerStrategy.baseImage") - ); - - case BuildStrategyType.JENKINS_PIPELINE: - return (T) new JenkinsPipelineStrategy(get("spec.strategy"), getPropertyKeys()); - - default: - } - return null; - } - - @Override - public String getPushSecret() { - return asString("spec.output.pushSecret.name"); - } - - @Override - public IBuildStatus getBuildStatus() { - return new BuildStatus(get("status"), this.propertyKeys); - } - +public class Build extends KubernetesResource implements IBuild { + + private static final String BUILD_MESSAGE = "status.message"; + private static final String BUILD_PODNAME = "podName"; + private static final String BUILD_STATUS = "status.phase"; + private static final String BUILD_STATUS_CANCELLED = "status.cancelled"; + private static final String OUTPUT_KIND = "spec.output.to.kind"; + private static final String OUTPUT_NAME = "spec.output.to.name"; + + private static final String COMPLETE = "Complete"; + private static final String FAILED = "Failed"; + private static final String CANCELLED = "Cancelled"; + private Map propertyKeys; + + public Build(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + this.propertyKeys = propertyKeys; + CapabilityInitializer.initializeCapabilities(getModifiableCapabilities(), this, client); + } + + @Override + public String getStatus() { + return asString(BUILD_STATUS); + } + + @Override + public String getMessage() { + return asString(BUILD_MESSAGE); + } + + @Override + public String getPodName() { + return asString(BUILD_PODNAME); + } + + @Override + public boolean cancel() { + String currentStatus = getStatus(); + if (!currentStatus.equalsIgnoreCase(COMPLETE) && !currentStatus.equalsIgnoreCase(FAILED) + && !currentStatus.equalsIgnoreCase(CANCELLED)) { + set(BUILD_STATUS_CANCELLED, true); + return true; + } + return false; + } + + @Override + public DockerImageURI getOutputTo() { + return new DockerImageURI(asString(OUTPUT_NAME)); + } + + @Override + public String getOutputKind() { + return asString(OUTPUT_KIND); + } + + @SuppressWarnings("unchecked") + @Override + public T getBuildSource() { + switch (asString("spec.source.type")) { + case BuildSourceType.GIT: + return (T) new GitBuildSource(asString("spec.source.git.uri"), asString("spec.source.git.ref"), + asString("spec.source.git.contextDir")); + default: + } + return null; + } + + @SuppressWarnings("unchecked") + public T getBuildStrategy() { + switch (asString("spec.strategy.type")) { + + case BuildStrategyType.CUSTOM: + return (T) new CustomBuildStrategy(asString("spec.strategy.customStrategy.image"), + asBoolean("spec.strategy.customStrategy.exposeDockerSocket"), + getEnvMap("spec.strategy.customStrategy.env")); + case BuildStrategyType.SOURCE: + return (T) new SourceBuildStrategy(get("spec.strategy"), getPropertyKeys()); + + case BuildStrategyType.DOCKER: + return (T) new DockerBuildStrategy(asString("spec.strategy.dockerStrategy.contextDir"), + asBoolean("spec.strategy.dockerStrategy.noCache"), + asString("spec.strategy.dockerStrategy.baseImage")); + + case BuildStrategyType.JENKINS_PIPELINE: + return (T) new JenkinsPipelineStrategy(get("spec.strategy"), getPropertyKeys()); + + default: + } + return null; + } + + @Override + public String getPushSecret() { + return asString("spec.output.pushSecret.name"); + } + + @Override + public IBuildStatus getBuildStatus() { + return new BuildStatus(get("status"), this.propertyKeys); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index dd18faa9..a0c13bed 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.ArrayList; @@ -40,48 +41,47 @@ import com.openshift.restclient.model.build.ISourceBuildStrategy; import com.openshift.restclient.model.build.IWebhookTrigger; -/** - * @author Jeff Cantrill - */ public class BuildConfig extends KubernetesResource implements IBuildConfig { - - private static final String BUILDCONFIG_SOURCE_CONTEXTDIR = "spec.source.contextDir"; - private static final String BUILDCONFIG_SOURCE_TYPE = "spec.source.type"; - private static final String BUILDCONFIG_SOURCE_URI = "spec.source.git.uri"; - private static final String BUILDCONFIG_SOURCE_REF = "spec.source.git.ref"; - - public static final String BUILDCONFIG_TYPE = "spec.strategy.type"; - private static final String BUILDCONFIG_CUSTOM_IMAGE = "spec.strategy.customStrategy.image"; - private static final String BUILDCONFIG_CUSTOM_EXPOSEDOCKERSOCKET = "spec.strategy.customStrategy.exposeDockerSocket"; - private static final String BUILDCONFIG_CUSTOM_ENV = "spec.strategy.customStrategy.env"; - public static final String BUILDCONFIG_DOCKER_CONTEXTDIR = "spec.strategy.dockerStrategy.contextDir"; - public static final String BUILDCONFIG_DOCKER_NOCACHE = "spec.strategy.dockerStrategy.noCache"; - public static final String BUILDCONFIG_DOCKER_BASEIMAGE = "spec.strategy.dockerStrategy.baseImage"; - private static final String BUILDCONFIG_OUTPUT_REPO = "spec.output.to.name"; - private static final String BUILDCONFIG_TRIGGERS = "spec.triggers"; - private static final String BUILDCONFIG_STRATEGY = "spec.strategy"; - private static final String BUILD_CONFIG_WEBHOOK_GITHUB_SECRET = "github.secret"; - private static final String BUILD_CONFIG_WEBHOOK_GENERIC_SECRET = "generic.secret"; - private static final String BUILD_CONFIG_IMAGECHANGE_IMAGE = "imageChange.image"; - private static final String BUILD_CONFIG_IMAGECHANGE_NAME = "imageChange.from.name"; - private static final String BUILD_CONFIG_IMAGECHANGE_TAG = "imageChange.tag"; - public BuildConfig(ModelNode node, IClient client, Map overrideProperties) { - super(node, client, null); - CapabilityInitializer.initializeCapabilities(getModifiableCapabilities(), this, client); - } + private static final String BUILDCONFIG_SOURCE_CONTEXTDIR = "spec.source.contextDir"; + private static final String BUILDCONFIG_SOURCE_TYPE = "spec.source.type"; + private static final String BUILDCONFIG_SOURCE_URI = "spec.source.git.uri"; + private static final String BUILDCONFIG_SOURCE_REF = "spec.source.git.ref"; + + public static final String BUILDCONFIG_TYPE = "spec.strategy.type"; + private static final String BUILDCONFIG_CUSTOM_IMAGE = "spec.strategy.customStrategy.image"; + private static final String BUILDCONFIG_CUSTOM_EXPOSEDOCKERSOCKET = "spec.strategy.customStrategy.exposeDockerSocket"; + private static final String BUILDCONFIG_CUSTOM_ENV = "spec.strategy.customStrategy.env"; + public static final String BUILDCONFIG_DOCKER_CONTEXTDIR = "spec.strategy.dockerStrategy.contextDir"; + public static final String BUILDCONFIG_DOCKER_NOCACHE = "spec.strategy.dockerStrategy.noCache"; + public static final String BUILDCONFIG_DOCKER_BASEIMAGE = "spec.strategy.dockerStrategy.baseImage"; + private static final String BUILDCONFIG_OUTPUT_REPO = "spec.output.to.name"; + private static final String BUILDCONFIG_TRIGGERS = "spec.triggers"; + private static final String BUILDCONFIG_STRATEGY = "spec.strategy"; + private static final String BUILD_CONFIG_WEBHOOK_GITHUB_SECRET = "github.secret"; + private static final String BUILD_CONFIG_WEBHOOK_GENERIC_SECRET = "generic.secret"; + private static final String BUILD_CONFIG_IMAGECHANGE_IMAGE = "imageChange.image"; + private static final String BUILD_CONFIG_IMAGECHANGE_NAME = "imageChange.from.name"; + private static final String BUILD_CONFIG_IMAGECHANGE_TAG = "imageChange.tag"; - @Override - public IObjectReference getBuildOutputReference() { - return new ObjectReference(get("spec.output.to")); - } + public BuildConfig(ModelNode node, IClient client, Map overrideProperties) { + super(node, client, null); + CapabilityInitializer.initializeCapabilities(getModifiableCapabilities(), this, client); + } - @Override - public List getBuildTriggers() { - List triggers = new ArrayList(); - if (has(BUILDCONFIG_TRIGGERS)) { + @Override + public IObjectReference getBuildOutputReference() { + return new ObjectReference(get("spec.output.to")); + } + + @Override + public List getBuildTriggers() { + List triggers = new ArrayList(); + if (has(BUILDCONFIG_TRIGGERS)) { List list = get(BUILDCONFIG_TRIGGERS).asList(); - final String url = getClient() != null && StringUtils.isNotEmpty(getNamespaceName()) ? getClient().getResourceURI(this) : ""; + final String url = getClient() != null && StringUtils.isNotEmpty(getNamespaceName()) + ? getClient().getResourceURI(this) + : ""; for (ModelNode node : list) { String type = node.get(TYPE).asString(); switch (type) { @@ -101,158 +101,162 @@ public List getBuildTriggers() { break; case BuildTriggerType.CONFIG_CHANGE: triggers.add(new ImageChangeTrigger(BuildTriggerType.CONFIG_CHANGE, null, null)); + break; default: } - } + } } return triggers; - } + } - @Override - public void addBuildTrigger(IBuildTrigger trigger) { - ModelNode triggers = get(BUILDCONFIG_TRIGGERS); - ModelNode triggerNode = triggers.add(); - switch(trigger.getType()) { - case BuildTriggerType.GENERIC: - if(!(trigger instanceof IWebhookTrigger)) { - throw new IllegalArgumentException("IBuildTrigger of type generic does not implement IWebhookTrigger"); - } - IWebhookTrigger generic = (IWebhookTrigger)trigger; - triggerNode.get(getPath(BUILD_CONFIG_WEBHOOK_GENERIC_SECRET)).set(generic.getSecret()); - break; - case BuildTriggerType.GITHUB: - if(!(trigger instanceof IWebhookTrigger)) { - throw new IllegalArgumentException("IBuildTrigger of type github does not implement IWebhookTrigger"); - } - IWebhookTrigger github = (IWebhookTrigger)trigger; - triggerNode.get(getPath(BUILD_CONFIG_WEBHOOK_GITHUB_SECRET)).set(github.getSecret()); - break; - case BuildTriggerType.IMAGE_CHANGE:{ - if(!(trigger instanceof IImageChangeTrigger)) { - throw new IllegalArgumentException("IBuildTrigger of type imageChange does not implement IImageChangeTrigger"); - } - IImageChangeTrigger image = (IImageChangeTrigger)trigger; - if(image.getImage() != null) - triggerNode.get(getPath(BUILD_CONFIG_IMAGECHANGE_IMAGE)).set(image.getImage().toString()); - if(image.getFrom() != null) - triggerNode.get(getPath(BUILD_CONFIG_IMAGECHANGE_NAME)).set(image.getFrom().toString()); - if(StringUtils.isNotEmpty(image.getTag())) - triggerNode.get(getPath(BUILD_CONFIG_IMAGECHANGE_TAG)).set(StringUtils.defaultIfBlank(image.getTag(), "")); - break; - - } - } - triggerNode.get(TYPE).set(trigger.getType()); - } + @Override + public void addBuildTrigger(IBuildTrigger trigger) { + ModelNode triggers = get(BUILDCONFIG_TRIGGERS); + ModelNode triggerNode = triggers.add(); + switch (trigger.getType()) { + case BuildTriggerType.GENERIC: + if (!(trigger instanceof IWebhookTrigger)) { + throw new IllegalArgumentException("IBuildTrigger of type generic does not implement IWebhookTrigger"); + } + IWebhookTrigger generic = (IWebhookTrigger) trigger; + triggerNode.get(getPath(BUILD_CONFIG_WEBHOOK_GENERIC_SECRET)).set(generic.getSecret()); + break; + case BuildTriggerType.GITHUB: + if (!(trigger instanceof IWebhookTrigger)) { + throw new IllegalArgumentException("IBuildTrigger of type github does not implement IWebhookTrigger"); + } + IWebhookTrigger github = (IWebhookTrigger) trigger; + triggerNode.get(getPath(BUILD_CONFIG_WEBHOOK_GITHUB_SECRET)).set(github.getSecret()); + break; + case BuildTriggerType.IMAGE_CHANGE: { + if (!(trigger instanceof IImageChangeTrigger)) { + throw new IllegalArgumentException( + "IBuildTrigger of type imageChange does not implement IImageChangeTrigger"); + } + IImageChangeTrigger image = (IImageChangeTrigger) trigger; + if (image.getImage() != null) { + triggerNode.get(getPath(BUILD_CONFIG_IMAGECHANGE_IMAGE)).set(image.getImage().toString()); + } + if (image.getFrom() != null) { + triggerNode.get(getPath(BUILD_CONFIG_IMAGECHANGE_NAME)).set(image.getFrom().toString()); + } + if (StringUtils.isNotEmpty(image.getTag())) { + triggerNode.get(getPath(BUILD_CONFIG_IMAGECHANGE_TAG)) + .set(StringUtils.defaultIfBlank(image.getTag(), "")); + } + break; - @Override - public String getOutputRepositoryName() { - return asString(BUILDCONFIG_OUTPUT_REPO); - } + } + } + triggerNode.get(TYPE).set(trigger.getType()); + } - public String getSourceURI() { - return asString(BUILDCONFIG_SOURCE_URI); - } - - @SuppressWarnings("unchecked") - @Override - public T getBuildSource() { - switch(asString(BUILDCONFIG_SOURCE_TYPE)){ - case BuildSourceType.GIT: - return (T) new GitBuildSource(asString(BUILDCONFIG_SOURCE_URI), asString(BUILDCONFIG_SOURCE_REF), asString(BUILDCONFIG_SOURCE_CONTEXTDIR)); - default: - } - return null; - } + @Override + public String getOutputRepositoryName() { + return asString(BUILDCONFIG_OUTPUT_REPO); + } - @Override - public void setBuildSource(IBuildSource source){ - switch(source.getType()) { - case BuildSourceType.GIT: - if(!(source instanceof IGitBuildSource)) { - throw new IllegalArgumentException("IBuildSource of type Git does not implement IGitBuildSource"); - } - IGitBuildSource git = (IGitBuildSource) source; - set(BUILDCONFIG_SOURCE_REF, git.getRef()); - break; - } - set(BUILDCONFIG_SOURCE_URI, source.getURI()); - set(BUILDCONFIG_SOURCE_TYPE, source.getType().toString()); - set(BUILDCONFIG_SOURCE_CONTEXTDIR, source.getContextDir()); - } - - @Override - public void setBuildStrategy(IBuildStrategy strategy) { - // Remove other strategies if already set? - switch(strategy.getType()) { - case BuildStrategyType.CUSTOM: - if ( !(strategy instanceof ICustomBuildStrategy)) { - throw new IllegalArgumentException("IBuildStrategy of type Custom does not implement ICustomBuildStrategy"); - } - ICustomBuildStrategy custom = (ICustomBuildStrategy)strategy; - if(custom.getImage() != null) { - set(BUILDCONFIG_CUSTOM_IMAGE, custom.getImage().toString()); - } - set(BUILDCONFIG_CUSTOM_EXPOSEDOCKERSOCKET, custom.exposeDockerSocket()); - if(custom.getEnvironmentVariables() != null) { - setEnvMap(BUILDCONFIG_CUSTOM_ENV, custom.getEnvironmentVariables()); - } - break; - case BuildStrategyType.SOURCE: - ISourceBuildStrategy source = (ISourceBuildStrategy) strategy; - get(BUILDCONFIG_STRATEGY).set(ModelNode.fromJSONString(source.toString())); - break; - case BuildStrategyType.DOCKER: - if ( !(strategy instanceof IDockerBuildStrategy)) { - throw new IllegalArgumentException("IBuildStrategy of type Custom does not implement IDockerBuildStrategy"); - } - IDockerBuildStrategy docker = (IDockerBuildStrategy)strategy; - if(docker.getBaseImage() != null) { - set(BUILDCONFIG_DOCKER_BASEIMAGE, docker.getBaseImage().toString()); - } - if(docker.getContextDir() != null) { - set(BUILDCONFIG_DOCKER_CONTEXTDIR, docker.getContextDir()); - } - set(BUILDCONFIG_DOCKER_NOCACHE, docker.isNoCache()); - break; - case BuildStrategyType.JENKINS_PIPELINE: - if ( !(strategy instanceof IJenkinsPipelineStrategy)) { - throw new IllegalArgumentException("IBuildStrategy of type Custom does not implement IJenkinsPipelineStrategy"); - } - IJenkinsPipelineStrategy jenkins = (IJenkinsPipelineStrategy)strategy; - get(BUILDCONFIG_STRATEGY).set(ModelNode.fromJSONString(jenkins.toString())); - break; - } + public String getSourceURI() { + return asString(BUILDCONFIG_SOURCE_URI); + } - set(BUILDCONFIG_TYPE, strategy.getType()); - } + @SuppressWarnings("unchecked") + @Override + public T getBuildSource() { + switch (asString(BUILDCONFIG_SOURCE_TYPE)) { + case BuildSourceType.GIT: + return (T) new GitBuildSource(asString(BUILDCONFIG_SOURCE_URI), asString(BUILDCONFIG_SOURCE_REF), + asString(BUILDCONFIG_SOURCE_CONTEXTDIR)); + default: + } + return null; + } - @SuppressWarnings("unchecked") - @Override - public T getBuildStrategy() { - switch(asString(BUILDCONFIG_TYPE)){ + @Override + public void setBuildSource(IBuildSource source) { + switch (source.getType()) { + case BuildSourceType.GIT: + if (!(source instanceof IGitBuildSource)) { + throw new IllegalArgumentException("IBuildSource of type Git does not implement IGitBuildSource"); + } + IGitBuildSource git = (IGitBuildSource) source; + set(BUILDCONFIG_SOURCE_REF, git.getRef()); + break; + } + set(BUILDCONFIG_SOURCE_URI, source.getURI()); + set(BUILDCONFIG_SOURCE_TYPE, source.getType().toString()); + set(BUILDCONFIG_SOURCE_CONTEXTDIR, source.getContextDir()); + } + + @Override + public void setBuildStrategy(IBuildStrategy strategy) { + // Remove other strategies if already set? + switch (strategy.getType()) { + case BuildStrategyType.CUSTOM: + if (!(strategy instanceof ICustomBuildStrategy)) { + throw new IllegalArgumentException( + "IBuildStrategy of type Custom does not implement ICustomBuildStrategy"); + } + ICustomBuildStrategy custom = (ICustomBuildStrategy) strategy; + if (custom.getImage() != null) { + set(BUILDCONFIG_CUSTOM_IMAGE, custom.getImage().toString()); + } + set(BUILDCONFIG_CUSTOM_EXPOSEDOCKERSOCKET, custom.exposeDockerSocket()); + if (custom.getEnvironmentVariables() != null) { + setEnvMap(BUILDCONFIG_CUSTOM_ENV, custom.getEnvironmentVariables()); + } + break; + case BuildStrategyType.SOURCE: + ISourceBuildStrategy source = (ISourceBuildStrategy) strategy; + get(BUILDCONFIG_STRATEGY).set(ModelNode.fromJSONString(source.toString())); + break; + case BuildStrategyType.DOCKER: + if (!(strategy instanceof IDockerBuildStrategy)) { + throw new IllegalArgumentException( + "IBuildStrategy of type Custom does not implement IDockerBuildStrategy"); + } + IDockerBuildStrategy docker = (IDockerBuildStrategy) strategy; + if (docker.getBaseImage() != null) { + set(BUILDCONFIG_DOCKER_BASEIMAGE, docker.getBaseImage().toString()); + } + if (docker.getContextDir() != null) { + set(BUILDCONFIG_DOCKER_CONTEXTDIR, docker.getContextDir()); + } + set(BUILDCONFIG_DOCKER_NOCACHE, docker.isNoCache()); + break; + case BuildStrategyType.JENKINS_PIPELINE: + if (!(strategy instanceof IJenkinsPipelineStrategy)) { + throw new IllegalArgumentException( + "IBuildStrategy of type Custom does not implement IJenkinsPipelineStrategy"); + } + IJenkinsPipelineStrategy jenkins = (IJenkinsPipelineStrategy) strategy; + get(BUILDCONFIG_STRATEGY).set(ModelNode.fromJSONString(jenkins.toString())); + break; + } - case BuildStrategyType.CUSTOM: - return (T) new CustomBuildStrategy( - asString(BUILDCONFIG_CUSTOM_IMAGE), - asBoolean(BUILDCONFIG_CUSTOM_EXPOSEDOCKERSOCKET), - getEnvMap(BUILDCONFIG_CUSTOM_ENV) - ); - case BuildStrategyType.SOURCE: - return (T) new SourceBuildStrategy(get(BUILDCONFIG_STRATEGY), getPropertyKeys()); + set(BUILDCONFIG_TYPE, strategy.getType()); + } - case BuildStrategyType.DOCKER: - return (T) new DockerBuildStrategy( - asString(BUILDCONFIG_DOCKER_CONTEXTDIR), - asBoolean(BUILDCONFIG_DOCKER_NOCACHE), - asString(BUILDCONFIG_DOCKER_BASEIMAGE) - ); + @SuppressWarnings("unchecked") + @Override + public T getBuildStrategy() { + switch (asString(BUILDCONFIG_TYPE)) { - case BuildStrategyType.JENKINS_PIPELINE: - return (T) new JenkinsPipelineStrategy(get(BUILDCONFIG_STRATEGY), getPropertyKeys()); + case BuildStrategyType.CUSTOM: + return (T) new CustomBuildStrategy(asString(BUILDCONFIG_CUSTOM_IMAGE), + asBoolean(BUILDCONFIG_CUSTOM_EXPOSEDOCKERSOCKET), getEnvMap(BUILDCONFIG_CUSTOM_ENV)); + case BuildStrategyType.SOURCE: + return (T) new SourceBuildStrategy(get(BUILDCONFIG_STRATEGY), getPropertyKeys()); - default: - } - return null; - } + case BuildStrategyType.DOCKER: + return (T) new DockerBuildStrategy(asString(BUILDCONFIG_DOCKER_CONTEXTDIR), + asBoolean(BUILDCONFIG_DOCKER_NOCACHE), asString(BUILDCONFIG_DOCKER_BASEIMAGE)); + + case BuildStrategyType.JENKINS_PIPELINE: + return (T) new JenkinsPipelineStrategy(get(BUILDCONFIG_STRATEGY), getPropertyKeys()); + + default: + } + return null; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/ConfigMap.java b/src/main/java/com/openshift/internal/restclient/model/ConfigMap.java index a0e2aee0..8786e5f0 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ConfigMap.java +++ b/src/main/java/com/openshift/internal/restclient/model/ConfigMap.java @@ -1,10 +1,11 @@ package com.openshift.internal.restclient.model; -import com.openshift.restclient.IClient; -import com.openshift.restclient.model.IConfigMap; +import java.util.Map; + import org.jboss.dmr.ModelNode; -import java.util.Map; +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.IConfigMap; /** * @author Ulf Lilleengen diff --git a/src/main/java/com/openshift/internal/restclient/model/Container.java b/src/main/java/com/openshift/internal/restclient/model/Container.java index c0299562..4e27e8ab 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Container.java +++ b/src/main/java/com/openshift/internal/restclient/model/Container.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import static com.openshift.internal.util.JBossDmrExtentions.asList; @@ -40,290 +41,289 @@ import com.openshift.restclient.model.volume.IVolumeMount; public class Container extends ModelNodeAdapter implements IContainer, ResourcePropertyKeys { - - private static final String IMAGE = "image"; - private static final String ENV = "env"; - private static final String IMAGE_PULL_POLICY = "imagePullPolicy"; - private static final String COMMAND = "command"; - private static final String COMMANDARGS = "args"; - private static final String LIFECYCLE = "lifecycle"; - private static final String VOLUMEMOUNTS = "volumeMounts"; - private static final String PROPERTY_REQUESTS_MEMORY = "resources.requests.memory"; - private static final String PROPERTY_REQUESTS_CPU = "resources.requests.cpu"; - private static final String PROPERTY_LIMITS_MEMORY = "resources.limits.memory"; - private static final String PROPERTY_LIMITS_CPU = "resources.limits.cpu"; - private static final String LIVENESSPROBE = "livenessProbe"; - private static final String READINESSPROBE = "readinessProbe"; - - private ModelNode node; - private Map propertyKeys; - - public Container(ModelNode node) { - this(node, Collections.emptyMap()); - } - /** - * - * @param node - * @param propertyKeys the override paths from the defaults - */ - public Container(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - this.node = node; - this.propertyKeys = propertyKeys; - } - - @Override - public void setName(String name) { - set(node, propertyKeys, NAME, name); - } - - @Override - public String getName() { - return asString(node, propertyKeys, NAME); - } - - @Override - public void setImage(DockerImageURI tag) { - set(node, propertyKeys, IMAGE, tag.getAbsoluteUri()); - } - - @Override - public DockerImageURI getImage() { - return new DockerImageURI(asString(node, propertyKeys, IMAGE)); - } - - @Override - public void setEnvVars(Map vars) { - if(!vars.isEmpty()) { - ModelNode env = get(node, propertyKeys, ENV); - env.clear(); - for (Entry var : vars.entrySet()) { - addEnvVar(var.getKey(), var.getValue()); - } - } - } - - @Override - public Map getEnvVars() { - HashMap hashMap = new HashMap<>(); - ModelNode env = get(node, propertyKeys, ENV); - if(env.isDefined()) { - for (ModelNode var : env.asList()) { - hashMap.put( - asString(var,propertyKeys,NAME), - asString(var,propertyKeys,VALUE) - ); - } - } - return hashMap; - } - - @Override - public void addEnvVar(String key, String value) { - ModelNode env = get(node, propertyKeys, ENV); - ModelNode varNode = new ModelNode(); - varNode.get(NAME).set(key); - varNode.get(VALUE).set(value); - env.add(varNode); - } - - @Override - public void setPorts(Set ports) { - ModelNode nodePorts = get(node, propertyKeys, PORTS); - nodePorts.clear(); - for (IPort port : ports) { - ModelNode portNode = nodePorts.add(); - new Port(portNode, port); - } - } - - @Override - public Set getPorts() { - ModelNode nodePorts = get(node, propertyKeys, PORTS); - Set ports = new HashSet<>(); - if(nodePorts.isDefined()) { - for (ModelNode port : nodePorts.asList()) { - ports.add(new Port(port)); - } - } - return ports; - } - - @Override - public void setImagePullPolicy(String policy) { - set(node, propertyKeys, IMAGE_PULL_POLICY, policy); - } - - @Override - public String getImagePullPolicy() { - return asString(node, propertyKeys, IMAGE_PULL_POLICY); - } - - @Override + + private static final String IMAGE = "image"; + private static final String ENV = "env"; + private static final String IMAGE_PULL_POLICY = "imagePullPolicy"; + private static final String COMMAND = "command"; + private static final String COMMANDARGS = "args"; + private static final String LIFECYCLE = "lifecycle"; + private static final String VOLUMEMOUNTS = "volumeMounts"; + private static final String PROPERTY_REQUESTS_MEMORY = "resources.requests.memory"; + private static final String PROPERTY_REQUESTS_CPU = "resources.requests.cpu"; + private static final String PROPERTY_LIMITS_MEMORY = "resources.limits.memory"; + private static final String PROPERTY_LIMITS_CPU = "resources.limits.cpu"; + private static final String LIVENESSPROBE = "livenessProbe"; + private static final String READINESSPROBE = "readinessProbe"; + + private ModelNode node; + private Map propertyKeys; + + public Container(ModelNode node) { + this(node, Collections.emptyMap()); + } + + /** + * + * @param node the node + * @param propertyKeys + * the override paths from the defaults + */ + public Container(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + this.node = node; + this.propertyKeys = propertyKeys; + } + + @Override + public void setName(String name) { + set(node, propertyKeys, NAME, name); + } + + @Override + public String getName() { + return asString(node, propertyKeys, NAME); + } + + @Override + public void setImage(DockerImageURI tag) { + set(node, propertyKeys, IMAGE, tag.getAbsoluteUri()); + } + + @Override + public DockerImageURI getImage() { + return new DockerImageURI(asString(node, propertyKeys, IMAGE)); + } + + @Override + public void setEnvVars(Map vars) { + if (!vars.isEmpty()) { + ModelNode env = get(node, propertyKeys, ENV); + env.clear(); + for (Entry var : vars.entrySet()) { + addEnvVar(var.getKey(), var.getValue()); + } + } + } + + @Override + public Map getEnvVars() { + HashMap hashMap = new HashMap<>(); + ModelNode env = get(node, propertyKeys, ENV); + if (env.isDefined()) { + for (ModelNode var : env.asList()) { + hashMap.put(asString(var, propertyKeys, NAME), asString(var, propertyKeys, VALUE)); + } + } + return hashMap; + } + + @Override + public void addEnvVar(String key, String value) { + ModelNode env = get(node, propertyKeys, ENV); + ModelNode varNode = new ModelNode(); + varNode.get(NAME).set(key); + varNode.get(VALUE).set(value); + env.add(varNode); + } + + @Override + public void setPorts(Set ports) { + ModelNode nodePorts = get(node, propertyKeys, PORTS); + nodePorts.clear(); + for (IPort port : ports) { + ModelNode portNode = nodePorts.add(); + new Port(portNode, port); + } + } + + @Override + public Set getPorts() { + ModelNode nodePorts = get(node, propertyKeys, PORTS); + Set ports = new HashSet<>(); + if (nodePorts.isDefined()) { + for (ModelNode port : nodePorts.asList()) { + ports.add(new Port(port)); + } + } + return ports; + } + + @Override + public void setImagePullPolicy(String policy) { + set(node, propertyKeys, IMAGE_PULL_POLICY, policy); + } + + @Override + public String getImagePullPolicy() { + return asString(node, propertyKeys, IMAGE_PULL_POLICY); + } + + @Override public void setCommand(List command) { set(node, propertyKeys, COMMAND, command.toArray(new String[0])); } - - @Override + + @Override public List getCommand() { return asList(node, propertyKeys, COMMAND, ModelType.STRING); } - - @Override + + @Override public void setCommandArgs(List args) { set(node, propertyKeys, COMMANDARGS, args.toArray(new String[0])); } - - @Override + + @Override public List getCommandArgs() { return asList(node, propertyKeys, COMMANDARGS, ModelType.STRING); } - @Override - public void setLifecycle(ILifecycle lifecycle) { - ModelNode lifecycleNode = ModelNode.fromJSONString(lifecycle.toJson()); - get(node, propertyKeys, LIFECYCLE).set(lifecycleNode); - } - - @Override - public ILifecycle getLifecycle() { - if (node.has(LIFECYCLE)) { - return Lifecycle.fromJson(get(node, propertyKeys, LIFECYCLE)); - } else { - return new Lifecycle.Builder().build(); - } - } - - @Override - public void setVolumes(Set volumes) { - ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); - mounts.clear(); - for (IVolume volume : volumes) { - new EmptyDirVolume(mounts.add(), volume); - } - } - - @Override - public Set getVolumes() { - Set volumes = new HashSet<>(); - ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); - if(mounts.isDefined()) { - for (ModelNode node : mounts.asList()) { - volumes.add(new VolumeMount(node)); - } - } - return volumes; - } - @Override - public void setVolumeMounts(Set volumes) { - ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); - mounts.clear(); - for (IVolumeMount volume : volumes) { - new VolumeMount(mounts.add(), volume); - } - } - - @Override - public Set getVolumeMounts() { - Set volumes = new HashSet<>(); - ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); - if(mounts.isDefined()) { - for (ModelNode node : mounts.asList()) { - volumes.add(new VolumeMount(node)); - } - } - return volumes; - } - - - @Override - public IVolumeMount addVolumeMount(String name) { - ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); - VolumeMount volume = new VolumeMount(mounts.add()); - volume.setName(name); - return volume; - } - - @Override - public String getRequestsMemory() { - return asString(node, propertyKeys, PROPERTY_REQUESTS_MEMORY); - } - - @Override - public void setRequestsMemory(String requestsMemory) { - ModelNode child = get(getNode(), propertyKeys, PROPERTY_REQUESTS_MEMORY); - if (StringUtils.isBlank(requestsMemory)) { - child.clear(); - } else { - child.set(requestsMemory); - } - } - - @Override - public String getRequestsCPU() { - return asString(node, propertyKeys, PROPERTY_REQUESTS_CPU); - } - - @Override - public void setRequestsCPU(String requestsCPU) { - ModelNode child = get(getNode(), propertyKeys, PROPERTY_REQUESTS_CPU); - if (StringUtils.isBlank(requestsCPU)) { - child.clear(); - } else { - child.set(requestsCPU); - } - } - - @Override - public String getLimitsMemory() { - return asString(node, propertyKeys, PROPERTY_LIMITS_MEMORY); - } - - @Override - public void setLimitsMemory(String limitsMemory) { - ModelNode child = get(getNode(), propertyKeys, PROPERTY_LIMITS_MEMORY); - if (StringUtils.isBlank(limitsMemory)) { - child.clear(); - } else { - child.set(limitsMemory); - } - } - - @Override - public String getLimitsCPU() { - return asString(node, propertyKeys, PROPERTY_LIMITS_CPU); - } - - @Override - public void setLimitsCPU(String limitsCPU) { - ModelNode child = get(getNode(), propertyKeys, PROPERTY_LIMITS_CPU); - if (StringUtils.isBlank(limitsCPU)) { - child.clear(); - } else { - child.set(limitsCPU); - } - } - - @Override - public IProbe getReadinessProbe() { - ModelNode readinessProbeNode = get(getNode(), propertyKeys, READINESSPROBE); - if (!readinessProbeNode.isDefined()) { - return null; - } - return new Probe(readinessProbeNode); - } - - @Override - public IProbe getLivenessProbe() { - ModelNode lifenessProbeNode = get(getNode(), propertyKeys, LIVENESSPROBE); - if (!lifenessProbeNode.isDefined()) { - return null; - } - return new Probe(lifenessProbeNode); - } - - @Override - public String toJSONString() { - return super.toJson(false); - } + @Override + public void setLifecycle(ILifecycle lifecycle) { + ModelNode lifecycleNode = ModelNode.fromJSONString(lifecycle.toJson()); + get(node, propertyKeys, LIFECYCLE).set(lifecycleNode); + } + + @Override + public ILifecycle getLifecycle() { + if (node.has(LIFECYCLE)) { + return Lifecycle.fromJson(get(node, propertyKeys, LIFECYCLE)); + } else { + return new Lifecycle.Builder().build(); + } + } + + @Override + public void setVolumes(Set volumes) { + ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); + mounts.clear(); + for (IVolume volume : volumes) { + new EmptyDirVolume(mounts.add(), volume); + } + } + + @Override + public Set getVolumes() { + Set volumes = new HashSet<>(); + ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); + if (mounts.isDefined()) { + for (ModelNode node : mounts.asList()) { + volumes.add(new VolumeMount(node)); + } + } + return volumes; + } + + @Override + public void setVolumeMounts(Set volumes) { + ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); + mounts.clear(); + for (IVolumeMount volume : volumes) { + new VolumeMount(mounts.add(), volume); + } + } + + @Override + public Set getVolumeMounts() { + Set volumes = new HashSet<>(); + ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); + if (mounts.isDefined()) { + for (ModelNode node : mounts.asList()) { + volumes.add(new VolumeMount(node)); + } + } + return volumes; + } + + @Override + public IVolumeMount addVolumeMount(String name) { + ModelNode mounts = get(node, propertyKeys, VOLUMEMOUNTS); + VolumeMount volume = new VolumeMount(mounts.add()); + volume.setName(name); + return volume; + } + + @Override + public String getRequestsMemory() { + return asString(node, propertyKeys, PROPERTY_REQUESTS_MEMORY); + } + + @Override + public void setRequestsMemory(String requestsMemory) { + ModelNode child = get(getNode(), propertyKeys, PROPERTY_REQUESTS_MEMORY); + if (StringUtils.isBlank(requestsMemory)) { + child.clear(); + } else { + child.set(requestsMemory); + } + } + + @Override + public String getRequestsCPU() { + return asString(node, propertyKeys, PROPERTY_REQUESTS_CPU); + } + + @Override + public void setRequestsCPU(String requestsCPU) { + ModelNode child = get(getNode(), propertyKeys, PROPERTY_REQUESTS_CPU); + if (StringUtils.isBlank(requestsCPU)) { + child.clear(); + } else { + child.set(requestsCPU); + } + } + + @Override + public String getLimitsMemory() { + return asString(node, propertyKeys, PROPERTY_LIMITS_MEMORY); + } + + @Override + public void setLimitsMemory(String limitsMemory) { + ModelNode child = get(getNode(), propertyKeys, PROPERTY_LIMITS_MEMORY); + if (StringUtils.isBlank(limitsMemory)) { + child.clear(); + } else { + child.set(limitsMemory); + } + } + + @Override + public String getLimitsCPU() { + return asString(node, propertyKeys, PROPERTY_LIMITS_CPU); + } + + @Override + public void setLimitsCPU(String limitsCPU) { + ModelNode child = get(getNode(), propertyKeys, PROPERTY_LIMITS_CPU); + if (StringUtils.isBlank(limitsCPU)) { + child.clear(); + } else { + child.set(limitsCPU); + } + } + + @Override + public IProbe getReadinessProbe() { + ModelNode readinessProbeNode = get(getNode(), propertyKeys, READINESSPROBE); + if (!readinessProbeNode.isDefined()) { + return null; + } + return new Probe(readinessProbeNode); + } + + @Override + public IProbe getLivenessProbe() { + ModelNode lifenessProbeNode = get(getNode(), propertyKeys, LIVENESSPROBE); + if (!lifenessProbeNode.isDefined()) { + return null; + } + return new Probe(lifenessProbeNode); + } + + @Override + public String toJson(){ + return super.toJson(false); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/DeploymentConfig.java b/src/main/java/com/openshift/internal/restclient/model/DeploymentConfig.java index bb4d0f16..5067e166 100644 --- a/src/main/java/com/openshift/internal/restclient/model/DeploymentConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/DeploymentConfig.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; @@ -29,167 +30,164 @@ import com.openshift.restclient.model.deploy.DeploymentTriggerType; import com.openshift.restclient.model.deploy.IDeploymentTrigger; -/** - * @author Jeff Cantrill - */ -public class DeploymentConfig extends ReplicationController implements IDeploymentConfig{ - - public static final String DEPLOYMENTCONFIG_CONTAINERS = "spec.template.spec.containers"; - private static final String DEPLOYMENTCONFIG_TRIGGERS = "spec.triggers"; - private static final String DEPLOYMENTCONFIG_STRATEGY = "spec.strategy.type"; - private static final String DEPLOYMENTCONFIG_LATEST_VERSION = "status.latestVersion"; - private static final String DEPLOYMENTCONFIG_CAUSES = "status.details.causes"; - - private static final String TYPE = "type"; - private static final String IMAGE_CHANGE = "ImageChange"; - private static final String IMAGE_TRIGGER = "imageTrigger"; - private static final String FROM = "from"; - private static final String NAME = "name"; - private static final String IMAGE_CHANGE_PARAMS = "imageChangeParams"; - private static final String LAST_TRIGGER_IMAGE = "lastTriggeredImage"; - private static final String IMAGE_TRIGGER_FROM_NAME = IMAGE_TRIGGER + "." + FROM + "." + NAME; - private static final String IMAGE_CHANGE_PARAMS_FROM_NAME = IMAGE_CHANGE_PARAMS + "." + FROM + "." + NAME; - private static final String IMAGE_CHANGE_PARAMS_LAST_TRIGGER_IMAGE = IMAGE_CHANGE_PARAMS + "." + LAST_TRIGGER_IMAGE; - - private final Map propertyKeys; - - public DeploymentConfig(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - this.propertyKeys = propertyKeys; - initializeCapabilities(getModifiableCapabilities(), this, getClient()); - } - - @Override - public Collection getTriggerTypes(){ - List types = new ArrayList(); - ModelNode triggers = get(DEPLOYMENTCONFIG_TRIGGERS); - for (ModelNode node : triggers.asList()) { - types.add(asString(node,TYPE)); - } - return types; - } - - @Override - public Collection getTriggers() { - List triggers = new ArrayList<>(); - ModelNode list = get(DEPLOYMENTCONFIG_TRIGGERS); - for (ModelNode node : list.asList()) { - String type = asString(node,TYPE); - switch(type) { - case(DeploymentTriggerType.CONFIG_CHANGE): - triggers.add(new ConfigChangeTrigger(node, propertyKeys)); - break; - case(DeploymentTriggerType.IMAGE_CHANGE): - triggers.add(new ImageChangeTrigger(node, propertyKeys)); - break; - } - } - return triggers; - } - - //FIXME - public List getImageNames(){ - List names = new ArrayList(); - List containers = get(DEPLOYMENTCONFIG_CONTAINERS).asList(); - for (ModelNode container : containers) { - names.add(container.get("image").asString()); - } - return names; - } - - - - @Override - public int getLatestVersionNumber() { - return asInt(DEPLOYMENTCONFIG_LATEST_VERSION); - } - - - - @Override - public void setLatestVersionNumber(int newVersionNumber) { - set(DEPLOYMENTCONFIG_LATEST_VERSION, newVersionNumber); - } - - @Override - public IDeploymentTrigger addTrigger(String type) { - ModelNode triggers = get(DEPLOYMENTCONFIG_TRIGGERS); - ModelNode triggerNode = triggers.add(); - triggerNode.get(TYPE).set(type); - switch(type) { - case DeploymentTriggerType.IMAGE_CHANGE: - return new ImageChangeTrigger(triggerNode, propertyKeys); - case DeploymentTriggerType.CONFIG_CHANGE: - default: - } - return new DeploymentTrigger(triggerNode, propertyKeys); - } - - @Override - public String getDeploymentStrategyType() { - return asString(DEPLOYMENTCONFIG_STRATEGY); - } - - @Override - public boolean haveTriggersFired() { - ModelNode causes = get(DEPLOYMENTCONFIG_CAUSES); - if (causes.getType() == ModelType.UNDEFINED || causes.getType() != ModelType.LIST) - return false; - return causes.asList().size() > 0; - } - - @Override - public boolean didImageTrigger(String imageNameTag) { - if (!haveTriggersFired() || imageNameTag == null) - return false; - ModelNode causes = get(DEPLOYMENTCONFIG_CAUSES); - if (causes.getType() == ModelType.UNDEFINED || - causes.getType() != ModelType.LIST) - return false; - for (ModelNode cause : causes.asList()) { - String type = asString(cause, TYPE); - if (type.equalsIgnoreCase(IMAGE_CHANGE)) { - String triggerName = asString(cause, IMAGE_TRIGGER_FROM_NAME); - DockerImageURI uri = new DockerImageURI(triggerName); - if (imageNameTag.equals(uri.getNameAndTag())) - return true; - } - } - return false; - } - - @Override - public String getImageHexIDForImageNameAndTag(String imageNameTag) { - ModelNode triggers = get(DEPLOYMENTCONFIG_TRIGGERS); - if (triggers.getType() == ModelType.UNDEFINED || triggers.getType() != ModelType.LIST || imageNameTag == null) - return null; - for (ModelNode trigger : triggers.asList()) { - if (asString(trigger, TYPE).equalsIgnoreCase(IMAGE_CHANGE)) { - String nameTag = null; - nameTag = asString(trigger, IMAGE_CHANGE_PARAMS_FROM_NAME); - if (imageNameTag.equals(nameTag)) { - return asString(trigger, IMAGE_CHANGE_PARAMS_LAST_TRIGGER_IMAGE); - } - } - } - return null; - } - - @Override - public String getImageNameAndTagForTriggeredDeployment() { - ModelNode causes = get(DEPLOYMENTCONFIG_CAUSES); - if (causes.getType() == ModelType.UNDEFINED || causes.getType() != ModelType.LIST) - return null; - for (ModelNode cause : causes.asList()) { - String type = asString(cause, TYPE); - if (type.equalsIgnoreCase(IMAGE_CHANGE)) { - String imageTag = asString(cause, IMAGE_TRIGGER_FROM_NAME); - DockerImageURI uri = new DockerImageURI(imageTag); - return uri.getNameAndTag(); - } - } - return null; - } - - +public class DeploymentConfig extends ReplicationController implements IDeploymentConfig { + + public static final String DEPLOYMENTCONFIG_CONTAINERS = "spec.template.spec.containers"; + private static final String DEPLOYMENTCONFIG_TRIGGERS = "spec.triggers"; + private static final String DEPLOYMENTCONFIG_STRATEGY = "spec.strategy.type"; + private static final String DEPLOYMENTCONFIG_LATEST_VERSION = "status.latestVersion"; + private static final String DEPLOYMENTCONFIG_CAUSES = "status.details.causes"; + + private static final String TYPE = "type"; + private static final String IMAGE_CHANGE = "ImageChange"; + private static final String IMAGE_TRIGGER = "imageTrigger"; + private static final String FROM = "from"; + private static final String NAME = "name"; + private static final String IMAGE_CHANGE_PARAMS = "imageChangeParams"; + private static final String LAST_TRIGGER_IMAGE = "lastTriggeredImage"; + private static final String IMAGE_TRIGGER_FROM_NAME = IMAGE_TRIGGER + "." + FROM + "." + NAME; + private static final String IMAGE_CHANGE_PARAMS_FROM_NAME = IMAGE_CHANGE_PARAMS + "." + FROM + "." + NAME; + private static final String IMAGE_CHANGE_PARAMS_LAST_TRIGGER_IMAGE = IMAGE_CHANGE_PARAMS + "." + LAST_TRIGGER_IMAGE; + + private final Map propertyKeys; + + public DeploymentConfig(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + this.propertyKeys = propertyKeys; + initializeCapabilities(getModifiableCapabilities(), this, getClient()); + } + + @Override + public Collection getTriggerTypes() { + List types = new ArrayList(); + ModelNode triggers = get(DEPLOYMENTCONFIG_TRIGGERS); + for (ModelNode node : triggers.asList()) { + types.add(asString(node, TYPE)); + } + return types; + } + + @Override + public Collection getTriggers() { + List triggers = new ArrayList<>(); + ModelNode list = get(DEPLOYMENTCONFIG_TRIGGERS); + for (ModelNode node : list.asList()) { + String type = asString(node, TYPE); + switch (type) { + case (DeploymentTriggerType.CONFIG_CHANGE): + triggers.add(new ConfigChangeTrigger(node, propertyKeys)); + break; + case (DeploymentTriggerType.IMAGE_CHANGE): + triggers.add(new ImageChangeTrigger(node, propertyKeys)); + break; + } + } + return triggers; + } + + // FIXME + public List getImageNames() { + List names = new ArrayList(); + List containers = get(DEPLOYMENTCONFIG_CONTAINERS).asList(); + for (ModelNode container : containers) { + names.add(container.get("image").asString()); + } + return names; + } + + @Override + public int getLatestVersionNumber() { + return asInt(DEPLOYMENTCONFIG_LATEST_VERSION); + } + + @Override + public void setLatestVersionNumber(int newVersionNumber) { + set(DEPLOYMENTCONFIG_LATEST_VERSION, newVersionNumber); + } + + @Override + public IDeploymentTrigger addTrigger(String type) { + ModelNode triggers = get(DEPLOYMENTCONFIG_TRIGGERS); + ModelNode triggerNode = triggers.add(); + triggerNode.get(TYPE).set(type); + switch (type) { + case DeploymentTriggerType.IMAGE_CHANGE: + return new ImageChangeTrigger(triggerNode, propertyKeys); + case DeploymentTriggerType.CONFIG_CHANGE: + default: + } + return new DeploymentTrigger(triggerNode, propertyKeys); + } + + @Override + public String getDeploymentStrategyType() { + return asString(DEPLOYMENTCONFIG_STRATEGY); + } + + @Override + public boolean haveTriggersFired() { + ModelNode causes = get(DEPLOYMENTCONFIG_CAUSES); + if (causes.getType() == ModelType.UNDEFINED || causes.getType() != ModelType.LIST) { + return false; + } + return causes.asList().size() > 0; + } + + @Override + public boolean didImageTrigger(String imageNameTag) { + if (!haveTriggersFired() || imageNameTag == null) { + return false; + } + ModelNode causes = get(DEPLOYMENTCONFIG_CAUSES); + if (causes.getType() == ModelType.UNDEFINED || causes.getType() != ModelType.LIST) { + return false; + } + for (ModelNode cause : causes.asList()) { + String type = asString(cause, TYPE); + if (type.equalsIgnoreCase(IMAGE_CHANGE)) { + String triggerName = asString(cause, IMAGE_TRIGGER_FROM_NAME); + DockerImageURI uri = new DockerImageURI(triggerName); + if (imageNameTag.equals(uri.getNameAndTag())) { + return true; + } + } + } + return false; + } + + @Override + public String getImageHexIDForImageNameAndTag(String imageNameTag) { + ModelNode triggers = get(DEPLOYMENTCONFIG_TRIGGERS); + if (triggers.getType() == ModelType.UNDEFINED || triggers.getType() != ModelType.LIST || imageNameTag == null) { + return null; + } + for (ModelNode trigger : triggers.asList()) { + if (asString(trigger, TYPE).equalsIgnoreCase(IMAGE_CHANGE)) { + String nameTag = null; + nameTag = asString(trigger, IMAGE_CHANGE_PARAMS_FROM_NAME); + if (imageNameTag.equals(nameTag)) { + return asString(trigger, IMAGE_CHANGE_PARAMS_LAST_TRIGGER_IMAGE); + } + } + } + return null; + } + + @Override + public String getImageNameAndTagForTriggeredDeployment() { + ModelNode causes = get(DEPLOYMENTCONFIG_CAUSES); + if (causes.getType() == ModelType.UNDEFINED || causes.getType() != ModelType.LIST) { + return null; + } + for (ModelNode cause : causes.asList()) { + String type = asString(cause, TYPE); + if (type.equalsIgnoreCase(IMAGE_CHANGE)) { + String imageTag = asString(cause, IMAGE_TRIGGER_FROM_NAME); + DockerImageURI uri = new DockerImageURI(imageTag); + return uri.getNameAndTag(); + } + } + return null; + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java b/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java index 62ce34de..060770a2 100644 --- a/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java +++ b/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import static com.openshift.internal.util.JBossDmrExtentions.asString; @@ -24,104 +25,103 @@ public class EnvironmentVariable extends ModelNodeAdapter implements IEnvironmentVariable, ResourcePropertyKeys { - public EnvironmentVariable(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - } - - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), NAME); - } - - @Override - public String getValue() { - return asString(getNode(), getPropertyKeys(), VALUE); - } - - @Override - public IEnvVarSource getValueFrom() { - if(getNode().hasDefined("fieldRef")) { - return new IObjectFieldSelector(){ - @Override - public String getApiVersion() { - return asString(getNode(), getPropertyKeys(), "fieldRef.apiVersion"); - } - - @Override - public String getFieldPath() { - return asString(getNode(), getPropertyKeys(), "fieldRef.fieldPath"); - } - - }; - }else if(getNode().hasDefined("configMapKeyRef")) { - return new IConfigMapKeySelector() { - - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), "configMapKeyRef.name"); - } - - @Override - public String getKey() { - return asString(getNode(), getPropertyKeys(), "configMapKeyRef.key"); - } - }; - - }else if(getNode().hasDefined("secretKeyRef")) { - return new ISecretKeySelector() { - - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), "secretKeyRef.name"); - } - - @Override - public String getKey() { - return asString(getNode(), getPropertyKeys(), "secretKeyRef.key"); - } - }; - } - return null; - } - - - @Override - public boolean equals(Object object) { - if (!(object instanceof IEnvironmentVariable)) { - return false; - } - - IEnvironmentVariable otherVar = (IEnvironmentVariable) object; - String thisName = getName(); - String otherName = otherVar.getName(); - if (thisName == null) { - if (otherName != null) { - return false; - } - } else { - if (!thisName.equals(otherName)) { - return false; - } - } - - String thisValue = getValue(); - String otherValue = otherVar.getValue(); - if (thisValue == null) { - if (otherValue != null) { - return false; - } - } else { - if (!thisValue.equals(otherValue)) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - String name = getName(); - String value = getValue(); - return 37 * (name == null? 0 : name.hashCode()) + (value == null? 0 : value.hashCode()); - } + public EnvironmentVariable(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), NAME); + } + + @Override + public String getValue() { + return asString(getNode(), getPropertyKeys(), VALUE); + } + + @Override + public IEnvVarSource getValueFrom() { + if (getNode().hasDefined("fieldRef")) { + return new IObjectFieldSelector() { + @Override + public String getApiVersion() { + return asString(getNode(), getPropertyKeys(), "fieldRef.apiVersion"); + } + + @Override + public String getFieldPath() { + return asString(getNode(), getPropertyKeys(), "fieldRef.fieldPath"); + } + + }; + } else if (getNode().hasDefined("configMapKeyRef")) { + return new IConfigMapKeySelector() { + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), "configMapKeyRef.name"); + } + + @Override + public String getKey() { + return asString(getNode(), getPropertyKeys(), "configMapKeyRef.key"); + } + }; + + } else if (getNode().hasDefined("secretKeyRef")) { + return new ISecretKeySelector() { + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), "secretKeyRef.name"); + } + + @Override + public String getKey() { + return asString(getNode(), getPropertyKeys(), "secretKeyRef.key"); + } + }; + } + return null; + } + + @Override + public boolean equals(Object object) { + if (!(object instanceof IEnvironmentVariable)) { + return false; + } + + IEnvironmentVariable otherVar = (IEnvironmentVariable) object; + String thisName = getName(); + String otherName = otherVar.getName(); + if (thisName == null) { + if (otherName != null) { + return false; + } + } else { + if (!thisName.equals(otherName)) { + return false; + } + } + + String thisValue = getValue(); + String otherValue = otherVar.getValue(); + if (thisValue == null) { + if (otherValue != null) { + return false; + } + } else { + if (!thisValue.equals(otherValue)) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + String name = getName(); + String value = getValue(); + return 37 * (name == null ? 0 : name.hashCode()) + (value == null ? 0 : value.hashCode()); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/ExecAction.java b/src/main/java/com/openshift/internal/restclient/model/ExecAction.java index 6986043a..38b61051 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ExecAction.java +++ b/src/main/java/com/openshift/internal/restclient/model/ExecAction.java @@ -8,14 +8,16 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.model; -import com.openshift.restclient.model.IExecAction; -import org.jboss.dmr.ModelNode; +package com.openshift.internal.restclient.model; import java.util.ArrayList; import java.util.Collections; +import org.jboss.dmr.ModelNode; + +import com.openshift.restclient.model.IExecAction; + /** * @author Ulf Lilleengen */ diff --git a/src/main/java/com/openshift/internal/restclient/model/ImageStream.java b/src/main/java/com/openshift/internal/restclient/model/ImageStream.java index c1c3d06f..1cbca30e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ImageStream.java +++ b/src/main/java/com/openshift/internal/restclient/model/ImageStream.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.ArrayList; @@ -23,121 +24,120 @@ import com.openshift.restclient.model.IImageStream; import com.openshift.restclient.model.image.ITagReference; -/** - * @author Jeff Cantrill - */ public class ImageStream extends KubernetesResource implements IImageStream { - private static final String DOCKER_IMAGE_REPO = "spec.dockerImageRepository"; - private static final String STATUS_DOCKER_IMAGE_REPO = "status.dockerImageRepository"; - private static final String SPEC_TAGS = "spec.tags"; - private static final String STATUS_TAGS = "status.tags"; - private static final String TAG = "tag"; - private static final String ITEMS = "items"; - private static final String IMAGE = "image"; - private Map propertyKeys; - - public ImageStream(){ - this(new ModelNode(), null, null); - } - - public ImageStream(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - this.propertyKeys = propertyKeys; - } - - @Override - public void setDockerImageRepository(DockerImageURI uri) { - setDockerImageRepository(uri.getAbsoluteUri()); - } - - @Override - public void setDockerImageRepository(String uri) { - set(DOCKER_IMAGE_REPO, uri); - } - - @Override - public DockerImageURI getDockerImageRepository() { - if(getNode().has(getPath(DOCKER_IMAGE_REPO))) { - return new DockerImageURI(asString(DOCKER_IMAGE_REPO)); - } - return new DockerImageURI(asString(STATUS_DOCKER_IMAGE_REPO)); - } - - @Override - public Collection getTagNames() { - ModelNode node = get(STATUS_TAGS); - if(!node.isDefined()) return new ArrayList<>(); - return node.asList().stream().map(n->asString(n,TAG)).collect(Collectors.toList()); - } - - @Override - public Collection getTags() { - ModelNode node = get(SPEC_TAGS); - if(!node.isDefined()) return new ArrayList<>(); - return node.asList().stream().map(n->new TagReference(n, propertyKeys)).collect(Collectors.toList()); - } - - - - @Override - public ITagReference addTag(String name, String fromKind, String fromName) { - TagReference reference = new TagReference(name, fromKind, fromName); - //add last since its copy of node. future sets will do nothing - ModelNode tags = get(SPEC_TAGS); - tags.add(reference.getNode()); - return reference; - } - - @Override - public ITagReference addTag(String name, String fromKind, String fromName, String fromNamespace) { - TagReference reference = new TagReference(name, fromKind, fromName, fromNamespace); - //add last since its copy of node. future sets will do nothing - ModelNode tags = get(SPEC_TAGS); - tags.add(reference.getNode()); - return reference; - } - - @Override - public void setTag(String newTag, String fromTag) { - ModelNode tags = get(SPEC_TAGS); - ModelNode tag = new ModelNode(); - tag.get("name").set(newTag); - ModelNode from = new ModelNode(); - from.get("kind").set("ImageStreamTag"); - from.get("name").set(fromTag); - tag.get("from").set(from); - tags.add(tag); - } - - protected String getImageId(List itemWrappers) { - for (ModelNode itemWrapper : itemWrappers) { - ModelNode image = itemWrapper.get(IMAGE); - if (image != null) { - return image.asString(); - } - } - return null; - } - - @Override - public String getImageId(String tagName) { - String imageId = null; - ModelNode tags = get(STATUS_TAGS); - if (tags.getType() != ModelType.LIST || tagName == null) - return null; - - List tagWrappers = tags.asList(); - for (ModelNode tagWrapper : tagWrappers) { - ModelNode tag = tagWrapper.get(TAG); - ModelNode items = tagWrapper.get(ITEMS); - if (tag.asString().equals(tagName) && items.getType() == ModelType.LIST) { - imageId = getImageId(items.asList()); - break; - } - } - return imageId; - } - -} + private static final String DOCKER_IMAGE_REPO = "spec.dockerImageRepository"; + private static final String STATUS_DOCKER_IMAGE_REPO = "status.dockerImageRepository"; + private static final String SPEC_TAGS = "spec.tags"; + private static final String STATUS_TAGS = "status.tags"; + private static final String TAG = "tag"; + private static final String ITEMS = "items"; + private static final String IMAGE = "image"; + private Map propertyKeys; + + public ImageStream() { + this(new ModelNode(), null, null); + } + + public ImageStream(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + this.propertyKeys = propertyKeys; + } + + @Override + public void setDockerImageRepository(DockerImageURI uri) { + setDockerImageRepository(uri.getAbsoluteUri()); + } + + @Override + public void setDockerImageRepository(String uri) { + set(DOCKER_IMAGE_REPO, uri); + } + + @Override + public DockerImageURI getDockerImageRepository() { + if (getNode().has(getPath(DOCKER_IMAGE_REPO))) { + return new DockerImageURI(asString(DOCKER_IMAGE_REPO)); + } + return new DockerImageURI(asString(STATUS_DOCKER_IMAGE_REPO)); + } + + @Override + public Collection getTagNames() { + ModelNode node = get(STATUS_TAGS); + if (!node.isDefined()) { + return new ArrayList<>(); + } + return node.asList().stream().map(n -> asString(n, TAG)).collect(Collectors.toList()); + } + @Override + public Collection getTags() { + ModelNode node = get(SPEC_TAGS); + if (!node.isDefined()) { + return new ArrayList<>(); + } + return node.asList().stream().map(n -> new TagReference(n, propertyKeys)).collect(Collectors.toList()); + } + + @Override + public ITagReference addTag(String name, String fromKind, String fromName) { + TagReference reference = new TagReference(name, fromKind, fromName); + // add last since its copy of node. future sets will do nothing + ModelNode tags = get(SPEC_TAGS); + tags.add(reference.getNode()); + return reference; + } + + @Override + public ITagReference addTag(String name, String fromKind, String fromName, String fromNamespace) { + TagReference reference = new TagReference(name, fromKind, fromName, fromNamespace); + // add last since its copy of node. future sets will do nothing + ModelNode tags = get(SPEC_TAGS); + tags.add(reference.getNode()); + return reference; + } + + @Override + public void setTag(String newTag, String fromTag) { + ModelNode tag = new ModelNode(); + tag.get("name").set(newTag); + ModelNode from = new ModelNode(); + from.get("kind").set("ImageStreamTag"); + from.get("name").set(fromTag); + tag.get("from").set(from); + ModelNode tags = get(SPEC_TAGS); + tags.add(tag); + } + + protected String getImageId(List itemWrappers) { + for (ModelNode itemWrapper : itemWrappers) { + ModelNode image = itemWrapper.get(IMAGE); + if (image != null) { + return image.asString(); + } + } + return null; + } + + @Override + public String getImageId(String tagName) { + String imageId = null; + ModelNode tags = get(STATUS_TAGS); + if (tags.getType() != ModelType.LIST || tagName == null) { + return null; + } + + List tagWrappers = tags.asList(); + for (ModelNode tagWrapper : tagWrappers) { + ModelNode tag = tagWrapper.get(TAG); + ModelNode items = tagWrapper.get(ITEMS); + if (tag.asString().equals(tagName) && items.getType() == ModelType.LIST) { + imageId = getImageId(items.asList()); + break; + } + } + return imageId; + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/model/KubernetesEvent.java b/src/main/java/com/openshift/internal/restclient/model/KubernetesEvent.java index 812f16cb..37902c45 100644 --- a/src/main/java/com/openshift/internal/restclient/model/KubernetesEvent.java +++ b/src/main/java/com/openshift/internal/restclient/model/KubernetesEvent.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.Map; @@ -19,70 +20,67 @@ import com.openshift.restclient.model.IEvent; import com.openshift.restclient.model.IObjectReference; -/** - * @author Jeff Cantrill - */ public class KubernetesEvent extends KubernetesResource implements IEvent { - public KubernetesEvent(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } - - @Override - public String getReason() { - return asString("reason"); - } - - @Override - public String getMessage() { - return asString("message"); - } - - @Override - public IObjectReference getInvolvedObject() { - return new ObjectReference(get("involvedObject")); - } - - @Override - public String getFirstSeenTimestamp() { - return asString("firstTimestamp"); - } - - @Override - public String getLastSeenTimestamp() { - return asString("lastTimestamp"); - } - - @Override - public int getCount() { - return asInt("count"); - } - - @Override - public String getType() { - return asString("type"); - } - - @Override - public IEventSource getEventSource() { - return new EventSource(get("source"), this.getPropertyKeys()); - } - - private static class EventSource extends ModelNodeAdapter implements IEventSource{ - - protected EventSource(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - } - - @Override - public String getComponent() { - return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "component"); - } - - @Override - public String getHost() { - return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "host"); - } - - } + public KubernetesEvent(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } + + @Override + public String getReason() { + return asString("reason"); + } + + @Override + public String getMessage() { + return asString("message"); + } + + @Override + public IObjectReference getInvolvedObject() { + return new ObjectReference(get("involvedObject")); + } + + @Override + public String getFirstSeenTimestamp() { + return asString("firstTimestamp"); + } + + @Override + public String getLastSeenTimestamp() { + return asString("lastTimestamp"); + } + + @Override + public int getCount() { + return asInt("count"); + } + + @Override + public String getType() { + return asString("type"); + } + + @Override + public IEventSource getEventSource() { + return new EventSource(get("source"), this.getPropertyKeys()); + } + + private static class EventSource extends ModelNodeAdapter implements IEventSource { + + protected EventSource(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public String getComponent() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "component"); + } + + @Override + public String getHost() { + return JBossDmrExtentions.asString(getNode(), getPropertyKeys(), "host"); + } + + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java b/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java index 7a4a16b2..792c7c34 100644 --- a/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java +++ b/src/main/java/com/openshift/internal/restclient/model/KubernetesResource.java @@ -6,14 +6,16 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; +import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; + import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; -import com.openshift.restclient.model.INamespace; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; @@ -23,363 +25,363 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.model.INamespace; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IResource; -import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; - /** * Resource is an abstract representation of a Kubernetes resource * - * @author Jeff Cantrill */ public class KubernetesResource implements IResource, ResourcePropertyKeys { - - private ModelNode node; - private IClient client; - private Map, ICapability> capabilities = new HashMap, ICapability>(); - private Map propertyKeys; - private IProject project; - private INamespace namespace; - - /** - * - * @param node - * @param client - * @param overrideProperties the map of properties that override the defaults - */ - public KubernetesResource(ModelNode node, IClient client, Map overrideProperties){ - if(overrideProperties == null) overrideProperties = new HashMap(); - this.node = node; - this.client = client; - this.propertyKeys = overrideProperties; - initializeCapabilities(capabilities, this, client); - } - - @Override - public String getResourceVersion() { - return asString(METADATA_RESOURCE_VERSION); - } - - @Override - public Map getMetadata() { - return asMap(METADATA); - } - - @SuppressWarnings("unchecked") - @Override - public T getCapability(Class capability) { - return (T) capabilities.get(capability); - } - - public Set> getCapabilities(){ - return Collections.unmodifiableSet(capabilities.keySet()); - } - - protected Map, ICapability> getModifiableCapabilities(){ - return capabilities; - } - - @Override - public boolean supports(Class capability) { - return capabilities.containsKey(capability); - } - - @SuppressWarnings("unchecked") - @Override - public R accept(CapabilityVisitor visitor, R unsupportedValue){ - if(capabilities.containsKey(visitor.getCapabilityType())){ - T capability = (T) capabilities.get(visitor.getCapabilityType()); - return (R) visitor.visit(capability); - } - return unsupportedValue; - } - - @Override - public IProject getProject() { - if(this.project == null) { - this.project = client.get(ResourceKind.PROJECT, getNamespaceName(), ""); - } - return this.project; - } - - @Override + + private ModelNode node; + private IClient client; + private Map, ICapability> capabilities = new HashMap, ICapability>(); + private Map propertyKeys; + private IProject project; + private INamespace namespace; + + /** + * + * @param overrideProperties + * the map of properties that override the defaults + */ + public KubernetesResource(ModelNode node, IClient client, Map overrideProperties) { + if (overrideProperties == null) { + overrideProperties = new HashMap(); + } + this.node = node; + this.client = client; + this.propertyKeys = overrideProperties; + initializeCapabilities(capabilities, this, client); + } + + @Override + public String getResourceVersion() { + return asString(METADATA_RESOURCE_VERSION); + } + + @Override + public Map getMetadata() { + return asMap(METADATA); + } + + @SuppressWarnings("unchecked") + @Override + public T getCapability(Class capability) { + return (T) capabilities.get(capability); + } + + public Set> getCapabilities() { + return Collections.unmodifiableSet(capabilities.keySet()); + } + + protected Map, ICapability> getModifiableCapabilities() { + return capabilities; + } + + @Override + public boolean supports(Class capability) { + return capabilities.containsKey(capability); + } + + @SuppressWarnings("unchecked") + @Override + public R accept(CapabilityVisitor visitor, R unsupportedValue) { + if (capabilities.containsKey(visitor.getCapabilityType())) { + T capability = (T) capabilities.get(visitor.getCapabilityType()); + return (R) visitor.visit(capability); + } + return unsupportedValue; + } + + @Override + public IProject getProject() { + if (this.project == null) { + this.project = client.get(ResourceKind.PROJECT, getNamespaceName(), ""); + } + return this.project; + } + + @Override public INamespace getNamespace() { - if (this.namespace == null) { - this.namespace = client.get(ResourceKind.NAMESPACE, getNamespaceName(), ""); + if (this.namespace == null) { + this.namespace = client.get(ResourceKind.NAMESPACE, getNamespaceName(), ""); } return this.namespace; } - @Override - public Map getAnnotations() { - return asMap(ANNOTATIONS); - } - - @Override - public String getAnnotation(String key) { - return getAnnotations().get(key); - } - - - @Override - public void setAnnotation(String name, String value) { - if(value == null) return; - ModelNode annotations = get(ANNOTATIONS); - annotations.get(name).set(value); - } - - @Override - public void removeAnnotation(String name) { - ModelNode annotations = get(ANNOTATIONS); - annotations.remove(name); - } - - @Override - public boolean isAnnotatedWith(String key) { - Map annotations = getAnnotations(); - return annotations.containsKey(key); - } - - public Map getPropertyKeys(){ - return this.propertyKeys; - } - - public IClient getClient(){ - return client; - } - - public void setNode(ModelNode node) { - this.node = node.clone(); - } - public ModelNode getNode(){ - return node; - } - - public void refresh(){ - //TODO find better way to bypass serialization/deserialization - this.node = ModelNode.fromJSONString(client.get(getKind(), getName(), getNamespaceName()).toString()); - } - - @Override - public String getKind(){ - return asString(KIND); - } - - @Override - public String getApiVersion(){ - return asString(APIVERSION); - } - - @Override - public String getCreationTimeStamp(){ - return asString(CREATION_TIMESTAMP); - } - @Override - public String getName(){ - return asString(METADATA_NAME); - } - - public void setName(String name) { - set(METADATA_NAME, name); - } - - @Override - public String getNamespaceName(){ - return asString(METADATA_NAMESPACE); - } - - public void setNamespace(String namespace){ - set(METADATA_NAMESPACE, namespace); - } - - @Override - public void addLabel(String key, String value) { - ModelNode labels = node.get(getPath(LABELS)); - labels.get(key).set(value); - } - - - @Override - public Map getLabels() { - return asMap(LABELS); - } - - /*---------- utility methods ------*/ - protected boolean has(String key) { - return node.has(getPath(key)); - } - - protected ModelNode get(String key){ - return get(node, key); - } - protected ModelNode get(ModelNode node, String key){ - return node.get(getPath(key)); - } - - protected Map getEnvMap(String key) { - Map values = new HashMap(); - ModelNode source = node.get(getPath(key)); - if(source.getType() == ModelType.LIST){ - for (ModelNode value : source.asList()) { - values.put(value.get("name").asString(), value.get("value").asString()); - } - } - return values; - } - - protected void set(String key, Map values) { - JBossDmrExtentions.set(node, propertyKeys, key, values); - } - - protected void set(String key, int value) { - JBossDmrExtentions.set(node, propertyKeys, key, value); - } - - protected void set(ModelNode node, String key, int value) { - JBossDmrExtentions.set(node, propertyKeys, key, value); - } - - protected void set(String key, String value){ - JBossDmrExtentions.set(node, propertyKeys, key, value); - } - - protected void set(ModelNode node, String key, String value){ - JBossDmrExtentions.set(node, propertyKeys, key, value); - } - - protected void set(String key, boolean value){ - JBossDmrExtentions.set(node, propertyKeys, key, value); - } - - protected void set(ModelNode node, String key, boolean value){ - JBossDmrExtentions.set(node, propertyKeys, key, value); - } - - protected void setEnvMap(String key, Map values) { - ModelNode mapNodeParent = node.get(getPath(key)); - for(Map.Entry value: values.entrySet()) { - ModelNode mapNode = mapNodeParent.add(); - mapNode.get("name").set(value.getKey()); - mapNode.get("value").set(value.getValue()); - } - } - - protected String[] getPath(String key) { - return JBossDmrExtentions.getPath(propertyKeys, key); - } - - protected String asString(ModelNode node, String subKey) { - return JBossDmrExtentions.asString(node, propertyKeys, subKey); - } - - protected int asInt(String key){ - return JBossDmrExtentions.asInt(node, propertyKeys, key); - } - - protected int asInt(ModelNode node, String key){ - return JBossDmrExtentions.asInt(node, propertyKeys, key); - } - - protected Map asMap(String property){ - return JBossDmrExtentions.asMap(this.node, propertyKeys, property); - } - - protected String asString(String property){ - return JBossDmrExtentions.asString(node, propertyKeys, property); - } - - protected boolean asBoolean(ModelNode node, String property) { - return JBossDmrExtentions.asBoolean(node, propertyKeys, property); - } - - protected boolean asBoolean(String property) { - return JBossDmrExtentions.asBoolean(node, propertyKeys, property); - } - - protected Set asSet(String property, ModelType type) { - return JBossDmrExtentions.asSet(node, propertyKeys, property, type); - } - - protected void set(String property, Set values) { - JBossDmrExtentions.set(node, propertyKeys, property, values); - } - - protected void set(String property, String... values) { - JBossDmrExtentions.set(node, propertyKeys, property, values); - } - - @Override - public String toString() { - return toJson(true); - } - - public String toPrettyString(){ - return toJson(false); - } - - @Override - public int hashCode() { - String namespace = getNamespaceName(); - String name = getName(); - String kind = getKind(); - final int prime = 31; - return prime * (namespace.hashCode() + name.hashCode() + kind.hashCode()); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - else if (obj == null) - return false; - else if (getClass() != obj.getClass()) - return false; - else { - KubernetesResource other = (KubernetesResource) obj; - if (getKind() != null){ - if (!getKind().equals(other.getKind())) { - return false; - } - } else { - if (other.getKind() != null) { - return false; - } - } - if (getNamespaceName() != null) { - if(!getNamespaceName().equals(other.getNamespaceName())) { - return false; - } - } else { - if (other.getNamespaceName() != null) { - return false; - } - } - if (getName() != null) { - if(!getName().equals(other.getName())) { - return false; - } - } else { - if (other.getName() != null) { - return false; - } - } - - } - return true; - } - - @Override - public String toJson() { - return toJson(false); - } - - @Override - public String toJson(boolean compact) { - return JBossDmrExtentions.toJsonString(node, compact); - } - - -} + @Override + public Map getAnnotations() { + return asMap(ANNOTATIONS); + } + + @Override + public String getAnnotation(String key) { + return getAnnotations().get(key); + } + + @Override + public void setAnnotation(String name, String value) { + if (value == null) { + return; + } + ModelNode annotations = get(ANNOTATIONS); + annotations.get(name).set(value); + } + + @Override + public void removeAnnotation(String name) { + ModelNode annotations = get(ANNOTATIONS); + annotations.remove(name); + } + + @Override + public boolean isAnnotatedWith(String key) { + Map annotations = getAnnotations(); + return annotations.containsKey(key); + } + + public Map getPropertyKeys() { + return this.propertyKeys; + } + + public IClient getClient() { + return client; + } + + public void setNode(ModelNode node) { + this.node = node.clone(); + } + + public ModelNode getNode() { + return node; + } + + public void refresh() { + // TODO find better way to bypass serialization/deserialization + this.node = ModelNode.fromJSONString(client.get(getKind(), getName(), getNamespaceName()).toString()); + } + + @Override + public String getKind() { + return asString(KIND); + } + + @Override + public String getApiVersion() { + return asString(APIVERSION); + } + + @Override + public String getCreationTimeStamp() { + return asString(CREATION_TIMESTAMP); + } + + @Override + public String getName() { + return asString(METADATA_NAME); + } + + public void setName(String name) { + set(METADATA_NAME, name); + } + + @Override + public String getNamespaceName() { + return asString(METADATA_NAMESPACE); + } + + public void setNamespace(String namespace) { + set(METADATA_NAMESPACE, namespace); + } + + @Override + public void addLabel(String key, String value) { + ModelNode labels = node.get(getPath(LABELS)); + labels.get(key).set(value); + } + + @Override + public Map getLabels() { + return asMap(LABELS); + } + + /*---------- utility methods ------*/ + protected boolean has(String key) { + return node.has(getPath(key)); + } + + protected ModelNode get(String key) { + return get(node, key); + } + + protected ModelNode get(ModelNode node, String key) { + return node.get(getPath(key)); + } + + protected Map getEnvMap(String key) { + Map values = new HashMap(); + ModelNode source = node.get(getPath(key)); + if (source.getType() == ModelType.LIST) { + for (ModelNode value : source.asList()) { + values.put(value.get("name").asString(), value.get("value").asString()); + } + } + return values; + } + + protected void set(String key, Map values) { + JBossDmrExtentions.set(node, propertyKeys, key, values); + } + + protected void set(String key, int value) { + JBossDmrExtentions.set(node, propertyKeys, key, value); + } + + protected void set(ModelNode node, String key, int value) { + JBossDmrExtentions.set(node, propertyKeys, key, value); + } + + protected void set(String key, String value) { + JBossDmrExtentions.set(node, propertyKeys, key, value); + } + + protected void set(ModelNode node, String key, String value) { + JBossDmrExtentions.set(node, propertyKeys, key, value); + } + + protected void set(String key, boolean value) { + JBossDmrExtentions.set(node, propertyKeys, key, value); + } + + protected void set(ModelNode node, String key, boolean value) { + JBossDmrExtentions.set(node, propertyKeys, key, value); + } + + protected void set(String property, Set values) { + JBossDmrExtentions.set(node, propertyKeys, property, values); + } + + protected void set(String property, String... values) { + JBossDmrExtentions.set(node, propertyKeys, property, values); + } + + protected void setEnvMap(String key, Map values) { + ModelNode mapNodeParent = node.get(getPath(key)); + for (Map.Entry value : values.entrySet()) { + ModelNode mapNode = mapNodeParent.add(); + mapNode.get("name").set(value.getKey()); + mapNode.get("value").set(value.getValue()); + } + } + + protected String[] getPath(String key) { + return JBossDmrExtentions.getPath(propertyKeys, key); + } + + protected String asString(ModelNode node, String subKey) { + return JBossDmrExtentions.asString(node, propertyKeys, subKey); + } + + protected String asString(String property) { + return JBossDmrExtentions.asString(node, propertyKeys, property); + } + + protected int asInt(String key) { + return JBossDmrExtentions.asInt(node, propertyKeys, key); + } + + protected int asInt(ModelNode node, String key) { + return JBossDmrExtentions.asInt(node, propertyKeys, key); + } + + protected Map asMap(String property) { + return JBossDmrExtentions.asMap(this.node, propertyKeys, property); + } + + protected boolean asBoolean(ModelNode node, String property) { + return JBossDmrExtentions.asBoolean(node, propertyKeys, property); + } + + protected boolean asBoolean(String property) { + return JBossDmrExtentions.asBoolean(node, propertyKeys, property); + } + @SuppressWarnings("rawtypes") + protected Set asSet(String property, ModelType type) { + return JBossDmrExtentions.asSet(node, propertyKeys, property, type); + } + + @Override + public String toString() { + return toJson(true); + } + + public String toPrettyString() { + return toJson(false); + } + + @Override + public int hashCode() { + String namespace = getNamespaceName(); + String name = getName(); + String kind = getKind(); + final int prime = 31; + return prime * (namespace.hashCode() + name.hashCode() + kind.hashCode()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null) { + return false; + } else if (getClass() != obj.getClass()) { + return false; + } else { + KubernetesResource other = (KubernetesResource) obj; + if (getKind() != null) { + if (!getKind().equals(other.getKind())) { + return false; + } + } else { + if (other.getKind() != null) { + return false; + } + } + if (getNamespaceName() != null) { + if (!getNamespaceName().equals(other.getNamespaceName())) { + return false; + } + } else { + if (other.getNamespaceName() != null) { + return false; + } + } + if (getName() != null) { + if (!getName().equals(other.getName())) { + return false; + } + } else { + if (other.getName() != null) { + return false; + } + } + } + return true; + } + + @Override + public String toJson() { + return toJson(false); + } + + @Override + public String toJson(boolean compact) { + return JBossDmrExtentions.toJsonString(node, compact); + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java b/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java index 5bd0ed00..bd4f3339 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java +++ b/src/main/java/com/openshift/internal/restclient/model/Lifecycle.java @@ -8,13 +8,15 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; -import com.openshift.restclient.model.IHandler; -import com.openshift.restclient.model.ILifecycle; +import java.util.Optional; + import org.jboss.dmr.ModelNode; -import java.util.Optional; +import com.openshift.restclient.model.IHandler; +import com.openshift.restclient.model.ILifecycle; /** * @author Ulf Lilleengen @@ -44,8 +46,10 @@ public Optional getPreStop() { @Override public String toJson() { ModelNode node = new ModelNode(); - preStop.ifPresent(handler -> node.get(PRESTOP).get(handler.getType()).set(ModelNode.fromJSONString(handler.toJson()))); - postStart.ifPresent(handler -> node.get(POSTSTART).get(handler.getType()).set(ModelNode.fromJSONString(handler.toJson()))); + preStop.ifPresent( + handler -> node.get(PRESTOP).get(handler.getType()).set(ModelNode.fromJSONString(handler.toJson()))); + postStart.ifPresent( + handler -> node.get(POSTSTART).get(handler.getType()).set(ModelNode.fromJSONString(handler.toJson()))); return node.toJSONString(true); } diff --git a/src/main/java/com/openshift/internal/restclient/model/LimitRange.java b/src/main/java/com/openshift/internal/restclient/model/LimitRange.java index 2896cb05..cf33253c 100644 --- a/src/main/java/com/openshift/internal/restclient/model/LimitRange.java +++ b/src/main/java/com/openshift/internal/restclient/model/LimitRange.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.Map; @@ -19,9 +20,8 @@ public class LimitRange extends KubernetesResource implements ILimitRange { - public LimitRange(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public LimitRange(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/List.java b/src/main/java/com/openshift/internal/restclient/model/List.java index abb2a44f..a52fb3cc 100644 --- a/src/main/java/com/openshift/internal/restclient/model/List.java +++ b/src/main/java/com/openshift/internal/restclient/model/List.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.ArrayList; @@ -21,60 +22,58 @@ import com.openshift.restclient.model.IList; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ -public class List extends KubernetesResource implements IList{ +public class List extends KubernetesResource implements IList { + + private static final String ITEMS = "items"; + + private String kind; + private Collection items; + + public List(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + String listKind = asString(KIND); + if (StringUtils.isNotBlank(listKind)) { + kind = listKind.substring(0, listKind.length() - "List".length()); + } + } - private static final String ITEMS = "items"; - - private String kind; - private Collection items; - public List(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - String listKind = asString(KIND); - if(StringUtils.isNotBlank(listKind)) { - kind = listKind.substring(0, listKind.length() - "List".length()); - } - } - - @Override - public Collection getItems(){ - if(items == null) { - ModelNode listNode = get(ITEMS); - if (listNode.isDefined()) { - Collection nodes = listNode.asList(); - items = new ArrayList<>(nodes.size()); - IResourceFactory factory = getClient().getResourceFactory(); - if (factory != null) { - for (ModelNode node : nodes) { - if (kind != null && !node.get(KIND).isDefined()) { - set(node, KIND, kind); - } - if(!node.get(APIVERSION).isDefined()) { - set(node, APIVERSION, getApiVersion()); - } - IResource resource = factory.create(node.toJSONString(true)); - items.add(resource); - } - } - } else { - items = Collections.emptyList(); - } - } - return Collections.unmodifiableCollection(items); - } + @Override + public Collection getItems() { + if (items == null) { + ModelNode listNode = get(ITEMS); + if (listNode.isDefined()) { + Collection nodes = listNode.asList(); + items = new ArrayList<>(nodes.size()); + IResourceFactory factory = getClient().getResourceFactory(); + if (factory != null) { + for (ModelNode node : nodes) { + if (kind != null && !node.get(KIND).isDefined()) { + set(node, KIND, kind); + } + if (!node.get(APIVERSION).isDefined()) { + set(node, APIVERSION, getApiVersion()); + } + IResource resource = factory.create(node.toJSONString(true)); + items.add(resource); + } + } + } else { + items = Collections.emptyList(); + } + } + return Collections.unmodifiableCollection(items); + } - @Override - public void addAll(Collection items) { - if(this.items == null) { - this.items = new ArrayList<>(); - } - ModelNode itemNode = get(ITEMS); - for (IResource resource : items) { - itemNode.add(ModelNode.fromJSONString(resource.toString())); - this.items.add(resource); - } - } + @Override + public void addAll(Collection items) { + if (this.items == null) { + this.items = new ArrayList<>(); + } + ModelNode itemNode = get(ITEMS); + for (IResource resource : items) { + itemNode.add(ModelNode.fromJSONString(resource.toString())); + this.items.add(resource); + } + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java b/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java index ade6ecac..1a83dab2 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java +++ b/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.Map; @@ -18,44 +19,39 @@ import com.openshift.restclient.model.JSONSerializeable; /** - * Adapter class between what we want - * and the backing DMR json store - * @author Jeff Cantrill + * Adapter class between what we want and the backing DMR json store * */ public class ModelNodeAdapter implements JSONSerializeable { - - private ModelNode node; - private Map propertyKeys; - - protected ModelNodeAdapter(ModelNode node, Map propertyKeys) { - this.node = node; - this.propertyKeys = propertyKeys; - } + private ModelNode node; + private Map propertyKeys; - protected ModelNode getNode(){ - return node; - } - - @Override - public String toJson() { - return toJson(false); - } + protected ModelNodeAdapter(ModelNode node, Map propertyKeys) { + this.node = node; + this.propertyKeys = propertyKeys; + } - public String toJson(boolean compact) { - return JBossDmrExtentions.toJsonString(node, compact); - } + protected ModelNode getNode() { + return node; + } - protected Map getPropertyKeys() { - return propertyKeys; - } + @Override + public String toJson() { + return toJson(false); + } + public String toJson(boolean compact) { + return JBossDmrExtentions.toJsonString(node, compact); + } + protected Map getPropertyKeys() { + return propertyKeys; + } - @Override - public String toString() { - return toJson(false); - } + @Override + public String toString() { + return toJson(false); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/ModelNodeBuilder.java b/src/main/java/com/openshift/internal/restclient/model/ModelNodeBuilder.java index c4ce16f8..f5fa85ea 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ModelNodeBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/ModelNodeBuilder.java @@ -8,57 +8,56 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; +import java.util.Collections; +import java.util.Map; + import org.jboss.dmr.ModelNode; import com.openshift.internal.util.JBossDmrExtentions; -import java.util.Collections; -import java.util.Map; - /** - * Builder to streamline the creation - * of ModelNode trees - * @author jeff.cantrill + * Builder to streamline the creation of ModelNode trees * */ public class ModelNodeBuilder { - - private static final Map PROPS = Collections.emptyMap(); - private ModelNode node; - public ModelNodeBuilder() { - this.node = new ModelNode(); - } + private static final Map PROPS = Collections.emptyMap(); + private ModelNode node; + + public ModelNodeBuilder() { + this.node = new ModelNode(); + } + + public ModelNodeBuilder set(String path, String value) { + JBossDmrExtentions.set(node, PROPS, path, value); + return this; + } + + public ModelNodeBuilder set(String path, ModelNode child) { + JBossDmrExtentions.get(node, PROPS, path).set(child); + return this; + } + + public ModelNodeBuilder set(String path, int value) { + JBossDmrExtentions.set(node, PROPS, path, value); + return this; + } - public ModelNodeBuilder set(String path, String value) { - JBossDmrExtentions.set(node, PROPS, path, value); - return this; - } + public ModelNodeBuilder set(String path, boolean value) { + JBossDmrExtentions.set(node, PROPS, path, value); + return this; + } - public ModelNodeBuilder set(String path, ModelNode child) { - JBossDmrExtentions.get(node, PROPS, path).set(child); - return this; - } + public ModelNodeBuilder add(String path, ModelNodeBuilder builder) { + node.get(JBossDmrExtentions.getPath(path)).add(builder.build()); + return this; + } - public ModelNodeBuilder set(String path, int value) { - JBossDmrExtentions.set(node, PROPS, path, value); - return this; - } + public ModelNode build() { + return this.node; + } - public ModelNodeBuilder set(String path, boolean value) { - JBossDmrExtentions.set(node, PROPS, path, value); - return this; - } - - public ModelNodeBuilder add(String path, ModelNodeBuilder builder) { - node.get(JBossDmrExtentions.getPath(path)).add(builder.build()); - return this; - } - - public ModelNode build() { - return this.node; - } - } diff --git a/src/main/java/com/openshift/internal/restclient/model/Namespace.java b/src/main/java/com/openshift/internal/restclient/model/Namespace.java index 6ac5f7ed..1caedf3d 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Namespace.java +++ b/src/main/java/com/openshift/internal/restclient/model/Namespace.java @@ -1,15 +1,16 @@ package com.openshift.internal.restclient.model; -import com.openshift.restclient.IClient; -import com.openshift.restclient.model.INamespace; -import com.openshift.restclient.model.IResource; -import org.jboss.dmr.ModelNode; +import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; import java.util.ArrayList; import java.util.List; import java.util.Map; -import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; +import org.jboss.dmr.ModelNode; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.INamespace; +import com.openshift.restclient.model.IResource; public class Namespace extends KubernetesResource implements INamespace { @@ -24,7 +25,9 @@ public Namespace(ModelNode node, IClient client, Map property @Override public List getResources(String kind) { - if(getClient() == null) return new ArrayList<>(); + if(getClient() == null) { + return new ArrayList<>(); + } return getClient().list(kind, getName()); } diff --git a/src/main/java/com/openshift/internal/restclient/model/ObjectReference.java b/src/main/java/com/openshift/internal/restclient/model/ObjectReference.java index 6a4e7120..5a9410b9 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ObjectReference.java +++ b/src/main/java/com/openshift/internal/restclient/model/ObjectReference.java @@ -8,10 +8,16 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; -import static com.openshift.internal.restclient.model.properties.ResourcePropertyKeys.*; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.restclient.model.properties.ResourcePropertyKeys.APIVERSION; +import static com.openshift.internal.restclient.model.properties.ResourcePropertyKeys.KIND; +import static com.openshift.internal.restclient.model.properties.ResourcePropertyKeys.NAME; +import static com.openshift.internal.restclient.model.properties.ResourcePropertyKeys.NAMESPACE; +import static com.openshift.internal.restclient.model.properties.ResourcePropertyKeys.RESOURCE_VERSION; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.Collections; import java.util.Map; @@ -22,94 +28,99 @@ import com.openshift.restclient.model.IObjectReference; public class ObjectReference implements IObjectReference { - - private static final Map KEYS = Collections.emptyMap(); - private ModelNode node; - - public ObjectReference(ModelNode node) { - this.node = node; - } - - @Override - public String getKind() { - return asString(node, null, KIND); - } - - public void setKind(String kind) { - set(node, KEYS, KIND, kind); - } - - public void setName(String name) { - set(node, KEYS, NAME, name); - } - - public void setNamespace(String namespace) { - set(node, KEYS, NAMESPACE, namespace); - } - - @Override - public String getApiVersion() { - return asString(node, null, APIVERSION); - } - - @Override - public String getResourceVersion() { - return asString(node, null, RESOURCE_VERSION); - } - - @Override - public String getName() { - return asString(node, null, NAME); - } - - @Override - public String getNamespace() { - return asString(node, null, "namespace"); - } - - @Override - public String getFieldPath() { - return asString(node, null, "fieldPath"); - } - - @Override - public String getUID() { - return asString(node, null, "uid"); - } - - @Override - public String toJson() { - return JBossDmrExtentions.toJsonString(node, false); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((node == null) ? 0 : node.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ObjectReference other = (ObjectReference) obj; - if (node == null) { - if (other.node != null) - return false; - } else if (!node.equals(other.node)) - return false; - return true; - } - - @Override - public String toString() { - return toJson(); - } + + private static final Map KEYS = Collections.emptyMap(); + private ModelNode node; + + public ObjectReference(ModelNode node) { + this.node = node; + } + + @Override + public String getKind() { + return asString(node, null, KIND); + } + + public void setKind(String kind) { + set(node, KEYS, KIND, kind); + } + + public void setName(String name) { + set(node, KEYS, NAME, name); + } + + public void setNamespace(String namespace) { + set(node, KEYS, NAMESPACE, namespace); + } + + @Override + public String getApiVersion() { + return asString(node, null, APIVERSION); + } + + @Override + public String getResourceVersion() { + return asString(node, null, RESOURCE_VERSION); + } + + @Override + public String getName() { + return asString(node, null, NAME); + } + + @Override + public String getNamespace() { + return asString(node, null, "namespace"); + } + + @Override + public String getFieldPath() { + return asString(node, null, "fieldPath"); + } + + @Override + public String getUID() { + return asString(node, null, "uid"); + } + + @Override + public String toJson() { + return JBossDmrExtentions.toJsonString(node, false); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((node == null) ? 0 : node.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ObjectReference other = (ObjectReference) obj; + if (node == null) { + if (other.node != null) { + return false; + } + } else if (!node.equals(other.node)) { + return false; + } + return true; + } + + @Override + public String toString() { + return toJson(); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index 109b8c89..ffd9e086 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; @@ -29,123 +30,122 @@ import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IPort; -/** - * @author Jeff Cantrill - */ public class Pod extends KubernetesResource implements IPod { - private static final String POD_IP = "status.podIP"; - private static final String POD_HOST = "status.hostIP"; - private static final String POD_CONTAINERS = "spec.containers"; - private static final String POD_DELETION_TIMESTAMP = "metadata.deletionTimestamp"; - - private static final String POD_STATUS_PHASE = "status.phase"; - private static final String POD_STATUS_REASON = "status.reason"; - private static final String POD_STATUS_CONTAINER_STATUSES = "status.containerStatuses"; - - // container reasons fields and corresponding status prefixes - private static final List POD_STATUS_CONTAINER_STATES = new ArrayList() {{ - add(new String[]{"state.waiting.reason", ""}); - add(new String[]{"state.terminated.reason", ""}); - add(new String[]{"state.terminated.signal", "Signal: "}); - add(new String[]{"state.terminated.exitCode", "Exit Code: "}); - }}; - - public Pod(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - initializeCapabilities(getModifiableCapabilities(), this, client); - } - - @Override - public String getIP() { - return asString(POD_IP); - } - - @Override - public String getHost() { - return asString(POD_HOST); - } - - @Override - public Collection getImages() { - Collection images = new ArrayList(); - ModelNode node = get(POD_CONTAINERS); - if(node.getType() != ModelType.LIST) return images; - for (ModelNode entry : node.asList()) { - images.add(entry.get("image").asString()); - } - return images; - } - - /** - * The logic of the method is a copied from 'podStatus' function of - * [app/scripts/filters/resources.js] of [openshift/origin-web-console] - */ - - @Override - public String getStatus() { - if (has(POD_DELETION_TIMESTAMP)) { - return "Terminating"; - } - ModelNode node = get(POD_STATUS_CONTAINER_STATUSES); - if (node.getType() == ModelType.LIST) { - for (ModelNode containerStatus : node.asList()) { - String status = getContainerStatusStringIfExist(containerStatus); - if (status != null) { - return status; - } - } - } - return has(POD_STATUS_REASON) ? asString(POD_STATUS_REASON) : asString(POD_STATUS_PHASE); - } - - private String getContainerStatusStringIfExist(ModelNode containerStatus) { - for (String[] pathAndLabel: POD_STATUS_CONTAINER_STATES) { - String path = pathAndLabel[0]; - String statusPostfix = JBossDmrExtentions.asString(containerStatus, null, path); - if (StringUtils.isNotEmpty(statusPostfix)) { - String label = pathAndLabel[1]; - return label + statusPostfix; - } - } - return null; - } - - @Override - public Set getContainerPorts() { - Set ports = new HashSet(); - ModelNode node = get(POD_CONTAINERS); - if(node.getType() == ModelType.LIST) { - for (ModelNode container : node.asList()) { - ModelNode containerPorts = container.get(getPath(PORTS)); - if(containerPorts.getType() == ModelType.LIST) { - for (ModelNode portNode : containerPorts.asList()) { - ports.add(new Port(portNode)); - } - } - } - } - return Collections.unmodifiableSet(ports); - } - - @Override - public IContainer addContainer(String name) { - ModelNode containers = get(POD_CONTAINERS); - Container container = new Container(containers.add()); - container.setName(name); - return container; - } - - @Override - public Collection getContainers() { - ModelNode containers = get(POD_CONTAINERS); - if(containers.isDefined() && ModelType.LIST == containers.getType()) { - return containers.asList().stream().map(n->new Container(n, getPropertyKeys())).collect(Collectors.toList()); - } - return Collections.emptyList(); - } - - - - + private static final String POD_IP = "status.podIP"; + private static final String POD_HOST = "status.hostIP"; + private static final String POD_CONTAINERS = "spec.containers"; + private static final String POD_DELETION_TIMESTAMP = "metadata.deletionTimestamp"; + + private static final String POD_STATUS_PHASE = "status.phase"; + private static final String POD_STATUS_REASON = "status.reason"; + private static final String POD_STATUS_CONTAINER_STATUSES = "status.containerStatuses"; + + // container reasons fields and corresponding status prefixes + private static final List POD_STATUS_CONTAINER_STATES = new ArrayList() { + { + add(new String[] { "state.waiting.reason", "" }); + add(new String[] { "state.terminated.reason", "" }); + add(new String[] { "state.terminated.signal", "Signal: " }); + add(new String[] { "state.terminated.exitCode", "Exit Code: " }); + } + }; + + public Pod(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + initializeCapabilities(getModifiableCapabilities(), this, client); + } + + @Override + public String getIP() { + return asString(POD_IP); + } + + @Override + public String getHost() { + return asString(POD_HOST); + } + + @Override + public Collection getImages() { + Collection images = new ArrayList(); + ModelNode node = get(POD_CONTAINERS); + if (node.getType() != ModelType.LIST) { + return images; + } + for (ModelNode entry : node.asList()) { + images.add(entry.get("image").asString()); + } + return images; + } + + /** + * The logic of the method is a copied from 'podStatus' function of + * [app/scripts/filters/resources.js] of [openshift/origin-web-console] + */ + + @Override + public String getStatus() { + if (has(POD_DELETION_TIMESTAMP)) { + return "Terminating"; + } + ModelNode node = get(POD_STATUS_CONTAINER_STATUSES); + if (node.getType() == ModelType.LIST) { + for (ModelNode containerStatus : node.asList()) { + String status = getContainerStatusStringIfExist(containerStatus); + if (status != null) { + return status; + } + } + } + return has(POD_STATUS_REASON) ? asString(POD_STATUS_REASON) : asString(POD_STATUS_PHASE); + } + + private String getContainerStatusStringIfExist(ModelNode containerStatus) { + for (String[] pathAndLabel : POD_STATUS_CONTAINER_STATES) { + String path = pathAndLabel[0]; + String statusPostfix = JBossDmrExtentions.asString(containerStatus, null, path); + if (StringUtils.isNotEmpty(statusPostfix)) { + String label = pathAndLabel[1]; + return label + statusPostfix; + } + } + return null; + } + + @Override + public Set getContainerPorts() { + Set ports = new HashSet(); + ModelNode node = get(POD_CONTAINERS); + if (node.getType() == ModelType.LIST) { + for (ModelNode container : node.asList()) { + ModelNode containerPorts = container.get(getPath(PORTS)); + if (containerPorts.getType() == ModelType.LIST) { + for (ModelNode portNode : containerPorts.asList()) { + ports.add(new Port(portNode)); + } + } + } + } + return Collections.unmodifiableSet(ports); + } + + @Override + public IContainer addContainer(String name) { + ModelNode containers = get(POD_CONTAINERS); + Container container = new Container(containers.add()); + container.setName(name); + return container; + } + + @Override + public Collection getContainers() { + ModelNode containers = get(POD_CONTAINERS); + if (containers.isDefined() && ModelType.LIST == containers.getType()) { + return containers.asList().stream().map(n -> new Container(n, getPropertyKeys())) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/Port.java b/src/main/java/com/openshift/internal/restclient/model/Port.java index 5ab9fd03..7569da53 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Port.java +++ b/src/main/java/com/openshift/internal/restclient/model/Port.java @@ -8,9 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asInt; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.HashMap; import java.util.Map; @@ -20,103 +23,105 @@ import com.openshift.restclient.model.IPort; -/** - * - * @author Jeff Cantrill - * - */ public class Port implements IPort { - - private static final String PROPERTY_NAME = "name"; - private static final String PROPERTY_PROTOCOL = "protocol"; - private static final String PROPERTY_CONTAINER_PORT = "containerPort"; - private static final Map KEY_MAP = new HashMap<>(); - - static { - KEY_MAP.put(PROPERTY_NAME, new String[] {PROPERTY_NAME}); - KEY_MAP.put(PROPERTY_PROTOCOL, new String[] {PROPERTY_PROTOCOL}); - KEY_MAP.put(PROPERTY_CONTAINER_PORT, new String[] {PROPERTY_CONTAINER_PORT}); - } - - private ModelNode node; - - public Port(ModelNode node) { - this.node = node; - } - - public Port(ModelNode node, IPort port) { - this(node); - if(StringUtils.isNotEmpty(port.getName())) { - setName(port.getName()); - } - setProtocol(port.getProtocol()); - setContainerPort(port.getContainerPort()); - } - - public ModelNode getNode() { - return this.node; - } - - @Override - public String getName() { - return asString(node, KEY_MAP, PROPERTY_NAME); - } - - public void setName(String name) { - set(node, KEY_MAP, PROPERTY_NAME, name); - } - - public void setContainerPort(int port) { - set(node, KEY_MAP, PROPERTY_CONTAINER_PORT, port); - } - - @Override - public int getContainerPort() { - return asInt(node, KEY_MAP, PROPERTY_CONTAINER_PORT); - } - - public void setProtocol(String name) { - set(node, KEY_MAP, PROPERTY_PROTOCOL, name); - } - - @Override - public String getProtocol() { - return asString(node, KEY_MAP, PROPERTY_PROTOCOL); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + getContainerPort(); - result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); - result = prime * result + ((getProtocol() == null) ? 0 : getProtocol().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Port other = (Port) obj; - if (getContainerPort() != other.getContainerPort()) - return false; - if (getName() == null) { - if (other.getName() != null) - return false; - } else if (!getName().equals(other.getName())) - return false; - if (getProtocol() == null) { - if (other.getProtocol() != null) - return false; - } else if (!getProtocol().equals(other.getProtocol())) - return false; - return true; - } - - + + private static final String PROPERTY_NAME = "name"; + private static final String PROPERTY_PROTOCOL = "protocol"; + private static final String PROPERTY_CONTAINER_PORT = "containerPort"; + private static final Map KEY_MAP = new HashMap<>(); + + static { + KEY_MAP.put(PROPERTY_NAME, new String[] { PROPERTY_NAME }); + KEY_MAP.put(PROPERTY_PROTOCOL, new String[] { PROPERTY_PROTOCOL }); + KEY_MAP.put(PROPERTY_CONTAINER_PORT, new String[] { PROPERTY_CONTAINER_PORT }); + } + + private ModelNode node; + + public Port(ModelNode node) { + this.node = node; + } + + public Port(ModelNode node, IPort port) { + this(node); + if (StringUtils.isNotEmpty(port.getName())) { + setName(port.getName()); + } + setProtocol(port.getProtocol()); + setContainerPort(port.getContainerPort()); + } + + public ModelNode getNode() { + return this.node; + } + + @Override + public String getName() { + return asString(node, KEY_MAP, PROPERTY_NAME); + } + + public void setName(String name) { + set(node, KEY_MAP, PROPERTY_NAME, name); + } + + public void setContainerPort(int port) { + set(node, KEY_MAP, PROPERTY_CONTAINER_PORT, port); + } + + @Override + public int getContainerPort() { + return asInt(node, KEY_MAP, PROPERTY_CONTAINER_PORT); + } + + public void setProtocol(String name) { + set(node, KEY_MAP, PROPERTY_PROTOCOL, name); + } + + @Override + public String getProtocol() { + return asString(node, KEY_MAP, PROPERTY_PROTOCOL); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getContainerPort(); + result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); + result = prime * result + ((getProtocol() == null) ? 0 : getProtocol().hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Port other = (Port) obj; + if (getContainerPort() != other.getContainerPort()) { + return false; + } + if (getName() == null) { + if (other.getName() != null) { + return false; + } + } else if (!getName().equals(other.getName())) { + return false; + } + if (getProtocol() == null) { + if (other.getProtocol() != null) { + return false; + } + } else if (!getProtocol().equals(other.getProtocol())) { + return false; + } + return true; + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/Project.java b/src/main/java/com/openshift/internal/restclient/model/Project.java index 9e200a09..9de52420 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Project.java +++ b/src/main/java/com/openshift/internal/restclient/model/Project.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; @@ -23,56 +24,54 @@ /** * DMR implementation of a project - * @author Jeff Cantrill */ -public class Project extends KubernetesResource implements IProject{ - - private static final String ANNOTATION_DISPLAY_NAME = "openshift.io/display-name"; - private static final String ANNOTATION_DESCRIPTION = "openshift.io/description"; - - public Project(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - initializeCapabilities(getModifiableCapabilities(), this, getClient()); - } - - @Override - public IProject getProject() { - return this; - } +public class Project extends KubernetesResource implements IProject { + + private static final String ANNOTATION_DISPLAY_NAME = "openshift.io/display-name"; + private static final String ANNOTATION_DESCRIPTION = "openshift.io/description"; - @Override - public String getNamespaceName() { - if(StringUtils.isEmpty(super.getNamespaceName())) - return getName(); - return super.getNamespaceName(); - } + public Project(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + initializeCapabilities(getModifiableCapabilities(), this, getClient()); + } + @Override + public IProject getProject() { + return this; + } - @Override - public String getDisplayName(){ - return getAnnotation(ANNOTATION_DISPLAY_NAME); - } - - public void setDisplayName(String name) { - setAnnotation(ANNOTATION_DISPLAY_NAME, name); - } - + @Override + public String getNamespaceName() { + if (StringUtils.isEmpty(super.getNamespaceName())) { + return getName(); + } + return super.getNamespaceName(); + } - @Override - public String getDescription() { - return getAnnotation(ANNOTATION_DESCRIPTION); - } + @Override + public String getDisplayName() { + return getAnnotation(ANNOTATION_DISPLAY_NAME); + } + public void setDisplayName(String name) { + setAnnotation(ANNOTATION_DISPLAY_NAME, name); + } - @Override - public void setDescription(String value) { - setAnnotation(ANNOTATION_DESCRIPTION, value); - } + @Override + public String getDescription() { + return getAnnotation(ANNOTATION_DESCRIPTION); + } + @Override + public void setDescription(String value) { + setAnnotation(ANNOTATION_DESCRIPTION, value); + } - @Override - public List getResources(String kind){ - if(getClient() == null) return new ArrayList(); - return getClient().list(kind, getName()); - } + @Override + public List getResources(String kind) { + if (getClient() == null) { + return new ArrayList(); + } + return getClient().list(kind, getName()); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java index 8b2bccb3..80be4d70 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java +++ b/src/main/java/com/openshift/internal/restclient/model/ReplicationController.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; @@ -21,12 +22,11 @@ import java.util.Set; import java.util.stream.Collectors; -import com.openshift.internal.restclient.model.volume.EmptyDirVolumeSource; -import com.openshift.restclient.model.volume.IEmptyDirVolumeSource; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.jboss.dmr.ModelType; +import com.openshift.internal.restclient.model.volume.EmptyDirVolumeSource; import com.openshift.internal.restclient.model.volume.VolumeMount; import com.openshift.internal.restclient.model.volume.VolumeSource; import com.openshift.internal.util.JBossDmrExtentions; @@ -36,349 +36,352 @@ import com.openshift.restclient.model.IEnvironmentVariable; import com.openshift.restclient.model.IPort; import com.openshift.restclient.model.IReplicationController; +import com.openshift.restclient.model.volume.IEmptyDirVolumeSource; import com.openshift.restclient.model.volume.IVolumeMount; import com.openshift.restclient.model.volume.IVolumeSource; -/** - * @author Jeff Cantrill - */ -public class ReplicationController extends KubernetesResource implements IReplicationController{ - - public static final String SPEC_TEMPLATE_CONTAINERS = "spec.template.spec.containers"; - protected static final String SPEC_TEMPLATE_LABELS = "spec.template.metadata.labels"; - protected static final String VOLUMES = "spec.template.spec.volumes"; - protected static final String SPEC_REPLICAS = "spec.replicas"; - protected static final String SPEC_SELECTOR = "spec.selector"; - protected static final String STATUS_REPLICA = "status.replicas"; - protected static final String SERVICEACCOUNTNAME = "spec.template.spec.serviceAccountName"; - - protected static final String IMAGE = "image"; - protected static final String ENV = "env"; - private Map propertyKeys; - - public ReplicationController(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - this.propertyKeys = propertyKeys; - initializeCapabilities(getModifiableCapabilities(), this, getClient()); - } - - @Override - public void setEnvironmentVariable(String name, String value) { - setEnvironmentVariable(null, name, value); - } - - @Override - public void setEnvironmentVariable(String containerName, String name, String value) { - String defaultedContainerName = StringUtils.defaultIfBlank(containerName, ""); - ModelNode specContainers = get(SPEC_TEMPLATE_CONTAINERS); - if(specContainers.isDefined()) { //should ALWAYS exist - List containers = specContainers.asList(); - if(!containers.isEmpty()) { - - Optional opt = containers.stream().filter(n->defaultedContainerName.equals(asString(n, NAME))).findFirst(); - ModelNode node = opt.isPresent() ? opt.get() : containers.get(0); - ModelNode envNode = get(node, ENV); - - List varList = new ArrayList<>(); - if (ModelType.LIST.equals(envNode.getType())){ - varList.addAll(envNode.asList()); - } - - //Check if variable already exists - Optional targetVar = varList.stream().filter(n->name.equals(asString(n, NAME))).findFirst(); - - ModelNode var; - if (targetVar.isPresent()) { - var = targetVar.get(); - int i = varList.indexOf(var); - set(var, VALUE, value); - varList.set(i, var); - } else { - var = new ModelNode(); - set(var, NAME, name); - set(var, VALUE, value); - varList.add(var); - } - envNode.set(varList); - } - } - } - - @Override - public void removeEnvironmentVariable(String name) { - removeEnvironmentVariable(null, name); - } - - @Override - public void removeEnvironmentVariable(String containerName, String name) { - if(name == null) { - throw new IllegalArgumentException("Name cannot be null."); - } - String defaultedContainerName = StringUtils.defaultIfBlank(containerName, ""); - ModelNode specContainers = get(SPEC_TEMPLATE_CONTAINERS); - if(specContainers.isDefined()) { //should ALWAYS exist - List containers = specContainers.asList(); - if(!containers.isEmpty()) { - - Optional opt = containers.stream().filter(n->defaultedContainerName.equals(asString(n, NAME))).findFirst(); - ModelNode node = opt.isPresent() ? opt.get() : containers.get(0); - ModelNode envNode = get(node, ENV); - - List varList = new ArrayList<>(); - if (ModelType.LIST.equals(envNode.getType())){ - varList.addAll(envNode.asList()); - } - - //Check if variable exists - Optional targetVar = varList.stream().filter(n->name.equals(asString(n, NAME))).findFirst(); - - ModelNode var; - if (targetVar.isPresent()) { - var = targetVar.get(); - int i = varList.indexOf(var); - varList.remove(i); - envNode.set(varList); - } else { - //do nothing - } - } - } - } - - @Override - public Collection getEnvironmentVariables() { - return getEnvironmentVariables(null); - } - - @Override - public Collection getEnvironmentVariables(String containerName) { - String name = StringUtils.defaultIfBlank(containerName, ""); - ModelNode specContainers = get(SPEC_TEMPLATE_CONTAINERS); - if(specContainers.isDefined()) { - List containers = specContainers.asList(); - if(!containers.isEmpty()) { - Optional opt = containers.stream().filter(n->name.equals(asString(n, NAME))).findFirst(); - ModelNode node = opt.isPresent() ? opt.get() : containers.get(0); - ModelNode envNode = get(node, ENV); - if(envNode.isDefined()) { - return envNode.asList() - .stream() - .map(n-> new EnvironmentVariable(n, propertyKeys)) - .collect(Collectors.toList()); - } - } - } - return Collections.emptyList(); - } - - @Override - public int getDesiredReplicaCount() { - return asInt(SPEC_REPLICAS); - } - - @Override - public int getReplicas() { - return getDesiredReplicaCount(); - } - - @Override - public void setDesiredReplicaCount(int count) { - set(SPEC_REPLICAS, count); - } - - @Override - public void setReplicas(int count) { - setDesiredReplicaCount(count); - } - - @Override - public Map getReplicaSelector() { - return asMap(SPEC_SELECTOR); - } - - - @Override - public void setReplicaSelector(String key, String value) { - Map selector = new HashMap<>(); - selector.put(key, value); - setReplicaSelector(selector); - } - - @Override - public void setReplicaSelector(Map selector) { - get(SPEC_SELECTOR).clear(); - set(SPEC_SELECTOR, selector); - selector.forEach((k,v)->addTemplateLabel(k,v)); - } - @Override - public int getCurrentReplicaCount() { - return asInt(STATUS_REPLICA); - } - - @Override - public Collection getImages() { - ModelNode node = get(SPEC_TEMPLATE_CONTAINERS); - if(node.getType() != ModelType.LIST) return new ArrayList<>(); - Collection list = new ArrayList<>(); - for (ModelNode entry : node.asList()) { - list.add(entry.get(IMAGE).asString()); - } - return list; - } - - @Override - public IContainer getContainer(String name) { - if(StringUtils.isBlank(name)) { - return null; - } - ModelNode containers = get(SPEC_TEMPLATE_CONTAINERS); - if(containers.isDefined() && containers.getType() == ModelType.LIST ) { - Optional first = containers.asList().stream().filter(n->name.equals(JBossDmrExtentions.asString(n, this.propertyKeys, NAME))).findFirst(); - if(first.isPresent()) { - return new Container(first.get(), this.propertyKeys); - } - } - return null; - } - - @Override - public Collection getContainers() { - ModelNode containers = get(SPEC_TEMPLATE_CONTAINERS); - if(containers.isDefined() && containers.getType() == ModelType.LIST ) { - return containers.asList().stream().map(n->new Container(n, this.propertyKeys)).collect(Collectors.toList()); - } - return Collections.emptyList(); - } - - @Override - public Map getTemplateLabels() { - return asMap(SPEC_TEMPLATE_LABELS); - } - - @Override - public void addTemplateLabel(String key, String value) { - ModelNode labels = get(SPEC_TEMPLATE_LABELS); - labels.get(key).set(value); - } - - @Override - public IContainer addContainer(DockerImageURI tag, Set containerPorts, Map envVars){ - return addContainer(tag.getName(), tag, containerPorts, envVars, new ArrayList()); - } - - @Override - public IContainer addContainer(String name, DockerImageURI tag, Set containerPorts, Map envVars, List emptyDirVolumes) { - - IContainer container = addContainer(name); - container.setImage(tag); - - if(!emptyDirVolumes.isEmpty()) { - Set volumes = new HashSet<>(); - for (String path : emptyDirVolumes) { - VolumeMount volume = new VolumeMount(new ModelNode()); - volume.setMountPath(path); - volume.setName(String.format("%s-%s", name, emptyDirVolumes.indexOf(path) + 1)); - volumes.add(volume); - addEmptyDirVolumeToPodSpec(volume); - } - container.setVolumeMounts(volumes); - } - if(!containerPorts.isEmpty()) { - Set ports = new HashSet<>(); - for (IPort port : containerPorts) { - ports.add(new Port(new ModelNode(), port)); - } - container.setPorts(ports); - } - container.setEnvVars(envVars); - return container; - } - - private boolean hasVolumeNamed(ModelNode volNode, String name) { - if(volNode.isDefined()) { - List podVolumes = volNode.asList(); - for (ModelNode node : podVolumes) { - if(name.equals(asString(node,NAME))) { - return true; - } - } - } - return false; - } - - private void addEmptyDirVolumeToPodSpec(VolumeMount volume) { - ModelNode volNode = get(VOLUMES); - if (hasVolumeNamed(volNode, volume.getName())) { - //already exists - return; - } - IEmptyDirVolumeSource volumeSource = new EmptyDirVolumeSource(volume.getName()); - volumeSource.setMedium(""); - addVolume(volumeSource); - } - - @Override - public IContainer addContainer(String name) { - ModelNode containers = get(SPEC_TEMPLATE_CONTAINERS); - Container container = new Container(containers.add()); - container.setName(name); - return container; - } - - @Override - public void setContainers(Collection containers) { - ModelNode nodeContainers = get(SPEC_TEMPLATE_CONTAINERS); - nodeContainers.clear(); - if (containers != null) { - containers.forEach(c -> nodeContainers.add(ModelNode.fromJSONString(c.toJSONString()))); - } - } - - @Override - public Set getVolumes() { - ModelNode vol = get(VOLUMES); - Set volumes = new HashSet<>(); - if(vol.isDefined()) { - for (ModelNode node : vol.asList()) { - volumes.add(VolumeSource.create(node)); - } - } - return volumes; - } - - @Override - public void setVolumes(Set volumeSources) { - ModelNode vol = get(VOLUMES); - vol.clear(); - if (volumeSources != null) { - volumeSources.forEach(v -> vol.add(ModelNode.fromJSONString(v.toJSONString()))); - } - } - - @Override - public void addVolume(IVolumeSource volumeSource) { - ModelNode volList = get(VOLUMES); - if (hasVolumeNamed(volList, volumeSource.getName())) { - //already exists - return; - } - volList.add(ModelNode.fromJSONString(volumeSource.toJSONString())); - } - - +public class ReplicationController extends KubernetesResource implements IReplicationController { + + public static final String SPEC_TEMPLATE_CONTAINERS = "spec.template.spec.containers"; + protected static final String SPEC_TEMPLATE_LABELS = "spec.template.metadata.labels"; + protected static final String VOLUMES = "spec.template.spec.volumes"; + protected static final String SPEC_REPLICAS = "spec.replicas"; + protected static final String SPEC_SELECTOR = "spec.selector"; + protected static final String STATUS_REPLICA = "status.replicas"; + protected static final String SERVICEACCOUNTNAME = "spec.template.spec.serviceAccountName"; + + protected static final String IMAGE = "image"; + protected static final String ENV = "env"; + private Map propertyKeys; + + public ReplicationController(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + this.propertyKeys = propertyKeys; + initializeCapabilities(getModifiableCapabilities(), this, getClient()); + } + + @Override + public void setEnvironmentVariable(String name, String value) { + setEnvironmentVariable(null, name, value); + } + + @Override + public void setEnvironmentVariable(String containerName, String name, String value) { + String defaultedContainerName = StringUtils.defaultIfBlank(containerName, ""); + ModelNode specContainers = get(SPEC_TEMPLATE_CONTAINERS); + if (specContainers.isDefined()) { // should ALWAYS exist + List containers = specContainers.asList(); + if (!containers.isEmpty()) { + + Optional opt = containers.stream() + .filter(n -> defaultedContainerName.equals(asString(n, NAME))).findFirst(); + ModelNode node = opt.isPresent() ? opt.get() : containers.get(0); + ModelNode envNode = get(node, ENV); + + List varList = new ArrayList<>(); + if (ModelType.LIST.equals(envNode.getType())) { + varList.addAll(envNode.asList()); + } + + // Check if variable already exists + Optional targetVar = varList.stream().filter(n -> name.equals(asString(n, NAME))) + .findFirst(); + + ModelNode var; + if (targetVar.isPresent()) { + var = targetVar.get(); + int i = varList.indexOf(var); + set(var, VALUE, value); + varList.set(i, var); + } else { + var = new ModelNode(); + set(var, NAME, name); + set(var, VALUE, value); + varList.add(var); + } + envNode.set(varList); + } + } + } + + @Override + public void removeEnvironmentVariable(String name) { + removeEnvironmentVariable(null, name); + } + + @Override + public void removeEnvironmentVariable(String containerName, String name) { + if (name == null) { + throw new IllegalArgumentException("Name cannot be null."); + } + String defaultedContainerName = StringUtils.defaultIfBlank(containerName, ""); + ModelNode specContainers = get(SPEC_TEMPLATE_CONTAINERS); + if (specContainers.isDefined()) { // should ALWAYS exist + List containers = specContainers.asList(); + if (!containers.isEmpty()) { + + Optional opt = containers.stream() + .filter(n -> defaultedContainerName.equals(asString(n, NAME))).findFirst(); + ModelNode node = opt.isPresent() ? opt.get() : containers.get(0); + ModelNode envNode = get(node, ENV); + + List varList = new ArrayList<>(); + if (ModelType.LIST.equals(envNode.getType())) { + varList.addAll(envNode.asList()); + } + + // Check if variable exists + Optional targetVar = varList.stream().filter(n -> name.equals(asString(n, NAME))) + .findFirst(); + + ModelNode var; + if (targetVar.isPresent()) { + var = targetVar.get(); + int i = varList.indexOf(var); + varList.remove(i); + envNode.set(varList); + } else { + // do nothing + } + } + } + } + + @Override + public Collection getEnvironmentVariables() { + return getEnvironmentVariables(null); + } + + @Override + public Collection getEnvironmentVariables(String containerName) { + String name = StringUtils.defaultIfBlank(containerName, ""); + ModelNode specContainers = get(SPEC_TEMPLATE_CONTAINERS); + if (specContainers.isDefined()) { + List containers = specContainers.asList(); + if (!containers.isEmpty()) { + Optional opt = containers.stream().filter(n -> name.equals(asString(n, NAME))).findFirst(); + ModelNode node = opt.isPresent() ? opt.get() : containers.get(0); + ModelNode envNode = get(node, ENV); + if (envNode.isDefined()) { + return envNode.asList().stream().map(n -> new EnvironmentVariable(n, propertyKeys)) + .collect(Collectors.toList()); + } + } + } + return Collections.emptyList(); + } + + @Override + public int getDesiredReplicaCount() { + return asInt(SPEC_REPLICAS); + } + + @Override + public int getReplicas() { + return getDesiredReplicaCount(); + } + + @Override + public void setDesiredReplicaCount(int count) { + set(SPEC_REPLICAS, count); + } + + @Override + public void setReplicas(int count) { + setDesiredReplicaCount(count); + } + + @Override + public Map getReplicaSelector() { + return asMap(SPEC_SELECTOR); + } + + @Override + public void setReplicaSelector(String key, String value) { + Map selector = new HashMap<>(); + selector.put(key, value); + setReplicaSelector(selector); + } + + @Override + public void setReplicaSelector(Map selector) { + get(SPEC_SELECTOR).clear(); + set(SPEC_SELECTOR, selector); + selector.forEach((k, v) -> addTemplateLabel(k, v)); + } + + @Override + public int getCurrentReplicaCount() { + return asInt(STATUS_REPLICA); + } + + @Override + public Collection getImages() { + ModelNode node = get(SPEC_TEMPLATE_CONTAINERS); + if (node.getType() != ModelType.LIST) { + return new ArrayList<>(); + } + Collection list = new ArrayList<>(); + for (ModelNode entry : node.asList()) { + list.add(entry.get(IMAGE).asString()); + } + return list; + } + + @Override + public IContainer getContainer(String name) { + if (StringUtils.isBlank(name)) { + return null; + } + ModelNode containers = get(SPEC_TEMPLATE_CONTAINERS); + if (containers.isDefined() && containers.getType() == ModelType.LIST) { + Optional first = containers.asList().stream() + .filter(n -> name.equals(JBossDmrExtentions.asString(n, this.propertyKeys, NAME))).findFirst(); + if (first.isPresent()) { + return new Container(first.get(), this.propertyKeys); + } + } + return null; + } + + @Override + public Collection getContainers() { + ModelNode containers = get(SPEC_TEMPLATE_CONTAINERS); + if (containers.isDefined() && containers.getType() == ModelType.LIST) { + return containers.asList().stream().map(n -> new Container(n, this.propertyKeys)) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } + + @Override + public Map getTemplateLabels() { + return asMap(SPEC_TEMPLATE_LABELS); + } + + @Override + public void addTemplateLabel(String key, String value) { + ModelNode labels = get(SPEC_TEMPLATE_LABELS); + labels.get(key).set(value); + } + + @Override + public IContainer addContainer(DockerImageURI tag, Set containerPorts, Map envVars) { + return addContainer(tag.getName(), tag, containerPorts, envVars, new ArrayList()); + } + + @Override + public IContainer addContainer(String name, DockerImageURI tag, Set containerPorts, + Map envVars, List emptyDirVolumes) { + + IContainer container = addContainer(name); + container.setImage(tag); + + if (!emptyDirVolumes.isEmpty()) { + Set volumes = new HashSet<>(); + for (String path : emptyDirVolumes) { + VolumeMount volume = new VolumeMount(new ModelNode()); + volume.setMountPath(path); + volume.setName(String.format("%s-%s", name, emptyDirVolumes.indexOf(path) + 1)); + volumes.add(volume); + addEmptyDirVolumeToPodSpec(volume); + } + container.setVolumeMounts(volumes); + } + if (!containerPorts.isEmpty()) { + Set ports = new HashSet<>(); + for (IPort port : containerPorts) { + ports.add(new Port(new ModelNode(), port)); + } + container.setPorts(ports); + } + container.setEnvVars(envVars); + return container; + } + + @Override + public IContainer addContainer(String name) { + ModelNode containers = get(SPEC_TEMPLATE_CONTAINERS); + Container container = new Container(containers.add()); + container.setName(name); + return container; + } + + private boolean hasVolumeNamed(ModelNode volNode, String name) { + if (volNode.isDefined()) { + List podVolumes = volNode.asList(); + for (ModelNode node : podVolumes) { + if (name.equals(asString(node, NAME))) { + return true; + } + } + } + return false; + } + + private void addEmptyDirVolumeToPodSpec(VolumeMount volume) { + ModelNode volNode = get(VOLUMES); + if (hasVolumeNamed(volNode, volume.getName())) { + // already exists + return; + } + IEmptyDirVolumeSource volumeSource = new EmptyDirVolumeSource(volume.getName()); + volumeSource.setMedium(""); + addVolume(volumeSource); + } + + @Override + public void setContainers(Collection containers) { + ModelNode nodeContainers = get(SPEC_TEMPLATE_CONTAINERS); + nodeContainers.clear(); + if (containers != null) { + containers.forEach(c -> nodeContainers.add(ModelNode.fromJSONString(c.toJson()))); + } + } + + @Override + public Set getVolumes() { + ModelNode vol = get(VOLUMES); + Set volumes = new HashSet<>(); + if (vol.isDefined()) { + for (ModelNode node : vol.asList()) { + volumes.add(VolumeSource.create(node)); + } + } + return volumes; + } + + @Override + public void setVolumes(Set volumeSources) { + ModelNode vol = get(VOLUMES); + vol.clear(); + if (volumeSources != null) { + volumeSources.forEach(v -> vol.add(ModelNode.fromJSONString(v.toJSONString()))); + } + } + + @Override + public void addVolume(IVolumeSource volumeSource) { + ModelNode volList = get(VOLUMES); + if (hasVolumeNamed(volList, volumeSource.getName())) { + // already exists + return; + } + volList.add(ModelNode.fromJSONString(volumeSource.toJSONString())); + } @SuppressWarnings("unchecked") - @Override - public T addVolume(String volumetype, String name) { - ModelNode volList = get(VOLUMES); - ModelNode node = volList.add(); - node.get(volumetype).set(new ModelNode()); - IVolumeSource source = VolumeSource.create(node); - source.setName(name); - return (T) source; - } - - @Override + @Override + public T addVolume(String volumetype, String name) { + ModelNode volList = get(VOLUMES); + ModelNode node = volList.add(); + node.get(volumetype).set(new ModelNode()); + IVolumeSource source = VolumeSource.create(node); + source.setName(name); + return (T) source; + } + + @Override public void setServiceAccountName(String serviceAccountName) { set(SERVICEACCOUNTNAME, serviceAccountName); } diff --git a/src/main/java/com/openshift/internal/restclient/model/ResourceQuota.java b/src/main/java/com/openshift/internal/restclient/model/ResourceQuota.java index becdd904..2b05a589 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ResourceQuota.java +++ b/src/main/java/com/openshift/internal/restclient/model/ResourceQuota.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.Map; @@ -19,9 +20,8 @@ public class ResourceQuota extends KubernetesResource implements IResourceQuota { - public ResourceQuota(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public ResourceQuota(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/Route.java b/src/main/java/com/openshift/internal/restclient/model/Route.java index 642db566..0e605c88 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Route.java +++ b/src/main/java/com/openshift/internal/restclient/model/Route.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.Map; @@ -18,79 +19,75 @@ import com.openshift.restclient.model.route.ITLSConfig; import com.openshift.restclient.model.route.ITargetPort; -/** - * @author Jeff Cantrill - */ public class Route extends KubernetesResource implements IRoute { - - private static final String ROUTE_HOST = "spec.host"; - private static final String ROUTE_PATH = "spec.path"; - private static final String ROUTE_KIND = "spec.to.kind"; - private static final String ROUTE_SERVICE_NAME = "spec.to.name"; - private static final String ROUTE_TLS = "spec.tls"; - private static final String ROUTE_TLS_TERMINATION_TYPE = "spec.tls.termination"; - private static final String ROUTE_TLS_CERTIFICATE = "spec.tls.certificate"; - private static final String ROUTE_TLS_KEY = "spec.tls.key"; - private static final String ROUTE_TLS_CACERT = "spec.tls.caCertificate"; - private static final String ROUTE_TLS_DESTINATION_CACERT = "spec.tls.destinationCACertificate"; - private static final String ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY = "spec.tls.insecureEdgeTerminationPolicy"; - private static final String ROUTE_PORT = "spec.port"; - private static final String ROUTE_PORT_TARGETPORT = "spec.port.targetPort"; - - public Route(ModelNode node, IClient client, - Map propertyKeys) { - super(node, client, propertyKeys); - } - - @Override - public String getHost() { - return asString(ROUTE_HOST); - } - - @Override - public void setHost(String host) { - get(ROUTE_HOST).set(host); - } - - @Override - public String getPath() { - return asString(ROUTE_PATH); - } - - @Override - public void setPath(String path) { - get(ROUTE_PATH).set(path); - } - - @Override - public String getServiceName() { - return asString(ROUTE_SERVICE_NAME); - } - - @Override - public void setServiceName(String serviceName) { - get(ROUTE_SERVICE_NAME).set(serviceName); - get(ROUTE_KIND).set(ResourceKind.SERVICE); - } - - @Override - public ITLSConfig getTLSConfig() { - if(get(ROUTE_TLS).isDefined()){ - return new TLSConfig(); - } - return null; - } - - @Override - public ITLSConfig createTLSConfig() { - ITLSConfig config = getTLSConfig(); - if(config == null) { - get(ROUTE_TLS).set(new ModelNode()); - config = new TLSConfig(); - } - return config; - } - + + private static final String ROUTE_HOST = "spec.host"; + private static final String ROUTE_PATH = "spec.path"; + private static final String ROUTE_KIND = "spec.to.kind"; + private static final String ROUTE_SERVICE_NAME = "spec.to.name"; + private static final String ROUTE_TLS = "spec.tls"; + private static final String ROUTE_TLS_TERMINATION_TYPE = "spec.tls.termination"; + private static final String ROUTE_TLS_CERTIFICATE = "spec.tls.certificate"; + private static final String ROUTE_TLS_KEY = "spec.tls.key"; + private static final String ROUTE_TLS_CACERT = "spec.tls.caCertificate"; + private static final String ROUTE_TLS_DESTINATION_CACERT = "spec.tls.destinationCACertificate"; + private static final String ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY = "spec.tls.insecureEdgeTerminationPolicy"; + private static final String ROUTE_PORT = "spec.port"; + private static final String ROUTE_PORT_TARGETPORT = "spec.port.targetPort"; + + public Route(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } + + @Override + public String getHost() { + return asString(ROUTE_HOST); + } + + @Override + public void setHost(String host) { + get(ROUTE_HOST).set(host); + } + + @Override + public String getPath() { + return asString(ROUTE_PATH); + } + + @Override + public void setPath(String path) { + get(ROUTE_PATH).set(path); + } + + @Override + public String getServiceName() { + return asString(ROUTE_SERVICE_NAME); + } + + @Override + public void setServiceName(String serviceName) { + get(ROUTE_SERVICE_NAME).set(serviceName); + get(ROUTE_KIND).set(ResourceKind.SERVICE); + } + + @Override + public ITLSConfig getTLSConfig() { + if (get(ROUTE_TLS).isDefined()) { + return new TLSConfig(); + } + return null; + } + + @Override + public ITLSConfig createTLSConfig() { + ITLSConfig config = getTLSConfig(); + if (config == null) { + get(ROUTE_TLS).set(new ModelNode()); + config = new TLSConfig(); + } + return config; + } + @Override public ITargetPort getPort() { if (get(ROUTE_PORT).isDefined()) { @@ -110,81 +107,79 @@ public ITargetPort createPort() { } @Override - public String getURL() { - String scheme = getTLSConfig() == null ? "http" : "https"; - String path = getPath(); - if(!path.startsWith("/")) { - path = "/" + path; - } - return String.format("%s://%s%s", scheme, getHost(), path); - } - - - - private class TLSConfig implements ITLSConfig { - - @Override - public String getTerminationType() { - return asString(ROUTE_TLS_TERMINATION_TYPE); - } - - @Override - public void setTerminationType(String type) { - get(ROUTE_TLS_TERMINATION_TYPE).set(type); - } - - @Override - public String getCertificate() { - return asString(ROUTE_TLS_CERTIFICATE); - } - - @Override - public void setCertificate(String certificate) { - get(ROUTE_TLS_CERTIFICATE).set(certificate); - } - - @Override - public String getKey() { - return asString(ROUTE_TLS_KEY); - } - - @Override - public void setKey(String key) { - get(ROUTE_TLS_KEY).set(key); - } - - @Override - public String getCACertificate() { - return asString(ROUTE_TLS_CACERT); - } - - @Override - public void setCACertificate(String caCertificate) { - get(ROUTE_TLS_CACERT).set(caCertificate); - } - - @Override - public String getDestinationCertificate() { - return asString(ROUTE_TLS_DESTINATION_CACERT); - } - - @Override - public void setDestinationCertificate(String destinationCertificate) { - get(ROUTE_TLS_DESTINATION_CACERT).set(destinationCertificate); - } - - @Override - public String getInsecureEdgeTerminationPolicy() { - return asString(ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY); - } - - @Override - public void setInsecureEdgeTerminationPolicy(String insecureEdgeTerminationPolicy) { - get(ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY).set(insecureEdgeTerminationPolicy); - } - } - - private class TargetPort implements ITargetPort { + public String getURL() { + String scheme = getTLSConfig() == null ? "http" : "https"; + String path = getPath(); + if (!path.startsWith("/")) { + path = "/" + path; + } + return String.format("%s://%s%s", scheme, getHost(), path); + } + + private class TLSConfig implements ITLSConfig { + + @Override + public String getTerminationType() { + return asString(ROUTE_TLS_TERMINATION_TYPE); + } + + @Override + public void setTerminationType(String type) { + get(ROUTE_TLS_TERMINATION_TYPE).set(type); + } + + @Override + public String getCertificate() { + return asString(ROUTE_TLS_CERTIFICATE); + } + + @Override + public void setCertificate(String certificate) { + get(ROUTE_TLS_CERTIFICATE).set(certificate); + } + + @Override + public String getKey() { + return asString(ROUTE_TLS_KEY); + } + + @Override + public void setKey(String key) { + get(ROUTE_TLS_KEY).set(key); + } + + @Override + public String getCACertificate() { + return asString(ROUTE_TLS_CACERT); + } + + @Override + public void setCACertificate(String caCertificate) { + get(ROUTE_TLS_CACERT).set(caCertificate); + } + + @Override + public String getDestinationCertificate() { + return asString(ROUTE_TLS_DESTINATION_CACERT); + } + + @Override + public void setDestinationCertificate(String destinationCertificate) { + get(ROUTE_TLS_DESTINATION_CACERT).set(destinationCertificate); + } + + @Override + public String getInsecureEdgeTerminationPolicy() { + return asString(ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY); + } + + @Override + public void setInsecureEdgeTerminationPolicy(String insecureEdgeTerminationPolicy) { + get(ROUTE_TLS_INSECURE_EDGE_TERMINATION_POLICY).set(insecureEdgeTerminationPolicy); + } + } + + private class TargetPort implements ITargetPort { @Override public String getTargetPortName() { return asString(ROUTE_PORT_TARGETPORT); @@ -208,5 +203,5 @@ public Integer getTargetPort() { public void setTargetPort(Integer port) { get(ROUTE_PORT_TARGETPORT).set(port); } - } + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/Secret.java b/src/main/java/com/openshift/internal/restclient/model/Secret.java index fb3a2c76..3a176562 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Secret.java +++ b/src/main/java/com/openshift/internal/restclient/model/Secret.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.io.ByteArrayOutputStream; @@ -24,46 +25,44 @@ * @author Jiri Pechanec */ public class Secret extends KubernetesResource implements ISecret { - - private static final String SECRET_TYPE = "type"; - private static final String SECRET_DATA = "data"; + private static final String SECRET_TYPE = "type"; + private static final String SECRET_DATA = "data"; + + public Secret(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } - public Secret(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } + @Override + public void addData(String key, InputStream data) { + try { + ByteArrayOutputStream os = new ByteArrayOutputStream(); + IOUtils.copy(data, os); + addData(key, os.toByteArray()); + } catch (IOException e) { + throw new IllegalArgumentException("Could not process data stream", e); + } + } - @Override - public void addData(String key, InputStream data) { - try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); - IOUtils.copy(data, os); - addData(key, os.toByteArray()); - } - catch (IOException e) { - throw new IllegalArgumentException("Could not process data stream", e); - } - } + @Override + public void addData(final String key, final byte[] data) { + ModelNode dataNode = get(SECRET_DATA); + dataNode.get(key).set(Base64Coder.encode(data)); + } - @Override - public void addData(final String key, final byte[] data) { - ModelNode dataNode = get(SECRET_DATA); - dataNode.get(key).set(Base64Coder.encode(data)); - } + @Override + public byte[] getData(final String key) { + return Base64Coder.decodeBinary(asMap(SECRET_DATA).get(key)); + } - @Override - public byte[] getData(final String key) { - return Base64Coder.decodeBinary(asMap(SECRET_DATA).get(key)); - } + @Override + public void setType(final String type) { + get(SECRET_TYPE).set(type.toString()); + } - @Override - public void setType(final String type) { - get(SECRET_TYPE).set(type.toString()); - } + @Override + public String getType() { + return asString(SECRET_TYPE); + } - @Override - public String getType() { - return asString(SECRET_TYPE); - } - } diff --git a/src/main/java/com/openshift/internal/restclient/model/Service.java b/src/main/java/com/openshift/internal/restclient/model/Service.java index 6b28240b..0f9a3fce 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Service.java +++ b/src/main/java/com/openshift/internal/restclient/model/Service.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; @@ -25,139 +26,150 @@ import com.openshift.restclient.model.IService; import com.openshift.restclient.model.IServicePort; -/** - * @author Jeff Cantrill - */ public class Service extends KubernetesResource implements IService { + private static final String SERVICE_SELECTOR = "spec.selector"; + private static final String SERVICE_PORT = "spec.ports"; + + public Service(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + initializeCapabilities(getModifiableCapabilities(), this, getClient()); + } + + @Override + public void setPort(int port) { + IServicePort lowestPort = getLowestPort(); + if (lowestPort == null) { + lowestPort = addPort(0, 0); + } + lowestPort.setPort(port); + } + + public IServicePort addPort(int port, int targetPort) { + return addPort(port, targetPort, null); + } - private static final String SERVICE_SELECTOR = "spec.selector"; - private static final String SERVICE_PORT = "spec.ports"; - - public Service(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - initializeCapabilities(getModifiableCapabilities(), this, getClient()); - } - - @Override - public void setPort(int port){ - IServicePort lowestPort = getLowestPort(); - if(lowestPort == null) { - lowestPort = addPort(0,0); - } - lowestPort.setPort(port); - } - - public IServicePort addPort(int port, int targetPort) { - return addPort(port, targetPort, null); - } - - public IServicePort addPort(int port, int targetPort, String name) { + public IServicePort addPort(int port, int targetPort, String name) { ServicePort servicePort = new ServicePort(get(SERVICE_PORT).add()); - if(port > 0) servicePort.setPort(port); - if(targetPort >0) servicePort.setTargetPort(targetPort); - if(StringUtils.isNotEmpty(name)) servicePort.setName(name); + if (port > 0) { + servicePort.setPort(port); + } + if (targetPort > 0) { + servicePort.setTargetPort(targetPort); + } + if (StringUtils.isNotEmpty(name)) { + servicePort.setName(name); + } return servicePort; } - - @Override - public int getPort(){ - IServicePort port = getLowestPort(); - return port != null ? port.getPort() : 0; - } - - private IServicePort getLowestPort() { - List ports = getPorts(); - return ports.size() == 0 ? null : ports.get(0); - } - @Override - public List getPorts() { - return getPorts(false); - } - - private List getPorts(boolean modifiable) { - List ports = new ArrayList<>(); - if(!get(SERVICE_PORT).isDefined()) return ports; - for (ModelNode node : get(SERVICE_PORT).asList()) { - ports.add(new ServicePort(node)); - } - Collections.sort(ports, new Comparator() { - @Override - public int compare(IServicePort first, IServicePort second) { - Integer port0 = first.getPort(); - Integer port1 = second.getPort(); - return port0.compareTo(port1); - } - }); - return modifiable ? ports : Collections.unmodifiableList(ports); - } - - @Override - public void setPorts(List ports) { - ModelNode portspec = get(SERVICE_PORT).clear(); - for (IServicePort port : ports) { - new ServicePort(portspec.add(), port); - } - } - - @Override - public Map getSelector(){ - return asMap(SERVICE_SELECTOR); - } - - @Override - public void setSelector(Map selector) { - ModelNode node = new ModelNode(); - for (Map.Entry entry : selector.entrySet()) { - node.get(entry.getKey()).set(entry.getValue()); - } - get(SERVICE_SELECTOR).set(node); - } - - - @Override - public void setSelector(String key, String value) { - get(SERVICE_SELECTOR).get(key).set(value); - } - - @Override - public void setTargetPort(int port) { - IServicePort portspec = getLowestPort(); - if(portspec == null) { - portspec = addPort(0,0); - } - portspec.setTargetPort(port); - } - - @Override - public String getTargetPort() { - IServicePort port = getLowestPort(); - return port != null ? port.getTargetPort() : "0"; - } - - @Override @Deprecated - public String getPortalIP() { - String tmp = asString("spec.portalIP"); - if (StringUtils.isBlank(tmp)) { - tmp = getClusterIP(); - } - return tmp; - } - - @Override - public String getClusterIP() { - return asString("spec.clusterIP"); - } - - @Override - public List getPods() { - if(getClient() == null) return new ArrayList(); - return getClient().list(ResourceKind.POD, getNamespaceName(), getSelector()); - } - - @Override - public String getType() { return asString("spec.type"); } - - @Override - public void setType(String type) { set("spec.type", type); } + + @Override + public int getPort() { + IServicePort port = getLowestPort(); + return port != null ? port.getPort() : 0; + } + + private IServicePort getLowestPort() { + List ports = getPorts(); + return ports.size() == 0 ? null : ports.get(0); + } + + @Override + public List getPorts() { + return getPorts(false); + } + + private List getPorts(boolean modifiable) { + List ports = new ArrayList<>(); + if (!get(SERVICE_PORT).isDefined()) { + return ports; + } + for (ModelNode node : get(SERVICE_PORT).asList()) { + ports.add(new ServicePort(node)); + } + Collections.sort(ports, new Comparator() { + @Override + public int compare(IServicePort first, IServicePort second) { + Integer port0 = first.getPort(); + Integer port1 = second.getPort(); + return port0.compareTo(port1); + } + }); + return modifiable ? ports : Collections.unmodifiableList(ports); + } + + @Override + public void setPorts(List ports) { + ModelNode portspec = get(SERVICE_PORT).clear(); + for (IServicePort port : ports) { + new ServicePort(portspec.add(), port); + } + } + + @Override + public Map getSelector() { + return asMap(SERVICE_SELECTOR); + } + + @Override + public void setSelector(Map selector) { + ModelNode node = new ModelNode(); + for (Map.Entry entry : selector.entrySet()) { + node.get(entry.getKey()).set(entry.getValue()); + } + get(SERVICE_SELECTOR).set(node); + } + + @Override + public void setSelector(String key, String value) { + get(SERVICE_SELECTOR).get(key).set(value); + } + + @Override + public void setTargetPort(int port) { + IServicePort portspec = getLowestPort(); + if (portspec == null) { + portspec = addPort(0, 0); + } + portspec.setTargetPort(port); + } + + @Override + public String getTargetPort() { + IServicePort port = getLowestPort(); + return port != null ? port.getTargetPort() : "0"; + } + + @Override + @Deprecated + public String getPortalIP() { + String tmp = asString("spec.portalIP"); + if (StringUtils.isBlank(tmp)) { + tmp = getClusterIP(); + } + return tmp; + } + + @Override + public String getClusterIP() { + return asString("spec.clusterIP"); + } + + @Override + public List getPods() { + if (getClient() == null) { + return new ArrayList(); + } + return getClient().list(ResourceKind.POD, getNamespaceName(), getSelector()); + } + + @Override + public String getType() { + return asString("spec.type"); + } + + @Override + public void setType(String type) { + set("spec.type", type); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/ServiceAccount.java b/src/main/java/com/openshift/internal/restclient/model/ServiceAccount.java index 4a76a5ee..dbc69e86 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ServiceAccount.java +++ b/src/main/java/com/openshift/internal/restclient/model/ServiceAccount.java @@ -6,63 +6,67 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ -package com.openshift.internal.restclient.model; -import com.openshift.restclient.IClient; -import com.openshift.restclient.model.serviceaccount.IServiceAccount; -import org.jboss.dmr.ModelNode; -import org.jboss.dmr.ModelType; +package com.openshift.internal.restclient.model; import java.util.ArrayList; import java.util.Collection; import java.util.Map; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.serviceaccount.IServiceAccount; + /** * @author David Simansky | dsimansk@redhat.com */ public class ServiceAccount extends KubernetesResource implements IServiceAccount { - private static final String SERVICE_ACCOUNT_SECRETS = "secrets"; - private static final String SERVICE_ACCOUNT_IMAGE_PULL_SECRETS = "imagePullSecrets"; - - - public ServiceAccount(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } + private static final String SERVICE_ACCOUNT_SECRETS = "secrets"; + private static final String SERVICE_ACCOUNT_IMAGE_PULL_SECRETS = "imagePullSecrets"; - @Override - public Collection getSecrets() { - Collection secrets = new ArrayList<>(); - ModelNode node = get(SERVICE_ACCOUNT_SECRETS); - if(node.getType() != ModelType.LIST) return secrets; - for (ModelNode entry : node.asList()) { - secrets.add(asString(entry, NAME)); - } - return secrets; - } + public ServiceAccount(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } - @Override - public void addSecret(String secret) { - ModelNode secretNodeName = get(SERVICE_ACCOUNT_SECRETS).add(); - set(secretNodeName, NAME, secret); - } + @Override + public Collection getSecrets() { + Collection secrets = new ArrayList<>(); + ModelNode node = get(SERVICE_ACCOUNT_SECRETS); + if (node.getType() != ModelType.LIST) { + return secrets; + } + for (ModelNode entry : node.asList()) { + secrets.add(asString(entry, NAME)); + } + return secrets; + } - @Override - public Collection getImagePullSecrets() { - Collection secrets = new ArrayList<>(); - ModelNode node = get(SERVICE_ACCOUNT_IMAGE_PULL_SECRETS); - if(node.getType() != ModelType.LIST) return secrets; - for (ModelNode entry : node.asList()) { - secrets.add(asString(entry, NAME)); - } - return secrets; - } + @Override + public void addSecret(String secret) { + ModelNode secretNodeName = get(SERVICE_ACCOUNT_SECRETS).add(); + set(secretNodeName, NAME, secret); + } - @Override - public void addImagePullSecret(String imagePullSecret) { - ModelNode secretNodeName = get(SERVICE_ACCOUNT_IMAGE_PULL_SECRETS).add(); - set(secretNodeName, NAME, imagePullSecret); - } + @Override + public Collection getImagePullSecrets() { + Collection secrets = new ArrayList<>(); + ModelNode node = get(SERVICE_ACCOUNT_IMAGE_PULL_SECRETS); + if (node.getType() != ModelType.LIST) { + return secrets; + } + for (ModelNode entry : node.asList()) { + secrets.add(asString(entry, NAME)); + } + return secrets; + } + @Override + public void addImagePullSecret(String imagePullSecret) { + ModelNode secretNodeName = get(SERVICE_ACCOUNT_IMAGE_PULL_SECRETS).add(); + set(secretNodeName, NAME, imagePullSecret); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/ServicePort.java b/src/main/java/com/openshift/internal/restclient/model/ServicePort.java index 66717cb8..56ed35b1 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ServicePort.java +++ b/src/main/java/com/openshift/internal/restclient/model/ServicePort.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import static com.openshift.internal.util.JBossDmrExtentions.asInt; @@ -22,133 +23,139 @@ import com.openshift.restclient.model.IServicePort; -/** - * @author Jeff Cantrill - */ public class ServicePort extends ModelNodeAdapter implements IServicePort { - private static final String PROPERTY_NAME = "name"; - private static final String PROPERTY_PORT = "port"; - private static final String PROPERTY_PROTOCOL = "protocol"; - private static final String PROPERTY_TARGET_PORT = "targetPort"; - private static final Map KEY_MAP = new HashMap<>(); - - static { - KEY_MAP.put(PROPERTY_NAME, new String[] {PROPERTY_NAME}); - KEY_MAP.put(PROPERTY_PORT, new String[] {PROPERTY_PORT}); - KEY_MAP.put(PROPERTY_PROTOCOL, new String[] {PROPERTY_PROTOCOL}); - KEY_MAP.put(PROPERTY_TARGET_PORT, new String[] {PROPERTY_TARGET_PORT}); - } - - public ServicePort(ModelNode node) { - super(node, KEY_MAP); - } - - /** - * copy constructor - * @param the node to copy - * @param spec - */ - public ServicePort(ModelNode node, IServicePort port) { - this(node); - setName(port.getName()); - setPort(port.getPort()); - setProtocol(port.getProtocol()); - setTargetPort(port.getTargetPort()); - } - - @Override - public String getName() { - return asString(getNode(), KEY_MAP, PROPERTY_NAME); - } - - @Override - public void setName(String name) { - set(getNode(), KEY_MAP, PROPERTY_NAME, name); - } - - @Override - public String getTargetPort() { - return asString(getNode(), KEY_MAP, PROPERTY_TARGET_PORT); - } - - @Override - public void setTargetPort(int port) { - set(getNode(), KEY_MAP, PROPERTY_TARGET_PORT, port); - } - - @Override - public void setTargetPort(String name) { - if(StringUtils.isNumeric(name)) { - setTargetPort((Integer.parseInt(name))); - return; - } - set(getNode(), KEY_MAP, PROPERTY_TARGET_PORT, name); - } - - @Override - public void setPort(int port) { - set(getNode(), KEY_MAP, PROPERTY_PORT, port); - } - - @Override - public int getPort() { - return asInt(getNode(), KEY_MAP, PROPERTY_PORT); - } - - @Override - public String getProtocol() { - return asString(getNode(), KEY_MAP, PROPERTY_PROTOCOL); - } - - public void setProtocol(String proto) { - set(getNode(), KEY_MAP, PROPERTY_PROTOCOL, proto); - } - - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + getPort(); - result = prime * result + getTargetPort().hashCode(); - result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); - result = prime * result + ((getProtocol() == null) ? 0 : getProtocol().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ServicePort other = (ServicePort) obj; - if (getPort() != other.getPort()) - return false; - if (getTargetPort() == null) { - if (other.getTargetPort() != null) - return false; - } else if (!getTargetPort().equals(other.getTargetPort())) - return false; - if (getName() == null) { - if (other.getName() != null) - return false; - } else if (!getName().equals(other.getName())) - return false; - if (getProtocol() == null) { - if (other.getProtocol() != null) - return false; - } else if (!getProtocol().equals(other.getProtocol())) - return false; - return true; - } - - @Override - public String toString() { - return toJson(false); - } - - + private static final String PROPERTY_NAME = "name"; + private static final String PROPERTY_PORT = "port"; + private static final String PROPERTY_PROTOCOL = "protocol"; + private static final String PROPERTY_TARGET_PORT = "targetPort"; + private static final Map KEY_MAP = new HashMap<>(); + + static { + KEY_MAP.put(PROPERTY_NAME, new String[] { PROPERTY_NAME }); + KEY_MAP.put(PROPERTY_PORT, new String[] { PROPERTY_PORT }); + KEY_MAP.put(PROPERTY_PROTOCOL, new String[] { PROPERTY_PROTOCOL }); + KEY_MAP.put(PROPERTY_TARGET_PORT, new String[] { PROPERTY_TARGET_PORT }); + } + + public ServicePort(ModelNode node) { + super(node, KEY_MAP); + } + + /** + * copy constructor + * + * @param node the node to copy + * @param port the service ort + */ + public ServicePort(ModelNode node, IServicePort port) { + this(node); + setName(port.getName()); + setPort(port.getPort()); + setProtocol(port.getProtocol()); + setTargetPort(port.getTargetPort()); + } + + @Override + public String getName() { + return asString(getNode(), KEY_MAP, PROPERTY_NAME); + } + + @Override + public void setName(String name) { + set(getNode(), KEY_MAP, PROPERTY_NAME, name); + } + + @Override + public String getTargetPort() { + return asString(getNode(), KEY_MAP, PROPERTY_TARGET_PORT); + } + + @Override + public void setTargetPort(int port) { + set(getNode(), KEY_MAP, PROPERTY_TARGET_PORT, port); + } + + @Override + public void setTargetPort(String name) { + if (StringUtils.isNumeric(name)) { + setTargetPort((Integer.parseInt(name))); + return; + } + set(getNode(), KEY_MAP, PROPERTY_TARGET_PORT, name); + } + + @Override + public void setPort(int port) { + set(getNode(), KEY_MAP, PROPERTY_PORT, port); + } + + @Override + public int getPort() { + return asInt(getNode(), KEY_MAP, PROPERTY_PORT); + } + + @Override + public String getProtocol() { + return asString(getNode(), KEY_MAP, PROPERTY_PROTOCOL); + } + + public void setProtocol(String proto) { + set(getNode(), KEY_MAP, PROPERTY_PROTOCOL, proto); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + getPort(); + result = prime * result + getTargetPort().hashCode(); + result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); + result = prime * result + ((getProtocol() == null) ? 0 : getProtocol().hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ServicePort other = (ServicePort) obj; + if (getPort() != other.getPort()) { + return false; + } + if (getTargetPort() == null) { + if (other.getTargetPort() != null) { + return false; + } + } else if (!getTargetPort().equals(other.getTargetPort())) { + return false; + } + if (getName() == null) { + if (other.getName() != null) { + return false; + } + } else if (!getName().equals(other.getName())) { + return false; + } + if (getProtocol() == null) { + if (other.getProtocol() != null) { + return false; + } + } else if (!getProtocol().equals(other.getProtocol())) { + return false; + } + return true; + } + + @Override + public String toString() { + return toJson(false); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/Status.java b/src/main/java/com/openshift/internal/restclient/model/Status.java index 1dac6b37..3b59e45e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Status.java +++ b/src/main/java/com/openshift/internal/restclient/model/Status.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; import java.util.HashMap; @@ -16,45 +17,42 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.model.IStatus; -/** - * @author Jeff Cantrill - */ -public class Status extends KubernetesResource implements IStatus{ - - private static final String STATUS_MESSAGE = "message"; - private static final String STATUS_CODE = "code"; - private static final String STATUS_STATUS = "status"; - - public Status(String json) { - this(ModelNode.fromJSONString(json), null, new HashMap<>()); - } - - public Status(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } - - public String getMessage(){ - return asString(STATUS_MESSAGE); - } - - @Override - public int getCode() { - return asInt(STATUS_CODE); - } - - @Override - public String getStatus() { - return asString(STATUS_STATUS); - } - - @Override - public boolean isFailure() { - return FAILURE.equalsIgnoreCase(getStatus()); - } - - @Override - public boolean isSuccess() { - return SUCCESS.equalsIgnoreCase(getStatus()); - } +public class Status extends KubernetesResource implements IStatus { + + private static final String STATUS_MESSAGE = "message"; + private static final String STATUS_CODE = "code"; + private static final String STATUS_STATUS = "status"; + + public Status(String json) { + this(ModelNode.fromJSONString(json), null, new HashMap<>()); + } + + public Status(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } + + public String getMessage() { + return asString(STATUS_MESSAGE); + } + + @Override + public int getCode() { + return asInt(STATUS_CODE); + } + + @Override + public String getStatus() { + return asString(STATUS_STATUS); + } + + @Override + public boolean isFailure() { + return FAILURE.equalsIgnoreCase(getStatus()); + } + + @Override + public boolean isSuccess() { + return SUCCESS.equalsIgnoreCase(getStatus()); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/authorization/OpenshiftPolicy.java b/src/main/java/com/openshift/internal/restclient/model/authorization/OpenshiftPolicy.java index 9d804c71..e6ce92ce 100644 --- a/src/main/java/com/openshift/internal/restclient/model/authorization/OpenshiftPolicy.java +++ b/src/main/java/com/openshift/internal/restclient/model/authorization/OpenshiftPolicy.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.authorization; import java.util.Map; @@ -20,9 +21,8 @@ public class OpenshiftPolicy extends KubernetesResource implements IPolicy { - public OpenshiftPolicy(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public OpenshiftPolicy(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/authorization/OpenshiftRole.java b/src/main/java/com/openshift/internal/restclient/model/authorization/OpenshiftRole.java index e2e9c615..10b10f86 100644 --- a/src/main/java/com/openshift/internal/restclient/model/authorization/OpenshiftRole.java +++ b/src/main/java/com/openshift/internal/restclient/model/authorization/OpenshiftRole.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.authorization; import java.util.Map; @@ -20,9 +21,8 @@ public class OpenshiftRole extends KubernetesResource implements IRole { - public OpenshiftRole(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public OpenshiftRole(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/authorization/PolicyBinding.java b/src/main/java/com/openshift/internal/restclient/model/authorization/PolicyBinding.java index 957f997a..154b68bf 100644 --- a/src/main/java/com/openshift/internal/restclient/model/authorization/PolicyBinding.java +++ b/src/main/java/com/openshift/internal/restclient/model/authorization/PolicyBinding.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.authorization; import java.util.Map; @@ -20,9 +21,8 @@ public class PolicyBinding extends KubernetesResource implements IPolicyBinding { - public PolicyBinding(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public PolicyBinding(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/authorization/RoleBinding.java b/src/main/java/com/openshift/internal/restclient/model/authorization/RoleBinding.java index 73cfaad0..844ecd79 100644 --- a/src/main/java/com/openshift/internal/restclient/model/authorization/RoleBinding.java +++ b/src/main/java/com/openshift/internal/restclient/model/authorization/RoleBinding.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.authorization; import java.util.Collections; @@ -26,86 +27,86 @@ public class RoleBinding extends KubernetesResource implements IRoleBinding { - private static final String ROLE_REF = "roleRef"; - private static final String USER_NAMES = "userNames"; - private static final String GROUP_NAMES = "groupNames"; - - public RoleBinding(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } - - @Override - public void setUserNames(Set names) { - if(names == null) { - names = Collections.emptySet(); - } - set(USER_NAMES, names); - } - - @SuppressWarnings("unchecked") - @Override - public Set getUserNames() { - return asSet(USER_NAMES, ModelType.STRING); - } - - @Override - public void addUserName(String name) { - get(USER_NAMES).add(name); - } - - @Override - public void setGroupNames(Set names) { - if(names == null) { - names = Collections.emptySet(); - } - set(GROUP_NAMES, names); - - } - - @SuppressWarnings("unchecked") - @Override - public Set getGroupNames() { - return asSet(GROUP_NAMES, ModelType.STRING); - } - - @Override - public void addGroupName(String name) { - get(GROUP_NAMES).add(name); - } - - @Override - public void setSubjects(Set subjects) { - if(subjects == null) - subjects = Collections.emptySet(); - ModelNode node = get("subjects"); - node.clear(); - for (IObjectReference ref : subjects) { - node.add(ModelNode.fromJSONString(ref.toJson())); - } - } - - @Override - public Set getSubjects() { - Set set = new HashSet<>(); - ModelNode node = get("subjects"); - if(node.isDefined()) { - for (ModelNode ref : node.asList()) { - set.add(new ObjectReference(ref)); - } - } - return set; - } - - @Override - public IObjectReference getRoleRef() { - return new ObjectReference(get(ROLE_REF)); - } - - @Override - public void setRoleRef(IObjectReference roleRef) { - ModelNode node = get(ROLE_REF); - node.set(ModelNode.fromJSONString(roleRef.toJson())); - } - - + private static final String ROLE_REF = "roleRef"; + private static final String USER_NAMES = "userNames"; + private static final String GROUP_NAMES = "groupNames"; + + public RoleBinding(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } + + @Override + public void setUserNames(Set names) { + if (names == null) { + names = Collections.emptySet(); + } + set(USER_NAMES, names); + } + + @SuppressWarnings("unchecked") + @Override + public Set getUserNames() { + return asSet(USER_NAMES, ModelType.STRING); + } + + @Override + public void addUserName(String name) { + get(USER_NAMES).add(name); + } + + @Override + public void setGroupNames(Set names) { + if (names == null) { + names = Collections.emptySet(); + } + set(GROUP_NAMES, names); + + } + + @SuppressWarnings("unchecked") + @Override + public Set getGroupNames() { + return asSet(GROUP_NAMES, ModelType.STRING); + } + + @Override + public void addGroupName(String name) { + get(GROUP_NAMES).add(name); + } + + @Override + public void setSubjects(Set subjects) { + if (subjects == null) { + subjects = Collections.emptySet(); + } + ModelNode node = get("subjects"); + node.clear(); + for (IObjectReference ref : subjects) { + node.add(ModelNode.fromJSONString(ref.toJson())); + } + } + + @Override + public Set getSubjects() { + Set set = new HashSet<>(); + ModelNode node = get("subjects"); + if (node.isDefined()) { + for (ModelNode ref : node.asList()) { + set.add(new ObjectReference(ref)); + } + } + return set; + } + + @Override + public IObjectReference getRoleRef() { + return new ObjectReference(get(ROLE_REF)); + } + + @Override + public void setRoleRef(IObjectReference roleRef) { + ModelNode node = get(ROLE_REF); + node.set(ModelNode.fromJSONString(roleRef.toJson())); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java index 50a2cc27..03e4c58d 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.build; import java.util.List; @@ -29,268 +30,265 @@ /** * Impl of a builder to create buildconfigs - * @author jeff.cantrill * */ public class BuildConfigBuilder implements IBuildConfigBuilder { - - private SourceStrategyBuilder sourceStrategyBuilder; - private GitSourceBuilder gitSourceBuilder; - private JenkinsPipelineStrategyBuilder jenkinsPipelineStrategyBuilder; - private String imageStreamTagOutput; - private boolean buildOnConfigChange; - private boolean buildOnImageChange; - private boolean buildOnSourceChange; - private final IClient client; - private String name; - private String namespace; - private Map labels; - - public BuildConfigBuilder(IClient client) { - this.client = client; - } - - @Override - public boolean isSupported() { - return true; - } - - @Override - public String getName() { - return BuildConfigBuilder.class.getSimpleName(); - } - - @Override - public IBuildConfigBuilder named(String name) { - this.name = name; - return this; - } - - @Override - public IBuildConfigBuilder inNamespace(String namespace) { - this.namespace = namespace; - return this; - } - - @Override - public IBuildConfigBuilder withLabels(Map labels) { - this.labels = labels; - return this; - } - - @Override - public IBuildConfig build() { - BuildConfig bc = client.getResourceFactory().stub(ResourceKind.BUILD_CONFIG, this.name, this.namespace); - - if(sourceStrategyBuilder != null) { - bc.setBuildStrategy(sourceStrategyBuilder.build(bc.getPropertyKeys())); - } else if (jenkinsPipelineStrategyBuilder != null) { - bc.setBuildStrategy(jenkinsPipelineStrategyBuilder.build(bc.getPropertyKeys())); - } - - if(gitSourceBuilder != null) { - bc.setBuildSource(gitSourceBuilder.build()); - } - - if (labels != null && !labels.isEmpty()) { - for (Map.Entry label : labels.entrySet()) { - bc.addLabel(label.getKey(), label.getValue()); - } - } - - DockerImageURI uri = new DockerImageURI(imageStreamTagOutput); - IObjectReference outRef = bc.getBuildOutputReference(); - outRef.setKind(ResourceKind.IMAGE_STREAM_TAG); - outRef.setName(uri.getNameAndTag()); - if(StringUtils.isNotBlank(uri.getUserName())) { - outRef.setNamespace(uri.getUserName()); - } - - bc.addBuildTrigger(new WebhookTrigger(BuildTriggerType.GENERIC, UUID.randomUUID().toString(), null)); - if(buildOnImageChange) { - bc.addBuildTrigger(new ImageChangeTrigger(BuildTriggerType.IMAGE_CHANGE, null, null, null)); - } - if(buildOnConfigChange) { - bc.addBuildTrigger(new ImageChangeTrigger(BuildTriggerType.CONFIG_CHANGE,null, null, null)); - } - if(buildOnSourceChange) { - bc.addBuildTrigger(new WebhookTrigger(BuildTriggerType.GITHUB, UUID.randomUUID().toString(), null)); - } - - return bc; - } - - @Override - public IBuildConfigBuilder buildOnSourceChange(boolean onSourceChange) { - this.buildOnSourceChange = onSourceChange; - return this; - } - - @Override - public IBuildConfigBuilder buildOnImageChange(boolean onImageChange) { - this.buildOnImageChange = onImageChange; - return this; - } - - @Override - public IBuildConfigBuilder buildOnConfigChange(boolean onConfigChange) { - this.buildOnConfigChange = onConfigChange; - return this; - } - - @Override - public IBuildConfigBuilder toImageStreamTag(String tag) { - imageStreamTagOutput = tag; - return this; - } - - @Override - public ISourceStrategyBuilder usingSourceStrategy() { - sourceStrategyBuilder = new SourceStrategyBuilder(this); - return sourceStrategyBuilder; - } - - @Override - public IGitSourceBuilder fromGitSource() { - gitSourceBuilder = new GitSourceBuilder(this); - return gitSourceBuilder; - } - - @Override - public IJenkinsPipelineStrategyBuilder usingJenkinsPipelineStrategy() { - jenkinsPipelineStrategyBuilder = new JenkinsPipelineStrategyBuilder(this); - return jenkinsPipelineStrategyBuilder; - } - - class GitSourceBuilder implements IGitSourceBuilder { - - private IBuildConfigBuilder builder; - private String url; - private String ref; - private String contextDir; - - GitSourceBuilder(IBuildConfigBuilder builder){ - this.builder = builder; - } - - private GitBuildSource build() { - return new GitBuildSource(url, ref, contextDir); - } - - @Override - public IBuildConfigBuilder end() { - return builder; - } - - @Override - public IGitSourceBuilder fromGitUrl(String url) { - this.url = url; - return this; - } - - @Override - public IGitSourceBuilder usingGitReference(String ref) { - this.ref = ref; - return this; - } - - @Override - public IGitSourceBuilder inContextDir(String contextDir) { - this.contextDir = contextDir; - return this; - } - - } - - - class SourceStrategyBuilder implements ISourceStrategyBuilder{ - - private IBuildConfigBuilder builder; - private List envVars; - private String namespace; - private String tag; - private String fromKind; - - SourceStrategyBuilder(IBuildConfigBuilder builder){ - this.builder = builder; - } - - public SourceBuildStrategy build(Map overrides) { - SourceBuildStrategy strategy = new SourceBuildStrategy(new ModelNode(), overrides); - strategy.setEnvVars(envVars); - strategy.setFromNamespace(namespace); - strategy.setImage(new DockerImageURI(tag)); - strategy.setFromKind(fromKind); - return strategy; - } - - @Override - public IBuildConfigBuilder end() { - return builder; - } - - @Override - public ISourceStrategyBuilder fromImageStreamTag(String tag) { - this.tag = tag; - this.fromKind = ResourceKind.IMAGE_STREAM_TAG; - return this; - } - - @Override - public ISourceStrategyBuilder inNamespace(String namespace) { - this.namespace = namespace; - return this; - } - - - @Override - public ISourceStrategyBuilder withEnvVars(List envVars) { - this.envVars = envVars; - return this; - } - - @Override - public ISourceStrategyBuilder fromDockerImage(String tag) { - this.tag = tag; - this.fromKind = "DockerImage"; - return this; - } - } - - class JenkinsPipelineStrategyBuilder implements IJenkinsPipelineStrategyBuilder { - - private IBuildConfigBuilder builder; - private String jenkinsFilePath; - private String jenkinsFile; - - JenkinsPipelineStrategyBuilder(IBuildConfigBuilder builder){ - this.builder = builder; - } - - @Override - public IJenkinsPipelineStrategyBuilder usingFile(String file) { - this.jenkinsFile = file; - return this; - } - - @Override - public IJenkinsPipelineStrategyBuilder usingFilePath(String filePath) { - this.jenkinsFilePath = filePath; - return this; - } - - private JenkinsPipelineStrategy build(Map overrides) { - JenkinsPipelineStrategy strategy = new JenkinsPipelineStrategy(new ModelNode(), overrides); - strategy.setJenkinsfilePath(jenkinsFilePath); - strategy.setJenkinsfile(jenkinsFile); - return strategy; - } - - @Override - public IBuildConfigBuilder end() { - return builder; - } - - } - + + private SourceStrategyBuilder sourceStrategyBuilder; + private GitSourceBuilder gitSourceBuilder; + private JenkinsPipelineStrategyBuilder jenkinsPipelineStrategyBuilder; + private String imageStreamTagOutput; + private boolean buildOnConfigChange; + private boolean buildOnImageChange; + private boolean buildOnSourceChange; + private final IClient client; + private String name; + private String namespace; + private Map labels; + + public BuildConfigBuilder(IClient client) { + this.client = client; + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return BuildConfigBuilder.class.getSimpleName(); + } + + @Override + public IBuildConfigBuilder named(String name) { + this.name = name; + return this; + } + + @Override + public IBuildConfigBuilder inNamespace(String namespace) { + this.namespace = namespace; + return this; + } + + @Override + public IBuildConfigBuilder withLabels(Map labels) { + this.labels = labels; + return this; + } + + @Override + public IBuildConfig build() { + BuildConfig bc = client.getResourceFactory().stub(ResourceKind.BUILD_CONFIG, this.name, this.namespace); + + if (sourceStrategyBuilder != null) { + bc.setBuildStrategy(sourceStrategyBuilder.build(bc.getPropertyKeys())); + } else if (jenkinsPipelineStrategyBuilder != null) { + bc.setBuildStrategy(jenkinsPipelineStrategyBuilder.build(bc.getPropertyKeys())); + } + + if (gitSourceBuilder != null) { + bc.setBuildSource(gitSourceBuilder.build()); + } + + if (labels != null && !labels.isEmpty()) { + for (Map.Entry label : labels.entrySet()) { + bc.addLabel(label.getKey(), label.getValue()); + } + } + + DockerImageURI uri = new DockerImageURI(imageStreamTagOutput); + IObjectReference outRef = bc.getBuildOutputReference(); + outRef.setKind(ResourceKind.IMAGE_STREAM_TAG); + outRef.setName(uri.getNameAndTag()); + if (StringUtils.isNotBlank(uri.getUserName())) { + outRef.setNamespace(uri.getUserName()); + } + + bc.addBuildTrigger(new WebhookTrigger(BuildTriggerType.GENERIC, UUID.randomUUID().toString(), null)); + if (buildOnImageChange) { + bc.addBuildTrigger(new ImageChangeTrigger(BuildTriggerType.IMAGE_CHANGE, null, null, null)); + } + if (buildOnConfigChange) { + bc.addBuildTrigger(new ImageChangeTrigger(BuildTriggerType.CONFIG_CHANGE, null, null, null)); + } + if (buildOnSourceChange) { + bc.addBuildTrigger(new WebhookTrigger(BuildTriggerType.GITHUB, UUID.randomUUID().toString(), null)); + } + + return bc; + } + + @Override + public IBuildConfigBuilder buildOnSourceChange(boolean onSourceChange) { + this.buildOnSourceChange = onSourceChange; + return this; + } + + @Override + public IBuildConfigBuilder buildOnImageChange(boolean onImageChange) { + this.buildOnImageChange = onImageChange; + return this; + } + + @Override + public IBuildConfigBuilder buildOnConfigChange(boolean onConfigChange) { + this.buildOnConfigChange = onConfigChange; + return this; + } + + @Override + public IBuildConfigBuilder toImageStreamTag(String tag) { + imageStreamTagOutput = tag; + return this; + } + + @Override + public ISourceStrategyBuilder usingSourceStrategy() { + sourceStrategyBuilder = new SourceStrategyBuilder(this); + return sourceStrategyBuilder; + } + + @Override + public IGitSourceBuilder fromGitSource() { + gitSourceBuilder = new GitSourceBuilder(this); + return gitSourceBuilder; + } + + @Override + public IJenkinsPipelineStrategyBuilder usingJenkinsPipelineStrategy() { + jenkinsPipelineStrategyBuilder = new JenkinsPipelineStrategyBuilder(this); + return jenkinsPipelineStrategyBuilder; + } + + class GitSourceBuilder implements IGitSourceBuilder { + + private IBuildConfigBuilder builder; + private String url; + private String ref; + private String contextDir; + + GitSourceBuilder(IBuildConfigBuilder builder) { + this.builder = builder; + } + + private GitBuildSource build() { + return new GitBuildSource(url, ref, contextDir); + } + + @Override + public IBuildConfigBuilder end() { + return builder; + } + + @Override + public IGitSourceBuilder fromGitUrl(String url) { + this.url = url; + return this; + } + + @Override + public IGitSourceBuilder usingGitReference(String ref) { + this.ref = ref; + return this; + } + + @Override + public IGitSourceBuilder inContextDir(String contextDir) { + this.contextDir = contextDir; + return this; + } + + } + + class SourceStrategyBuilder implements ISourceStrategyBuilder { + + private IBuildConfigBuilder builder; + private List envVars; + private String namespace; + private String tag; + private String fromKind; + + SourceStrategyBuilder(IBuildConfigBuilder builder) { + this.builder = builder; + } + + public SourceBuildStrategy build(Map overrides) { + SourceBuildStrategy strategy = new SourceBuildStrategy(new ModelNode(), overrides); + strategy.setEnvVars(envVars); + strategy.setFromNamespace(namespace); + strategy.setImage(new DockerImageURI(tag)); + strategy.setFromKind(fromKind); + return strategy; + } + + @Override + public IBuildConfigBuilder end() { + return builder; + } + + @Override + public ISourceStrategyBuilder fromImageStreamTag(String tag) { + this.tag = tag; + this.fromKind = ResourceKind.IMAGE_STREAM_TAG; + return this; + } + + @Override + public ISourceStrategyBuilder inNamespace(String namespace) { + this.namespace = namespace; + return this; + } + + @Override + public ISourceStrategyBuilder withEnvVars(List envVars) { + this.envVars = envVars; + return this; + } + + @Override + public ISourceStrategyBuilder fromDockerImage(String tag) { + this.tag = tag; + this.fromKind = "DockerImage"; + return this; + } + } + + class JenkinsPipelineStrategyBuilder implements IJenkinsPipelineStrategyBuilder { + + private IBuildConfigBuilder builder; + private String jenkinsFilePath; + private String jenkinsFile; + + JenkinsPipelineStrategyBuilder(IBuildConfigBuilder builder) { + this.builder = builder; + } + + @Override + public IJenkinsPipelineStrategyBuilder usingFile(String file) { + this.jenkinsFile = file; + return this; + } + + @Override + public IJenkinsPipelineStrategyBuilder usingFilePath(String filePath) { + this.jenkinsFilePath = filePath; + return this; + } + + private JenkinsPipelineStrategy build(Map overrides) { + JenkinsPipelineStrategy strategy = new JenkinsPipelineStrategy(new ModelNode(), overrides); + strategy.setJenkinsfilePath(jenkinsFilePath); + strategy.setJenkinsfile(jenkinsFile); + return strategy; + } + + @Override + public IBuildConfigBuilder end() { + return builder; + } + + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java index 8a541e02..076b9a21 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildRequest.java @@ -8,77 +8,69 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.model.build; -import com.openshift.internal.restclient.model.KubernetesResource; -import com.openshift.restclient.IClient; -import com.openshift.restclient.model.build.IBuildRequest; -import org.jboss.dmr.ModelNode; +package com.openshift.internal.restclient.model.build; import java.util.ArrayList; import java.util.List; import java.util.Map; -/** - * - * @author Jeff Cantrill - * - */ -public class BuildRequest extends KubernetesResource implements IBuildRequest{ - - private static final String COMMIT = "commit"; - private static final String GIT = "git"; - private static final String BIGGIT = "Git"; - private static final String TYPE = "type"; - private static final String REVISION = "revision"; - private static final String REVISION_GIT_COMMIT = REVISION + "." + GIT + "." + COMMIT; - private static final String REVISION_TYPE = REVISION + "." + TYPE; - private static final String TRIGGERED_BY = "triggeredBy"; - private static final String MESSAGE = "message"; - private static final String ENV = "env"; - - - public BuildRequest(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } - - - @Override - public void setCommitId(String commitId) { - set(REVISION_TYPE, BIGGIT); - set(REVISION_GIT_COMMIT, commitId); - } - - - @Override - public void addBuildCause(String cause) { - ModelNode triggeredBys = get(TRIGGERED_BY); - triggeredBys.add(MESSAGE, cause); - } - - - @Override - public String getCommitId() { - return get(REVISION_GIT_COMMIT).asString(); - } - +import org.jboss.dmr.ModelNode; - @Override - public List getBuildCauses() { - List causes = get(TRIGGERED_BY).asList(); - ArrayList ret = new ArrayList<>(); - for (ModelNode cause : causes) { - ret.add(cause.asString()); - } - return ret; - } +import com.openshift.internal.restclient.model.KubernetesResource; +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.build.IBuildRequest; - @Override - public void setEnvironmentVariable(String name, String value) { - ModelNode envs = get(ENV); - ModelNode entry = envs.add(); - entry.get(NAME).set(name); - entry.get(VALUE).set(value); - } +public class BuildRequest extends KubernetesResource implements IBuildRequest { + + private static final String COMMIT = "commit"; + private static final String GIT = "git"; + private static final String BIGGIT = "Git"; + private static final String TYPE = "type"; + private static final String REVISION = "revision"; + private static final String REVISION_GIT_COMMIT = REVISION + "." + GIT + "." + COMMIT; + private static final String REVISION_TYPE = REVISION + "." + TYPE; + private static final String TRIGGERED_BY = "triggeredBy"; + private static final String MESSAGE = "message"; + private static final String ENV = "env"; + + public BuildRequest(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } + + @Override + public void setCommitId(String commitId) { + set(REVISION_TYPE, BIGGIT); + set(REVISION_GIT_COMMIT, commitId); + } + + @Override + public void addBuildCause(String cause) { + ModelNode triggeredBys = get(TRIGGERED_BY); + triggeredBys.add(MESSAGE, cause); + } + + @Override + public String getCommitId() { + return get(REVISION_GIT_COMMIT).asString(); + } + + @Override + public List getBuildCauses() { + List causes = get(TRIGGERED_BY).asList(); + ArrayList ret = new ArrayList<>(); + for (ModelNode cause : causes) { + ret.add(cause.asString()); + } + return ret; + } + + @Override + public void setEnvironmentVariable(String name, String value) { + ModelNode envs = get(ENV); + ModelNode entry = envs.add(); + entry.get(NAME).set(name); + entry.get(VALUE).set(value); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildStatus.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildStatus.java index 226c731b..78b4bdcc 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildStatus.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildStatus.java @@ -8,9 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.build; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.get; + import java.util.Map; import org.jboss.dmr.ModelNode; @@ -21,33 +24,32 @@ public class BuildStatus extends ModelNodeAdapter implements IBuildStatus { - public BuildStatus(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - } - - @Override - public String getPhase() { - return asString(getNode(), getPropertyKeys(), "phase"); - } - - @Override - public String getStartTime() { - return asString(getNode(), getPropertyKeys(), "startTimestamp"); - } - - @Override - public long getDuration() { - ModelNode node = get(getNode(), getPropertyKeys(), "duration"); - if(!node.isDefined()) { - return 0L; - } - return node.asLong(); - } - - @Override - public DockerImageURI getOutputDockerImage() { - return new DockerImageURI(asString(getNode(), getPropertyKeys(), "outputDockerImageReference")); - } - - + public BuildStatus(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public String getPhase() { + return asString(getNode(), getPropertyKeys(), "phase"); + } + + @Override + public String getStartTime() { + return asString(getNode(), getPropertyKeys(), "startTimestamp"); + } + + @Override + public long getDuration() { + ModelNode node = get(getNode(), getPropertyKeys(), "duration"); + if (!node.isDefined()) { + return 0L; + } + return node.asLong(); + } + + @Override + public DockerImageURI getOutputDockerImage() { + return new DockerImageURI(asString(getNode(), getPropertyKeys(), "outputDockerImageReference")); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/CustomBuildStrategy.java b/src/main/java/com/openshift/internal/restclient/model/build/CustomBuildStrategy.java index bfe04f49..d739f0c3 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/CustomBuildStrategy.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/CustomBuildStrategy.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; import java.util.Map; @@ -14,38 +15,36 @@ import com.openshift.restclient.model.build.BuildStrategyType; import com.openshift.restclient.model.build.ICustomBuildStrategy; -/** - * @author Jeff Cantrill - */ public class CustomBuildStrategy implements ICustomBuildStrategy { - private DockerImageURI image; - private boolean exposeDockerSocket; - private Map env; - - public CustomBuildStrategy(String image, boolean exposeDockerSocket, Map env){ - this.image = new DockerImageURI(image); - this.exposeDockerSocket = exposeDockerSocket; - this.env = env; - } - @Override - public String getType() { - return BuildStrategyType.CUSTOM; - } - - @Override - public Map getEnvironmentVariables() { - return env; - } - - @Override - public boolean exposeDockerSocket() { - return exposeDockerSocket; - } - - @Override - public DockerImageURI getImage() { - return image; - } + private DockerImageURI image; + private boolean exposeDockerSocket; + private Map env; + + public CustomBuildStrategy(String image, boolean exposeDockerSocket, Map env) { + this.image = new DockerImageURI(image); + this.exposeDockerSocket = exposeDockerSocket; + this.env = env; + } + + @Override + public String getType() { + return BuildStrategyType.CUSTOM; + } + + @Override + public Map getEnvironmentVariables() { + return env; + } + + @Override + public boolean exposeDockerSocket() { + return exposeDockerSocket; + } + + @Override + public DockerImageURI getImage() { + return image; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/DockerBuildStrategy.java b/src/main/java/com/openshift/internal/restclient/model/build/DockerBuildStrategy.java index 35c9f16e..ae958756 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/DockerBuildStrategy.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/DockerBuildStrategy.java @@ -6,46 +6,43 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.build.BuildStrategyType; import com.openshift.restclient.model.build.IDockerBuildStrategy; -/** - * @author Jeff Cantrill - */ public class DockerBuildStrategy implements IDockerBuildStrategy { - private boolean noCache; - private DockerImageURI image; - private String contextDir; - - public DockerBuildStrategy(String contextDir, boolean noCache, - String baseImage) { - this.contextDir = contextDir; - this.noCache = noCache; - this.image = new DockerImageURI(baseImage); - } - - @Override - public String getType() { - return BuildStrategyType.DOCKER; - } - - @Override - public String getContextDir() { - return contextDir; - } - - @Override - public boolean isNoCache() { - return noCache; - } - - @Override - public DockerImageURI getBaseImage() { - return image; - } + private boolean noCache; + private DockerImageURI image; + private String contextDir; + + public DockerBuildStrategy(String contextDir, boolean noCache, String baseImage) { + this.contextDir = contextDir; + this.noCache = noCache; + this.image = new DockerImageURI(baseImage); + } + + @Override + public String getType() { + return BuildStrategyType.DOCKER; + } + + @Override + public String getContextDir() { + return contextDir; + } + + @Override + public boolean isNoCache() { + return noCache; + } + + @Override + public DockerImageURI getBaseImage() { + return image; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/GitBuildSource.java b/src/main/java/com/openshift/internal/restclient/model/build/GitBuildSource.java index 8f02adc3..083a8228 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/GitBuildSource.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/GitBuildSource.java @@ -6,56 +6,54 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; import com.openshift.restclient.model.build.BuildSourceType; import com.openshift.restclient.model.build.IGitBuildSource; -/** - * @author Jeff Cantrill - */ public class GitBuildSource implements IGitBuildSource { - private String ref; - private String uri; - private String contextDir; - - public GitBuildSource(String uri, String ref, String contextDir){ - this.ref = ref; - this.uri = uri; - this.contextDir = contextDir; - } - - @Override - public String getType() { - return BuildSourceType.GIT; - } - - @Override - public String getURI() { - return uri; - } - - public void setURI(String uri) { - this.uri = uri; - } - - @Override - public String getRef() { - return ref; - } - - public void setRef(String ref) { - this.ref = ref; - } - - @Override - public String getContextDir() { - return contextDir; - } - - public void setContextDir(String contextDir) { - this.contextDir = contextDir; - } + private String ref; + private String uri; + private String contextDir; + + public GitBuildSource(String uri, String ref, String contextDir) { + this.ref = ref; + this.uri = uri; + this.contextDir = contextDir; + } + + @Override + public String getType() { + return BuildSourceType.GIT; + } + + @Override + public String getURI() { + return uri; + } + + public void setURI(String uri) { + this.uri = uri; + } + + @Override + public String getRef() { + return ref; + } + + public void setRef(String ref) { + this.ref = ref; + } + + @Override + public String getContextDir() { + return contextDir; + } + + public void setContextDir(String contextDir) { + this.contextDir = contextDir; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/ImageChangeTrigger.java b/src/main/java/com/openshift/internal/restclient/model/build/ImageChangeTrigger.java index 1d2c878c..6eee76ff 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/ImageChangeTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/ImageChangeTrigger.java @@ -6,89 +6,97 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; import static org.apache.commons.lang.StringUtils.isNotBlank; + import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.build.BuildTriggerType; import com.openshift.restclient.model.build.IImageChangeTrigger; -/** - * @author Jeff Cantrill - */ public class ImageChangeTrigger implements IImageChangeTrigger { - private String tag; - private DockerImageURI image; - private DockerImageURI from; - private final String type; + private String tag; + private DockerImageURI image; + private DockerImageURI from; + private final String type; + + public ImageChangeTrigger(String image, String from, String tag) { + this(BuildTriggerType.IMAGE_CHANGE, image, from, tag); + } + + public ImageChangeTrigger(String type, String image, String from, String tag) { + this.type = type; + this.tag = tag; + this.image = isNotBlank(image) ? new DockerImageURI(image) : null; + this.from = isNotBlank(from) ? new DockerImageURI(from) : null; + } - public ImageChangeTrigger(String image, String from, String tag) { - this(BuildTriggerType.IMAGE_CHANGE, image, from, tag); - } - - public ImageChangeTrigger(String type, String image, String from, String tag) { - this.type = type; - this.tag = tag; - this.image = isNotBlank(image) ? new DockerImageURI(image) : null; - this.from = isNotBlank(from) ? new DockerImageURI(from) : null; - } + @Override + public String getType() { + return type; + } - @Override - public String getType() { - return type; - } + @Override + public DockerImageURI getImage() { + return image; + } - @Override - public DockerImageURI getImage() { - return image; - } + @Override + public DockerImageURI getFrom() { + return from; + } - @Override - public DockerImageURI getFrom() { - return from; - } + @Override + public String getTag() { + return this.tag; + } - @Override - public String getTag() { - return this.tag; - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((from == null) ? 0 : from.hashCode()); + result = prime * result + ((image == null) ? 0 : image.hashCode()); + result = prime * result + ((tag == null) ? 0 : tag.hashCode()); + return result; + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((from == null) ? 0 : from.hashCode()); - result = prime * result + ((image == null) ? 0 : image.hashCode()); - result = prime * result + ((tag == null) ? 0 : tag.hashCode()); - return result; - } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ImageChangeTrigger other = (ImageChangeTrigger) obj; + if (from == null) { + if (other.from != null) { + return false; + } + } else if (!from.equals(other.from)) { + return false; + } + if (image == null) { + if (other.image != null) { + return false; + } + } else if (!image.equals(other.image)) { + return false; + } + if (tag == null) { + if (other.tag != null) { + return false; + } + } else if (!tag.equals(other.tag)) { + return false; + } + return true; + } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ImageChangeTrigger other = (ImageChangeTrigger) obj; - if (from == null) { - if (other.from != null) - return false; - } else if (!from.equals(other.from)) - return false; - if (image == null) { - if (other.image != null) - return false; - } else if (!image.equals(other.image)) - return false; - if (tag == null) { - if (other.tag != null) - return false; - } else if (!tag.equals(other.tag)) - return false; - return true; - } - } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java b/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java index 6e3fe82a..434a7404 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/JenkinsPipelineStrategy.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.build; import static com.openshift.internal.util.JBossDmrExtentions.asString; @@ -31,60 +32,59 @@ /** * @author Andre Dietisheim */ -public class JenkinsPipelineStrategy extends ModelNodeAdapter implements IJenkinsPipelineStrategy, ResourcePropertyKeys { +public class JenkinsPipelineStrategy extends ModelNodeAdapter + implements IJenkinsPipelineStrategy, ResourcePropertyKeys { + + public JenkinsPipelineStrategy(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + set(node, propertyKeys, TYPE, BuildStrategyType.JENKINS_PIPELINE); + } - public JenkinsPipelineStrategy(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - set(node, propertyKeys, TYPE, BuildStrategyType.JENKINS_PIPELINE); - } + @Override + public String getType() { + return asString(getNode(), getPropertyKeys(), TYPE); + } - @Override - public String getType() { - return asString(getNode(), getPropertyKeys(), TYPE); - } + @Override + public void setJenkinsfilePath(String filePath) { + set(getNode(), getPropertyKeys(), JENKINS_FILE_PATH, filePath); + } - @Override - public void setJenkinsfilePath(String filePath) { - set(getNode(),getPropertyKeys(), JENKINS_FILE_PATH, filePath); - } + @Override + public String getJenkinsfilePath() { + return asString(getNode(), getPropertyKeys(), JENKINS_FILE_PATH); + } - @Override - public String getJenkinsfilePath() { - return asString(getNode(), getPropertyKeys(), JENKINS_FILE_PATH); - } + @Override + public void setJenkinsfile(String file) { + set(getNode(), getPropertyKeys(), JENKINS_FILE, file); + } - @Override - public void setJenkinsfile(String file) { - set(getNode(),getPropertyKeys(), JENKINS_FILE, file); - } + @Override + public String getJenkinsfile() { + return asString(getNode(), getPropertyKeys(), JENKINS_FILE); + } - @Override - public String getJenkinsfile() { - return asString(getNode(), getPropertyKeys(), JENKINS_FILE); - } - - @Override - public Collection getEnvVars() { - String [] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); - ModelNode envNode = getNode().get(path); - if (envNode.isDefined()) { - return envNode.asList() - .stream() - .map(n -> new EnvironmentVariable(n, getPropertyKeys())) - .collect(Collectors.toList()); - } - return Collections.emptyList(); - } + @Override + public Collection getEnvVars() { + String[] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); + ModelNode envNode = getNode().get(path); + if (envNode.isDefined()) { + return envNode.asList().stream().map(n -> new EnvironmentVariable(n, getPropertyKeys())) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } - @Override - public void setEnvVars(Collection envVars) { - if (envVars == null) { - return; - } - String [] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); - ModelNode envNode = getNode().get(path); - envNode.clear(); - envVars.forEach(v->envNode.add(ModelNode.fromJSONString(v.toJson()))); - } + @Override + public void setEnvVars(Collection envVars) { + if (envVars == null) { + return; + } + String[] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); + ModelNode envNode = getNode().get(path); + envNode.clear(); + envVars.forEach(v -> envNode.add(ModelNode.fromJSONString(v.toJson()))); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/STIBuildStrategy.java b/src/main/java/com/openshift/internal/restclient/model/build/STIBuildStrategy.java index 97d884fc..dc394e84 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/STIBuildStrategy.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/STIBuildStrategy.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; import java.util.Map; @@ -14,52 +15,49 @@ import com.openshift.restclient.model.build.BuildStrategyType; import com.openshift.restclient.model.build.ISTIBuildStrategy; -/** - * @author Jeff Cantrill - */ @Deprecated -public class STIBuildStrategy implements ISTIBuildStrategy{ - - private DockerImageURI image; - private String scriptsLocation; - private boolean incremental; - private Map envVars; - - public STIBuildStrategy(String image, String scriptsLocation, boolean incremental, Map envVars) { - this.image = new DockerImageURI(image); - this.scriptsLocation = scriptsLocation; - this.incremental = incremental; - this.envVars = envVars; - } - - @Override - public String getType() { - return BuildStrategyType.STI; - } - - @Override - public DockerImageURI getImage() { - return image; - } - - @Override - public String getScriptsLocation() { - return scriptsLocation; - } - - @Override - public Map getEnvironmentVariables() { - return envVars; - } - - @Override - public boolean incremental() { - return incremental; - } - - @Override - public boolean forceClean() { - return !incremental; - } +public class STIBuildStrategy implements ISTIBuildStrategy { + + private DockerImageURI image; + private String scriptsLocation; + private boolean incremental; + private Map envVars; + + public STIBuildStrategy(String image, String scriptsLocation, boolean incremental, Map envVars) { + this.image = new DockerImageURI(image); + this.scriptsLocation = scriptsLocation; + this.incremental = incremental; + this.envVars = envVars; + } + + @Override + public String getType() { + return BuildStrategyType.STI; + } + + @Override + public DockerImageURI getImage() { + return image; + } + + @Override + public String getScriptsLocation() { + return scriptsLocation; + } + + @Override + public Map getEnvironmentVariables() { + return envVars; + } + + @Override + public boolean incremental() { + return incremental; + } + + @Override + public boolean forceClean() { + return !incremental; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/SourceBuildStrategy.java b/src/main/java/com/openshift/internal/restclient/model/build/SourceBuildStrategy.java index 40995bfb..ae18a929 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/SourceBuildStrategy.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/SourceBuildStrategy.java @@ -8,9 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.build; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asBoolean; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.Collection; import java.util.Collections; @@ -31,127 +34,121 @@ import com.openshift.restclient.model.build.BuildStrategyType; import com.openshift.restclient.model.build.ISourceBuildStrategy; -/** - * - * @author Jeff Cantrill - * - */ -public class SourceBuildStrategy extends ModelNodeAdapter implements ISourceBuildStrategy, ResourcePropertyKeys{ - - public static final String FROM_IMAGE = "sourceStrategy.from.name"; - public static final String FROM_KIND = "sourceStrategy.from.kind"; - public static final String FROM_NAMESPACE = "sourceStrategy.from.namespace"; - public static final String SCRIPTS = "sourceStrategy.scripts"; - public static final String INCREMENTAL = "sourceStrategy.incremental"; - public static final String ENV = "sourceStrategy.env"; - - public SourceBuildStrategy(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - set(node, propertyKeys, TYPE, BuildStrategyType.SOURCE); - } - - @Override - public String getType() { - return asString(getNode(), getPropertyKeys(), TYPE); - } - - @Override - public String getFromNamespace() { - return asString(getNode(), getPropertyKeys(), FROM_NAMESPACE); - } - - @Override - public void setFromNamespace(String namespace) { - set(getNode(), getPropertyKeys(), FROM_NAMESPACE, namespace); - } - - @Override - public String getFromKind() { - return asString(getNode(),getPropertyKeys(), FROM_KIND); - } - - @Override - public void setFromKind(String kind) { - set(getNode(),getPropertyKeys(), FROM_KIND, kind); - } - - @Override - public DockerImageURI getImage() { - return new DockerImageURI(asString(getNode(), getPropertyKeys(), FROM_IMAGE)); - } - - @Override - public void setImage(DockerImageURI image) { - set(getNode(), getPropertyKeys(), FROM_IMAGE, image.toString()); - } - - @Override - public String getScriptsLocation() { - return asString(getNode(), getPropertyKeys(), SCRIPTS); - } - - @Override - public void setScriptsLocation(String location) { - set(getNode(), getPropertyKeys(), SCRIPTS, location); - } - - @Override - public Collection getEnvVars() { - String [] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); - ModelNode envNode = getNode().get(path); - if(envNode.isDefined()) { - return envNode.asList() - .stream() - .map(n-> new EnvironmentVariable(n, getPropertyKeys())) - .collect(Collectors.toList()); - } - return Collections.emptyList(); - } - - @Override - public void setEnvVars(Collection envVars) { - if(envVars == null) return; - String [] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); - ModelNode envNode = getNode().get(path); - envNode.clear(); - envVars.forEach(v->envNode.add(ModelNode.fromJSONString(v.toJson()))); - } - - @Override - public Map getEnvironmentVariables() { - String [] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); - ModelNode env = getNode().get(path); - Map values = new HashMap<>(); - if(env.getType() == ModelType.LIST){ - for (ModelNode value : env.asList()) { - values.put(value.get(NAME).asString(), value.get(VALUE).asString()); - } - } - return values; - } - - @Override - public void setEnvironmentVariables(Map envVars) { - String [] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); - ModelNode env = getNode().get(path); - env.clear(); - for (Entry entry : envVars.entrySet()) { - ModelNode var = new ModelNode(); - var.get(NAME).set(entry.getKey()); - var.get(VALUE).set(entry.getValue()); - env.add(var); - } - } - - @Override - public boolean incremental() { - return asBoolean(getNode(), getPropertyKeys(), INCREMENTAL); - } - - @Override - public void setIncremental(boolean isIncremental) { - set(getNode(), getPropertyKeys(), INCREMENTAL, isIncremental); - } - - +public class SourceBuildStrategy extends ModelNodeAdapter implements ISourceBuildStrategy, ResourcePropertyKeys { + + public static final String FROM_IMAGE = "sourceStrategy.from.name"; + public static final String FROM_KIND = "sourceStrategy.from.kind"; + public static final String FROM_NAMESPACE = "sourceStrategy.from.namespace"; + public static final String SCRIPTS = "sourceStrategy.scripts"; + public static final String INCREMENTAL = "sourceStrategy.incremental"; + public static final String ENV = "sourceStrategy.env"; + + public SourceBuildStrategy(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + set(node, propertyKeys, TYPE, BuildStrategyType.SOURCE); + } + + @Override + public String getType() { + return asString(getNode(), getPropertyKeys(), TYPE); + } + + @Override + public String getFromNamespace() { + return asString(getNode(), getPropertyKeys(), FROM_NAMESPACE); + } + + @Override + public void setFromNamespace(String namespace) { + set(getNode(), getPropertyKeys(), FROM_NAMESPACE, namespace); + } + + @Override + public String getFromKind() { + return asString(getNode(), getPropertyKeys(), FROM_KIND); + } + + @Override + public void setFromKind(String kind) { + set(getNode(), getPropertyKeys(), FROM_KIND, kind); + } + + @Override + public DockerImageURI getImage() { + return new DockerImageURI(asString(getNode(), getPropertyKeys(), FROM_IMAGE)); + } + + @Override + public void setImage(DockerImageURI image) { + set(getNode(), getPropertyKeys(), FROM_IMAGE, image.toString()); + } + + @Override + public String getScriptsLocation() { + return asString(getNode(), getPropertyKeys(), SCRIPTS); + } + + @Override + public void setScriptsLocation(String location) { + set(getNode(), getPropertyKeys(), SCRIPTS, location); + } + + @Override + public Collection getEnvVars() { + String[] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); + ModelNode envNode = getNode().get(path); + if (envNode.isDefined()) { + return envNode.asList().stream().map(n -> new EnvironmentVariable(n, getPropertyKeys())) + .collect(Collectors.toList()); + } + return Collections.emptyList(); + } + + @Override + public void setEnvVars(Collection envVars) { + if (envVars == null) { + return; + } + String[] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); + ModelNode envNode = getNode().get(path); + envNode.clear(); + envVars.forEach(v -> envNode.add(ModelNode.fromJSONString(v.toJson()))); + } + + @Override + public Map getEnvironmentVariables() { + String[] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); + ModelNode env = getNode().get(path); + Map values = new HashMap<>(); + if (env.getType() == ModelType.LIST) { + for (ModelNode value : env.asList()) { + values.put(value.get(NAME).asString(), value.get(VALUE).asString()); + } + } + return values; + } + + @Override + public void setEnvironmentVariables(Map envVars) { + String[] path = JBossDmrExtentions.getPath(getPropertyKeys(), ENV); + ModelNode env = getNode().get(path); + env.clear(); + for (Entry entry : envVars.entrySet()) { + ModelNode var = new ModelNode(); + var.get(NAME).set(entry.getKey()); + var.get(VALUE).set(entry.getValue()); + env.add(var); + } + } + + @Override + public boolean incremental() { + return asBoolean(getNode(), getPropertyKeys(), INCREMENTAL); + } + + @Override + public void setIncremental(boolean isIncremental) { + set(getNode(), getPropertyKeys(), INCREMENTAL, isIncremental); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/WebhookTrigger.java b/src/main/java/com/openshift/internal/restclient/model/build/WebhookTrigger.java index b7457157..cfe48a9f 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/WebhookTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/WebhookTrigger.java @@ -6,75 +6,76 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; import org.apache.commons.lang.StringUtils; + import com.openshift.restclient.model.build.IWebhookTrigger; -/** - * @author Jeff Cantrill - */ public class WebhookTrigger implements IWebhookTrigger { - private String type; - private String secret; - private String baseURL; + private String type; + private String secret; + private String baseURL; + + public WebhookTrigger(String triggerType, String secret, String baseURL) { + this.type = triggerType; + this.secret = secret; + this.baseURL = baseURL; + } + + @Override + public String getType() { + return type; + } - public WebhookTrigger(String triggerType, String secret, String baseURL) { - this.type = triggerType; - this.secret = secret; - this.baseURL = baseURL; - } + @Override + public String getSecret() { + return secret; + } - @Override - public String getType() { - return type; - } + @Override + public String getWebhookURL() { + if (StringUtils.isBlank(baseURL)) { + return ""; + } - @Override - public String getSecret() { - return secret; - } + return String.format("%s/webhooks/%s/%s", baseURL, secret, type.toLowerCase()); + } - @Override - public String getWebhookURL() { - if(StringUtils.isBlank(baseURL)){ - return ""; - } - - return String.format("%s/webhooks/%s/%s", - baseURL, - secret, - type.toLowerCase() - ); - } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((secret == null) ? 0 : secret.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((secret == null) ? 0 : secret.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - return result; - } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + WebhookTrigger other = (WebhookTrigger) obj; + if (secret == null) { + if (other.secret != null) { + return false; + } + } else if (!secret.equals(other.secret)) { + return false; + } + if (type != other.type) { + return false; + } + return true; + } - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - WebhookTrigger other = (WebhookTrigger) obj; - if (secret == null) { - if (other.secret != null) - return false; - } else if (!secret.equals(other.secret)) - return false; - if (type != other.type) - return false; - return true; - } - } diff --git a/src/main/java/com/openshift/internal/restclient/model/deploy/ConfigChangeTrigger.java b/src/main/java/com/openshift/internal/restclient/model/deploy/ConfigChangeTrigger.java index dfe21567..29f47a53 100644 --- a/src/main/java/com/openshift/internal/restclient/model/deploy/ConfigChangeTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/model/deploy/ConfigChangeTrigger.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.deploy; import java.util.Map; @@ -18,8 +19,8 @@ public class ConfigChangeTrigger extends DeploymentTrigger implements IDeploymentConfigChangeTrigger { - public ConfigChangeTrigger(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - } + public ConfigChangeTrigger(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentRequest.java b/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentRequest.java index 001ef2f9..1fabcc70 100644 --- a/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentRequest.java +++ b/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentRequest.java @@ -8,9 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.deploy; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asBoolean; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.Map; diff --git a/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentTrigger.java b/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentTrigger.java index 8abe271b..b47abaac 100644 --- a/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/model/deploy/DeploymentTrigger.java @@ -8,9 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.deploy; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asString; + import java.util.Map; import org.jboss.dmr.ModelNode; @@ -18,31 +20,26 @@ import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.model.deploy.IDeploymentTrigger; -/** - * - * @author Jeff Cantrill - * - */ public class DeploymentTrigger implements IDeploymentTrigger, ResourcePropertyKeys { - - final private ModelNode node; - final private Map propertyKeys; - - public DeploymentTrigger(ModelNode node, Map propertyKeys) { - this.node = node; - this.propertyKeys = propertyKeys; - } - - @Override - public String getType() { - return asString(node, propertyKeys, TYPE); - } - - protected ModelNode getNode() { - return node; - } - - protected Map getPropertyKeys(){ - return this.propertyKeys; - } + + private final ModelNode node; + private final Map propertyKeys; + + public DeploymentTrigger(ModelNode node, Map propertyKeys) { + this.node = node; + this.propertyKeys = propertyKeys; + } + + @Override + public String getType() { + return asString(node, propertyKeys, TYPE); + } + + protected ModelNode getNode() { + return node; + } + + protected Map getPropertyKeys() { + return this.propertyKeys; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/deploy/ImageChangeTrigger.java b/src/main/java/com/openshift/internal/restclient/model/deploy/ImageChangeTrigger.java index 1fecf320..4f98db2d 100644 --- a/src/main/java/com/openshift/internal/restclient/model/deploy/ImageChangeTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/model/deploy/ImageChangeTrigger.java @@ -8,9 +8,13 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.deploy; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asBoolean; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.get; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.ArrayList; import java.util.Arrays; @@ -25,85 +29,84 @@ import com.openshift.restclient.model.deploy.IDeploymentImageChangeTrigger; public class ImageChangeTrigger extends DeploymentTrigger implements IDeploymentImageChangeTrigger { - - private static final String DEPLOYMENTCONFIG_TRIGGER_IMAGECHANGE_AUTO = "imageChangeParams.automatic"; - private static final String DEPLOYMENTCONFIG_TRIGGER_CONTAINERS = "imageChangeParams.containerNames"; - private static final String DEPLOYMENTCONFIG_TRIGGER_FROM = "imageChangeParams.from.name"; - private static final String DEPLOYMENTCONFIG_TRIGGER_FROM_KIND = "imageChangeParams.from.kind"; - private static final String FROM_NAMESPACE = "imageChangeParams.from.namespace"; - - public ImageChangeTrigger(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - } - - @Override - public DockerImageURI getFrom() { - return new DockerImageURI(asString(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM)); - } - - @Override - public void setFrom(DockerImageURI fromImage) { - if(StringUtils.isBlank(asString(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM_KIND))) { - setKind(ResourceKind.IMAGE_STREAM_TAG); - } - set(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM, fromImage.getAbsoluteUri()); - } - - @Override - public void setNamespace(String namespace) { - set(getNode(), getPropertyKeys(), FROM_NAMESPACE, namespace); - } - - @Override - public String getNamespace() { - return asString(getNode(), getPropertyKeys(), FROM_NAMESPACE); - } - - @Override - public void setKind(String kind) { - set(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM_KIND, kind); - } - - @Override - public String getKind() { - return asString(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM_KIND); - } - - @Override - public boolean isAutomatic() { - return asBoolean(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_IMAGECHANGE_AUTO); - } - - @Override - public void setAutomatic(boolean auto) { - set(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_IMAGECHANGE_AUTO, auto); - } - - @Override - public Collection getContainerNames() { - Collection containers = new ArrayList<>(); - ModelNode containerNode = get(getNode(), getPropertyKeys(),DEPLOYMENTCONFIG_TRIGGER_CONTAINERS); - if(containerNode.isDefined()) { - for (ModelNode node : containerNode.asList()) { - containers.add(node.asString()); - } - } - return containers ; - } - - @Override - public void setContainerNames(Collection names) { - ModelNode containerNode = get(getNode(), getPropertyKeys(),DEPLOYMENTCONFIG_TRIGGER_CONTAINERS); - containerNode.clear(); - for (String name : names) { - containerNode.add(name); - } - } - - @Override - public void setContainerName(String name) { - setContainerNames(Arrays.asList(name)); - } - - + + private static final String DEPLOYMENTCONFIG_TRIGGER_IMAGECHANGE_AUTO = "imageChangeParams.automatic"; + private static final String DEPLOYMENTCONFIG_TRIGGER_CONTAINERS = "imageChangeParams.containerNames"; + private static final String DEPLOYMENTCONFIG_TRIGGER_FROM = "imageChangeParams.from.name"; + private static final String DEPLOYMENTCONFIG_TRIGGER_FROM_KIND = "imageChangeParams.from.kind"; + private static final String FROM_NAMESPACE = "imageChangeParams.from.namespace"; + + public ImageChangeTrigger(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public DockerImageURI getFrom() { + return new DockerImageURI(asString(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM)); + } + + @Override + public void setFrom(DockerImageURI fromImage) { + if (StringUtils.isBlank(asString(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM_KIND))) { + setKind(ResourceKind.IMAGE_STREAM_TAG); + } + set(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM, fromImage.getAbsoluteUri()); + } + + @Override + public void setNamespace(String namespace) { + set(getNode(), getPropertyKeys(), FROM_NAMESPACE, namespace); + } + + @Override + public String getNamespace() { + return asString(getNode(), getPropertyKeys(), FROM_NAMESPACE); + } + + @Override + public void setKind(String kind) { + set(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM_KIND, kind); + } + + @Override + public String getKind() { + return asString(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_FROM_KIND); + } + + @Override + public boolean isAutomatic() { + return asBoolean(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_IMAGECHANGE_AUTO); + } + + @Override + public void setAutomatic(boolean auto) { + set(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_IMAGECHANGE_AUTO, auto); + } + + @Override + public Collection getContainerNames() { + Collection containers = new ArrayList<>(); + ModelNode containerNode = get(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_CONTAINERS); + if (containerNode.isDefined()) { + for (ModelNode node : containerNode.asList()) { + containers.add(node.asString()); + } + } + return containers; + } + + @Override + public void setContainerNames(Collection names) { + ModelNode containerNode = get(getNode(), getPropertyKeys(), DEPLOYMENTCONFIG_TRIGGER_CONTAINERS); + containerNode.clear(); + for (String name : names) { + containerNode.add(name); + } + } + + @Override + public void setContainerName(String name) { + setContainerNames(Arrays.asList(name)); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/image/ImageStreamImport.java b/src/main/java/com/openshift/internal/restclient/model/image/ImageStreamImport.java index d5568969..38882fb0 100644 --- a/src/main/java/com/openshift/internal/restclient/model/image/ImageStreamImport.java +++ b/src/main/java/com/openshift/internal/restclient/model/image/ImageStreamImport.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.image; import java.util.ArrayList; @@ -25,74 +26,64 @@ import com.openshift.restclient.model.IStatus; import com.openshift.restclient.model.image.IImageStreamImport; -/** - * - * @author jeff.cantrill - * - */ public class ImageStreamImport extends KubernetesResource implements IImageStreamImport { - private static final String FROM_KIND = "from.kind"; - public static final String IMAGE_DOCKER_IMAGE_REFERENCE = "image.dockerImageReference"; - private static final String SPEC_IMAGES = "spec.images"; - private static final String SPEC_IMPORT = "spec.import"; - private static final String STATUS = "status"; - public static final String STATUS_IMAGES = "status.images"; - private static final String TAG = "tag"; + private static final String FROM_KIND = "from.kind"; + public static final String IMAGE_DOCKER_IMAGE_REFERENCE = "image.dockerImageReference"; + private static final String SPEC_IMAGES = "spec.images"; + private static final String SPEC_IMPORT = "spec.import"; + private static final String STATUS = "status"; + public static final String STATUS_IMAGES = "status.images"; + private static final String TAG = "tag"; - public ImageStreamImport(ModelNode node, IClient client, Map overrideProperties) { - super(node, client, overrideProperties); - } + public ImageStreamImport(ModelNode node, IClient client, Map overrideProperties) { + super(node, client, overrideProperties); + } - @Override - public void setImport(boolean importTags) { - set(SPEC_IMPORT, importTags); - } + @Override + public void setImport(boolean importTags) { + set(SPEC_IMPORT, importTags); + } - @Override - public boolean isImport() { - return asBoolean(SPEC_IMPORT); - } + @Override + public boolean isImport() { + return asBoolean(SPEC_IMPORT); + } - @Override - public void addImage(String fromKind, DockerImageURI imageUri) { - ModelNode image = new ModelNode(); - set(image, FROM_KIND, fromKind); - set(image, "from.name", imageUri.getAbsoluteUri()); - get(SPEC_IMAGES).add(image); - } + @Override + public void addImage(String fromKind, DockerImageURI imageUri) { + ModelNode image = new ModelNode(); + set(image, FROM_KIND, fromKind); + set(image, "from.name", imageUri.getAbsoluteUri()); + get(SPEC_IMAGES).add(image); + } - @Override - public Collection getImageStatus() { - Collection status = new ArrayList<>(); - ModelNode images = get(STATUS_IMAGES); - if(images.isDefined()) { - images.asList() - .stream() - .filter(n->get(n,STATUS).isDefined()) - .forEach(n->status.add(new Status(get(n,STATUS), getClient(), getPropertyKeys()))); - } - return status; - } + @Override + public Collection getImageStatus() { + Collection status = new ArrayList<>(); + ModelNode images = get(STATUS_IMAGES); + if (images.isDefined()) { + images.asList().stream().filter(n -> get(n, STATUS).isDefined()) + .forEach(n -> status.add(new Status(get(n, STATUS), getClient(), getPropertyKeys()))); + } + return status; + } - @Override - public String getImageJsonFor(DockerImageURI uri) { - return getImageJsonFor(uri.getTag()); - } + @Override + public String getImageJsonFor(DockerImageURI uri) { + return getImageJsonFor(uri.getTag()); + } - @Override - public String getImageJsonFor(String tag) { - ModelNode images = get(STATUS_IMAGES); - if(images.isDefined() && StringUtils.isNotBlank(tag)) { - Optional node = images.asList() - .stream() - .filter(n->tag.equals(asString(n,TAG))) - .findFirst(); - if(node.isPresent()) { - return node.get().toJSONString(true); - } - } - return null; - } + @Override + public String getImageJsonFor(String tag) { + ModelNode images = get(STATUS_IMAGES); + if (images.isDefined() && StringUtils.isNotBlank(tag)) { + Optional node = images.asList().stream().filter(n -> tag.equals(asString(n, TAG))).findFirst(); + if (node.isPresent()) { + return node.get().toJSONString(true); + } + } + return null; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/image/TagReference.java b/src/main/java/com/openshift/internal/restclient/model/image/TagReference.java index cca64ae9..1c99db29 100644 --- a/src/main/java/com/openshift/internal/restclient/model/image/TagReference.java +++ b/src/main/java/com/openshift/internal/restclient/model/image/TagReference.java @@ -8,9 +8,13 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.image; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asMap; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.get; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.HashMap; import java.util.Map; @@ -25,61 +29,63 @@ public class TagReference extends ModelNodeAdapter implements ITagReference, ResourcePropertyKeys { - private static final String TAG_ANNOTATIONS = "annotations"; - - public TagReference(String name, String fromKind, String fromName) { - super(new ModelNode(), new HashMap<>()); - setName(name); - ObjectReference from = (ObjectReference) getFrom(); - from.setKind(fromKind); - from.setName(fromName); - } - - public TagReference(String name, String fromKind, String fromName, String fromNamespace) { - this(name, fromKind, fromName); - ObjectReference from = (ObjectReference) getFrom(); - from.setNamespace(fromNamespace); - } - - public TagReference(ModelNode node, Map propertyKeys) { - super(node, propertyKeys); - } - - @Override - public boolean isAnnotatedWith(String key) { - return getAnnotations().containsKey(key); - } - - @Override - public String getAnnotation(String key) { - return getAnnotations().get(key); - } - - @Override - public void setAnnotation(String key, String value) { - if(value == null) return; - ModelNode annotations = get(getNode(), getPropertyKeys(), TAG_ANNOTATIONS); - annotations.get(key).set(value); - } - - @Override - public Map getAnnotations() { - return asMap(getNode(), getPropertyKeys(), TAG_ANNOTATIONS); - } - - @Override - public String getName() { - return asString(getNode(),getPropertyKeys(), NAME); - } - - public void setName(String name) { - set(getNode(),getPropertyKeys(), NAME, name); - } - - @Override - public IObjectReference getFrom() { - ModelNode from = get(getNode(), getPropertyKeys(), FROM); - return new ObjectReference(from); - } - + private static final String TAG_ANNOTATIONS = "annotations"; + + public TagReference(String name, String fromKind, String fromName) { + super(new ModelNode(), new HashMap<>()); + setName(name); + ObjectReference from = (ObjectReference) getFrom(); + from.setKind(fromKind); + from.setName(fromName); + } + + public TagReference(String name, String fromKind, String fromName, String fromNamespace) { + this(name, fromKind, fromName); + ObjectReference from = (ObjectReference) getFrom(); + from.setNamespace(fromNamespace); + } + + public TagReference(ModelNode node, Map propertyKeys) { + super(node, propertyKeys); + } + + @Override + public boolean isAnnotatedWith(String key) { + return getAnnotations().containsKey(key); + } + + @Override + public String getAnnotation(String key) { + return getAnnotations().get(key); + } + + @Override + public void setAnnotation(String key, String value) { + if (value == null) { + return; + } + ModelNode annotations = get(getNode(), getPropertyKeys(), TAG_ANNOTATIONS); + annotations.get(key).set(value); + } + + @Override + public Map getAnnotations() { + return asMap(getNode(), getPropertyKeys(), TAG_ANNOTATIONS); + } + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), NAME); + } + + public void setName(String name) { + set(getNode(), getPropertyKeys(), NAME, name); + } + + @Override + public IObjectReference getFrom() { + ModelNode from = get(getNode(), getPropertyKeys(), FROM); + return new ObjectReference(from); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/kubeclient/Cluster.java b/src/main/java/com/openshift/internal/restclient/model/kubeclient/Cluster.java index 99d1ac4d..4fbe6f44 100644 --- a/src/main/java/com/openshift/internal/restclient/model/kubeclient/Cluster.java +++ b/src/main/java/com/openshift/internal/restclient/model/kubeclient/Cluster.java @@ -8,44 +8,46 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.kubeclient; import java.util.HashMap; import java.util.Map; + import com.openshift.restclient.model.kubeclient.ICluster; public class Cluster implements ICluster { - private static final String SERVER = "server"; - private static final String INSECURE_SKIP_TLS_VERIFY = "insecure-skip-tls-verify"; - private String name; - private Map cluster = new HashMap<>(); - - public void setCluster(Map cluster) { - this.cluster.clear(); - this.cluster.putAll(cluster); - } - - @Override - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - @Override - public String getServer() { - return (String) cluster.get(SERVER); - } - - @Override - public boolean isInsecureSkipTLSVerify() { - if(cluster.containsKey(INSECURE_SKIP_TLS_VERIFY)) { - return (Boolean) cluster.get(INSECURE_SKIP_TLS_VERIFY); - } - return false; - } + private static final String SERVER = "server"; + private static final String INSECURE_SKIP_TLS_VERIFY = "insecure-skip-tls-verify"; + private String name; + private Map cluster = new HashMap<>(); + + public void setCluster(Map cluster) { + this.cluster.clear(); + this.cluster.putAll(cluster); + } + + @Override + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String getServer() { + return (String) cluster.get(SERVER); + } + + @Override + public boolean isInsecureSkipTLSVerify() { + if (cluster.containsKey(INSECURE_SKIP_TLS_VERIFY)) { + return (Boolean) cluster.get(INSECURE_SKIP_TLS_VERIFY); + } + return false; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/kubeclient/Context.java b/src/main/java/com/openshift/internal/restclient/model/kubeclient/Context.java index 049df17e..9ee34b18 100644 --- a/src/main/java/com/openshift/internal/restclient/model/kubeclient/Context.java +++ b/src/main/java/com/openshift/internal/restclient/model/kubeclient/Context.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.kubeclient; import java.util.HashMap; @@ -18,41 +19,42 @@ /** * KubeConfig context - * @author jeff.cantrill * */ -public class Context implements IContext, ResourcePropertyKeys{ - - private static final String USER = "user"; - private static final String CLUSTER = "cluster"; - private Map context = new HashMap<>(); - private String name; - - public void setContext(Map context) { - this.context.clear(); - this.context.putAll(context); - } - @Override - public String getCluster() { - return context.get(CLUSTER); - } - - @Override - public String getUser() { - return context.get(USER); - } - - @Override - public String getNamespace() { - return context.get(NAMESPACE); - } - @Override - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - +public class Context implements IContext, ResourcePropertyKeys { + + private static final String USER = "user"; + private static final String CLUSTER = "cluster"; + private Map context = new HashMap<>(); + private String name; + + public void setContext(Map context) { + this.context.clear(); + this.context.putAll(context); + } + + @Override + public String getCluster() { + return context.get(CLUSTER); + } + + @Override + public String getUser() { + return context.get(USER); + } + + @Override + public String getNamespace() { + return context.get(NAMESPACE); + } + + @Override + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfig.java b/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfig.java index 308e19b5..b0dad58f 100644 --- a/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfig.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.kubeclient; import java.util.ArrayList; @@ -21,52 +22,54 @@ /** * Kube Client config impl * - * @author jeff.cantrill * */ public class KubeClientConfig implements IKubeClientConfig { - private Collection clusters = new ArrayList<>(); - private Collection contexts = new ArrayList<>(); - private String currentContext = ""; - private Collection users = new ArrayList<>(); - - public void setApiVersion(String apiVersion) { - - } - - @Override - public Collection< ICluster> getClusters() { - return clusters; - } - - public void setClusters(Collection clusters) { - this.clusters = clusters; - } - - @Override - public Collection getContexts() { - return contexts; - } - public void setContexts(Collection contexts) { - this.contexts = contexts; - } - - @Override - public String getCurrentContext() { - // TODO Auto-generated method stub - return currentContext; - } - public void setCurrentContext(String currentContext) { - this.currentContext = currentContext; - } - @Override - public Collection getUsers() { - return users; - } - - public void setUsers(Collection users) { - this.users = users; - } + private Collection clusters = new ArrayList<>(); + private Collection contexts = new ArrayList<>(); + private String currentContext = ""; + private Collection users = new ArrayList<>(); + + public void setApiVersion(String apiVersion) { + + } + + @Override + public Collection getClusters() { + return clusters; + } + + public void setClusters(Collection clusters) { + this.clusters = clusters; + } + + @Override + public Collection getContexts() { + return contexts; + } + + public void setContexts(Collection contexts) { + this.contexts = contexts; + } + + @Override + public String getCurrentContext() { + // TODO Auto-generated method stub + return currentContext; + } + + public void setCurrentContext(String currentContext) { + this.currentContext = currentContext; + } + + @Override + public Collection getUsers() { + return users; + } + + public void setUsers(Collection users) { + this.users = users; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfigConstructor.java b/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfigConstructor.java index 36a050fd..cff04166 100644 --- a/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfigConstructor.java +++ b/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfigConstructor.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.kubeclient; import org.yaml.snakeyaml.TypeDescription; @@ -15,21 +16,21 @@ import org.yaml.snakeyaml.introspector.PropertyUtils; public class KubeClientConfigConstructor extends Constructor { - - private static final String USERS = "users"; - private static final String CLUSTERS = "clusters"; - private static final String CONTEXTS = "contexts"; - - public KubeClientConfigConstructor(PropertyUtils propertyUtils) { - super(KubeClientConfig.class); - - TypeDescription configTypeDesc = new TypeDescription(KubeClientConfig.class); - configTypeDesc.putListPropertyType(CONTEXTS, Context.class); - configTypeDesc.putListPropertyType(CLUSTERS, Cluster.class); - configTypeDesc.putListPropertyType(USERS, User.class); - addTypeDescription(configTypeDesc); - - setPropertyUtils(propertyUtils); - } + + private static final String USERS = "users"; + private static final String CLUSTERS = "clusters"; + private static final String CONTEXTS = "contexts"; + + public KubeClientConfigConstructor(PropertyUtils propertyUtils) { + super(KubeClientConfig.class); + + TypeDescription configTypeDesc = new TypeDescription(KubeClientConfig.class); + configTypeDesc.putListPropertyType(CONTEXTS, Context.class); + configTypeDesc.putListPropertyType(CLUSTERS, Cluster.class); + configTypeDesc.putListPropertyType(USERS, User.class); + addTypeDescription(configTypeDesc); + + setPropertyUtils(propertyUtils); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/kubeclient/User.java b/src/main/java/com/openshift/internal/restclient/model/kubeclient/User.java index f2fcc20d..0fbf8925 100644 --- a/src/main/java/com/openshift/internal/restclient/model/kubeclient/User.java +++ b/src/main/java/com/openshift/internal/restclient/model/kubeclient/User.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.kubeclient; import java.util.Map; @@ -16,25 +17,25 @@ public class User implements IUser { - private String name; - private Map user; - - public void setUser(Map user) { - this.user = user; - } - @Override - public String getToken() { - return user.get("token"); - } - - @Override - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - + private String name; + private Map user; + + public void setUser(Map user) { + this.user = user; + } + + @Override + public String getToken() { + return user.get("token"); + } + + @Override + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthAccessToken.java b/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthAccessToken.java index e409f472..cda92d9f 100644 --- a/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthAccessToken.java +++ b/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthAccessToken.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.oauth; import java.util.Map; @@ -18,16 +19,10 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.model.oauth.IOAuthAccessToken; -/** - * - * @author Jeff Cantrill - * - */ public class OAuthAccessToken extends KubernetesResource implements IOAuthAccessToken { - public OAuthAccessToken(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public OAuthAccessToken(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthAuthorizeToken.java b/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthAuthorizeToken.java index c5331e29..53a6840e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthAuthorizeToken.java +++ b/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthAuthorizeToken.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.oauth; import java.util.Map; @@ -18,16 +19,10 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.model.oauth.IOAuthAuthorizeToken; -/** - * - * @author Jeff Cantrill - * - */ public class OAuthAuthorizeToken extends KubernetesResource implements IOAuthAuthorizeToken { - public OAuthAuthorizeToken(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public OAuthAuthorizeToken(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthClient.java b/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthClient.java index a0c96f41..9954348c 100644 --- a/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthClient.java +++ b/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthClient.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.oauth; import java.util.Map; @@ -18,16 +19,10 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.model.oauth.IOAuthClient; -/** - * - * @author Jeff Cantrill - * - */ public class OAuthClient extends KubernetesResource implements IOAuthClient { - public OAuthClient(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public OAuthClient(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthClientAuthorization.java b/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthClientAuthorization.java index 20f2fd73..9a5c3460 100644 --- a/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthClientAuthorization.java +++ b/src/main/java/com/openshift/internal/restclient/model/oauth/OAuthClientAuthorization.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.oauth; import java.util.Map; @@ -20,9 +21,8 @@ public class OAuthClientAuthorization extends KubernetesResource implements IOAuthClientAuthorization { - public OAuthClientAuthorization(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - // TODO Auto-generated constructor stub - } + public OAuthClientAuthorization(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/probe/Probe.java b/src/main/java/com/openshift/internal/restclient/model/probe/Probe.java index 84c37966..eab2519f 100644 --- a/src/main/java/com/openshift/internal/restclient/model/probe/Probe.java +++ b/src/main/java/com/openshift/internal/restclient/model/probe/Probe.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.probe; import static com.openshift.internal.util.JBossDmrExtentions.asInt; @@ -24,65 +25,64 @@ * @author Andre Dietisheim */ public class Probe extends ModelNodeAdapter implements IProbe { - - private static final String INITIAL_DELAY_SECONDS = "initialDelaySeconds"; - private static final String TIMEOUT_SECONDS = "timeoutSeconds"; - private static final String PERIOD_SECONDS = "periodSeconds"; - private static final String SUCCESS_THRESHOLD = "successThreshold"; - private static final String FAILURE_THRESHOLD = "failureThreshold"; - - public Probe(ModelNode node) { - super(node, new HashMap()); - } - - @Override - public void setInitialDelaySeconds(int delay) { - set(getNode(), getPropertyKeys(), INITIAL_DELAY_SECONDS, delay); - } - - @Override - public int getInitialDelaySeconds() { - return asInt(getNode(), getPropertyKeys(), INITIAL_DELAY_SECONDS); - } - - @Override - public void setPeriodSeconds(int period) { - set(getNode(), getPropertyKeys(), PERIOD_SECONDS, period); - } - - @Override - public int getPeriodSeconds() { - return asInt(getNode(), getPropertyKeys(), PERIOD_SECONDS); - } - - @Override - public void setSuccessThreshold(int threshold) { - set(getNode(), getPropertyKeys(), SUCCESS_THRESHOLD, threshold); - } - - @Override - public int getSuccessThreshold() { - return asInt(getNode(), getPropertyKeys(), SUCCESS_THRESHOLD); - } - - @Override - public void setFailureThreshold(int failureThreshold) { - set(getNode(), getPropertyKeys(), FAILURE_THRESHOLD, failureThreshold); - } - - @Override - public int getFailureThreshold() { - return asInt(getNode(), getPropertyKeys(), FAILURE_THRESHOLD); - } - - - @Override - public void setTimeoutSeconds(int timeout) { - set(getNode(), getPropertyKeys(), TIMEOUT_SECONDS, timeout); - } - - @Override - public int getTimeoutSeconds() { - return asInt(getNode(), getPropertyKeys(), TIMEOUT_SECONDS); - } + + private static final String INITIAL_DELAY_SECONDS = "initialDelaySeconds"; + private static final String TIMEOUT_SECONDS = "timeoutSeconds"; + private static final String PERIOD_SECONDS = "periodSeconds"; + private static final String SUCCESS_THRESHOLD = "successThreshold"; + private static final String FAILURE_THRESHOLD = "failureThreshold"; + + public Probe(ModelNode node) { + super(node, new HashMap()); + } + + @Override + public void setInitialDelaySeconds(int delay) { + set(getNode(), getPropertyKeys(), INITIAL_DELAY_SECONDS, delay); + } + + @Override + public int getInitialDelaySeconds() { + return asInt(getNode(), getPropertyKeys(), INITIAL_DELAY_SECONDS); + } + + @Override + public void setPeriodSeconds(int period) { + set(getNode(), getPropertyKeys(), PERIOD_SECONDS, period); + } + + @Override + public int getPeriodSeconds() { + return asInt(getNode(), getPropertyKeys(), PERIOD_SECONDS); + } + + @Override + public void setSuccessThreshold(int threshold) { + set(getNode(), getPropertyKeys(), SUCCESS_THRESHOLD, threshold); + } + + @Override + public int getSuccessThreshold() { + return asInt(getNode(), getPropertyKeys(), SUCCESS_THRESHOLD); + } + + @Override + public void setFailureThreshold(int failureThreshold) { + set(getNode(), getPropertyKeys(), FAILURE_THRESHOLD, failureThreshold); + } + + @Override + public int getFailureThreshold() { + return asInt(getNode(), getPropertyKeys(), FAILURE_THRESHOLD); + } + + @Override + public void setTimeoutSeconds(int timeout) { + set(getNode(), getPropertyKeys(), TIMEOUT_SECONDS, timeout); + } + + @Override + public int getTimeoutSeconds() { + return asInt(getNode(), getPropertyKeys(), TIMEOUT_SECONDS); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/project/OpenshiftProjectRequest.java b/src/main/java/com/openshift/internal/restclient/model/project/OpenshiftProjectRequest.java index bb09814e..cb1a3caf 100644 --- a/src/main/java/com/openshift/internal/restclient/model/project/OpenshiftProjectRequest.java +++ b/src/main/java/com/openshift/internal/restclient/model/project/OpenshiftProjectRequest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.project; import java.util.Map; @@ -20,31 +21,31 @@ public class OpenshiftProjectRequest extends KubernetesResource implements IProjectRequest { - private static final String DISPLAYNAME = "displayName"; - private static final String DESCRIPTION = "description"; + private static final String DISPLAYNAME = "displayName"; + private static final String DESCRIPTION = "description"; - public OpenshiftProjectRequest(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } + public OpenshiftProjectRequest(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } - @Override - public void setDisplayName(String name) { - set(DISPLAYNAME, name); - } + @Override + public void setDisplayName(String name) { + set(DISPLAYNAME, name); + } - @Override - public String getDisplayName() { - return asString(DISPLAYNAME); - } + @Override + public String getDisplayName() { + return asString(DISPLAYNAME); + } - @Override - public void setDescription(String description) { - set(DESCRIPTION, description); - } + @Override + public void setDescription(String description) { + set(DESCRIPTION, description); + } - @Override - public String getDescription() { - return asString(DESCRIPTION); - } + @Override + public String getDescription() { + return asString(DESCRIPTION); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertiesRegistry.java b/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertiesRegistry.java index 735a558a..6c88f2a4 100644 --- a/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertiesRegistry.java +++ b/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertiesRegistry.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.properties; import java.util.Arrays; @@ -21,126 +22,129 @@ /** * Registry of paths that override a default - * - * @author Jeff Cantrill */ public class ResourcePropertiesRegistry implements ResourcePropertyKeys { - private static ResourcePropertiesRegistry instance; - - private final Map> versionPropertyMap = new HashMap>(); - - private ResourcePropertiesRegistry(){ - } - - public static final ResourcePropertiesRegistry getInstance(){ - if(instance == null){ - instance = new ResourcePropertiesRegistry(); - } - return instance; - } - - /** - * Retrieve a given resource property map for a given version - * @param apiVersion - * @param kind - * - * @return The set of paths for the properties of the resource - */ - public Map get(final String apiVersion, final String kind) { - final VersionKey key = new VersionKey(apiVersion, kind); - if(!versionPropertyMap.containsKey(key)){ - return new HashMap(); - } - return versionPropertyMap.get(key); - } - - public KubernetesAPIVersion [] getSupportedKubernetesVersions(){ - return new KubernetesAPIVersion[] {KubernetesAPIVersion.v1}; - } - - public OpenShiftAPIVersion[] getSupportedOpenShiftVersions(){ - return new OpenShiftAPIVersion[] {OpenShiftAPIVersion.v1}; - } - - /** - * The maximum Kubernetes API supported by this client - * @return - * @throws IncompatibleApiVersionsException if the client can not support the server - */ - public KubernetesAPIVersion getMaxSupportedKubernetesVersion(List serverVersions) { - return getMaxSupportedVersion(Arrays.asList(getSupportedKubernetesVersions()), serverVersions); - } - - /** - * The maximum OpenShift API supported by this client - * @return - * @throws IncompatibleApiVersionsException if the client can not support the server - */ - public OpenShiftAPIVersion getMaxSupportedOpenShiftVersion(List serverVersions){ - return getMaxSupportedVersion(Arrays.asList(getSupportedOpenShiftVersions()), serverVersions); - } - - private T getMaxSupportedVersion(List clientVersions, List serverVersions) { - Collections.sort(clientVersions, new APIModelVersion.VersionComparitor()); - Collections.sort(serverVersions, new APIModelVersion.VersionComparitor()); - T maxClientVersion = clientVersions.get(clientVersions.size() - 1); - T maxServerVersion = serverVersions.get(serverVersions.size() - 1); - if(serverVersions.contains(maxClientVersion)) { - return maxClientVersion; - } - if(clientVersions.contains(maxServerVersion)) { - return maxServerVersion; - } - throw new IncompatibleApiVersionsException(clientVersions.toString(), serverVersions.toString()); - } - - private static class VersionKey { - private String version; - private String kind; - - VersionKey(APIModelVersion version, String kind){ - this(version.toString(), kind); - } - - VersionKey(String version, String kind){ - this.version = version.toString(); - this.kind = kind; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result - + ((kind == null) ? 0 : kind.hashCode()); - result = prime * result - + ((version == null) ? 0 : version.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - VersionKey other = (VersionKey) obj; - if (kind == null) { - if (other.kind != null) - return false; - } else if (!kind.equals(other.kind)) - return false; - if (version == null) { - if (other.version != null) - return false; - } else if (!version.equals(other.version)) - return false; - return true; - } - - } + private static ResourcePropertiesRegistry instance; + + private final Map> versionPropertyMap = new HashMap>(); + + private ResourcePropertiesRegistry() { + } + + public static final ResourcePropertiesRegistry getInstance() { + if (instance == null) { + instance = new ResourcePropertiesRegistry(); + } + return instance; + } + + /** + * Retrieve a given resource property map for a given version + * + * @return The set of paths for the properties of the resource + */ + public Map get(final String apiVersion, final String kind) { + final VersionKey key = new VersionKey(apiVersion, kind); + if (!versionPropertyMap.containsKey(key)) { + return new HashMap(); + } + return versionPropertyMap.get(key); + } + + public KubernetesAPIVersion[] getSupportedKubernetesVersions() { + return new KubernetesAPIVersion[] { KubernetesAPIVersion.v1 }; + } + + public OpenShiftAPIVersion[] getSupportedOpenShiftVersions() { + return new OpenShiftAPIVersion[] { OpenShiftAPIVersion.v1 }; + } + + /** + * The maximum Kubernetes API supported by this client + * + * @throws IncompatibleApiVersionsException + * if the client can not support the server + */ + public KubernetesAPIVersion getMaxSupportedKubernetesVersion(List serverVersions) { + return getMaxSupportedVersion(Arrays.asList(getSupportedKubernetesVersions()), serverVersions); + } + + /** + * The maximum OpenShift API supported by this client + * + * @throws IncompatibleApiVersionsException + * if the client can not support the server + */ + public OpenShiftAPIVersion getMaxSupportedOpenShiftVersion(List serverVersions) { + return getMaxSupportedVersion(Arrays.asList(getSupportedOpenShiftVersions()), serverVersions); + } + + private T getMaxSupportedVersion(List clientVersions, List serverVersions) { + Collections.sort(clientVersions, new APIModelVersion.VersionComparitor()); + Collections.sort(serverVersions, new APIModelVersion.VersionComparitor()); + T maxClientVersion = clientVersions.get(clientVersions.size() - 1); + T maxServerVersion = serverVersions.get(serverVersions.size() - 1); + if (serverVersions.contains(maxClientVersion)) { + return maxClientVersion; + } + if (clientVersions.contains(maxServerVersion)) { + return maxServerVersion; + } + throw new IncompatibleApiVersionsException(clientVersions.toString(), serverVersions.toString()); + } + + private static class VersionKey { + private String version; + private String kind; + + VersionKey(APIModelVersion version, String kind) { + this(version.toString(), kind); + } + + VersionKey(String version, String kind) { + this.version = version.toString(); + this.kind = kind; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((kind == null) ? 0 : kind.hashCode()); + result = prime * result + ((version == null) ? 0 : version.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + VersionKey other = (VersionKey) obj; + if (kind == null) { + if (other.kind != null) { + return false; + } + } else if (!kind.equals(other.kind)) { + return false; + } + if (version == null) { + if (other.version != null) { + return false; + } + } else if (!version.equals(other.version)) { + return false; + } + return true; + } + + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java b/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java index 21f2beb5..9cfc9400 100644 --- a/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java +++ b/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java @@ -6,33 +6,32 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.properties; /** * Keys used to determine where a given property is for a given resource - * - * @author Jeff Cantrill */ public interface ResourcePropertyKeys { - - static final String APIVERSION = "apiVersion"; - static final String KIND = "kind"; - static final String ANNOTATIONS = "metadata.annotations"; - static final String CREATION_TIMESTAMP = "metadata.creationTimestamp"; - static final String LABELS = "metadata.labels"; - static final String METADATA = "metadata"; - static final String METADATA_NAME = "metadata.name"; - static final String METADATA_RESOURCE_VERSION = "metadata.resourceVersion"; - static final String METADATA_NAMESPACE = "metadata.namespace"; + static final String APIVERSION = "apiVersion"; + static final String KIND = "kind"; + + static final String ANNOTATIONS = "metadata.annotations"; + static final String CREATION_TIMESTAMP = "metadata.creationTimestamp"; + static final String LABELS = "metadata.labels"; + static final String METADATA = "metadata"; + static final String METADATA_NAME = "metadata.name"; + static final String METADATA_RESOURCE_VERSION = "metadata.resourceVersion"; + static final String METADATA_NAMESPACE = "metadata.namespace"; - static final String FROM = "from"; - static final String NAME = "name"; - static final String NAMESPACE = "namespace"; - static final String OBJECTS = "objects"; - static final String PORTS = "ports"; - static final String PROTOCOL = "protocol"; - static final String RESOURCE_VERSION = "resourceVersion"; - static final String VALUE = "value"; - static final String TYPE = "type"; + static final String FROM = "from"; + static final String NAME = "name"; + static final String NAMESPACE = "namespace"; + static final String OBJECTS = "objects"; + static final String PORTS = "ports"; + static final String PROTOCOL = "protocol"; + static final String RESOURCE_VERSION = "resourceVersion"; + static final String VALUE = "value"; + static final String TYPE = "type"; } diff --git a/src/main/java/com/openshift/internal/restclient/model/template/Parameter.java b/src/main/java/com/openshift/internal/restclient/model/template/Parameter.java index cbac2ae1..54e9db38 100644 --- a/src/main/java/com/openshift/internal/restclient/model/template/Parameter.java +++ b/src/main/java/com/openshift/internal/restclient/model/template/Parameter.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.template; import org.apache.commons.lang.StringUtils; @@ -14,130 +15,126 @@ import com.openshift.restclient.model.template.IParameter; /** - * Parameter implementation for a template - * Foregoing versioned implementation of this type for now since it is unlikely to change - * and it is not a versioned resource in Kubernetes. Update as needed - * - * @author Jeff Cantrill + * Parameter implementation for a template Foregoing versioned implementation of + * this type for now since it is unlikely to change and it is not a versioned + * resource in Kubernetes. Update as needed */ -public class Parameter implements IParameter{ - - private static final String VALUE = "value"; - - private ModelNode node; - - public Parameter(ModelNode node){ - this.node = node; - } - - - @Override - public IParameter clone() { - return new Parameter(node.clone()); - } - - @Override - public String getName() { - return asString("name"); - } - - @Override - public String getDescription() { - return asString("description"); - } - - @Override - public void setValue(String value) { - node.get(VALUE).set(value); - } - - @Override - public String getValue() { - return asString(VALUE); - } - - @Override - public String getGeneratorName() { - return StringUtils.defaultIfEmpty(asString("generate"),asString("generator")); - } - - @Override - public String getFrom() { - return asString("from"); - } - - @Override - public boolean isRequired() { - if(node.hasDefined("required")) { - return node.get("required").asBoolean(); - } - return false; - } - - private String asString(String key) { - ModelNode value = node.get(key); - if(value.isDefined()) - return value.asString(); - return ""; - } - - - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + - ((getFrom() == null) ? 0 : getFrom().hashCode()) - + ((getGeneratorName() == null) ? 0 : getGeneratorName().hashCode()) - + ((getName() == null) ? 0 : getName().hashCode()) - + ((getValue() == null) ? 0 : getValue().hashCode()) - + Boolean.valueOf(isRequired()).hashCode(); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Parameter other = (Parameter) obj; - if (getFrom() == null) { - if (other.getFrom() != null) { - return false; - } - } else if (!getFrom().equals(other.getFrom())) { - return false; - } - if (getGeneratorName() == null) { - if (other.getGeneratorName() != null) { - return false; - } - } else if (!getGeneratorName().equals(other.getGeneratorName())) { - return false; - } - if (getName() == null) { - if (other.getName() != null) { - return false; - } - } else if (!getName().equals(other.getName())) { - return false; - } - if (getValue() == null) { - if (other.getValue() != null) { - return false; - } - } else if (!getValue().equals(other.getValue())) { - return false; - } - if (isRequired() != other.isRequired()) { - return false; - } - return true; - } - +public class Parameter implements IParameter { + + private static final String VALUE = "value"; + + private ModelNode node; + + public Parameter(ModelNode node) { + this.node = node; + } + + @Override + public IParameter clone() { + return new Parameter(node.clone()); + } + + @Override + public String getName() { + return asString("name"); + } + + @Override + public String getDescription() { + return asString("description"); + } + + @Override + public void setValue(String value) { + node.get(VALUE).set(value); + } + + @Override + public String getValue() { + return asString(VALUE); + } + + @Override + public String getGeneratorName() { + return StringUtils.defaultIfEmpty(asString("generate"), asString("generator")); + } + + @Override + public String getFrom() { + return asString("from"); + } + + @Override + public boolean isRequired() { + if (node.hasDefined("required")) { + return node.get("required").asBoolean(); + } + return false; + } + + private String asString(String key) { + ModelNode value = node.get(key); + if (value.isDefined()) { + return value.asString(); + } + return ""; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getFrom() == null) ? 0 : getFrom().hashCode()) + + ((getGeneratorName() == null) ? 0 : getGeneratorName().hashCode()) + + ((getName() == null) ? 0 : getName().hashCode()) + ((getValue() == null) ? 0 : getValue().hashCode()) + + Boolean.valueOf(isRequired()).hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Parameter other = (Parameter) obj; + if (getFrom() == null) { + if (other.getFrom() != null) { + return false; + } + } else if (!getFrom().equals(other.getFrom())) { + return false; + } + if (getGeneratorName() == null) { + if (other.getGeneratorName() != null) { + return false; + } + } else if (!getGeneratorName().equals(other.getGeneratorName())) { + return false; + } + if (getName() == null) { + if (other.getName() != null) { + return false; + } + } else if (!getName().equals(other.getName())) { + return false; + } + if (getValue() == null) { + if (other.getValue() != null) { + return false; + } + } else if (!getValue().equals(other.getValue())) { + return false; + } + if (isRequired() != other.isRequired()) { + return false; + } + return true; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/template/Template.java b/src/main/java/com/openshift/internal/restclient/model/template/Template.java index a1eaae8e..e131ad44 100644 --- a/src/main/java/com/openshift/internal/restclient/model/template/Template.java +++ b/src/main/java/com/openshift/internal/restclient/model/template/Template.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.template; import java.util.ArrayList; @@ -27,106 +28,99 @@ import com.openshift.restclient.model.template.IParameter; import com.openshift.restclient.model.template.ITemplate; -/** - * @author Jeff Cantrill - */ -public class Template extends KubernetesResource implements ITemplate{ - - private static final String TEMPLATE_PARAMETERS = "parameters"; - private static final String TEMPLATE_OBJECT_LABELS = "labels"; - - - public Template(ModelNode node, IClient client, Map overrideProperties) { - super(node, client, overrideProperties); - } - - @Override - public Map getObjectLabels() { - return Collections.unmodifiableMap(asMap(TEMPLATE_OBJECT_LABELS)); - } - - @Override - public void addObjectLabel(String key, String value) { - ModelNode labels = getNode().get(getPath(TEMPLATE_OBJECT_LABELS)); - labels.get(key).set(value); - } - - @Override - public Map getParameters() { - Map params = new HashMap(); - ModelNode modelNode = get(TEMPLATE_PARAMETERS); - if(modelNode.isDefined()) { - Collection nodes = modelNode.asList(); - for (ModelNode node : nodes) { - Parameter p = new Parameter(node); - params.put(p.getName(), p); - } - } - return params; - } - - @Override - public Collection getObjects() { - if(!getNode().has(OBJECTS)) { - return Collections.emptyList(); - } - Collection nodes = get(OBJECTS).asList(); - List resources = new ArrayList(nodes.size()); - IResourceFactory factory = getClient().getResourceFactory(); - if(factory != null){ - for (ModelNode node : nodes) { - resources.add(factory.create(node.toJSONString(true))); - } - } - return resources; - } - - @Override - public void updateParameterValues(Collection parameters) { - Map actuals = getParameters(); - for (IParameter param : parameters) { - if(actuals.containsKey(param.getName())) { - actuals.get(param.getName()).setValue(param.getValue()); - } - } - } - - @Override - public void updateParameter(String key, String value) { - Map params = getParameters(); - if(params.containsKey(key)) { - params.get(key).setValue(value); - } - } - - /** - * Returns true if this template contains the given text - * in name or tags. - * - * @param filterText - * @param template - * @return - */ - @Override - public boolean isMatching(final String text) { - if (StringUtils.isBlank(text)) { - return true; - } - if (getName().contains(text)) { - return true; - } - - return accept(new CapabilityVisitor() { - @Override - public Boolean visit(ITags capability) { - for (String tag : capability.getTags()) { - if (tag.contains(text)) { - return true; - } - } - return false; - } - }, false); - } +public class Template extends KubernetesResource implements ITemplate { + + private static final String TEMPLATE_PARAMETERS = "parameters"; + private static final String TEMPLATE_OBJECT_LABELS = "labels"; + + public Template(ModelNode node, IClient client, Map overrideProperties) { + super(node, client, overrideProperties); + } + + @Override + public Map getObjectLabels() { + return Collections.unmodifiableMap(asMap(TEMPLATE_OBJECT_LABELS)); + } + + @Override + public void addObjectLabel(String key, String value) { + ModelNode labels = getNode().get(getPath(TEMPLATE_OBJECT_LABELS)); + labels.get(key).set(value); + } + + @Override + public Map getParameters() { + Map params = new HashMap(); + ModelNode modelNode = get(TEMPLATE_PARAMETERS); + if (modelNode.isDefined()) { + Collection nodes = modelNode.asList(); + for (ModelNode node : nodes) { + Parameter p = new Parameter(node); + params.put(p.getName(), p); + } + } + return params; + } + + @Override + public Collection getObjects() { + if (!getNode().has(OBJECTS)) { + return Collections.emptyList(); + } + Collection nodes = get(OBJECTS).asList(); + List resources = new ArrayList(nodes.size()); + IResourceFactory factory = getClient().getResourceFactory(); + if (factory != null) { + for (ModelNode node : nodes) { + resources.add(factory.create(node.toJSONString(true))); + } + } + return resources; + } + + @Override + public void updateParameterValues(Collection parameters) { + Map actuals = getParameters(); + for (IParameter param : parameters) { + if (actuals.containsKey(param.getName())) { + actuals.get(param.getName()).setValue(param.getValue()); + } + } + } + + @Override + public void updateParameter(String key, String value) { + Map params = getParameters(); + if (params.containsKey(key)) { + params.get(key).setValue(value); + } + } + + /** + * Returns true if this template contains the given text in name or + * tags. + * + */ + @Override + public boolean isMatching(final String text) { + if (StringUtils.isBlank(text)) { + return true; + } + if (getName().contains(text)) { + return true; + } + + return accept(new CapabilityVisitor() { + @Override + public Boolean visit(ITags capability) { + for (String tag : capability.getTags()) { + if (tag.contains(text)) { + return true; + } + } + return false; + } + }, false); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java index 21c64e6f..6c0cd952 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.user; import java.util.Map; @@ -20,20 +21,20 @@ public class OpenShiftUser extends KubernetesResource implements IUser { - private static final String USER_FULLNAME = "fullName"; - - public OpenShiftUser(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } - - @Override - public String getFullName() { - return asString(USER_FULLNAME); - } - - @Override - public String getUID() { - return asString("metadata.uid"); - } - + private static final String USER_FULLNAME = "fullName"; + + public OpenShiftUser(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } + + @Override + public String getFullName() { + return asString(USER_FULLNAME); + } + + @Override + public String getUID() { + return asString("metadata.uid"); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/AbstractVolume.java b/src/main/java/com/openshift/internal/restclient/model/volume/AbstractVolume.java index e4a47c40..f8bb6f98 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/AbstractVolume.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/AbstractVolume.java @@ -8,9 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asBoolean; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.HashMap; @@ -20,69 +23,60 @@ import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.model.volume.IVolume; -/** - * - * @author Jeff Cantrill - * - */ -public abstract class AbstractVolume - extends ModelNodeAdapter - implements IVolume, ResourcePropertyKeys{ - - private static final String READONLY = "readOnly"; - private static final String MOUNT_PATH = "mountPath"; - - public AbstractVolume(ModelNode node) { - super(node, new HashMap()); - } - - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), NAME); - } - - @Override - public void setName(String name) { - set(getNode(), getPropertyKeys(), NAME, name); - } - - @Override - public void setMountPath(String path) { - set(getNode(), getPropertyKeys(), MOUNT_PATH, path); - } - - @Override - public String getMountPath() { - return asString(getNode(), getPropertyKeys(), MOUNT_PATH); - } - - @Override - public void setReadOnly(boolean readonly) { - set(getNode(), getPropertyKeys(), READONLY, readonly); - } - - @Override - public boolean isReadOnly() { - return asBoolean(getNode(), getPropertyKeys(), READONLY); - } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof AbstractVolume)) - return false; - AbstractVolume other = (AbstractVolume) obj; - return getName().equals(other.getName()) && - getMountPath().equals(other.getMountPath()) && - isReadOnly() == other.isReadOnly(); - } - - @Override - public int hashCode() { - int code = isReadOnly() ? 1 : 0; - code = code + getName().hashCode(); - return code + getMountPath().hashCode(); - } - - - +public abstract class AbstractVolume extends ModelNodeAdapter implements IVolume, ResourcePropertyKeys { + + private static final String READONLY = "readOnly"; + private static final String MOUNT_PATH = "mountPath"; + + public AbstractVolume(ModelNode node) { + super(node, new HashMap()); + } + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), NAME); + } + + @Override + public void setName(String name) { + set(getNode(), getPropertyKeys(), NAME, name); + } + + @Override + public void setMountPath(String path) { + set(getNode(), getPropertyKeys(), MOUNT_PATH, path); + } + + @Override + public String getMountPath() { + return asString(getNode(), getPropertyKeys(), MOUNT_PATH); + } + + @Override + public void setReadOnly(boolean readonly) { + set(getNode(), getPropertyKeys(), READONLY, readonly); + } + + @Override + public boolean isReadOnly() { + return asBoolean(getNode(), getPropertyKeys(), READONLY); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AbstractVolume)) { + return false; + } + AbstractVolume other = (AbstractVolume) obj; + return getName().equals(other.getName()) && getMountPath().equals(other.getMountPath()) + && isReadOnly() == other.isReadOnly(); + } + + @Override + public int hashCode() { + int code = isReadOnly() ? 1 : 0; + code = code + getName().hashCode(); + return code + getMountPath().hashCode(); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/EmptyDirVolume.java b/src/main/java/com/openshift/internal/restclient/model/volume/EmptyDirVolume.java index fb17f056..b8150ccd 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/EmptyDirVolume.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/EmptyDirVolume.java @@ -7,30 +7,27 @@ * * Contributors: * Red Hat, Inc. - initial API and implementation - ******************************************************************************/package com.openshift.internal.restclient.model.volume; + ******************************************************************************/ + +package com.openshift.internal.restclient.model.volume; import org.jboss.dmr.ModelNode; import com.openshift.restclient.model.volume.IVolume; -/** - * - * @author Jeff Cantrill - * - */ public class EmptyDirVolume extends AbstractVolume { - public EmptyDirVolume(ModelNode node, IVolume volume) { - super(node); - if(volume != null) { - setMountPath(volume.getMountPath()); - setReadOnly(volume.isReadOnly()); - setName(volume.getName()); - } - } + public EmptyDirVolume(ModelNode node, IVolume volume) { + super(node); + if (volume != null) { + setMountPath(volume.getMountPath()); + setReadOnly(volume.isReadOnly()); + setName(volume.getName()); + } + } - public EmptyDirVolume(ModelNode node) { - this(node, null); - } + public EmptyDirVolume(ModelNode node) { + this(node, null); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/EmptyDirVolumeSource.java b/src/main/java/com/openshift/internal/restclient/model/volume/EmptyDirVolumeSource.java index 8bec3b9a..307e1e6d 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/EmptyDirVolumeSource.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/EmptyDirVolumeSource.java @@ -8,15 +8,17 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.model.volume; -import com.openshift.restclient.model.volume.IEmptyDirVolumeSource; -import com.openshift.restclient.model.volume.VolumeType; -import org.jboss.dmr.ModelNode; +package com.openshift.internal.restclient.model.volume; import static com.openshift.internal.util.JBossDmrExtentions.asString; import static com.openshift.internal.util.JBossDmrExtentions.set; +import org.jboss.dmr.ModelNode; + +import com.openshift.restclient.model.volume.IEmptyDirVolumeSource; +import com.openshift.restclient.model.volume.VolumeType; + /** * @author Ulf Lilleengen */ diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/HostPathVolumeSource.java b/src/main/java/com/openshift/internal/restclient/model/volume/HostPathVolumeSource.java index fc7870fc..576829d8 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/HostPathVolumeSource.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/HostPathVolumeSource.java @@ -8,9 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; import org.jboss.dmr.ModelNode; @@ -18,25 +20,24 @@ /** * Implementation of a hostpath volume source - * @author jeff.cantrill * */ -public class HostPathVolumeSource extends VolumeSource implements IHostPathVolumeSource{ +public class HostPathVolumeSource extends VolumeSource implements IHostPathVolumeSource { - private static final String PATH = "hostPath.path"; + private static final String PATH = "hostPath.path"; - public HostPathVolumeSource(ModelNode node) { - super(node); - } + public HostPathVolumeSource(ModelNode node) { + super(node); + } - @Override - public String getPath() { - return asString(getNode(), getPropertyKeys(), PATH); - } + @Override + public String getPath() { + return asString(getNode(), getPropertyKeys(), PATH); + } - @Override - public void setPath(String path) { - set(getNode(), getPropertyKeys(), PATH, path); - } + @Override + public void setPath(String path) { + set(getNode(), getPropertyKeys(), PATH, path); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java index 3c7b6dec..d350fd4e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume; import java.util.Map; @@ -30,238 +31,252 @@ import com.openshift.restclient.model.volume.property.IPersistentVolumeProperties; import com.openshift.restclient.utils.MemoryUnit; - public class PersistentVolume extends KubernetesResource implements IPersistentVolume { - private static final String PV_ACCESS_MODES = "spec.accessModes"; - private static final String PV_CAPACITY = "spec.capacity.storage"; - private static final String PV_RECLAIM_POLICY = "spec.persistentVolumeReclaimPolicy"; - private static final String PV_NFS = "spec.nfs"; - private static final String PV_HOST_PATH = "spec.hostPath"; - private static final String PV_SPEC = "spec"; - private static final String SERVER = "server"; - private static final String PATH = "path"; - private static final String READ_ONLY = "readOnly"; + private static final String PV_ACCESS_MODES = "spec.accessModes"; + private static final String PV_CAPACITY = "spec.capacity.storage"; + private static final String PV_RECLAIM_POLICY = "spec.persistentVolumeReclaimPolicy"; + private static final String PV_NFS = "spec.nfs"; + private static final String PV_HOST_PATH = "spec.hostPath"; + private static final String PV_SPEC = "spec"; + private static final String SERVER = "server"; + private static final String PATH = "path"; + private static final String READ_ONLY = "readOnly"; - public PersistentVolume(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } + public PersistentVolume(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } - /** - * @param unit the designated unit. One of "Ki", "Mi", "Gi", "Ti", "Pi", "Ei". - * @return 0, if conversion not possible. Otherwise the capacity in given units. - * @see {@link PersistentVolume#convert(String, MemoryUnit)} - * @throws IllegalArgumentException if not supported {@code unit} given. - */ - @Override - public long getCapacity(String unit) { - String capacity = asString(PV_CAPACITY); - return convert(capacity, MemoryUnit.valueOf(unit)); - } + /** + * @param unit + * the designated unit. One of "Ki", "Mi", "Gi", "Ti", "Pi", "Ei". + * @return 0, if conversion not possible. Otherwise the capacity in given units. + * @see {@link PersistentVolume#convert(String, MemoryUnit)} + * @throws IllegalArgumentException + * if not supported {@code unit} given. + */ + @Override + public long getCapacity(String unit) { + String capacity = asString(PV_CAPACITY); + return convert(capacity, MemoryUnit.valueOf(unit)); + } - /** - * @param unit the designated unit. One of {@link MemoryUnit}'s Ki, Mi, Gi, Ti, Pi, Ei. - * @return 0, if conversion not possible. Otherwise the capacity in given units. - * @see {@link PersistentVolume#convert(String, MemoryUnit)} - * @throws IllegalArgumentException if not supported {@code unit} given. - */ - @Override - public long getCapacity(MemoryUnit unit) { - String capacity = asString(PV_CAPACITY); - return convert(capacity, unit); - } + /** + * @param unit + * the designated unit. One of {@link MemoryUnit}'s Ki, Mi, Gi, Ti, + * Pi, Ei. + * @return 0, if conversion not possible. Otherwise the capacity in given units. + * @see {@link PersistentVolume#convert(String, MemoryUnit)} + * @throws IllegalArgumentException + * if not supported {@code unit} given. + */ + @Override + public long getCapacity(MemoryUnit unit) { + String capacity = asString(PV_CAPACITY); + return convert(capacity, unit); + } - /** - * @return the capacity in bytes. - */ - @Override - public long getCapacity() { - String capacity = asString(PV_CAPACITY); - return Math.multiplyExact(convert(capacity, MemoryUnit.Ki), 1024L); - } + /** + * @return the capacity in bytes. + */ + @Override + public long getCapacity() { + String capacity = asString(PV_CAPACITY); + return Math.multiplyExact(convert(capacity, MemoryUnit.Ki), 1024L); + } - /** - * Sets the capacity. There is no conversion between units. - * @param capacity the capacity - * @param unit the unit - */ - @Override - public void setCapacity(long capacity, MemoryUnit unit) { - set(PV_CAPACITY, capacity + unit.name()); - } + /** + * Sets the capacity. There is no conversion between units. + * + * @param capacity + * the capacity + * @param unit + * the unit + */ + @Override + public void setCapacity(long capacity, MemoryUnit unit) { + set(PV_CAPACITY, capacity + unit.name()); + } - /** - * @return the unit in which the capacity is represent. - * @see {@link MemoryUnit} - */ - @Override - public MemoryUnit getCapacityUnit() { - return parseCapacityUnit(asString(PV_CAPACITY)); - } + /** + * @return the unit in which the capacity is represent. + * @see {@link MemoryUnit} + */ + @Override + public MemoryUnit getCapacityUnit() { + return parseCapacityUnit(asString(PV_CAPACITY)); + } - /** - * @return access modes - * @see {@link com.openshift.restclient.model.volume.PVCAccessModes} - * @see - */ - @Override - public Set getAccessModes() { - return asSet(PV_ACCESS_MODES, ModelType.STRING); - } + /** + * @return access modes + * @see {@link com.openshift.restclient.model.volume.PVCAccessModes} + * @see + */ + @Override + public Set getAccessModes() { + return asSet(PV_ACCESS_MODES, ModelType.STRING); + } - /** - * Sets the access modes. - * If there are any modes present, they are overridden by the {@code modes} parameter. - * @param modes the access modes - */ - @Override - public void setAccessModes(String... modes) { - get(PV_ACCESS_MODES).setEmptyList(); - set(PV_ACCESS_MODES, modes); - } + /** + * Sets the access modes. If there are any modes present, they are overridden by + * the {@code modes} parameter. + * + * @param modes + * the access modes + */ + @Override + public void setAccessModes(String... modes) { + get(PV_ACCESS_MODES).setEmptyList(); + set(PV_ACCESS_MODES, modes); + } - /** - * @return the value of 'spec.persistentVolumeReclaimPolicy' - */ - @Override - public String getReclaimPolicy() { - return asString(PV_RECLAIM_POLICY); - } + /** + * @return the value of 'spec.persistentVolumeReclaimPolicy' + */ + @Override + public String getReclaimPolicy() { + return asString(PV_RECLAIM_POLICY); + } - /** - * Sets the 'spec.persistentVolumeReclaimPolicy' value - * @param policy the policy string - */ - @Override - public void setReclaimPolicy(String policy) { - set(PV_RECLAIM_POLICY, policy); - } + /** + * Sets the 'spec.persistentVolumeReclaimPolicy' value + * + * @param policy + * the policy string + */ + @Override + public void setReclaimPolicy(String policy) { + set(PV_RECLAIM_POLICY, policy); + } - /** - * @return specific persistent volume type - */ - @Override - public IPersistentVolumeProperties getPersistentVolumeProperties() { - IPersistentVolumeProperties properties; - switch(getPVType()) { - case VolumeType.HOST_PATH: - properties = createHostPathVolumeProperties(); - break; - case VolumeType.NFS: - properties = createNFSVolumeProperties(); - break; - default: - properties = null; - break; - } - return properties; - } + /** + * @return specific persistent volume type + */ + @Override + public IPersistentVolumeProperties getPersistentVolumeProperties() { + IPersistentVolumeProperties properties; + switch (getPVType()) { + case VolumeType.HOST_PATH: + properties = createHostPathVolumeProperties(); + break; + case VolumeType.NFS: + properties = createNFSVolumeProperties(); + break; + default: + properties = null; + break; + } + return properties; + } - /** - * Sets the volume type properties. - * @param properties the properties - */ - @Override - public void setPersistentVolumeProperties(IPersistentVolumeProperties properties) { - if(properties instanceof AbstractPersistentVolumeProperties) { - ((AbstractPersistentVolumeProperties) properties).setProperties(getNode()); - } - } + /** + * Sets the volume type properties. + * + * @param properties + * the properties + */ + @Override + public void setPersistentVolumeProperties(IPersistentVolumeProperties properties) { + if (properties instanceof AbstractPersistentVolumeProperties) { + ((AbstractPersistentVolumeProperties) properties).setProperties(getNode()); + } + } - /** - * @return a string value of the type. One of {@link VolumeType}. - */ - public String getPVType() { - final ModelNode spec = get(PV_SPEC); - return VolumeType.getTypes().stream() - .filter(spec::hasDefined) - .findFirst().get(); - } + /** + * @return a string value of the type. One of {@link VolumeType}. + */ + public String getPVType() { + final ModelNode spec = get(PV_SPEC); + return VolumeType.getTypes().stream().filter(spec::hasDefined).findFirst().get(); + } - /** - * @return values of 'spec.nfs' wrapped in {@link INfsVolumeProperties} - */ - private INfsVolumeProperties createNFSVolumeProperties() { - ModelNode node = get(PV_NFS); - String server = asString(node, SERVER); - String path = asString(node, PATH); - boolean readOnly = asBoolean(node, READ_ONLY); - return new NfsVolumeProperties(server, path, readOnly); - } + /** + * @return values of 'spec.nfs' wrapped in {@link INfsVolumeProperties} + */ + private INfsVolumeProperties createNFSVolumeProperties() { + ModelNode node = get(PV_NFS); + String server = asString(node, SERVER); + String path = asString(node, PATH); + boolean readOnly = asBoolean(node, READ_ONLY); + return new NfsVolumeProperties(server, path, readOnly); + } - /** - * @return the value of 'spec.hostPath.path' wrapped in {@link IHostPathVolumeProperties} - */ - private IHostPathVolumeProperties createHostPathVolumeProperties() { - ModelNode node = get(PV_HOST_PATH); - String path = asString(node, PATH); - return new HostPathVolumeProperties(path); - } + /** + * @return the value of 'spec.hostPath.path' wrapped in + * {@link IHostPathVolumeProperties} + */ + private IHostPathVolumeProperties createHostPathVolumeProperties() { + ModelNode node = get(PV_HOST_PATH); + String path = asString(node, PATH); + return new HostPathVolumeProperties(path); + } - /** - * Converts capacity string (i.e. '10Gi') to it's numeric representation. - * The following assumptions are used to compute values: - * One Ki = 2^10 - * One Mi = 2^20 - * One Gi = 2^30 - * One Ti = 2^40 - * One Pi = 2^50 - * One Ei = 2^60 - * - * Java's type long can contain max value of 2^64, enough for a few Exbibytes. - * Following equation is used to convert values: - * - * kubernetesGivenNumber << (10 * i), where << is implicit multiplication by powers of 2 and (10 * i) is the order of magnitude. - * Example: convert 1Ti to Mi = 1Ti << (10*2) = 1 * 2^20 = 2^20 - * - * @param capacity the capacity string - * @param designatedUnit the designated unit of type {@link MemoryUnit}. Possible values 'Ki, Mi, Gi, Ti, Pi, Ei'. - * @return 0 if conversion is not possible, otherwise the numeric representation converted to designatedUnit. - * Conversion is not possible when the designatedUnit cannot contain the unit given by Kubernetes in integral form. - */ - private static long convert(final String capacity, final MemoryUnit designatedUnit) { - long number = parseCapacityValue(capacity); - MemoryUnit currentUnit = parseCapacityUnit(capacity); + /** + * Converts capacity string (i.e. '10Gi') to it's numeric representation. The + * following assumptions are used to compute values: One Ki = 2^10 One Mi = 2^20 + * One Gi = 2^30 One Ti = 2^40 One Pi = 2^50 One Ei = 2^60 + * + * Java's type long can contain max value of 2^64, enough for a few Exbibytes. + * Following equation is used to convert values: + * + * kubernetesGivenNumber << (10 * i), where << is implicit multiplication by + * powers of 2 and (10 * i) is the order of magnitude. Example: convert 1Ti to + * Mi = 1Ti << (10*2) = 1 * 2^20 = 2^20 + * + * @param capacity + * the capacity string + * @param designatedUnit + * the designated unit of type {@link MemoryUnit}. Possible values + * 'Ki, Mi, Gi, Ti, Pi, Ei'. + * @return 0 if conversion is not possible, otherwise the numeric representation + * converted to designatedUnit. Conversion is not possible when the + * designatedUnit cannot contain the unit given by Kubernetes in + * integral form. + */ + private static long convert(final String capacity, final MemoryUnit designatedUnit) { + long number = parseCapacityValue(capacity); + MemoryUnit currentUnit = parseCapacityUnit(capacity); - int operation = currentUnit.compareTo(designatedUnit); - if(operation == 0L) { - return number; - } else if(operation > 0L) { - return safeMultiplicationBy1024(number, operation); //number << (10 * operation); - } else { - return 0L; - } - } + int operation = currentUnit.compareTo(designatedUnit); + if (operation == 0L) { + return number; + } else if (operation > 0L) { + return safeMultiplicationBy1024(number, operation); // number << (10 * operation); + } else { + return 0L; + } + } - /** - * @throws ArithmeticException if computation overflows - */ - private static long safeMultiplicationBy1024(long value, long times) { - long multiplicand = (long) Math.pow(1024L, times); - return Math.multiplyExact(value, multiplicand); - } + /** + * @throws ArithmeticException + * if computation overflows + */ + private static long safeMultiplicationBy1024(long value, long times) { + long multiplicand = (long) Math.pow(1024L, times); + return Math.multiplyExact(value, multiplicand); + } - private static long parseCapacityValue(String capacityString) { - if(capacityString == null) { - return 0L; - } - Pattern pattern = Pattern.compile("(\\d+)(\\w{2})"); - Matcher m = pattern.matcher(capacityString); - if(!m.find()) { - return 0L; - } - return Long.parseLong(m.group(1)); - } + private static long parseCapacityValue(String capacityString) { + if (capacityString == null) { + return 0L; + } + Pattern pattern = Pattern.compile("(\\d+)(\\w{2})"); + Matcher m = pattern.matcher(capacityString); + if (!m.find()) { + return 0L; + } + return Long.parseLong(m.group(1)); + } - private static MemoryUnit parseCapacityUnit(String capacityString) { - if(capacityString == null) { - return null; - } - Pattern pattern = Pattern.compile("(\\d+)(\\w{2})"); - Matcher m = pattern.matcher(capacityString); - if(!m.find()) { - return null; - } - return MemoryUnit.valueOf(m.group(2)); - } + private static MemoryUnit parseCapacityUnit(String capacityString) { + if (capacityString == null) { + return null; + } + Pattern pattern = Pattern.compile("(\\d+)(\\w{2})"); + Matcher m = pattern.matcher(capacityString); + if (!m.find()) { + return null; + } + return MemoryUnit.valueOf(m.group(2)); + } } \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java index f5f48703..8f55493b 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume; import java.util.HashSet; @@ -21,57 +22,54 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.model.volume.IPersistentVolumeClaim; -/** - * - * @author Jeff Cantrill - * - */ public class PersistentVolumeClaim extends KubernetesResource implements IPersistentVolumeClaim { - private static final String PVC_ACCESS_MODES = "spec.accessModes"; - private static final String PVC_REQUESTED_STORAGE = "spec.resources.requests.storage"; - private static final String STATUS_PHASE = "status.phase"; - private static final String PVC_VOLUME_NAME = "spec.volumeName"; + private static final String PVC_ACCESS_MODES = "spec.accessModes"; + private static final String PVC_REQUESTED_STORAGE = "spec.resources.requests.storage"; + private static final String STATUS_PHASE = "status.phase"; + private static final String PVC_VOLUME_NAME = "spec.volumeName"; - public PersistentVolumeClaim(ModelNode node, IClient client, Map propertyKeys) { - super(node, client, propertyKeys); - } + public PersistentVolumeClaim(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } - @Override - public Set getAccessModes() { - Set modes = new HashSet<>(); - ModelNode modelNode = get(PVC_ACCESS_MODES); - if(!modelNode.isDefined() || !modelNode.getType().equals(ModelType.LIST)) return modes; - for (ModelNode node : modelNode.asList()) { - modes.add(node.asString()); - } - return modes; - } + @Override + public Set getAccessModes() { + Set modes = new HashSet<>(); + ModelNode modelNode = get(PVC_ACCESS_MODES); + if (!modelNode.isDefined() || !modelNode.getType().equals(ModelType.LIST)) { + return modes; + } + for (ModelNode node : modelNode.asList()) { + modes.add(node.asString()); + } + return modes; + } - @Override - public void setAccessModes(Set accessModes) { - ModelNode modelNode = get(PVC_ACCESS_MODES); - modelNode.clear(); - accessModes.stream().forEach(modelNode::add); - } + @Override + public void setAccessModes(Set accessModes) { + ModelNode modelNode = get(PVC_ACCESS_MODES); + modelNode.clear(); + accessModes.stream().forEach(modelNode::add); + } - @Override - public String getRequestedStorage() { - return asString(PVC_REQUESTED_STORAGE); - } + @Override + public String getRequestedStorage() { + return asString(PVC_REQUESTED_STORAGE); + } - @Override - public void setRequestedStorage(String requestedStorage) { - set(PVC_REQUESTED_STORAGE, requestedStorage); - } + @Override + public void setRequestedStorage(String requestedStorage) { + set(PVC_REQUESTED_STORAGE, requestedStorage); + } - @Override - public String getStatus() { - return asString(STATUS_PHASE); - } + @Override + public String getStatus() { + return asString(STATUS_PHASE); + } - @Override - public String getVolumeName() { - return asString(PVC_VOLUME_NAME); - } + @Override + public String getVolumeName() { + return asString(PVC_VOLUME_NAME); + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaimVolumeSource.java b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaimVolumeSource.java index f939093d..2c6a5bba 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaimVolumeSource.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaimVolumeSource.java @@ -8,16 +8,18 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.model.volume; -import com.openshift.restclient.model.volume.IPersistentVolumeClaimVolumeSource; -import com.openshift.restclient.model.volume.VolumeType; -import org.jboss.dmr.ModelNode; +package com.openshift.internal.restclient.model.volume; import static com.openshift.internal.util.JBossDmrExtentions.asBoolean; import static com.openshift.internal.util.JBossDmrExtentions.asString; import static com.openshift.internal.util.JBossDmrExtentions.set; +import org.jboss.dmr.ModelNode; + +import com.openshift.restclient.model.volume.IPersistentVolumeClaimVolumeSource; +import com.openshift.restclient.model.volume.VolumeType; + /** * @author Ulf Lilleengen */ diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/SecretVolumeSource.java b/src/main/java/com/openshift/internal/restclient/model/volume/SecretVolumeSource.java index c05be612..c51b9331 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/SecretVolumeSource.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/SecretVolumeSource.java @@ -8,15 +8,17 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.model.volume; -import com.openshift.restclient.model.volume.ISecretVolumeSource; -import com.openshift.restclient.model.volume.VolumeType; -import org.jboss.dmr.ModelNode; +package com.openshift.internal.restclient.model.volume; import static com.openshift.internal.util.JBossDmrExtentions.asString; import static com.openshift.internal.util.JBossDmrExtentions.set; +import org.jboss.dmr.ModelNode; + +import com.openshift.restclient.model.volume.ISecretVolumeSource; +import com.openshift.restclient.model.volume.VolumeType; + /** * @author Ulf Lilleengen */ diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/VolumeMount.java b/src/main/java/com/openshift/internal/restclient/model/volume/VolumeMount.java index 080782a8..79a40cbc 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/VolumeMount.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/VolumeMount.java @@ -8,9 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asBoolean; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.HashMap; @@ -21,78 +24,69 @@ import com.openshift.restclient.model.volume.IVolume; import com.openshift.restclient.model.volume.IVolumeMount; -/** - * - * @author Jeff Cantrill - * - */ -public class VolumeMount - extends ModelNodeAdapter - implements IVolumeMount, IVolume, ResourcePropertyKeys{ - - private static final String READONLY = "readOnly"; - private static final String MOUNT_PATH = "mountPath"; - - public VolumeMount(ModelNode node) { - this(node, null); - } - - public VolumeMount(ModelNode node, IVolumeMount source) { - super(node, new HashMap()); - if(source != null) { - setMountPath(source.getMountPath()); - setReadOnly(source.isReadOnly()); - setName(source.getName()); - } - } - - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), NAME); - } - - @Override - public void setName(String name) { - set(getNode(), getPropertyKeys(), NAME, name); - } - - @Override - public void setMountPath(String path) { - set(getNode(), getPropertyKeys(), MOUNT_PATH, path); - } - - @Override - public String getMountPath() { - return asString(getNode(), getPropertyKeys(), MOUNT_PATH); - } - - @Override - public void setReadOnly(boolean readonly) { - set(getNode(), getPropertyKeys(), READONLY, readonly); - } - - @Override - public boolean isReadOnly() { - return asBoolean(getNode(), getPropertyKeys(), READONLY); - } - - @Override - public boolean equals(Object obj) { - if(!(obj instanceof VolumeMount)) - return false; - VolumeMount other = (VolumeMount) obj; - return getName().equals(other.getName()) && - getMountPath().equals(other.getMountPath()) && - isReadOnly() == other.isReadOnly(); - } - - @Override - public int hashCode() { - int code = isReadOnly() ? 1 : 0; - code = code + getName().hashCode(); - return code + getMountPath().hashCode(); - } - - - +public class VolumeMount extends ModelNodeAdapter implements IVolumeMount, IVolume, ResourcePropertyKeys { + + private static final String READONLY = "readOnly"; + private static final String MOUNT_PATH = "mountPath"; + + public VolumeMount(ModelNode node) { + this(node, null); + } + + public VolumeMount(ModelNode node, IVolumeMount source) { + super(node, new HashMap()); + if (source != null) { + setMountPath(source.getMountPath()); + setReadOnly(source.isReadOnly()); + setName(source.getName()); + } + } + + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), NAME); + } + + @Override + public void setName(String name) { + set(getNode(), getPropertyKeys(), NAME, name); + } + + @Override + public void setMountPath(String path) { + set(getNode(), getPropertyKeys(), MOUNT_PATH, path); + } + + @Override + public String getMountPath() { + return asString(getNode(), getPropertyKeys(), MOUNT_PATH); + } + + @Override + public void setReadOnly(boolean readonly) { + set(getNode(), getPropertyKeys(), READONLY, readonly); + } + + @Override + public boolean isReadOnly() { + return asBoolean(getNode(), getPropertyKeys(), READONLY); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof VolumeMount)) { + return false; + } + VolumeMount other = (VolumeMount) obj; + return getName().equals(other.getName()) && getMountPath().equals(other.getMountPath()) + && isReadOnly() == other.isReadOnly(); + } + + @Override + public int hashCode() { + int code = isReadOnly() ? 1 : 0; + code = code + getName().hashCode(); + return code + getMountPath().hashCode(); + } + } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/VolumeSource.java b/src/main/java/com/openshift/internal/restclient/model/volume/VolumeSource.java index a708b156..98aea8c4 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/VolumeSource.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/VolumeSource.java @@ -8,37 +8,32 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.set; import java.util.HashMap; -import com.openshift.restclient.model.volume.VolumeType; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import com.openshift.internal.restclient.model.ModelNodeAdapter; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.model.volume.IVolumeSource; +import com.openshift.restclient.model.volume.VolumeType; -/** - * - * @author Jeff Cantrill - * - */ -public abstract class VolumeSource - extends ModelNodeAdapter - implements IVolumeSource, ResourcePropertyKeys { +public abstract class VolumeSource extends ModelNodeAdapter implements IVolumeSource, ResourcePropertyKeys { - public VolumeSource(ModelNode node) { - super(node, new HashMap()); - } + public VolumeSource(ModelNode node) { + super(node, new HashMap()); + } - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), NAME); - } + @Override + public String getName() { + return asString(getNode(), getPropertyKeys(), NAME); + } @Override public void setName(String name) { @@ -61,9 +56,10 @@ public static IVolumeSource create(ModelNode node) { } else if (node.has(VolumeType.PERSISTENT_VOLUME_CLAIM)) { return new PersistentVolumeClaimVolumeSource(node); } else if (node.has(VolumeType.HOST_PATH)) { - return new HostPathVolumeSource(node); + return new HostPathVolumeSource(node); } else { - return new VolumeSource(node) {}; + return new VolumeSource(node) { + }; } } } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/property/AbstractPersistentVolumeProperties.java b/src/main/java/com/openshift/internal/restclient/model/volume/property/AbstractPersistentVolumeProperties.java index bd2ae78d..43f7e07c 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/property/AbstractPersistentVolumeProperties.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/property/AbstractPersistentVolumeProperties.java @@ -4,8 +4,8 @@ import com.openshift.restclient.model.volume.property.IPersistentVolumeProperties; -abstract public class AbstractPersistentVolumeProperties implements IPersistentVolumeProperties { +public abstract class AbstractPersistentVolumeProperties implements IPersistentVolumeProperties { - public abstract void setProperties(ModelNode node); + public abstract void setProperties(ModelNode node); } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/property/HostPathVolumeProperties.java b/src/main/java/com/openshift/internal/restclient/model/volume/property/HostPathVolumeProperties.java index f638c593..7236ba12 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/property/HostPathVolumeProperties.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/property/HostPathVolumeProperties.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume.property; import java.util.Objects; @@ -16,52 +17,53 @@ import com.openshift.restclient.model.volume.property.IHostPathVolumeProperties; - public class HostPathVolumeProperties extends AbstractPersistentVolumeProperties implements IHostPathVolumeProperties { - private static final String PV_SPEC = "spec"; - private static final String PV_HOST_PATH = "hostPath"; - private static final String PATH = "path"; + private static final String PV_SPEC = "spec"; + private static final String PV_HOST_PATH = "hostPath"; + private static final String PATH = "path"; - private String path; + private String path; - public HostPathVolumeProperties(String path) { - this.path = path; - } + public HostPathVolumeProperties(String path) { + this.path = path; + } - @Override - public void setProperties(ModelNode node) { - ModelNode hostPath = node.get(PV_SPEC, PV_HOST_PATH); - hostPath.set(PATH, path); - } + @Override + public void setProperties(ModelNode node) { + ModelNode hostPath = node.get(PV_SPEC, PV_HOST_PATH); + hostPath.set(PATH, path); + } - @Override - public String getPath() { - return path; - } + @Override + public String getPath() { + return path; + } - @Override - public void setPath(String path) { - this.path = path; - } + @Override + public void setPath(String path) { + this.path = path; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - HostPathVolumeProperties that = (HostPathVolumeProperties) o; - return Objects.equals(path, that.path); - } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + HostPathVolumeProperties that = (HostPathVolumeProperties) o; + return Objects.equals(path, that.path); + } - @Override - public int hashCode() { - return Objects.hash(path); - } + @Override + public int hashCode() { + return Objects.hash(path); + } - @Override - public String toString() { - return "HostPathVolumeProperties{" + - "path='" + path + '\'' + - '}'; - } + @Override + public String toString() { + return "HostPathVolumeProperties{" + "path='" + path + '\'' + '}'; + } } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/property/NfsVolumeProperties.java b/src/main/java/com/openshift/internal/restclient/model/volume/property/NfsVolumeProperties.java index 2c4fc756..4e478c8c 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/property/NfsVolumeProperties.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/property/NfsVolumeProperties.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume.property; import java.util.Objects; @@ -16,78 +17,77 @@ import com.openshift.restclient.model.volume.property.INfsVolumeProperties; - public class NfsVolumeProperties extends AbstractPersistentVolumeProperties implements INfsVolumeProperties { - private static final String PV_SPEC = "spec"; - private static final String PV_NFS = "nfs"; - private static final String SERVER = "server"; - private static final String PATH = "path"; - private static final String READ_ONLY = "readOnly"; - - private String server; - private String path; - private boolean readOnly; - - public NfsVolumeProperties(String server, String path, boolean readOnly) { - this.server = server; - this.path = path; - this.readOnly = readOnly; - } - - public String getServer() { - return server; - } - - public void setServer(String server) { - this.server = server; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public boolean isReadOnly() { - return readOnly; - } - - public void setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - } - - @Override - public void setProperties(ModelNode node) { - ModelNode nfs = node.get(PV_SPEC, PV_NFS); - nfs.get(SERVER).set(server); - nfs.get(PATH).set(path); - nfs.get(READ_ONLY).set(readOnly); - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - NfsVolumeProperties nfsVolumeProperties = (NfsVolumeProperties) o; - return Objects.equals(readOnly, nfsVolumeProperties.readOnly) && - Objects.equals(server, nfsVolumeProperties.server) && - Objects.equals(path, nfsVolumeProperties.path); - } - - @Override - public int hashCode() { - return Objects.hash(server, path, readOnly); - } - - @Override - public String toString() { - return "NfsVolumeProperties{" + - "server='" + server + '\'' + - ", path='" + path + '\'' + - ", readOnly=" + readOnly + - '}'; - } + private static final String PV_SPEC = "spec"; + private static final String PV_NFS = "nfs"; + private static final String SERVER = "server"; + private static final String PATH = "path"; + private static final String READ_ONLY = "readOnly"; + + private String server; + private String path; + private boolean readOnly; + + public NfsVolumeProperties(String server, String path, boolean readOnly) { + this.server = server; + this.path = path; + this.readOnly = readOnly; + } + + public String getServer() { + return server; + } + + public void setServer(String server) { + this.server = server; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public boolean isReadOnly() { + return readOnly; + } + + public void setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + } + + @Override + public void setProperties(ModelNode node) { + ModelNode nfs = node.get(PV_SPEC, PV_NFS); + nfs.get(SERVER).set(server); + nfs.get(PATH).set(path); + nfs.get(READ_ONLY).set(readOnly); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + NfsVolumeProperties nfsVolumeProperties = (NfsVolumeProperties) o; + return Objects.equals(readOnly, nfsVolumeProperties.readOnly) + && Objects.equals(server, nfsVolumeProperties.server) && Objects.equals(path, nfsVolumeProperties.path); + } + + @Override + public int hashCode() { + return Objects.hash(server, path, readOnly); + } + + @Override + public String toString() { + return "NfsVolumeProperties{" + "server='" + server + '\'' + ", path='" + path + '\'' + ", readOnly=" + readOnly + + '}'; + } } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java index c59b9ea4..189ee6bc 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.okhttp; import org.apache.commons.lang.StringUtils; @@ -19,34 +20,31 @@ import okhttp3.Headers; import okhttp3.Request.Builder; -/** - * - * @author jeff.cantrill - * - */ -public class BasicChallangeHandler implements IChallangeHandler{ - - private IAuthorizationContext context; - - public BasicChallangeHandler(IAuthorizationContext context) { - this.context = context; - } - - @Override - public boolean canHandle(Headers headers) { - return OpenShiftAuthenticator.AUTHORIZATION_BASIC.equalsIgnoreCase(headers.get(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE)); - } - - @Override - public Builder handleChallange(Builder builder) { - StringBuilder value = new StringBuilder(); - if(StringUtils.isNotBlank(context.getUserName())) { - value.append(context.getUserName()).append(":"); - } - if(StringUtils.isNotBlank(context.getPassword())) { - value.append(context.getPassword()); - } - return builder.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION, IHttpConstants.AUTHORIZATION_BASIC + " " + Base64Coder.encode(value.toString())); - } - +public class BasicChallangeHandler implements IChallangeHandler { + + private IAuthorizationContext context; + + public BasicChallangeHandler(IAuthorizationContext context) { + this.context = context; + } + + @Override + public boolean canHandle(Headers headers) { + return OpenShiftAuthenticator.AUTHORIZATION_BASIC + .equalsIgnoreCase(headers.get(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE)); + } + + @Override + public Builder handleChallange(Builder builder) { + StringBuilder value = new StringBuilder(); + if (StringUtils.isNotBlank(context.getUserName())) { + value.append(context.getUserName()).append(":"); + } + if (StringUtils.isNotBlank(context.getPassword())) { + value.append(context.getPassword()); + } + return builder.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION, + IHttpConstants.AUTHORIZATION_BASIC + " " + Base64Coder.encode(value.toString())); + } + } \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java index eed411dd..8e9a7ee8 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.okhttp; import okhttp3.Headers; @@ -16,25 +17,23 @@ /** * A challange handler that can retrieve a token - * @author jeff.cantrill * */ -interface IChallangeHandler{ - - /** - * Is able to handle a challange given the auth mechanism - * provided in the header - * - * @param headers - * @return true if can handle, false otherwise - */ - boolean canHandle(Headers headers); - - /** - * Handle the challange - * - * @param builder - * @return - */ - Request.Builder handleChallange(Builder builder); +interface IChallangeHandler { + + /** + * Is able to handle a challange given the auth mechanism provided in the header + * + * @param headers the headers + * @return true if can handle, false otherwise + */ + boolean canHandle(Headers headers); + + /** + * Handle the challange + * + * @param builder + * @return + */ + Request.Builder handleChallange(Builder builder); } \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java index f00e4554..7cb64f77 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.okhttp; import java.io.IOException; @@ -35,108 +36,97 @@ /** * OkHttp Authenticator implementations for OpenShift 3 - * @author jeff.cantrill * */ -public class OpenShiftAuthenticator implements Authenticator, IHttpConstants{ - - public static final String ACCESS_TOKEN = "access_token"; - private static final String AUTH_ATTEMPTS = "X-OPENSHIFT-AUTH-ATTEMPTS"; - private static final String CSRF_TOKEN = "X-CSRF-Token"; - private static final String ERROR = "error"; - private static final String ERROR_DETAILS = "error_details"; - - private Collection challangeHandlers = new ArrayList<>(); - private OkHttpClient okClient; - private IClient client; - - @Override - public Request authenticate(Route route, Response response) throws IOException { - if(unauthorizedForCluster(response)){ - String requestUrl = response.request().url().toString(); - Request authRequest = new Request.Builder() - .addHeader(CSRF_TOKEN, "1") - .url(route.address().url().toString() + "oauth/authorize?response_type=token&client_id=openshift-challenging-client") - .build(); - try ( - Response authResponse = tryAuth(authRequest)){ - if(authResponse.isSuccessful()) { - String token = extractAndSetAuthContextToken(authResponse); - return response.request().newBuilder() - .header(IHttpConstants.PROPERTY_AUTHORIZATION, String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)) - .build(); - } - } - throw new UnauthorizedException(captureAuthDetails(requestUrl), ResponseCodeInterceptor.getStatus(response.body().string())); - } - - return null; - } - - private boolean unauthorizedForCluster(Response response) { - String requestHost = response.request().url().host(); - return response.code() == IHttpConstants.STATUS_UNAUTHORIZED && client.getBaseURL().getHost().equals(requestHost); - } - - private Response tryAuth(Request authRequest) throws IOException { - return okClient - .newBuilder() - .authenticator(new Authenticator() { - - @Override - public Request authenticate(Route route, Response response) throws IOException { - if(StringUtils.isNotBlank(response.request().header(AUTH_ATTEMPTS))) { - return null; - } - if(StringUtils.isNotBlank(response.header(IHttpConstants.PROPERTY_WWW_AUTHENTICATE))) { - for (IChallangeHandler challangeHandler : challangeHandlers) { - if(!challangeHandler.canHandle(response.headers())) { - Builder requestBuilder = response.request().newBuilder() - .header(AUTH_ATTEMPTS, "1"); - return challangeHandler.handleChallange(requestBuilder).build(); - } - } - } - return null; - } - }) - .followRedirects(false) - .followRedirects(false) - .build() - .newCall(authRequest).execute(); - } - - private IAuthorizationDetails captureAuthDetails(String url) { - IAuthorizationDetails details = null; - Map pairs = URIUtils.splitFragment(url); - if (pairs.containsKey(ERROR)) { - details = new AuthorizationDetails(pairs.get(ERROR), pairs.get(ERROR_DETAILS)); - } - return details; - } - - private String extractAndSetAuthContextToken(Response response) { - String token = null; - Map pairs = URIUtils.splitFragment(response.header(PROPERTY_LOCATION)); - if (pairs.containsKey(ACCESS_TOKEN)) { - token = pairs.get(ACCESS_TOKEN); - IAuthorizationContext authContext = client.getAuthorizationContext(); - if(authContext != null) { - authContext.setToken(token); - } - } - return token; - } - - - public void setOkClient(OkHttpClient okClient) { - this.okClient = okClient; - } - - public void setClient(DefaultClient client) { - this.client = client; - challangeHandlers.clear(); - challangeHandlers.add(new BasicChallangeHandler(client.getAuthorizationContext())); - } +public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { + + public static final String ACCESS_TOKEN = "access_token"; + private static final String AUTH_ATTEMPTS = "X-OPENSHIFT-AUTH-ATTEMPTS"; + private static final String CSRF_TOKEN = "X-CSRF-Token"; + private static final String ERROR = "error"; + private static final String ERROR_DETAILS = "error_details"; + + private Collection challangeHandlers = new ArrayList<>(); + private OkHttpClient okClient; + private IClient client; + + @Override + public Request authenticate(Route route, Response response) throws IOException { + if (unauthorizedForCluster(response)) { + String requestUrl = response.request().url().toString(); + Request authRequest = new Request.Builder().addHeader(CSRF_TOKEN, "1").url(route.address().url().toString() + + "oauth/authorize?response_type=token&client_id=openshift-challenging-client").build(); + try (Response authResponse = tryAuth(authRequest)) { + if (authResponse.isSuccessful()) { + String token = extractAndSetAuthContextToken(authResponse); + return response.request().newBuilder().header(IHttpConstants.PROPERTY_AUTHORIZATION, + String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)).build(); + } + } + throw new UnauthorizedException(captureAuthDetails(requestUrl), + ResponseCodeInterceptor.getStatus(response.body().string())); + } + + return null; + } + + private boolean unauthorizedForCluster(Response response) { + String requestHost = response.request().url().host(); + return response.code() == IHttpConstants.STATUS_UNAUTHORIZED + && client.getBaseURL().getHost().equals(requestHost); + } + + private Response tryAuth(Request authRequest) throws IOException { + return okClient.newBuilder().authenticator(new Authenticator() { + + @Override + public Request authenticate(Route route, Response response) throws IOException { + if (StringUtils.isNotBlank(response.request().header(AUTH_ATTEMPTS))) { + return null; + } + if (StringUtils.isNotBlank(response.header(IHttpConstants.PROPERTY_WWW_AUTHENTICATE))) { + for (IChallangeHandler challangeHandler : challangeHandlers) { + if (!challangeHandler.canHandle(response.headers())) { + Builder requestBuilder = response.request().newBuilder().header(AUTH_ATTEMPTS, "1"); + return challangeHandler.handleChallange(requestBuilder).build(); + } + } + } + return null; + } + }).followRedirects(false).followRedirects(false).build().newCall(authRequest).execute(); + } + + private IAuthorizationDetails captureAuthDetails(String url) { + IAuthorizationDetails details = null; + Map pairs = URIUtils.splitFragment(url); + if (pairs.containsKey(ERROR)) { + details = new AuthorizationDetails(pairs.get(ERROR), pairs.get(ERROR_DETAILS)); + } + return details; + } + + private String extractAndSetAuthContextToken(Response response) { + String token = null; + Map pairs = URIUtils.splitFragment(response.header(PROPERTY_LOCATION)); + if (pairs.containsKey(ACCESS_TOKEN)) { + token = pairs.get(ACCESS_TOKEN); + IAuthorizationContext authContext = client.getAuthorizationContext(); + if (authContext != null) { + authContext.setToken(token); + } + } + return token; + } + + public void setOkClient(OkHttpClient okClient) { + this.okClient = okClient; + } + + public void setClient(DefaultClient client) { + this.client = client; + challangeHandlers.clear(); + challangeHandlers.add(new BasicChallangeHandler(client.getAuthorizationContext())); + } } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index a79fc2c5..a1d25ef5 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -8,8 +8,14 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.okhttp; +import java.io.IOException; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; + import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.authorization.AuthorizationDetails; import com.openshift.internal.restclient.model.Status; @@ -21,119 +27,118 @@ import com.openshift.restclient.authorization.ResourceForbiddenException; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IStatus; + import okhttp3.Interceptor; import okhttp3.Response; -import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; - -import java.io.IOException; /** * Interpret response codes and handle accordingly - * - * @author jeff.cantrill * */ public class ResponseCodeInterceptor implements Interceptor, IHttpConstants { - - public static final String X_OPENSHIFT_IGNORE_RCI = "X-OPENSHIFT-IGNORE-RCI"; - - private static final Logger LOGGER = Logger.getLogger(ResponseCodeInterceptor.class); - - private IClient client; - - /** - * If a request tag() implements this interface, HTTP errors - * will not throw OpenShift exceptions. - */ - public interface Ignore{} - - - @Override - public Response intercept(Chain chain) throws IOException { - Response response = chain.proceed(chain.request()); - if(!response.isSuccessful() && StringUtils.isBlank(response.request().header(X_OPENSHIFT_IGNORE_RCI))) { - switch(response.code()) { - case STATUS_UPGRADE_PROTOCOL: - case STATUS_MOVED_PERMANENTLY: - break; - case STATUS_MOVED_TEMPORARILY: - response = makeSuccessIfAuthorized(response); - break; - default: - if ( response.request().tag() instanceof Ignore == false ) { - throw createOpenShiftException(client, response, null); - } - } - } - return response; - } - - private Response makeSuccessIfAuthorized(Response response) { - String location = response.header(PROPERTY_LOCATION); - if(StringUtils.isNotBlank(location) && URIUtils.splitFragment(location).containsKey(OpenShiftAuthenticator.ACCESS_TOKEN)) { - response = response.newBuilder() - .request(response.request()) - .code(STATUS_OK) - .headers(response.headers()) - .build(); - } - return response; - } - - public void setClient(DefaultClient client) { - this.client = client; - } - - public static IStatus getStatus(String response) { - if(response != null && response.startsWith("{")) { - return new Status(response); - } - return null; - } - - public static OpenShiftException createOpenShiftException(IClient client, Response response, Throwable e) throws IOException{ - LOGGER.debug(response, e); - IStatus status = getStatus(response.body().string()); - int responseCode = response.code(); - if(status != null && status.getCode() != 0) { - responseCode = status.getCode(); - } - switch(responseCode) { - case STATUS_BAD_REQUEST: - return new BadRequestException(e, status, response.request().url().toString()); - case STATUS_FORBIDDEN: - return new ResourceForbiddenException(status != null ? status.getMessage() : "Resource Forbidden", status, e); - case STATUS_UNAUTHORIZED: - String link = String.format("%s/oauth/token/request", client.getBaseURL()); - AuthorizationDetails details = new AuthorizationDetails(response.headers(), link); - return new com.openshift.restclient.authorization.UnauthorizedException(details, status); - case IHttpConstants.STATUS_NOT_FOUND: - return new NotFoundException(e, status, status == null ? "Not Found" : status.getMessage()); - default: - return new OpenShiftException(e, status, "Exception trying to %s %s response code: %s", response.request().method(), response.request().url().toString(), responseCode); - } - } - - public static OpenShiftException createOpenShiftException(IClient client, int responseCode, String message, String response, Throwable e) throws IOException{ - LOGGER.debug(response, e); - IStatus status = getStatus(response); - if(status != null && status.getCode() != 0) { - responseCode = status.getCode(); - } - switch(responseCode) { - case STATUS_BAD_REQUEST: - return new BadRequestException(e, status, response); - case STATUS_FORBIDDEN: - return new ResourceForbiddenException(status != null ? status.getMessage() : "Resource Forbidden", status, e); - case STATUS_UNAUTHORIZED: - return new com.openshift.restclient.authorization.UnauthorizedException(client.getAuthorizationContext().getAuthorizationDetails(), status); - case IHttpConstants.STATUS_NOT_FOUND: - return new NotFoundException(status == null ? "Not Found" : status.getMessage()); - default: - return new OpenShiftException(e, status, "Exception trying to fetch %s response code: %s", response, responseCode); - } - } - - + + public static final String X_OPENSHIFT_IGNORE_RCI = "X-OPENSHIFT-IGNORE-RCI"; + + private static final Logger LOGGER = Logger.getLogger(ResponseCodeInterceptor.class); + + private IClient client; + + /** + * If a request tag() implements this interface, HTTP errors will not throw + * OpenShift exceptions. + */ + public interface Ignore { + } + + @Override + public Response intercept(Chain chain) throws IOException { + Response response = chain.proceed(chain.request()); + if (!response.isSuccessful() && StringUtils.isBlank(response.request().header(X_OPENSHIFT_IGNORE_RCI))) { + switch (response.code()) { + case STATUS_UPGRADE_PROTOCOL: + case STATUS_MOVED_PERMANENTLY: + break; + case STATUS_MOVED_TEMPORARILY: + response = makeSuccessIfAuthorized(response); + break; + default: + if (response.request().tag() instanceof Ignore == false) { + throw createOpenShiftException(client, response, null); + } + } + } + return response; + } + + private Response makeSuccessIfAuthorized(Response response) { + String location = response.header(PROPERTY_LOCATION); + if (StringUtils.isNotBlank(location) + && URIUtils.splitFragment(location).containsKey(OpenShiftAuthenticator.ACCESS_TOKEN)) { + response = response.newBuilder().request(response.request()).code(STATUS_OK).headers(response.headers()) + .build(); + } + return response; + } + + public void setClient(DefaultClient client) { + this.client = client; + } + + public static IStatus getStatus(String response) { + if (response != null && response.startsWith("{")) { + return new Status(response); + } + return null; + } + + public static OpenShiftException createOpenShiftException(IClient client, Response response, Throwable e) + throws IOException { + LOGGER.debug(response, e); + IStatus status = getStatus(response.body().string()); + int responseCode = response.code(); + if (status != null && status.getCode() != 0) { + responseCode = status.getCode(); + } + switch (responseCode) { + case STATUS_BAD_REQUEST: + return new BadRequestException(e, status, response.request().url().toString()); + case STATUS_FORBIDDEN: + return new ResourceForbiddenException(status != null ? status.getMessage() : "Resource Forbidden", status, + e); + case STATUS_UNAUTHORIZED: + String link = String.format("%s/oauth/token/request", client.getBaseURL()); + AuthorizationDetails details = new AuthorizationDetails(response.headers(), link); + return new com.openshift.restclient.authorization.UnauthorizedException(details, status); + case IHttpConstants.STATUS_NOT_FOUND: + return new NotFoundException(e, status, status == null ? "Not Found" : status.getMessage()); + default: + return new OpenShiftException(e, status, "Exception trying to %s %s response code: %s", + response.request().method(), response.request().url().toString(), responseCode); + } + } + + public static OpenShiftException createOpenShiftException(IClient client, int responseCode, String message, + String response, Throwable e) throws IOException { + LOGGER.debug(response, e); + IStatus status = getStatus(response); + if (status != null && status.getCode() != 0) { + responseCode = status.getCode(); + } + switch (responseCode) { + case STATUS_BAD_REQUEST: + return new BadRequestException(e, status, response); + case STATUS_FORBIDDEN: + return new ResourceForbiddenException(status != null ? status.getMessage() : "Resource Forbidden", status, + e); + case STATUS_UNAUTHORIZED: + return new com.openshift.restclient.authorization.UnauthorizedException( + client.getAuthorizationContext().getAuthorizationDetails(), status); + case IHttpConstants.STATUS_NOT_FOUND: + return new NotFoundException(status == null ? "Not Found" : status.getMessage()); + default: + return new OpenShiftException(e, status, "Exception trying to fetch %s response code: %s", response, + responseCode); + } + } + } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index 7e0e2601..9dd39c45 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.okhttp; import java.io.IOException; @@ -49,173 +50,170 @@ public class WatchClient implements IWatcher, IHttpConstants { - private static final Logger LOGGER = LoggerFactory.getLogger(WatchClient.class); - private DefaultClient client; - private OkHttpClient okClient; - private AtomicReference status = new AtomicReference<>(Status.Stopped); - private IApiTypeMapper typeMappings; - private Map endpointMap = Collections.synchronizedMap(new HashMap<>()); - - private enum Status { - Started, - Starting, - Stopped, - Stopping - } - - public WatchClient(DefaultClient client, IApiTypeMapper typeMapper, OkHttpClient okClient) { - this.client = client; - this.typeMappings = typeMapper; - this.okClient = okClient; - } - - @Override - public void stop() { - if(status.compareAndSet(Status.Started, Status.Stopping)) { - Map endpoints = new HashMap<>(endpointMap); - endpointMap.clear(); - endpoints.values().forEach(w->w.close()); - status.set(Status.Stopped); - } - } - - public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatchListener listener) { - - if(status.compareAndSet(Status.Stopped, Status.Starting)) { - try { - for (String kind : kinds) { - WatchEndpoint socket = new WatchEndpoint(client, listener, kind); - final String resourceVersion = getResourceVersion(kind, namespace, socket); - - final String endpoint = new URLBuilder(client.getBaseURL(), this.typeMappings) - .kind(kind) - .namespace(namespace) - .watch() - .addParmeter(ResourcePropertyKeys.RESOURCE_VERSION, resourceVersion) - .websocket(); - Request request = client.newRequestBuilderTo(endpoint) - .header(PROPERTY_ORIGIN, client.getBaseURL().toString()) - .header(PROPERTY_USER_AGENT, "openshift-restclient-java") - .build(); - WebSocketCall call = WebSocketCall.create(okClient.newBuilder().build(), request); - socket.setCall(call); - endpointMap.put(kind, socket); - call.enqueue(socket); - } - status.set(Status.Started); - } catch (Exception e) { - endpointMap.clear(); - status.set(Status.Stopped); - try { - throw ResponseCodeInterceptor.createOpenShiftException(client, 0, String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), null, e); - } catch (IOException e1) { - throw new OpenShiftException(e1, "IOException trying to create an OpenShift specific exception"); - } - } - } - return this; - } - - private String getResourceVersion(String kind, String namespace, WatchEndpoint endpoint) throws Exception{ - IList list = client.get(kind, namespace); - Collection items = list.getItems(); - List resources = new ArrayList<>(items.size()); - resources.addAll(items); - endpoint.setResources(resources); - return list.getResourceVersion(); - } - - static class WatchEndpoint implements WebSocketListener{ - - private IOpenShiftWatchListener listener; - private List resources; - private final String kind; - private final IClient client; - private WebSocket wsClient; - private WebSocketCall call; - - public WatchEndpoint(IClient client, IOpenShiftWatchListener listener, String kind) { - this.listener = listener; - this.kind = kind; - this.client = client; - } - - public void setCall(WebSocketCall call) { - this.call = call; - } - - void close() { - try { - if(wsClient != null) { - wsClient.close(STATUS_NORMAL_STOP, "Client was asked to stop."); - wsClient = null; - } - if(call != null) { - call.cancel(); - } - listener.disconnected(); - } catch (Exception e) { - LOGGER.debug("Unable to stop the watch client",e); - }finally { - wsClient = null; - } - } - - public void setResources(List resources) { - this.resources = resources; - } - - @Override - public void onClose(int statusCode, String reason) { - LOGGER.debug("WatchSocket closed for kind: {}, code: {}, reason: {}", new Object[]{kind, statusCode, reason}); - listener.disconnected(); - } - - @Override - public void onFailure(IOException err, Response response) { - LOGGER.debug("WatchSocket Error for kind {}: {}", kind, err); - try { - if (response == null) { - listener.error(ResponseCodeInterceptor.createOpenShiftException(client, 0, "", "", err)); - } else if (response.code() == IHttpConstants.STATUS_OK && err instanceof ProtocolException) { - // Just swallow it. Means the feature isn't supported in this OS server version yet. - // WebSocket creates error "Expected HTTP 101 response but was '200 OK'" - // This is described in the web socket specification. - LOGGER.debug("The feature isn't supported", err); - } else { - listener.error(ResponseCodeInterceptor.createOpenShiftException(client, response.code(), - response.body().string(), response.request().url().toString(), err)); - } - } catch (IOException e) { - LOGGER.error("IOException trying to notify listener of specific OpenShiftException", err); - listener.error(err); - } - } - - @Override - public void onMessage(ResponseBody body) throws IOException { - String message = body.string(); - LOGGER.debug(message); - ModelNode node = ModelNode.fromJSONString(message); - IOpenShiftWatchListener.ChangeType event = new ChangeType(node.get("type").asString()); - IResource resource = client.getResourceFactory().create(node.get("object").toJSONString(true)); - if(StringUtils.isEmpty(resource.getKind())) { - LOGGER.error("Unable to determine resource kind from: " + node.get("object").toJSONString(false)); - } - listener.received(resource, event); - } - - @Override - public void onOpen(WebSocket socket, Response response) { - LOGGER.debug("WatchSocket connected for {}", kind); - wsClient = socket; - listener.connected(resources); - } - - @Override - public void onPong(Buffer buffer) { - } - - } + private static final Logger LOGGER = LoggerFactory.getLogger(WatchClient.class); + private DefaultClient client; + private OkHttpClient okClient; + private AtomicReference status = new AtomicReference<>(Status.Stopped); + private IApiTypeMapper typeMappings; + private Map endpointMap = Collections.synchronizedMap(new HashMap<>()); + + private enum Status { + Started, Starting, Stopped, Stopping + } + + public WatchClient(DefaultClient client, IApiTypeMapper typeMapper, OkHttpClient okClient) { + this.client = client; + this.typeMappings = typeMapper; + this.okClient = okClient; + } + + @Override + public void stop() { + if (status.compareAndSet(Status.Started, Status.Stopping)) { + Map endpoints = new HashMap<>(endpointMap); + endpointMap.clear(); + endpoints.values().forEach(w -> w.close()); + status.set(Status.Stopped); + } + } + + public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatchListener listener) { + + if (status.compareAndSet(Status.Stopped, Status.Starting)) { + try { + for (String kind : kinds) { + WatchEndpoint socket = new WatchEndpoint(client, listener, kind); + final String resourceVersion = getResourceVersion(kind, namespace, socket); + + final String endpoint = new URLBuilder(client.getBaseURL(), this.typeMappings).kind(kind) + .namespace(namespace).watch() + .addParmeter(ResourcePropertyKeys.RESOURCE_VERSION, resourceVersion).websocket(); + Request request = client.newRequestBuilderTo(endpoint) + .header(PROPERTY_ORIGIN, client.getBaseURL().toString()) + .header(PROPERTY_USER_AGENT, "openshift-restclient-java").build(); + WebSocketCall call = WebSocketCall.create(okClient.newBuilder().build(), request); + socket.setCall(call); + endpointMap.put(kind, socket); + call.enqueue(socket); + } + status.set(Status.Started); + } catch (Exception e) { + endpointMap.clear(); + status.set(Status.Stopped); + try { + throw ResponseCodeInterceptor.createOpenShiftException(client, 0, + String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), + null, e); + } catch (IOException e1) { + throw new OpenShiftException(e1, "IOException trying to create an OpenShift specific exception"); + } + } + } + return this; + } + + private String getResourceVersion(String kind, String namespace, WatchEndpoint endpoint) throws Exception { + IList list = client.get(kind, namespace); + Collection items = list.getItems(); + List resources = new ArrayList<>(items.size()); + resources.addAll(items); + endpoint.setResources(resources); + return list.getResourceVersion(); + } + + static class WatchEndpoint implements WebSocketListener { + + private IOpenShiftWatchListener listener; + private List resources; + private final String kind; + private final IClient client; + private WebSocket wsClient; + private WebSocketCall call; + + public WatchEndpoint(IClient client, IOpenShiftWatchListener listener, String kind) { + this.listener = listener; + this.kind = kind; + this.client = client; + } + + public void setCall(WebSocketCall call) { + this.call = call; + } + + void close() { + try { + if (wsClient != null) { + wsClient.close(STATUS_NORMAL_STOP, "Client was asked to stop."); + wsClient = null; + } + if (call != null) { + call.cancel(); + } + listener.disconnected(); + } catch (Exception e) { + LOGGER.debug("Unable to stop the watch client", e); + } finally { + wsClient = null; + } + } + + public void setResources(List resources) { + this.resources = resources; + } + + @Override + public void onClose(int statusCode, String reason) { + LOGGER.debug("WatchSocket closed for kind: {}, code: {}, reason: {}", + new Object[] { kind, statusCode, reason }); + listener.disconnected(); + } + + @Override + public void onFailure(IOException err, Response response) { + LOGGER.debug("WatchSocket Error for kind {}: {}", kind, err); + try { + if (response == null) { + listener.error(ResponseCodeInterceptor.createOpenShiftException(client, 0, "", "", err)); + } else if (response.code() == IHttpConstants.STATUS_OK && err instanceof ProtocolException) { + // Just swallow it. Means the feature isn't supported in this OS server version + // yet. + // WebSocket creates error "Expected HTTP 101 response but was '200 OK'" + // This is described in the web socket specification. + LOGGER.debug("The feature isn't supported", err); + } else { + listener.error(ResponseCodeInterceptor.createOpenShiftException(client, response.code(), + response.body().string(), response.request().url().toString(), err)); + } + } catch (IOException e) { + LOGGER.error("IOException trying to notify listener of specific OpenShiftException", err); + listener.error(err); + } + } + + @Override + public void onMessage(ResponseBody body) throws IOException { + String message = body.string(); + LOGGER.debug(message); + ModelNode node = ModelNode.fromJSONString(message); + IOpenShiftWatchListener.ChangeType event = new ChangeType(node.get("type").asString()); + IResource resource = client.getResourceFactory().create(node.get("object").toJSONString(true)); + if (StringUtils.isEmpty(resource.getKind())) { + LOGGER.error("Unable to determine resource kind from: " + node.get("object").toJSONString(false)); + } + listener.received(resource, event); + } + + @Override + public void onOpen(WebSocket socket, Response response) { + LOGGER.debug("WatchSocket connected for {}", kind); + wsClient = socket; + listener.connected(resources); + } + + @Override + public void onPong(Buffer buffer) { + } + + } } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java b/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java index 7f20eebe..8ea9642e 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.okhttp; import java.io.IOException; @@ -20,29 +21,28 @@ /** * Adapter to WebSocketListener - * @author jeff.cantrill * */ -public class WebSocketAdapter implements WebSocketListener{ +public class WebSocketAdapter implements WebSocketListener { + + @Override + public void onOpen(WebSocket webSocket, Response response) { + } - @Override - public void onOpen(WebSocket webSocket, Response response) { - } + @Override + public void onFailure(IOException e, Response response) { + } - @Override - public void onFailure(IOException e, Response response) { - } + @Override + public void onMessage(ResponseBody message) throws IOException { + } - @Override - public void onMessage(ResponseBody message) throws IOException { - } + @Override + public void onPong(Buffer payload) { + } - @Override - public void onPong(Buffer payload) { - } + @Override + public void onClose(int code, String reason) { + } - @Override - public void onClose(int code, String reason) { - } - } \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/util/Assert.java b/src/main/java/com/openshift/internal/util/Assert.java index 11ea4a1d..626eb356 100644 --- a/src/main/java/com/openshift/internal/util/Assert.java +++ b/src/main/java/com/openshift/internal/util/Assert.java @@ -8,40 +8,39 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.util; - +package com.openshift.internal.util; /** * @author André Dietisheim */ public class Assert { - public static final class AssertionFailedException extends RuntimeException { - - private static final long serialVersionUID = 1L; - - public AssertionFailedException() { - super(); - } - - } - - public static V notNull(V value) { - if (value == null) { - throw new AssertionFailedException(); - } - return value; - } - - public static void notEmpty(String value) { - notNull(value); - isTrue(!value.isEmpty()); - } - - public static void isTrue(boolean assertion) { - if (!assertion) { - throw new AssertionFailedException(); - } - } + public static final class AssertionFailedException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public AssertionFailedException() { + super(); + } + + } + + public static V notNull(V value) { + if (value == null) { + throw new AssertionFailedException(); + } + return value; + } + + public static void notEmpty(String value) { + notNull(value); + isTrue(!value.isEmpty()); + } + + public static void isTrue(boolean assertion) { + if (!assertion) { + throw new AssertionFailedException(); + } + } } diff --git a/src/main/java/com/openshift/internal/util/JBossDmrExtentions.java b/src/main/java/com/openshift/internal/util/JBossDmrExtentions.java index 6c57d1e6..8cc7d26b 100644 --- a/src/main/java/com/openshift/internal/util/JBossDmrExtentions.java +++ b/src/main/java/com/openshift/internal/util/JBossDmrExtentions.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.util; import java.io.PrintWriter; @@ -24,180 +25,193 @@ import org.jboss.dmr.ModelType; /** - * Helper extensions to those provided - * by JBoss DMR library + * Helper extensions to those provided by JBoss DMR library * - * @author Jeff Cantrill */ public class JBossDmrExtentions { - - private JBossDmrExtentions (){ - } - - /** - * Serialize a node and sanitize the output - * by removing nulls - * @param node - * @param compact - * @return - */ - public static String toJsonString(ModelNode node, boolean compact) { - sanitize(node); - StringWriter writer = new StringWriter(); - node.writeJSONString(new PrintWriter(writer,true), compact); - return writer.toString(); - } - - private static void sanitize(ModelNode node) { - if(node.getType() == ModelType.OBJECT) { - Collection emptyKeys = new ArrayList<>(node.keys().size()); - for (String key : node.keys()) { - ModelNode child = node.get(key); - if(child.getType() == ModelType.UNDEFINED) { - emptyKeys.add(key); - }else { - sanitize(child); - } - if(child.getType() == ModelType.LIST) { - List entries = child.asList(); - if(entries.isEmpty()) { - emptyKeys.add(key); - } else { - final int listSize = entries.size(); - List nulls = new ArrayList<>(listSize); - for (int i=0; i < listSize; ++i) { - ModelNode e = entries.get(i); - if(!e.isDefined()) { - nulls.add(i); - }else { - sanitize(e); - } - } - Collections.reverse(nulls); - nulls.stream().forEach((i)->child.remove(i)); - if(child.asList().size() == 0) { - emptyKeys.add(key); - } - } - - } - } - emptyKeys.stream().forEach((key)->node.remove(key)); - } - } - - public static void set(ModelNode node, Map propertyKeys, String key, boolean value){ - if(propertyKeys == null) return; - ModelNode modelNode = node.get(getPath(propertyKeys, key)); - modelNode.set(value); - } - public static void set(ModelNode node, Map propertyKeys, String key, String value){ - if(propertyKeys == null) return; - set(node, getPath(propertyKeys, key), value); - } + private JBossDmrExtentions() { + } - public static void set(ModelNode node, String [] path, String value){ - if(value == null) return; - ModelNode modelNode = node.get(path); - modelNode.set(value); - } - - public static void set(ModelNode node, Map propertyKeys, String key, int value) { - if(propertyKeys == null) return; - ModelNode modelNode = node.get(getPath(propertyKeys, key)); - modelNode.set(value); - } + /** + * Serialize a node and sanitize the output by removing nulls + * + */ + public static String toJsonString(ModelNode node, boolean compact) { + sanitize(node); + StringWriter writer = new StringWriter(); + node.writeJSONString(new PrintWriter(writer, true), compact); + return writer.toString(); + } - public static void set(ModelNode node, Map propertyKeys, String key, Map values) { - if(propertyKeys == null) return; - ModelNode modelNode = node.get(getPath(propertyKeys, key)); - for (Entry entry : values.entrySet()) { - modelNode.get(entry.getKey()).set(entry.getValue()); - } - } + private static void sanitize(ModelNode node) { + if (node.getType() == ModelType.OBJECT) { + Collection emptyKeys = new ArrayList<>(node.keys().size()); + for (String key : node.keys()) { + ModelNode child = node.get(key); + if (child.getType() == ModelType.UNDEFINED) { + emptyKeys.add(key); + } else { + sanitize(child); + } + if (child.getType() == ModelType.LIST) { + List entries = child.asList(); + if (entries.isEmpty()) { + emptyKeys.add(key); + } else { + final int listSize = entries.size(); + List nulls = new ArrayList<>(listSize); + for (int i = 0; i < listSize; ++i) { + ModelNode e = entries.get(i); + if (!e.isDefined()) { + nulls.add(i); + } else { + sanitize(e); + } + } + Collections.reverse(nulls); + nulls.stream().forEach((i) -> child.remove(i)); + if (child.asList().size() == 0) { + emptyKeys.add(key); + } + } - /** - * - * @param root - * @param propertyKeys - * @param key - * @return - * @throws UnregisteredPropertyException if the property is not found in the property map - */ - public static Map asMap(ModelNode root, Map propertyKeys, String key){ - HashMap map = new HashMap(); - if(propertyKeys != null){ - String [] path = getPath(propertyKeys, key); - if(root.has(path)) { - ModelNode node = root.get(path); - if( !node.isDefined()) - return map; - for (String k : node.keys()) { - map.put(k, node.get(k).asString()); - } - } - } - return map; - } + } + } + emptyKeys.stream().forEach((key) -> node.remove(key)); + } + } + + public static void set(ModelNode node, Map propertyKeys, String key, boolean value) { + if (propertyKeys == null) { + return; + } + ModelNode modelNode = node.get(getPath(propertyKeys, key)); + modelNode.set(value); + } + + public static void set(ModelNode node, Map propertyKeys, String key, String value) { + if (propertyKeys == null) { + return; + } + set(node, getPath(propertyKeys, key), value); + } + + public static void set(ModelNode node, String[] path, String value) { + if (value == null) { + return; + } + ModelNode modelNode = node.get(path); + modelNode.set(value); + } + + public static void set(ModelNode node, Map propertyKeys, String key, int value) { + if (propertyKeys == null) { + return; + } + ModelNode modelNode = node.get(getPath(propertyKeys, key)); + modelNode.set(value); + } + + public static void set(ModelNode node, Map propertyKeys, String key, Map values) { + if (propertyKeys == null) { + return; + } + ModelNode modelNode = node.get(getPath(propertyKeys, key)); + for (Entry entry : values.entrySet()) { + modelNode.get(entry.getKey()).set(entry.getValue()); + } + } + + public static void set(ModelNode root, Map propertyKeys, String key, Set values) { + String[] path = getPath(propertyKeys, key); + ModelNode node = root.get(path); + for (String entry : values) { + node.add(entry); + } + } + + public static void set(ModelNode root, Map propertyKeys, String key, String... values) { + String[] path = getPath(propertyKeys, key); + ModelNode node = root.get(path); + for (String value : values) { + node.add(value); + } + } + + /** + * + * @throws UnregisteredPropertyException + * if the property is not found in the property map + */ + public static Map asMap(ModelNode root, Map propertyKeys, String key) { + HashMap map = new HashMap(); + if (propertyKeys != null) { + String[] path = getPath(propertyKeys, key); + if (root.has(path)) { + ModelNode node = root.get(path); + if (!node.isDefined()) { + return map; + } + for (String k : node.keys()) { + map.put(k, node.get(k).asString()); + } + } + } + return map; + } + + /** + * T the type to return which are valid DMR types (e.g. asString()). String is + * currently only supported. Add more as needed + * + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static Set asSet(ModelNode root, Map propertyKeys, String key, ModelType type) { + Set set = new HashSet(); + String[] path = getPath(propertyKeys, key); + if (root.has(path)) { + ModelNode node = root.get(path); + if (!node.isDefined()) { + return set; + } + for (ModelNode entry : node.asList()) { + Object instance = null; + switch (type) { + case STRING: + instance = entry.asString(); + break; + case BOOLEAN: + instance = entry.asBoolean(); + break; + case INT: + instance = entry.asInt(); + break; + default: + } + set.add(instance); + } + } + return set; + } - /** - * the type to return which are valid DMR types (e.g. asString()). - * String is currently only supported. Add more as needed - * @param root - * @param propertyKeys - * @param key - * @param type - * @return - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public static Set asSet(ModelNode root, Map propertyKeys, String key, ModelType type){ - Set set = new HashSet(); - String [] path = getPath(propertyKeys, key); - if(root.has(path)){ - ModelNode node = root.get(path); - if( !node.isDefined()) - return set; - for (ModelNode entry : node.asList()) { - Object instance = null; - switch(type) { - case STRING: - instance = entry.asString(); - break; - case BOOLEAN: - instance = entry.asBoolean(); - break; - case INT: - instance = entry.asInt(); - default: - } - set.add(instance); - } - } - return set; - } - - /** - * Returns an ordered List for items that need to be ordered - * such as command Args for containers. - * - * @param root - * @param propertyKeys - * @param key - * @param type - * @return + /** + * T Returns an ordered List for items that need to be ordered such as command + * Args for containers. + * */ @SuppressWarnings({ "rawtypes", "unchecked" }) - public static List asList(ModelNode root, Map propertyKeys, String key, ModelType type){ - List list = new ArrayList(); - String [] path = getPath(propertyKeys, key); - if(root.has(path)){ + public static List asList(ModelNode root, Map propertyKeys, String key, ModelType type) { + List list = new ArrayList(); + String[] path = getPath(propertyKeys, key); + if (root.has(path)) { ModelNode node = root.get(path); - if( !node.isDefined()) + if (!node.isDefined()) { return list; + } for (ModelNode entry : node.asList()) { Object instance = null; - switch(type) { + switch (type) { case STRING: instance = entry.asString(); break; @@ -206,6 +220,7 @@ public static List asList(ModelNode root, Map propertyKeys, S break; case INT: instance = entry.asInt(); + break; default: } list.add(instance); @@ -213,92 +228,72 @@ public static List asList(ModelNode root, Map propertyKeys, S } return list; } - - public static void set(ModelNode root, Map propertyKeys, String key, Set values) { - String [] path = getPath(propertyKeys, key); - ModelNode node = root.get(path); - for (String entry : values) { - node.add(entry); - } - } - public static void set(ModelNode root, Map propertyKeys, String key, String... values) { - String [] path = getPath(propertyKeys, key); - ModelNode node = root.get(path); - for (String value : values) { - node.add(value); - } - } - - /** - * - * @param node - * @param propertyKeys - * @param key - * @return - * @throws UnregisteredPropertyException if the property is not found in the property map - */ - public static int asInt(ModelNode node, Map propertyKeys, String key){ - String [] path = getPath(propertyKeys, key); - if(node.has(path)) { - ModelNode modelNode = node.get(path); - if( !modelNode.isDefined()){ - return 0; - } - return modelNode.asInt(); - } - return 0; - } - - /** - * - * @param node - * @param propertyKeys - * @param key - * @return - * @throws UnregisteredPropertyException if the property is not found in the property map - */ - public static String asString(ModelNode node, Map propertyKeys, String key){ - String[] path = getPath(propertyKeys, key); - if(!node.has(path)) return ""; - ModelNode modelNode = node.get(path); - if( !modelNode.isDefined()){ - return ""; - } - return modelNode.asString(); - } - - /** - * - * @param node - * @param propertyKeys - * @param key - * @return - * @throws UnregisteredPropertyException if the property is not found in the property map - */ - public static boolean asBoolean(ModelNode node, Map propertyKeys, String key) { - String [] path = getPath(propertyKeys, key); - if(!node.has(path)) return false; - ModelNode modelNode = node.get(path); - if( !modelNode.isDefined()){ - return false; - } - return modelNode.asBoolean(); - } - - public static ModelNode get(ModelNode node, Map propertyKeys, String key){ - return node.get(getPath(propertyKeys,key)); - } - - public static String[] getPath(Map propertyKeys, String key) { - if(propertyKeys != null && propertyKeys.containsKey(key)) { - return propertyKeys.get(key); //allow override - } - return key.split("\\."); - } - - @SuppressWarnings("unchecked") - public static String[] getPath(String key) { - return getPath(Collections.EMPTY_MAP, key); - } + + /** + * + * @throws UnregisteredPropertyException + * if the property is not found in the property map + */ + public static int asInt(ModelNode node, Map propertyKeys, String key) { + String[] path = getPath(propertyKeys, key); + if (node.has(path)) { + ModelNode modelNode = node.get(path); + if (!modelNode.isDefined()) { + return 0; + } + return modelNode.asInt(); + } + return 0; + } + + /** + * + * @throws UnregisteredPropertyException + * if the property is not found in the property map + */ + public static String asString(ModelNode node, Map propertyKeys, String key) { + String[] path = getPath(propertyKeys, key); + if (!node.has(path)) { + return ""; + } + ModelNode modelNode = node.get(path); + if (!modelNode.isDefined()) { + return ""; + } + return modelNode.asString(); + } + + /** + * + * @throws UnregisteredPropertyException + * if the property is not found in the property map + */ + public static boolean asBoolean(ModelNode node, Map propertyKeys, String key) { + String[] path = getPath(propertyKeys, key); + if (!node.has(path)) { + return false; + } + ModelNode modelNode = node.get(path); + if (!modelNode.isDefined()) { + return false; + } + return modelNode.asBoolean(); + } + + public static ModelNode get(ModelNode node, Map propertyKeys, String key) { + return node.get(getPath(propertyKeys, key)); + } + + public static String[] getPath(Map propertyKeys, String key) { + if (propertyKeys != null && propertyKeys.containsKey(key)) { + return propertyKeys.get(key); // allow override + } + return key.split("\\."); + } + + @SuppressWarnings("unchecked") + public static String[] getPath(String key) { + return getPath(Collections.EMPTY_MAP, key); + } } diff --git a/src/main/java/com/openshift/internal/util/StringSplitter.java b/src/main/java/com/openshift/internal/util/StringSplitter.java index ce74b1a6..80bb347f 100644 --- a/src/main/java/com/openshift/internal/util/StringSplitter.java +++ b/src/main/java/com/openshift/internal/util/StringSplitter.java @@ -8,47 +8,48 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.util; import java.util.ArrayList; import java.util.List; public class StringSplitter { - private StringSplitter() {} - - public static List split(String str, List result) { - boolean inQuote = false; - StringBuilder builder = new StringBuilder(); - - for(int i=0; i < str.length();++i) { - char c = str.charAt(i); - if (inQuote) { - if (c == '"') { - inQuote = false; - } else { - builder.append(c); - } - } else if (c == '"') { - inQuote = true; - } else if (c == ' ') { - if (builder.length() > 0) { - result.add(builder.toString()); - builder = new StringBuilder(); - } - } else { - builder.append(c); - } - } - if (builder.length() > 0) { - result.add(builder.toString()); - } - return result; - } + private StringSplitter() { + } + + public static List split(String str, List result) { + boolean inQuote = false; + StringBuilder builder = new StringBuilder(); + + for (int i = 0; i < str.length(); ++i) { + char c = str.charAt(i); + if (inQuote) { + if (c == '"') { + inQuote = false; + } else { + builder.append(c); + } + } else if (c == '"') { + inQuote = true; + } else if (c == ' ') { + if (builder.length() > 0) { + result.add(builder.toString()); + builder = new StringBuilder(); + } + } else { + builder.append(c); + } + } + if (builder.length() > 0) { + result.add(builder.toString()); + } + return result; + } - public static List split(String str) { - List result = new ArrayList<>(); - return split(str, result); - } - + public static List split(String str) { + List result = new ArrayList<>(); + return split(str, result); + } } diff --git a/src/main/java/com/openshift/internal/util/URIUtils.java b/src/main/java/com/openshift/internal/util/URIUtils.java index 5d91eb1d..3b498e2c 100644 --- a/src/main/java/com/openshift/internal/util/URIUtils.java +++ b/src/main/java/com/openshift/internal/util/URIUtils.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.util; import java.io.UnsupportedEncodingException; @@ -20,51 +21,49 @@ import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; - /** * Helper methods for manipulating URIs * - * @author Jeff Cantrill */ public class URIUtils { - private static final Logger LOG = Logger.getLogger(URIUtils.class); - - private URIUtils(){ - } - - public static Map splitFragment(String location){ - if(StringUtils.isEmpty(location)) { - return Collections.emptyMap(); - } - URI uri = null; - try { - uri = new URI(location); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - return splitFragment(uri); - } - - public static Map splitFragment(URI uri){ - return splitQuery(uri.getFragment()); - } - - public static Map splitQuery(String q) { - HashMap params = new HashMap(); - if (q != null) { - try { - String decoded = URLDecoder.decode(q, StandardCharsets.UTF_8.toString()); - String[] split = decoded.split("&"); - for (String pair : split) { - String[] keyValue = pair.split("="); - if(keyValue.length >= 2) { - params.put(keyValue[0], keyValue[1]); - } - } - } catch (UnsupportedEncodingException e) { - LOG.error("Unable to decode " + q, e); - } - } - return params; - } + private static final Logger LOG = Logger.getLogger(URIUtils.class); + + private URIUtils() { + } + + public static Map splitFragment(String location) { + if (StringUtils.isEmpty(location)) { + return Collections.emptyMap(); + } + URI uri = null; + try { + uri = new URI(location); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + return splitFragment(uri); + } + + public static Map splitFragment(URI uri) { + return splitQuery(uri.getFragment()); + } + + public static Map splitQuery(String q) { + HashMap params = new HashMap(); + if (q != null) { + try { + String decoded = URLDecoder.decode(q, StandardCharsets.UTF_8.toString()); + String[] split = decoded.split("&"); + for (String pair : split) { + String[] keyValue = pair.split("="); + if (keyValue.length >= 2) { + params.put(keyValue[0], keyValue[1]); + } + } + } catch (UnsupportedEncodingException e) { + LOG.error("Unable to decode " + q, e); + } + } + return params; + } } diff --git a/src/main/java/com/openshift/internal/util/URLUtils.java b/src/main/java/com/openshift/internal/util/URLUtils.java index e38055a3..c79fdb34 100644 --- a/src/main/java/com/openshift/internal/util/URLUtils.java +++ b/src/main/java/com/openshift/internal/util/URLUtils.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.util; import java.net.URL; @@ -18,61 +19,57 @@ */ public class URLUtils { - private static final Pattern URL_PATTERN = Pattern - .compile("(https?|ftp)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"); + private static final Pattern URL_PATTERN = Pattern + .compile("(https?|ftp)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"); + + private static final String HTTPS = "https"; + private static final String HTTP = "http"; + private static final String SCHEMA_SEPARATOR = "://"; - private static final String HTTPS = "https"; - private static final String HTTP = "http"; - private static final String SCHEMA_SEPARATOR = "://"; + public static final String SCHEME_HTTP = HTTP + SCHEMA_SEPARATOR; + public static final String SCHEME_HTTPS = HTTPS + SCHEMA_SEPARATOR; + public static final char USERNAME_SEPARATOR = '@'; - public static final String SCHEME_HTTP = HTTP + SCHEMA_SEPARATOR; - public static final String SCHEME_HTTPS = HTTPS + SCHEMA_SEPARATOR; - public static final char USERNAME_SEPARATOR = '@'; + private URLUtils() { + // inhibit instantiation + } - private URLUtils() { - // inhibit instantiation - } + public static String ensureStartsWithHttps(String url) { + if (url == null || url.isEmpty()) { + return url; + } - public static String ensureStartsWithHttps(String url) { - if (url == null - || url.isEmpty()) { - return url; - } + if (url.indexOf(SCHEMA_SEPARATOR) > 0) { + return url; + } - if (url.indexOf(SCHEMA_SEPARATOR) > 0) { - return url; - } + return new StringBuilder(HTTPS).append(SCHEMA_SEPARATOR).append(url).toString(); + } - return new StringBuilder(HTTPS) - .append(SCHEMA_SEPARATOR) - .append(url) - .toString(); - } + public static boolean isUrl(String string) { + return URL_PATTERN.matcher(string).matches(); + } - public static boolean isUrl(String string) { - return URL_PATTERN.matcher(string).matches(); - } + public static String appendPath(String parent, String child) { + if (parent.charAt(parent.length() - 1) == '/') { + if (child.charAt(0) == '/') { + return parent + child.substring(1); + } else { + return parent + child; + } + } else { + if (child.charAt(0) == '/') { + return parent + child; + } else { + return new StringBuilder(parent).append('/').append(child).toString(); + } + } + } - public static String appendPath(String parent, String child) { - if (parent.charAt(parent.length() - 1) == '/') { - if (child.charAt(0) == '/') { - return parent + child.substring(1); - } else { - return parent + child; - } - } else { - if (child.charAt(0) == '/') { - return parent + child; - } else { - return new StringBuilder(parent).append('/').append(child).toString(); - } - } - } - - public static String toString(URL url) { - if (url == null) { - return null; - } - return url.toString(); - } + public static String toString(URL url) { + if (url == null) { + return null; + } + return url.toString(); + } } diff --git a/src/main/java/com/openshift/internal/util/UnregisteredPropertyException.java b/src/main/java/com/openshift/internal/util/UnregisteredPropertyException.java index cc66fa6a..8a845345 100644 --- a/src/main/java/com/openshift/internal/util/UnregisteredPropertyException.java +++ b/src/main/java/com/openshift/internal/util/UnregisteredPropertyException.java @@ -8,17 +8,13 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.util; -/** - * - * @author Jeff Cantrill - * - */ @SuppressWarnings("serial") public class UnregisteredPropertyException extends RuntimeException { - public UnregisteredPropertyException(String property) { - super(String.format("No path was found for property '%s' in the property map.", property)); - } + public UnregisteredPropertyException(String property) { + super(String.format("No path was found for property '%s' in the property map.", property)); + } } diff --git a/src/main/java/com/openshift/restclient/BadRequestException.java b/src/main/java/com/openshift/restclient/BadRequestException.java index 6556e65f..a259f6f0 100644 --- a/src/main/java/com/openshift/restclient/BadRequestException.java +++ b/src/main/java/com/openshift/restclient/BadRequestException.java @@ -8,27 +8,25 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; import com.openshift.restclient.model.IStatus; /** - * The exception thrown when the client is trying to submit a request - * to with parameters that are not accepted by the server - * - * @author jeff.cantrill + * The exception thrown when the client is trying to submit a request to with + * parameters that are not accepted by the server * */ public class BadRequestException extends OpenShiftException { + /** + * + */ + private static final long serialVersionUID = -333562634088784896L; - /** - * - */ - private static final long serialVersionUID = -333562634088784896L; - - public BadRequestException(Throwable e, IStatus status, String endpoint) { - super(e, status, "%s", endpoint); - } + public BadRequestException(Throwable e, IStatus status, String endpoint) { + super(e, status, "%s", endpoint); + } } diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 0ce62c4f..636495f9 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; import java.io.IOException; @@ -46,288 +47,298 @@ /** * Builder to create IClient instances. - * @author jeff.cantrill * */ public class ClientBuilder { - - private String baseUrl; - private ISSLCertificateCallback sslCertificateCallback = new NoopSSLCertificateCallback(); - private boolean sslCertCallbackWithDefaultHostnameVerifier = false; - private X509Certificate certificate; - private Collection certificateCollection; - private String certificateAlias; - private IResourceFactory resourceFactory; - private String userName; - private String token; - private String password; - private String userAgentPrefix; - private Authenticator proxyAuthenticator; - - private int maxRequests = 64; - private int maxRequestsPerHost = 10; - - private int readTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; - private TimeUnit readTimeoutUnit = TimeUnit.MILLISECONDS; - private int connectTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; - private TimeUnit connectTimeoutUnit = TimeUnit.MILLISECONDS; - private int writeTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; - private TimeUnit writeTimeoutUnit = TimeUnit.MILLISECONDS; - - public ClientBuilder() { - this(null); - } - - public ClientBuilder(String baseUrl) { - this.baseUrl = baseUrl; - } - - public ClientBuilder sslCertificateCallback(ISSLCertificateCallback callback) { - this.sslCertificateCallback = callback == null ? new NoopSSLCertificateCallback() : callback; - return this; - } - - public ClientBuilder sslCertCallbackWithDefaultHostnameVerifier(boolean b) { - this.sslCertCallbackWithDefaultHostnameVerifier = b; - return this; - } - - public ClientBuilder sslCertificate(String alias, X509Certificate cert) { - this.certificateAlias = alias; - this.certificate = cert; - return this; - } - - public ClientBuilder sslCertificateCollection(String alias, Collection certs) { - this.certificateAlias = alias; - this.certificateCollection = certs; - return this; - } - - public ClientBuilder resourceFactory(IResourceFactory factory) { - this.resourceFactory = factory; - return this; - } - - public ClientBuilder toCluster(String baseUrl) { - this.baseUrl = baseUrl; - return this; - } - - public ClientBuilder withUserName(String userName) { - this.userName = userName; - return this; - } - - public ClientBuilder withPassword(String password) { - this.password = password; - return this; - } - - public ClientBuilder usingToken(String token) { - this.token = token; - return this; - } - - public ClientBuilder usingUserAgentPrefix(String prefix) { - this.userAgentPrefix = prefix; - return this; - } - - public ClientBuilder withConnectTimeout(int timeout, TimeUnit unit) { - this.connectTimeout = timeout; - this.connectTimeoutUnit = unit; - return this; - } - public ClientBuilder withReadTimeout(int timeout, TimeUnit unit) { - this.readTimeout = timeout; - this.readTimeoutUnit = unit; - return this; - } - public ClientBuilder withWriteTimeout(int timeout, TimeUnit unit) { - this.writeTimeout = timeout; - this.writeTimeoutUnit = unit; - return this; - } - - public ClientBuilder proxyAuthenticator(Authenticator proxyAuthenticator) { - this.proxyAuthenticator = proxyAuthenticator; - return this; - } - - /** - * The connect timeout parameter used for establishing - * the connection to a remote server - * @param connectInMillis A value in milliseconds - * @return - */ - public ClientBuilder withConnectTimeout(int connectInMillis) { - this.connectTimeout = connectInMillis; - return this; - } - - /** - * The maximum concurrent requests for this client. - * - * @param maxRequests the maximum number of concurrent requests - * @return the client builder - */ - public ClientBuilder withMaxRequests(int maxRequests) { - this.maxRequests = maxRequests; - return this; - } - + + private String baseUrl; + private ISSLCertificateCallback sslCertificateCallback = new NoopSSLCertificateCallback(); + private boolean sslCertCallbackWithDefaultHostnameVerifier = false; + private X509Certificate certificate; + private Collection certificateCollection; + private String certificateAlias; + private IResourceFactory resourceFactory; + private String userName; + private String token; + private String password; + private String userAgentPrefix; + private Authenticator proxyAuthenticator; + + private int maxRequests = 64; + private int maxRequestsPerHost = 10; + + private int readTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; + private TimeUnit readTimeoutUnit = TimeUnit.MILLISECONDS; + private int connectTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; + private TimeUnit connectTimeoutUnit = TimeUnit.MILLISECONDS; + private int writeTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; + private TimeUnit writeTimeoutUnit = TimeUnit.MILLISECONDS; + + public ClientBuilder() { + this(null); + } + + public ClientBuilder(String baseUrl) { + this.baseUrl = baseUrl; + } + + public ClientBuilder sslCertificateCallback(ISSLCertificateCallback callback) { + this.sslCertificateCallback = callback == null ? new NoopSSLCertificateCallback() : callback; + return this; + } + + public ClientBuilder sslCertCallbackWithDefaultHostnameVerifier(boolean b) { + this.sslCertCallbackWithDefaultHostnameVerifier = b; + return this; + } + + public ClientBuilder sslCertificate(String alias, X509Certificate cert) { + this.certificateAlias = alias; + this.certificate = cert; + return this; + } + + public ClientBuilder sslCertificateCollection(String alias, Collection certs) { + this.certificateAlias = alias; + this.certificateCollection = certs; + return this; + } + + public ClientBuilder resourceFactory(IResourceFactory factory) { + this.resourceFactory = factory; + return this; + } + + public ClientBuilder toCluster(String baseUrl) { + this.baseUrl = baseUrl; + return this; + } + + public ClientBuilder withUserName(String userName) { + this.userName = userName; + return this; + } + + public ClientBuilder withPassword(String password) { + this.password = password; + return this; + } + + public ClientBuilder usingToken(String token) { + this.token = token; + return this; + } + + public ClientBuilder usingUserAgentPrefix(String prefix) { + this.userAgentPrefix = prefix; + return this; + } + + public ClientBuilder withConnectTimeout(int timeout, TimeUnit unit) { + this.connectTimeout = timeout; + this.connectTimeoutUnit = unit; + return this; + } + + /** + * The connect timeout parameter used for establishing the connection to a + * remote server + * + * @param connectInMillis + * A value in milliseconds + */ + public ClientBuilder withConnectTimeout(int connectInMillis) { + this.connectTimeout = connectInMillis; + return this; + } + + public ClientBuilder withReadTimeout(int timeout, TimeUnit unit) { + this.readTimeout = timeout; + this.readTimeoutUnit = unit; + return this; + } + + public ClientBuilder withWriteTimeout(int timeout, TimeUnit unit) { + this.writeTimeout = timeout; + this.writeTimeoutUnit = unit; + return this; + } + + public ClientBuilder proxyAuthenticator(Authenticator proxyAuthenticator) { + this.proxyAuthenticator = proxyAuthenticator; + return this; + } + + + /** + * The maximum concurrent requests for this client. + * + * @param maxRequests + * the maximum number of concurrent requests + * @return the client builder + */ + public ClientBuilder withMaxRequests(int maxRequests) { + this.maxRequests = maxRequests; + return this; + } + /** * The maximum concurrent request for this client for a single host. * - * @param maxRequestsPerHost the maximum number of concurrent requests for a single host + * @param maxRequestsPerHost + * the maximum number of concurrent requests for a single host * @return the client builder */ - public ClientBuilder withMaxRequestsPerHost(int maxRequestsPerHost) { - this.maxRequestsPerHost = maxRequestsPerHost; - return this; - } - - /** - * Build a client - * - * @return - * @throws KeyManagementException - */ - public IClient build() { - try { - TrustManagerFactory trustManagerFactory = initTrustManagerFactory(certificateAlias, certificate, certificateCollection); - X509TrustManager trustManager = getCurrentTrustManager(trustManagerFactory); - SSLContext sslContext = SSLUtils.getSSLContext(trustManager); - - ResponseCodeInterceptor responseCodeInterceptor = new ResponseCodeInterceptor(); - OpenShiftAuthenticator authenticator = new OpenShiftAuthenticator(); - Dispatcher dispatcher = new Dispatcher(); - - //hiding these for now to since not certain - //if we need to really expose them. - dispatcher.setMaxRequests(maxRequests); - dispatcher.setMaxRequestsPerHost(maxRequestsPerHost); - String[] pieces = {this.userAgentPrefix, "openshift-restclient-java", Version.userAgent()}; - String userAgent = StringUtils.join(pieces, "/"); - - OkHttpClient.Builder builder = new OkHttpClient.Builder() - .addInterceptor(responseCodeInterceptor) - .addNetworkInterceptor(new Interceptor() { - @Override - public Response intercept(Chain chain) throws IOException { - Request agent = chain.request().newBuilder().header("User-Agent", userAgent).build(); - return chain.proceed(agent); - } - }) - .authenticator(authenticator) - .dispatcher(dispatcher) - .readTimeout(readTimeout, readTimeoutUnit) - .writeTimeout(writeTimeout, writeTimeoutUnit) - .connectTimeout(connectTimeout, connectTimeoutUnit) - .sslSocketFactory(sslContext.getSocketFactory(), trustManager); - - if (!this.sslCertCallbackWithDefaultHostnameVerifier) - builder.hostnameVerifier(sslCertificateCallback); - - if (proxyAuthenticator != null) { - builder.proxyAuthenticator(proxyAuthenticator); - } - - OkHttpClient okClient = builder.build(); - - IResourceFactory factory = defaultIfNull(resourceFactory, new ResourceFactory(null)); - AuthorizationContext authContext = new AuthorizationContext(token, userName, password); - DefaultClient client = new DefaultClient(new URL(this.baseUrl), okClient, factory, null, authContext); - - authContext.setClient(client); - responseCodeInterceptor.setClient(client); - authenticator.setClient(client); - authenticator.setOkClient(okClient); - - return client; - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) { - throw new OpenShiftException(e, "Unable to initialize client"); - } - } - - private T defaultIfNull(T value, T aDefault) { - if(value != null) - return value; - return aDefault; - } - - private X509TrustManager getCurrentTrustManager(TrustManagerFactory trustManagerFactory) throws NoSuchAlgorithmException, KeyStoreException { - for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { - if (trustManager instanceof X509TrustManager) { - X509TrustManager x509TrustManager = (X509TrustManager) trustManager; - return new CallbackTrustManager(x509TrustManager, this.sslCertificateCallback); - } - } - return null; - - } - - private TrustManagerFactory initTrustManagerFactory(String alias, X509Certificate cert, Collection certs) throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - if (alias != null && (cert != null || certs != null)) { - KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); - // need this load to initialize the key store, and allow for the subsequent set certificate entry - ks.load(null, null); - if (cert != null) { - cert.checkValidity(); - ks.setCertificateEntry(alias, cert); - } - if (certs != null) { - int i = 0; - for (X509Certificate x509 : certs) { - x509.checkValidity(); - ks.setCertificateEntry(alias + i, x509); - i++; - } - } - - - // testing has proven that you can only call init() once for a TrustManagerFactory wrt loading certs - // from the KeyStore ... subsequent KeyStore.setCertificateEntry / TrustManagerFactory.init calls are - // ignored. - // So if a specific cert is required to validate this connection's communication with the server, add it up front - // in the ctor. - trustManagerFactory.init(ks); - } else { - trustManagerFactory.init((KeyStore)null); - } - return trustManagerFactory; - } - - private static class CallbackTrustManager implements X509TrustManager { - - private X509TrustManager trustManager; - private ISSLCertificateCallback callback; - - private CallbackTrustManager(X509TrustManager currentTrustManager, ISSLCertificateCallback callback) - throws NoSuchAlgorithmException, KeyStoreException { - this.trustManager = currentTrustManager; - this.callback = callback; - } - - public X509Certificate[] getAcceptedIssuers() { - return trustManager.getAcceptedIssuers(); - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - try { - trustManager.checkServerTrusted(chain, authType); - } catch (CertificateException e) { - if (!callback.allowCertificate(chain)) { - throw e; - } - } - } - - public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - trustManager.checkServerTrusted(chain, authType); - } - } + public ClientBuilder withMaxRequestsPerHost(int maxRequestsPerHost) { + this.maxRequestsPerHost = maxRequestsPerHost; + return this; + } + + /** + * Build a client + * + * @throws KeyManagementException an exception + */ + public IClient build() { + try { + TrustManagerFactory trustManagerFactory = initTrustManagerFactory(certificateAlias, certificate, + certificateCollection); + X509TrustManager trustManager = getCurrentTrustManager(trustManagerFactory); + SSLContext sslContext = SSLUtils.getSSLContext(trustManager); + + ResponseCodeInterceptor responseCodeInterceptor = new ResponseCodeInterceptor(); + OpenShiftAuthenticator authenticator = new OpenShiftAuthenticator(); + Dispatcher dispatcher = new Dispatcher(); + + // hiding these for now to since not certain + // if we need to really expose them. + dispatcher.setMaxRequests(maxRequests); + dispatcher.setMaxRequestsPerHost(maxRequestsPerHost); + String[] pieces = { this.userAgentPrefix, "openshift-restclient-java", Version.userAgent() }; + String userAgent = StringUtils.join(pieces, "/"); + + OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(responseCodeInterceptor) + .addNetworkInterceptor(new Interceptor() { + @Override + public Response intercept(Chain chain) throws IOException { + Request agent = chain.request().newBuilder().header("User-Agent", userAgent).build(); + return chain.proceed(agent); + } + }).authenticator(authenticator).dispatcher(dispatcher).readTimeout(readTimeout, readTimeoutUnit) + .writeTimeout(writeTimeout, writeTimeoutUnit).connectTimeout(connectTimeout, connectTimeoutUnit) + .sslSocketFactory(sslContext.getSocketFactory(), trustManager); + + if (!this.sslCertCallbackWithDefaultHostnameVerifier) { + builder.hostnameVerifier(sslCertificateCallback); + } + + if (proxyAuthenticator != null) { + builder.proxyAuthenticator(proxyAuthenticator); + } + + OkHttpClient okClient = builder.build(); + + IResourceFactory factory = defaultIfNull(resourceFactory, new ResourceFactory(null)); + AuthorizationContext authContext = new AuthorizationContext(token, userName, password); + DefaultClient client = new DefaultClient(new URL(this.baseUrl), okClient, factory, null, authContext); + + authContext.setClient(client); + responseCodeInterceptor.setClient(client); + authenticator.setClient(client); + authenticator.setOkClient(okClient); + + return client; + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException e) { + throw new OpenShiftException(e, "Unable to initialize client"); + } + } + + private T defaultIfNull(T value, T theDefault) { + if (value != null) { + return value; + } + return theDefault; + } + + private X509TrustManager getCurrentTrustManager(TrustManagerFactory trustManagerFactory) + throws NoSuchAlgorithmException, KeyStoreException { + for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { + if (trustManager instanceof X509TrustManager) { + X509TrustManager x509TrustManager = (X509TrustManager) trustManager; + return new CallbackTrustManager(x509TrustManager, this.sslCertificateCallback); + } + } + return null; + + } + + private TrustManagerFactory initTrustManagerFactory(String alias, X509Certificate cert, + Collection certs) + throws NoSuchAlgorithmException, KeyStoreException, CertificateException, IOException { + TrustManagerFactory trustManagerFactory = TrustManagerFactory + .getInstance(TrustManagerFactory.getDefaultAlgorithm()); + if (alias != null && (cert != null || certs != null)) { + KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); + // need this load to initialize the key store, and allow for the subsequent set + // certificate entry + ks.load(null, null); + if (cert != null) { + cert.checkValidity(); + ks.setCertificateEntry(alias, cert); + } + if (certs != null) { + int i = 0; + for (X509Certificate x509 : certs) { + x509.checkValidity(); + ks.setCertificateEntry(alias + i, x509); + i++; + } + } + + // testing has proven that you can only call init() once for a + // TrustManagerFactory wrt loading certs + // from the KeyStore ... subsequent KeyStore.setCertificateEntry / + // TrustManagerFactory.init calls are + // ignored. + // So if a specific cert is required to validate this connection's communication + // with the server, add it up front + // in the ctor. + trustManagerFactory.init(ks); + } else { + trustManagerFactory.init((KeyStore) null); + } + return trustManagerFactory; + } + + private static class CallbackTrustManager implements X509TrustManager { + + private X509TrustManager trustManager; + private ISSLCertificateCallback callback; + + private CallbackTrustManager(X509TrustManager currentTrustManager, ISSLCertificateCallback callback) + throws NoSuchAlgorithmException, KeyStoreException { + this.trustManager = currentTrustManager; + this.callback = callback; + } + + public X509Certificate[] getAcceptedIssuers() { + return trustManager.getAcceptedIssuers(); + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + try { + trustManager.checkServerTrusted(chain, authType); + } catch (CertificateException e) { + if (!callback.allowCertificate(chain)) { + throw e; + } + } + } + + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + trustManager.checkServerTrusted(chain, authType); + } + } } diff --git a/src/main/java/com/openshift/restclient/IApiTypeMapper.java b/src/main/java/com/openshift/restclient/IApiTypeMapper.java index a6e4b290..9ae19e49 100644 --- a/src/main/java/com/openshift/restclient/IApiTypeMapper.java +++ b/src/main/java/com/openshift/restclient/IApiTypeMapper.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; import java.util.Collection; @@ -16,151 +17,144 @@ /** * Determine the supported api endpoints by the cluster - * - * @author jeff.cantrill * */ public interface IApiTypeMapper { - + static final String KUBE_API = "api"; static final String OS_API = "oapi"; static final String API_GROUPS_API = "apis"; static final String FWD_SLASH = "/"; + String getPreferedVersionFor(String endpoint); + + /** + * return the versioned endpoint for the given kind + * + * @param version + * the apiVersion, null or empty is best guess + * @throws UnsupportedEndpointException + * if unable to determine the endpoint for the given kind + */ + IVersionedApiResource getEndpointFor(String apiVersion, String kind); + + /** + * Using the kind and apiVersion, determine if the cluster is able to consume + * the given resource + * + * @return true if supported; false otherwise + */ + boolean isSupported(IResource resource); + + /** + * Using the kind determine if the cluster is able to consume the given resource + * + * @param kind + * the resource kind + * @return true if supported; false otherwise + */ + boolean isSupported(String kind); + + /** + * Using the kind and apiVersion, determine if the cluster is able to consume + * the given resource + * + * @param version + * the apiVersion, null or empty is best guess + * @param kind + * the resource kind + * @return true if supported; false otherwise + */ + boolean isSupported(String version, String kind); + + /** + * The api group for a given set of resources and the versions it supports. + * + * @author jeff.cantrill + * + */ + interface IApiGroup { + + /** + * The prefix for this api group (e.g. api, oapi, apis) + * + */ + String getPrefix(); + + /** + * The name of the api group + * + */ + String getName(); + + /** + * The list of supported versions for the group. + * + */ + Collection getVersions(); + + /** + * The prefered version for the group + * + */ + String getPreferedVersion(); + + /** + * Get the endpoint path for the given version + * + */ + String pathFor(String version); + } + + /** + * A description of an endpoint for a given resource and the capabilities it + * supports + * + * @author jeff.cantrill + */ + interface IVersionedApiResource { + + /** + * The prefix for this api group (e.g. api, oapi, apis) + * + */ + String getPrefix(); + + /** + * The groupname of the resource (e.g. extensions of extensions/v1beta1) + * + */ + String getApiGroupName(); + + /** + * The version of the resource (e.g. v1) + * + */ + String getVersion(); + + /** + * get resource name this group supports + * + */ + String getName(); + + /** + * the kind used with this resource + * + */ + String getKind(); + + /** + * @return true if the associated resource is namespaced + */ + boolean isNamespaced(); + + /** + * Determine if the capability is supported (e.g. builds/webhooks) + * + * @return true if the capability is supported. + */ + boolean isSupported(String capability); - - String getPreferedVersionFor(String endpoint); - - /** - * return the versioned endpoint for the given kind - * @param version the apiVersion, null or empty is best guess - * @param kind - * @return - * @throws UnsupportedEndpointException if unable to determine the endpoint for the given kind - */ - IVersionedApiResource getEndpointFor(String apiVersion, String kind); - - /** - * Using the kind and apiVersion, determine - * if the cluster is able to consume the - * given resource - * - * @param resource - * @return true if supported; false otherwise - */ - boolean isSupported(IResource resource); - - /** - * Using the kind determine - * if the cluster is able to consume the - * given resource - * - * @param kind the resource kind - * @return true if supported; false otherwise - */ - boolean isSupported(String kind); - - /** - * Using the kind and apiVersion, determine - * if the cluster is able to consume the - * given resource - * - * @param version the apiVersion, null or empty is best guess - * @param kind the resource kind - * @return true if supported; false otherwise - */ - boolean isSupported(String version, String kind); - - /** - * The api group for a given set of resources - * and the versions it supports. - * @author jeff.cantrill - * - */ - interface IApiGroup{ - - /** - * The prefix for this api group (e.g. api, oapi, apis) - * @return - */ - String getPrefix(); - - /** - * The name of the api group - * @return - */ - String getName(); - - /** - * The list of supported versions for the group. - * @return - */ - Collection getVersions(); - - /** - * The prefered version for the group - * @return - */ - String getPreferedVersion(); - - /** - * Get the endpoint path for the given version - * @param version - * @return - */ - String pathFor(String version); - } - - /** - * A description of an endpoint for - * a given resource and the capabilities - * it supports - * - * @author jeff.cantrill - */ - interface IVersionedApiResource{ - - /** - * The prefix for this api group (e.g. api, oapi, apis) - * @return - */ - String getPrefix(); - - /** - * The groupname of the resource (e.g. extensions of extensions/v1beta1) - * @return - */ - String getApiGroupName(); - - /** - * The version of the resource (e.g. v1) - * @return - */ - String getVersion(); - - /** - * get resource name this group supports - * @return - */ - String getName(); - - /** - * the kind used with this resource - * @return - */ - String getKind(); - - /** - * @return true if the associated resource is namespaced - */ - boolean isNamespaced(); - - /** - * Determine if the capability is supported - * (e.g. builds/webhooks) - * @return true if the capability is supported. - */ - boolean isSupported(String capability); - - } + } } diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index 66de4af3..b3c2c2e5 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; import java.net.URL; @@ -23,267 +24,303 @@ /** * Client is the the simplest interface for interacting with the OpenShift * master server. - * - * @author Jeff Cantrill * */ public interface IClient extends ICapable, Cloneable { - /* - * Watch for changes - * - * @param namespace The namespace to watch for changes in - * @param listener The listener to be notified on events - * @param kids The kinds to watch for - - */ - IWatcher watch(String namespace, IOpenShiftWatchListener listener, String...kinds); - - /* - * Watch for changes - * - * @param namespace The namespace to watch for changes in - * @param listener The listener to be notified on events - * @param kids The kinds to watch for - */ - IWatcher watch(IOpenShiftWatchListener listener, String...kinds); - - - /** - * Lists all possible resources of the given kind in the default namespace - * @param kind - * @return - */ - List list(String kind); - - /** - * Lists the given given resource kind scoping it to a specific namespace - * - * @param kind - * @param labels The label used to filter the resource - * @return - */ - List list(String kind, Map labels); - - - /** - * Lists the given given resource kind scoping it to a specific namespace - * - * @param kind - * @param namespace The namespace to scope the possible results of this list - * @return - */ - List list(String kind, String namespace); - - /** - * Lists the given given resource kind scoping it to a specific namespace - * - * @param kind - * @param namespace The namespace to scope the possible results of this list - * @param labels The label used to filter the resource - * @return - */ - List list(String kind, String namespace, Map labels); - - /** - * Lists the given given resource kind scoping it to a specific namespace - * - * @param kind - * @param namespace The namespace to scope the possible results of this list - * @param labelQuery The label used to filter the resource - * @return - */ - List list(String kind, String namespace, String labelQuery); - - /** - * - * @param kind - * @param name - * @param namespace - * @return - * @throws OpenShiftException if operation not supported for resource type - */ - T get(String kind, String name, String namespace); - - /** - * - * @return A raw list of the kind in the given namespace (e.g. ServiceList) - */ - IList get(String kind, String namespace); - - /** - * Creates the given resource in the namespace defined on the - * resource or the default namspace if undefined - * @param resource - * @return - * @throws UnsupportedOperationException if the resource is a list - */ - T create(T resource); - - /** - * Creates the given resource in the given namespace - * @param resource - * @param namespace - * @return - */ - T create(T resource, String namespace); - - /** - * Creates the given resource in the given namespace using the subresource - * @param kind - * @param namespace - * @param name - * @param subresource - * @param payload - * @return - */ - T create(String kind, String namespace, String name, String subresource, IResource payload); - - /** - * Creates a list of resources in the given namespace - * @param list The resource definitions - * @param namespace the namespace for the resources - * @return A collection of the resources created or the status - * instance of why the creation failed. - * @throws OpenShiftException if a status can not be determined from - * the exception - */ - Collection create(IList list, String namespace); - - /** - * Updates the given resource - * @param resource - * @return - * @throws UnsupportedOperationException if the resource is a list - */ - T update(T resource); - - /** - * Deletes the given resource. - * @param resource - * @throws UnsupportedOperationException if the resource is a list - */ - void delete(T resource); - - - /** - * Raw execution of a request - * @param httpMethod HttpMethod (e.g. POST) - * @param kind - * @param namespace - * @param name - * @param subresource subresource or capability - * @param payload the payload to sumit. only valid on non-get operations - * @return - * - */ - T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload); - - /** - * Raw execution of a request - * @param httpMethod HttpMethod (e.g. POST) - * @param kind - * @param namespace - * @param name - * @param subresource subresource or capability - * @param payload the payload to sumit. only valid on non-get operations - * @param params map of query parameters - * @return - * - */ - T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload, Map params); - - /** - * Raw execution of a request - * @param httpMethod HttpMethod (e.g. POST) - * @param kind - * @param namespace - * @param name - * @param subresource subresource or capability - * @param subcontext additional subContext (e.g. jolokia endpoint) - * Raw execution of a request that requires consumers to handle the response - * @return - */ - T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload, String subcontext); - - /** - * @param factory The factory to use for interpreting the response - * @param httpMethod HttpMethod (e.g. POST) - * @param kind - * @param namespace - * @param name - * @param subresource subresource or capability - * @param payload the payload to sumit. only valid on non-get operations - * @param subContext additional subContext - * @param params - * @return the raw payload string - */ - T execute(ITypeFactory factory, String httpMethod, String kind, String namespace, String name, - String subresource, String subContext, JSONSerializeable payload, - Map params); - - /** - * - * @return the base URL of this endpoint - */ - URL getBaseURL(); - - /** - * - * @param resource - * @return the uri to the resource (e.g. for crafting webhooks) - */ - String getResourceURI(IResource resource); - - /** - * Returns the OpenShift API version for this client - * @return - * @throws UnsupportedVersionException - * @throws {@link UnauthorizedException} - */ - String getOpenShiftAPIVersion() throws UnsupportedVersionException; - - /** - * The authorization context for this client. - * @return The context which will never be null - */ - IAuthorizationContext getAuthorizationContext(); - - /** - * Returns the resource factory used to create resources based on the - * response from the server - * @return - */ - IResourceFactory getResourceFactory(); - - /** - * Adapt this class to the given type - * @param klass - * @return an instance of the class or null if it can not - */ - default T adapt(Class klass) { - return null; - }; - - /** - * Query the server to determine if it - * is ready - * @return - * @throws OpenShiftException - */ - String getServerReadyStatus(); - - /** - * Query the server to determine the Openshift version - * @return - */ - String getOpenshiftMasterVersion(); - - /** - * Query the server to determine the Kubernetes version - * @return - */ - String getKubernetesMasterVersion(); - - IClient clone(); + /* + * Watch for changes + * + * @param namespace The namespace to watch for changes in + * + * @param listener The listener to be notified on events + * + * @param kids The kinds to watch for + * + */ + IWatcher watch(String namespace, IOpenShiftWatchListener listener, String... kinds); + + /* + * Watch for changes + * + * @param namespace The namespace to watch for changes in + * + * @param listener The listener to be notified on events + * + * @param kids The kinds to watch for + */ + IWatcher watch(IOpenShiftWatchListener listener, String... kinds); + + /** + * Lists all possible resources of the given kind in the default namespace + * + * @param kind + * @return + */ + List list(String kind); + + /** + * Lists the given given resource kind scoping it to a specific namespace + * + * @param kind + * @param labels + * The label used to filter the resource + * @return + */ + List list(String kind, Map labels); + + /** + * Lists the given given resource kind scoping it to a specific namespace + * + * @param kind + * @param namespace + * The namespace to scope the possible results of this list + * @return + */ + List list(String kind, String namespace); + + /** + * Lists the given given resource kind scoping it to a specific namespace + * + * @param kind + * @param namespace + * The namespace to scope the possible results of this list + * @param labels + * The label used to filter the resource + * @return + */ + List list(String kind, String namespace, Map labels); + + /** + * Lists the given given resource kind scoping it to a specific namespace + * + * @param kind + * @param namespace + * The namespace to scope the possible results of this list + * @param labelQuery + * The label used to filter the resource + * @return + */ + List list(String kind, String namespace, String labelQuery); + + /** + * + * @param kind + * @param name + * @param namespace + * @return + * @throws OpenShiftException + * if operation not supported for resource type + */ + T get(String kind, String name, String namespace); + + /** + * + * @return A raw list of the kind in the given namespace (e.g. ServiceList) + */ + IList get(String kind, String namespace); + + /** + * Creates the given resource in the namespace defined on the resource or the + * default namspace if undefined + * + * @param resource + * @return + * @throws UnsupportedOperationException + * if the resource is a list + */ + T create(T resource); + + /** + * Creates the given resource in the given namespace + * + * @param resource + * @param namespace + * @return + */ + T create(T resource, String namespace); + + /** + * Creates the given resource in the given namespace using the subresource + * + * @param kind + * @param namespace + * @param name + * @param subresource + * @param payload + * @return + */ + T create(String kind, String namespace, String name, String subresource, IResource payload); + + /** + * Creates a list of resources in the given namespace + * + * @param list + * The resource definitions + * @param namespace + * the namespace for the resources + * @return A collection of the resources created or the status instance of why + * the creation failed. + * @throws OpenShiftException + * if a status can not be determined from the exception + */ + Collection create(IList list, String namespace); + + /** + * Updates the given resource + * + * @param resource + * @return + * @throws UnsupportedOperationException + * if the resource is a list + */ + T update(T resource); + + /** + * Deletes the given resource. + * + * @param resource + * @throws UnsupportedOperationException + * if the resource is a list + */ + void delete(T resource); + + /** + * Raw execution of a request + * + * @param httpMethod + * HttpMethod (e.g. POST) + * @param kind + * @param namespace + * @param name + * @param subresource + * subresource or capability + * @param payload + * the payload to sumit. only valid on non-get operations + * @return + * + */ + T execute(String httpMethod, String kind, String namespace, String name, String subresource, + IResource payload); + + /** + * Raw execution of a request + * + * @param httpMethod + * HttpMethod (e.g. POST) + * @param kind + * @param namespace + * @param name + * @param subresource + * subresource or capability + * @param payload + * the payload to sumit. only valid on non-get operations + * @param params + * map of query parameters + * @return + * + */ + T execute(String httpMethod, String kind, String namespace, String name, String subresource, + IResource payload, Map params); + + /** + * Raw execution of a request + * + * @param httpMethod + * HttpMethod (e.g. POST) + * @param kind + * @param namespace + * @param name + * @param subresource + * subresource or capability + * @param subcontext + * additional subContext (e.g. jolokia endpoint) Raw execution of a + * request that requires consumers to handle the response + * @return + */ + T execute(String httpMethod, String kind, String namespace, String name, String subresource, + IResource payload, String subcontext); + + /** + * @param factory + * The factory to use for interpreting the response + * @param httpMethod + * HttpMethod (e.g. POST) + * @param kind + * @param namespace + * @param name + * @param subresource + * subresource or capability + * @param payload + * the payload to sumit. only valid on non-get operations + * @param subContext + * additional subContext + * @param params + * @return the raw payload string + */ + T execute(ITypeFactory factory, String httpMethod, String kind, String namespace, String name, + String subresource, String subContext, JSONSerializeable payload, Map params); + + /** + * + * @return the base URL of this endpoint + */ + URL getBaseURL(); + + /** + * + * @return the uri to the resource (e.g. for crafting webhooks) + */ + String getResourceURI(IResource resource); + + /** + * Returns the OpenShift API version for this client + * + * @throws {@link + * UnauthorizedException} + */ + String getOpenShiftAPIVersion() throws UnsupportedVersionException; + + /** + * The authorization context for this client. + * + * @return The context which will never be null + */ + IAuthorizationContext getAuthorizationContext(); + + /** + * Returns the resource factory used to create resources based on the response + * from the server + * + */ + IResourceFactory getResourceFactory(); + + /** + * Adapt this class to the given type + * + * @return an instance of the class or null if it can not + */ + default T adapt(Class klass) { + return null; + } + + /** + * Query the server to determine if it is ready + * + */ + String getServerReadyStatus(); + + /** + * Query the server to determine the Openshift version + * + */ + String getOpenshiftMasterVersion(); + + /** + * Query the server to determine the Kubernetes version + * + */ + String getKubernetesMasterVersion(); + + IClient clone(); } diff --git a/src/main/java/com/openshift/restclient/IOpenShiftWatchListener.java b/src/main/java/com/openshift/restclient/IOpenShiftWatchListener.java index 16196a5e..8d1c2ac1 100644 --- a/src/main/java/com/openshift/restclient/IOpenShiftWatchListener.java +++ b/src/main/java/com/openshift/restclient/IOpenShiftWatchListener.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; import java.util.List; @@ -15,102 +16,108 @@ import com.openshift.restclient.model.IResource; /** - * Handler to receive notification when a resource - * changes - * @author Jeff Cantrill + * Handler to receive notification when a resource changes * */ public interface IOpenShiftWatchListener { - - /** - * Called when an endpoint connects - * The initial set of resources returned when determining - * the resourceVersion to watch - * @param resources an Unmodifiable List - */ - void connected(List resources); - - /** - * Called when and endpoint disconnects - */ - void disconnected(); - - /** - * - * @param resource the resource that changed - * @param change the change type - */ - void received(IResource resource, ChangeType change); - - public class ChangeType { - - public static final ChangeType ADDED = new ChangeType("ADDED"); - public static final ChangeType MODIFIED = new ChangeType("MODIFIED"); - public static final ChangeType DELETED = new ChangeType("DELETED"); - - private String value; - - public ChangeType(String value) { - if (value != null) { - value = value.toUpperCase(); - } - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((getValue() == null) ? 0 : getValue().hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ChangeType other = (ChangeType) obj; - if (value == null) { - if (other.value != null) - return false; - } else if (!getValue().equals(other.getValue())) - return false; - return true; - } - } - - void error(Throwable err); - - /** - * Convenience class for implementing watch callbacks - * @author jeff.cantrill - * - */ - static class OpenShiftWatchListenerAdapter implements IOpenShiftWatchListener{ - - @Override - public void connected(List resources) { - } - - @Override - public void disconnected() { - } - - @Override - public void received(IResource resource, ChangeType change) { - } - - @Override - public void error(Throwable err) { - } - - } + + /** + * Called when an endpoint connects The initial set of resources returned when + * determining the resourceVersion to watch + * + * @param resources + * an Unmodifiable List + */ + void connected(List resources); + + /** + * Called when and endpoint disconnects + */ + void disconnected(); + + /** + * + * @param resource + * the resource that changed + * @param change + * the change type + */ + void received(IResource resource, ChangeType change); + + public class ChangeType { + + public static final ChangeType ADDED = new ChangeType("ADDED"); + public static final ChangeType MODIFIED = new ChangeType("MODIFIED"); + public static final ChangeType DELETED = new ChangeType("DELETED"); + + private String value; + + public ChangeType(String value) { + if (value != null) { + value = value.toUpperCase(); + } + this.value = value; + } + + public String getValue() { + return value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getValue() == null) ? 0 : getValue().hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ChangeType other = (ChangeType) obj; + if (value == null) { + if (other.value != null) { + return false; + } + } else if (!getValue().equals(other.getValue())) { + return false; + } + return true; + } + } + + void error(Throwable err); + + /** + * Convenience class for implementing watch callbacks + * + * + */ + static class OpenShiftWatchListenerAdapter implements IOpenShiftWatchListener { + + @Override + public void connected(List resources) { + } + + @Override + public void disconnected() { + } + + @Override + public void received(IResource resource, ChangeType change) { + } + + @Override + public void error(Throwable err) { + } + + } } diff --git a/src/main/java/com/openshift/restclient/IResourceFactory.java b/src/main/java/com/openshift/restclient/IResourceFactory.java index 1e2b2a6c..5a0bea73 100644 --- a/src/main/java/com/openshift/restclient/IResourceFactory.java +++ b/src/main/java/com/openshift/restclient/IResourceFactory.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; import java.io.InputStream; @@ -15,79 +16,84 @@ import com.openshift.restclient.model.IResource; /** - * Factory class for creating resources from a - * response string + * Factory class for creating resources from a response string * - * @author Jeff Cantrill */ -public interface IResourceFactory extends ITypeFactory{ - - /** - * Create a list of resources of the given kind - * from a response string - * @param json - * @param kind - * @return - * @throws ResourceFactoryException if it is unable to create resources - */ - List createList(String json, String kind); - - /** - * Create a resource from a response string - * @param response - * @return - * @throws ResourceFactoryException if it is unable to create resources - */ - T create(String response) ; +public interface IResourceFactory extends ITypeFactory { + + /** + * Create a list of resources of the given kind from a response string + * + * @throws ResourceFactoryException + * if it is unable to create resources + */ + List createList(String json, String kind); + + /** + * Create a resource from a response string + * + * @param response + * @return + * @throws ResourceFactoryException + * if it is unable to create resources + */ + T create(String response); + + /** + * Create a resource from a response string + * + * @param input + * Read the given input stream which assumes the input is parsable + * JSON representing a valid resource + * @return + * @throws ResourceFactoryException + * if it is unable to create resources + */ + T create(InputStream input); + + /** + * Create(or stub) a resource for a given version and kind + * + * @param version + * @param kind + * @return + */ + T create(String version, String kind); - /** - * Create a resource from a response string - * @param input Read the given input stream which assumes the input - * is parsable JSON representing a valid resource - * @return - * @throws ResourceFactoryException if it is unable to create resources - */ - T create(InputStream input) ; + /** + * Create(or stub) a resource for a given version and kind and name + * + * @param version + * @param kind + * @param name + * + * @return + */ + T create(String version, String kind, String name); - /** - * Create(or stub) a resource for a given version and kind - * @param version - * @param kind - * @return - */ - T create(String version, String kind); + /** + * Stub out the given resource kind using a version determined by the factory + * + * @param kind + * @param name + * @return + */ + T stub(String kind, String name); - /** - * Create(or stub) a resource for a given version and kind and name - * @param version - * @param kind - * @param name - * - * @return - */ - T create(String version, String kind, String name); + /** + * Stub out the given resource kind using a version determined by the factory + * + * @param kind + * @param name + * @param namespace + * @return + */ + T stub(String kind, String name, String namespace); - /** - * Stub out the given resource kind using a version determined by the factory - * @param kind - * @param name - * @return - */ - T stub(String kind, String name); + /** + * The client given to resources when they are created + * + */ + void setClient(IClient client); - /** - * Stub out the given resource kind using a version determined by the factory - * @param kind - * @param name - * @param namespace - * @return - */ - T stub(String kind, String name, String namespace); - - /** - * The client given to resources when they are created - * @param client - */ - void setClient(IClient client); - } diff --git a/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java b/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java index f5000349..6855ebbb 100644 --- a/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java +++ b/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; import java.security.cert.X509Certificate; @@ -17,12 +18,12 @@ * @author Andre Dietisheim */ public interface ISSLCertificateCallback extends HostnameVerifier { - - boolean allowCertificate(X509Certificate[] chain); - boolean allowHostname(String hostname, SSLSession session); - - default boolean verify(String hostname, SSLSession session) { - return allowHostname(hostname, session); - } + boolean allowCertificate(X509Certificate[] chain); + + boolean allowHostname(String hostname, SSLSession session); + + default boolean verify(String hostname, SSLSession session) { + return allowHostname(hostname, session); + } } diff --git a/src/main/java/com/openshift/restclient/IWatcher.java b/src/main/java/com/openshift/restclient/IWatcher.java index c6ce012d..4f080047 100644 --- a/src/main/java/com/openshift/restclient/IWatcher.java +++ b/src/main/java/com/openshift/restclient/IWatcher.java @@ -8,9 +8,10 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; public interface IWatcher { - - void stop(); + + void stop(); } diff --git a/src/main/java/com/openshift/restclient/IncompatibleApiVersionsException.java b/src/main/java/com/openshift/restclient/IncompatibleApiVersionsException.java index 61112880..fa8a58bd 100644 --- a/src/main/java/com/openshift/restclient/IncompatibleApiVersionsException.java +++ b/src/main/java/com/openshift/restclient/IncompatibleApiVersionsException.java @@ -6,23 +6,25 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; import java.util.Collection; import com.openshift.internal.restclient.KubernetesAPIVersion; -/** - * @author Jeff Cantrill - */ public class IncompatibleApiVersionsException extends OpenShiftException { - - private static final long serialVersionUID = 1L; - public IncompatibleApiVersionsException(Collection clientVersions,Collection serverVersions ){ - super(String.format("The client %s and server %s do not have compatible API versions.", clientVersions, serverVersions)); - } - public IncompatibleApiVersionsException(String clientVersions, String serverVersions ){ - super(String.format("The client %s and server %s do not have compatible API versions.", clientVersions, serverVersions)); - } + private static final long serialVersionUID = 1L; + + public IncompatibleApiVersionsException(Collection clientVersions, + Collection serverVersions) { + super(String.format("The client %s and server %s do not have compatible API versions.", clientVersions, + serverVersions)); + } + + public IncompatibleApiVersionsException(String clientVersions, String serverVersions) { + super(String.format("The client %s and server %s do not have compatible API versions.", clientVersions, + serverVersions)); + } } diff --git a/src/main/java/com/openshift/restclient/NoopSSLCertificateCallback.java b/src/main/java/com/openshift/restclient/NoopSSLCertificateCallback.java index 50b45f76..d2b44b86 100644 --- a/src/main/java/com/openshift/restclient/NoopSSLCertificateCallback.java +++ b/src/main/java/com/openshift/restclient/NoopSSLCertificateCallback.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; import java.security.cert.X509Certificate; @@ -19,14 +20,14 @@ */ public class NoopSSLCertificateCallback implements ISSLCertificateCallback { - @Override - public boolean allowCertificate(X509Certificate[] chain) { - return true; - } + @Override + public boolean allowCertificate(X509Certificate[] chain) { + return true; + } - @Override - public boolean allowHostname(String hostname, SSLSession session) { - return true; - } + @Override + public boolean allowHostname(String hostname, SSLSession session) { + return true; + } } diff --git a/src/main/java/com/openshift/restclient/NotFoundException.java b/src/main/java/com/openshift/restclient/NotFoundException.java index 9f539707..c279b205 100644 --- a/src/main/java/com/openshift/restclient/NotFoundException.java +++ b/src/main/java/com/openshift/restclient/NotFoundException.java @@ -7,31 +7,29 @@ * * Contributors: * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ + ******************************************************************************/ + package com.openshift.restclient; import com.openshift.restclient.model.IStatus; -/** - * @author jeff.cantrill - */ public class NotFoundException extends OpenShiftException { - private static final long serialVersionUID = 1L; + private static final long serialVersionUID = 1L; + + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } - public NotFoundException(String message, Throwable cause) { - super(message, cause); - } + public NotFoundException(String message) { + super(message); + } - public NotFoundException(String message) { - super(message); - } + public NotFoundException(Throwable cause) { + super(cause, ""); + } - public NotFoundException(Throwable cause) { - super(cause, ""); - } - - public NotFoundException(Throwable cause, IStatus status, String message, Object... arguments) { - super(cause, status, message, arguments); - } + public NotFoundException(Throwable cause, IStatus status, String message, Object... arguments) { + super(cause, status, message, arguments); + } } diff --git a/src/main/java/com/openshift/restclient/OpenShiftContext.java b/src/main/java/com/openshift/restclient/OpenShiftContext.java index 2a53f4cf..ee91b1d8 100644 --- a/src/main/java/com/openshift/restclient/OpenShiftContext.java +++ b/src/main/java/com/openshift/restclient/OpenShiftContext.java @@ -6,13 +6,14 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** - * OpenShift Context. + * OpenShift Context. * * @author Fred Bricon * @@ -20,44 +21,42 @@ */ public class OpenShiftContext { - private Map context = new ConcurrentHashMap<>(); - - private static ThreadLocal threadLocalBinary = new ThreadLocal() { - protected OpenShiftContext initialValue() { - return new OpenShiftContext(); - }; - }; - - private OpenShiftContext() { - } - - /** - * Returns the {@link OpenShiftContext} instance for the current {@link Thread}. - * - * @return an {@link OpenShiftContext} - */ - public static OpenShiftContext get() { - return threadLocalBinary.get(); - } - - public void put(String key, Object value) { - context.put(key, value); - } - - @SuppressWarnings("unchecked") - public T get(String key) { - T value = (T) context.get(key); - return value; - } - - public void remove(String key) { - context.remove(key); - } - - public void clear() { - context.clear(); - } - - - + private Map context = new ConcurrentHashMap<>(); + + private static ThreadLocal threadLocalBinary = new ThreadLocal() { + protected OpenShiftContext initialValue() { + return new OpenShiftContext(); + } + }; + + private OpenShiftContext() { + } + + /** + * Returns the {@link OpenShiftContext} instance for the current {@link Thread}. + * + * @return an {@link OpenShiftContext} + */ + public static OpenShiftContext get() { + return threadLocalBinary.get(); + } + + @SuppressWarnings("unchecked") + public T get(String key) { + T value = (T) context.get(key); + return value; + } + + public void put(String key, Object value) { + context.put(key, value); + } + + public void remove(String key) { + context.remove(key); + } + + public void clear() { + context.clear(); + } + } diff --git a/src/main/java/com/openshift/restclient/OpenShiftException.java b/src/main/java/com/openshift/restclient/OpenShiftException.java index 2553de82..1b7c28dd 100644 --- a/src/main/java/com/openshift/restclient/OpenShiftException.java +++ b/src/main/java/com/openshift/restclient/OpenShiftException.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; import org.apache.commons.lang.StringUtils; @@ -17,38 +18,36 @@ */ public class OpenShiftException extends RuntimeException { - private static final long serialVersionUID = -7076942050102006278L; - private IStatus status; - - public OpenShiftException(Throwable cause, String message, Object... arguments) { - super(String.format(message, arguments), cause); - } - - public OpenShiftException(String message, Object... arguments) { - this(null, null, message, arguments); - } - - public OpenShiftException(Throwable cause, IStatus status, String message, Object... arguments ) { - super(String.format(StringUtils.defaultIfBlank(message, ""), arguments), cause); - this.status = status; - } - - public IStatus getStatus(){ - return this.status; - } - - public boolean hasStatus() { - return this.status != null; - } - - @Override - public String getMessage() { - if(hasStatus()) { - return super.getMessage() + " " + status.getMessage(); - } - return super.getMessage(); - } - - - + private static final long serialVersionUID = -7076942050102006278L; + private IStatus status; + + public OpenShiftException(Throwable cause, String message, Object... arguments) { + super(String.format(message, arguments), cause); + } + + public OpenShiftException(String message, Object... arguments) { + this(null, null, message, arguments); + } + + public OpenShiftException(Throwable cause, IStatus status, String message, Object... arguments) { + super(String.format(StringUtils.defaultIfBlank(message, ""), arguments), cause); + this.status = status; + } + + public IStatus getStatus() { + return this.status; + } + + public boolean hasStatus() { + return this.status != null; + } + + @Override + public String getMessage() { + if (hasStatus()) { + return super.getMessage() + " " + status.getMessage(); + } + return super.getMessage(); + } + } diff --git a/src/main/java/com/openshift/restclient/ResourceFactoryException.java b/src/main/java/com/openshift/restclient/ResourceFactoryException.java index 69800270..7acb343b 100644 --- a/src/main/java/com/openshift/restclient/ResourceFactoryException.java +++ b/src/main/java/com/openshift/restclient/ResourceFactoryException.java @@ -6,16 +6,14 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; -/** - * @author Jeff Cantrill - */ public class ResourceFactoryException extends OpenShiftException { - private static final long serialVersionUID = 4215359575300693464L; + private static final long serialVersionUID = 4215359575300693464L; - public ResourceFactoryException(Throwable e, String message, Object... arguments) { - super(e, message, arguments); - } + public ResourceFactoryException(Throwable e, String message, Object... arguments) { + super(e, message, arguments); + } } diff --git a/src/main/java/com/openshift/restclient/ResourceKind.java b/src/main/java/com/openshift/restclient/ResourceKind.java index 17d7a392..1fa5a90b 100644 --- a/src/main/java/com/openshift/restclient/ResourceKind.java +++ b/src/main/java/com/openshift/restclient/ResourceKind.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; import java.util.Collection; @@ -16,137 +17,138 @@ import org.apache.commons.lang.StringUtils; /** - * ResourceKind are the various types of Kubernetes - * resources that are of interest + * ResourceKind are the various types of Kubernetes resources that are of + * interest * */ public final class ResourceKind { - - //OpenShift Kinds - public static final String BUILD = "Build"; - public static final String BUILD_CONFIG = "BuildConfig"; - public static final String DEPLOYMENT_CONFIG = "DeploymentConfig"; - public static final String IMAGE_STREAM = "ImageStream"; - public static final String IMAGE_STREAM_TAG = "ImageStreamTag"; - public static final String IMAGE_STREAM_IMPORT = "ImageStreamImport"; - public static final String NAMESPACE = "Namespace"; - public static final String OAUTH_ACCESS_TOKEN = "OAuthAccessToken"; - public static final String OAUTH_AUTHORIZE_TOKEN = "OAuthAuthorizeToken"; - public static final String OAUTH_CLIENT = "OAuthClient"; - public static final String OAUTH_CLIENT_AUTHORIZATION = "OAuthClientAuthorization"; - public static final String POLICY = "Policy"; - public static final String POLICY_BINDING = "PolicyBinding"; - public static final String PROJECT = "Project"; - public static final String PROJECT_REQUEST = "ProjectRequest"; - public static final String ROLE = "Role"; - public static final String ROLE_BINDING = "RoleBinding"; - public static final String ROUTE = "Route"; - public static final String TEMPLATE = "Template"; - public static final String USER = "User"; - - //Kubernetes Kinds - public static final String ENDPOINTS = "Endpoints"; - public static final String EVENT = "Event"; - public static final String LIMIT_RANGE = "LimitRange"; - public static final String POD = "Pod"; - public static final String PVC = "PersistentVolumeClaim"; - public static final String PERSISTENT_VOLUME = "PersistentVolume"; - public static final String REPLICATION_CONTROLLER = "ReplicationController"; - public static final String RESOURCE_QUOTA = "ResourceQuota"; - public static final String SERVICE = "Service"; - public static final String SECRET = "Secret"; - public static final String SERVICE_ACCOUNT = "ServiceAccount"; - public static final String CONFIG_MAP = "ConfigMap"; - /* - * These are not true resources that can be used (mostly) in - * RESTful operations - */ - public static final String BUILD_REQUEST = "BuildRequest"; - - @Deprecated - public static final String CONFIG = "Config";//not rest resource; - public static final String LIST = "List"; - public static final String STATUS = "Status";//not rest resource - public static final String PROCESSED_TEMPLATES = "ProcessedTemplates";//mechanism for processing templates - - /** - * The default if we haven't implemented the kind yet - */ - public static final String UNRECOGNIZED = "Unrecognized"; - - private static final Collection values; - - public static Collection values() { - return values; - } - - public static String pluralize(String kind) { - return pluralize(kind, false, false); - } - public static String pluralize(String kind, boolean lowercase, boolean uncapitalize) { - if(StringUtils.isBlank(kind)) return ""; - if(kind.endsWith("y")) - kind = kind.substring(0, kind.length()-1).concat("ies"); - else if(!kind.endsWith("s")) { - kind = kind.concat("s"); - } - if(lowercase) { - kind = kind.toLowerCase(); - } - if(uncapitalize) { - kind = StringUtils.uncapitalize(kind); - } - return kind; - } - - static { - Set set = new HashSet(); - //OpenShift Kinds - set.add(BUILD); - set.add(BUILD_CONFIG); - set.add(DEPLOYMENT_CONFIG); - set.add(IMAGE_STREAM ); - set.add(IMAGE_STREAM_TAG); - set.add(IMAGE_STREAM_IMPORT); - set.add(OAUTH_ACCESS_TOKEN); - set.add(OAUTH_AUTHORIZE_TOKEN); - set.add(OAUTH_CLIENT); - set.add(OAUTH_CLIENT_AUTHORIZATION); - set.add(POLICY); - set.add(POLICY_BINDING); - set.add(PROJECT ); - set.add(PROJECT_REQUEST); - set.add(ROLE); - set.add(ROLE_BINDING); - set.add(ROUTE); - set.add(TEMPLATE); - set.add(USER); - - //Kubernetes Kinds - set.add(EVENT); - set.add(LIMIT_RANGE); - set.add(POD); - set.add(PVC); - set.add(PERSISTENT_VOLUME); - set.add(REPLICATION_CONTROLLER); - set.add(RESOURCE_QUOTA); - set.add(SERVICE); - set.add(SECRET); - set.add(SERVICE_ACCOUNT); - set.add(CONFIG_MAP); - - /* - * These are not true resources that can be used (mostly) in - * RESTful operations - */ - set.add(BUILD_REQUEST); - set.add(CONFIG); - set.add(LIST); - set.add(STATUS); - set.add("ProcessedTemplates"); - values = Collections.unmodifiableCollection(set); - } - - private ResourceKind() { - } + + // OpenShift Kinds + public static final String BUILD = "Build"; + public static final String BUILD_CONFIG = "BuildConfig"; + public static final String DEPLOYMENT_CONFIG = "DeploymentConfig"; + public static final String IMAGE_STREAM = "ImageStream"; + public static final String IMAGE_STREAM_TAG = "ImageStreamTag"; + public static final String IMAGE_STREAM_IMPORT = "ImageStreamImport"; + public static final String NAMESPACE = "Namespace"; + public static final String OAUTH_ACCESS_TOKEN = "OAuthAccessToken"; + public static final String OAUTH_AUTHORIZE_TOKEN = "OAuthAuthorizeToken"; + public static final String OAUTH_CLIENT = "OAuthClient"; + public static final String OAUTH_CLIENT_AUTHORIZATION = "OAuthClientAuthorization"; + public static final String POLICY = "Policy"; + public static final String POLICY_BINDING = "PolicyBinding"; + public static final String PROJECT = "Project"; + public static final String PROJECT_REQUEST = "ProjectRequest"; + public static final String ROLE = "Role"; + public static final String ROLE_BINDING = "RoleBinding"; + public static final String ROUTE = "Route"; + public static final String TEMPLATE = "Template"; + public static final String USER = "User"; + + // Kubernetes Kinds + public static final String ENDPOINTS = "Endpoints"; + public static final String EVENT = "Event"; + public static final String LIMIT_RANGE = "LimitRange"; + public static final String POD = "Pod"; + public static final String PVC = "PersistentVolumeClaim"; + public static final String PERSISTENT_VOLUME = "PersistentVolume"; + public static final String REPLICATION_CONTROLLER = "ReplicationController"; + public static final String RESOURCE_QUOTA = "ResourceQuota"; + public static final String SERVICE = "Service"; + public static final String SECRET = "Secret"; + public static final String SERVICE_ACCOUNT = "ServiceAccount"; + public static final String CONFIG_MAP = "ConfigMap"; + /* + * These are not true resources that can be used (mostly) in RESTful operations + */ + public static final String BUILD_REQUEST = "BuildRequest"; + + @Deprecated + public static final String CONFIG = "Config";// not rest resource; + public static final String LIST = "List"; + public static final String STATUS = "Status";// not rest resource + public static final String PROCESSED_TEMPLATES = "ProcessedTemplates";// mechanism for processing templates + + /** + * The default if we haven't implemented the kind yet + */ + public static final String UNRECOGNIZED = "Unrecognized"; + + private static final Collection values; + + public static Collection values() { + return values; + } + + public static String pluralize(String kind) { + return pluralize(kind, false, false); + } + + public static String pluralize(String kind, boolean lowercase, boolean uncapitalize) { + if (StringUtils.isBlank(kind)) { + return ""; + } + if (kind.endsWith("y")) { + kind = kind.substring(0, kind.length() - 1).concat("ies"); + } else if (!kind.endsWith("s")) { + kind = kind.concat("s"); + } + if (lowercase) { + kind = kind.toLowerCase(); + } + if (uncapitalize) { + kind = StringUtils.uncapitalize(kind); + } + return kind; + } + + static { + Set set = new HashSet(); + // OpenShift Kinds + set.add(BUILD); + set.add(BUILD_CONFIG); + set.add(DEPLOYMENT_CONFIG); + set.add(IMAGE_STREAM); + set.add(IMAGE_STREAM_TAG); + set.add(IMAGE_STREAM_IMPORT); + set.add(OAUTH_ACCESS_TOKEN); + set.add(OAUTH_AUTHORIZE_TOKEN); + set.add(OAUTH_CLIENT); + set.add(OAUTH_CLIENT_AUTHORIZATION); + set.add(POLICY); + set.add(POLICY_BINDING); + set.add(PROJECT); + set.add(PROJECT_REQUEST); + set.add(ROLE); + set.add(ROLE_BINDING); + set.add(ROUTE); + set.add(TEMPLATE); + set.add(USER); + + // Kubernetes Kinds + set.add(EVENT); + set.add(LIMIT_RANGE); + set.add(POD); + set.add(PVC); + set.add(PERSISTENT_VOLUME); + set.add(REPLICATION_CONTROLLER); + set.add(RESOURCE_QUOTA); + set.add(SERVICE); + set.add(SECRET); + set.add(SERVICE_ACCOUNT); + set.add(CONFIG_MAP); + + /* + * These are not true resources that can be used (mostly) in RESTful operations + */ + set.add(BUILD_REQUEST); + set.add(CONFIG); + set.add(LIST); + set.add(STATUS); + set.add("ProcessedTemplates"); + values = Collections.unmodifiableCollection(set); + } + + private ResourceKind() { + } } diff --git a/src/main/java/com/openshift/restclient/UnsupportedEndpointException.java b/src/main/java/com/openshift/restclient/UnsupportedEndpointException.java index d710bd97..41cd11cb 100644 --- a/src/main/java/com/openshift/restclient/UnsupportedEndpointException.java +++ b/src/main/java/com/openshift/restclient/UnsupportedEndpointException.java @@ -8,25 +8,24 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; /** - * The exception thrown when the client is trying to submit a request - * to an unrecognized endpoint. This usually occurs when a newer client - * is trying to utilize a feature that is unavailable to an older server - * - * @author jeff.cantrill + * The exception thrown when the client is trying to submit a request to an + * unrecognized endpoint. This usually occurs when a newer client is trying to + * utilize a feature that is unavailable to an older server * */ public class UnsupportedEndpointException extends OpenShiftException { - /** - * - */ - private static final long serialVersionUID = -9004398690965821552L; + /** + * + */ + private static final long serialVersionUID = -9004398690965821552L; - public UnsupportedEndpointException(String message, Object... arguments) { - super(message, arguments); - } + public UnsupportedEndpointException(String message, Object... arguments) { + super(message, arguments); + } } diff --git a/src/main/java/com/openshift/restclient/UnsupportedOperationException.java b/src/main/java/com/openshift/restclient/UnsupportedOperationException.java index 89dd5195..afd8d199 100644 --- a/src/main/java/com/openshift/restclient/UnsupportedOperationException.java +++ b/src/main/java/com/openshift/restclient/UnsupportedOperationException.java @@ -6,18 +6,16 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; -/** - * @author Jeff Cantrill - */ // TODO: replace with a unique name (UnsupportedResourceOperationException?) // since there's an identical exception in jdk (which is a runtime exception, too) public class UnsupportedOperationException extends RuntimeException { - - private static final long serialVersionUID = 1L; - public UnsupportedOperationException(String message){ - super(message); - } + private static final long serialVersionUID = 1L; + + public UnsupportedOperationException(String message) { + super(message); + } } diff --git a/src/main/java/com/openshift/restclient/UnsupportedVersionException.java b/src/main/java/com/openshift/restclient/UnsupportedVersionException.java index b89256eb..140d0c34 100644 --- a/src/main/java/com/openshift/restclient/UnsupportedVersionException.java +++ b/src/main/java/com/openshift/restclient/UnsupportedVersionException.java @@ -6,20 +6,18 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; -/** - * @author Jeff Cantrill - */ public class UnsupportedVersionException extends OpenShiftException { - - private static final long serialVersionUID = 1L; - public UnsupportedVersionException(String version){ - super(String.format("OpenShift API version '%s' is not supported by this client", version)); - } + private static final long serialVersionUID = 1L; + + public UnsupportedVersionException(String version) { + super(String.format("OpenShift API version '%s' is not supported by this client", version)); + } - public UnsupportedVersionException(String message, Object... arguments) { - super(message, arguments); - } + public UnsupportedVersionException(String message, Object... arguments) { + super(message, arguments); + } } diff --git a/src/main/java/com/openshift/restclient/api/ITypeFactory.java b/src/main/java/com/openshift/restclient/api/ITypeFactory.java index 2a157a63..bad1a828 100644 --- a/src/main/java/com/openshift/restclient/api/ITypeFactory.java +++ b/src/main/java/com/openshift/restclient/api/ITypeFactory.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api; import java.util.Optional; @@ -15,29 +16,31 @@ import com.openshift.restclient.ResourceFactoryException; /** - * A factory that is able of producing - * types from a response - * @author jeff.cantrill + * A factory that is able of producing types from a response * */ public interface ITypeFactory { - /** - * Create a resource from a response string - * @param response - * @return - * @throws ResourceFactoryException if it is unable to create resources - */ - Object createInstanceFrom(String response); - - /** - * Stub out the given resource kind using a version determined by the factory - * @param kind - Required. For arg types it may be in the form of apigroup/version.kind - * @param name - The name of the kind which may only be significant for instances that - * can be persisted by the server (e.g. Service) - * @param namespace - The namespace of the kind which may only be significant for instance - * that can be persisted - * @return - */ - Object stubKind(String kind, Optional name, Optional namespace); + /** + * Create a resource from a response string + * + * @throws ResourceFactoryException + * if it is unable to create resources + */ + Object createInstanceFrom(String response); + + /** + * Stub out the given resource kind using a version determined by the factory + * + * @param kind + * - Required. For arg types it may be in the form of + * apigroup/version.kind + * @param name + * - The name of the kind which may only be significant for instances + * that can be persisted by the server (e.g. Service) + * @param namespace + * - The namespace of the kind which may only be significant for + * instance that can be persisted + */ + Object stubKind(String kind, Optional name, Optional namespace); } diff --git a/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java b/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java index 7fd81483..173346f5 100644 --- a/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java +++ b/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java @@ -8,143 +8,144 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.restclient.api.capabilities; -import com.openshift.restclient.capability.ICapability; -import com.openshift.restclient.capability.IStoppable; +package com.openshift.restclient.api.capabilities; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.capability.IStoppable; + /** * Runs container exec */ -public interface IPodExec extends ICapability{ - - /** - * Execute a command on a named container in this pod - * @param listener Listener for command output - * @param options Options for the exec - * @param commands A command to run and any arguments - * @return A Handle to allow termination of the connection - */ - IStoppable start( IPodExecOutputListener listener, Options options, String... commands ); - - - /** - * A callback for exec output - * - */ - interface IPodExecOutputListener{ - - /** - * Callback received on initial connection - */ - void onOpen(); - - /** - * Exec received stdout message - * @param message - */ - void onStdOut(String message); - - /** - * Exec received stderr message - * @param message - */ - void onStdErr(String message); - - /** - * Exec (channel 3) error message - * @param message - */ - void onExecErr(String message); - - /** - * Called by lower level errors - * @param e Exception causing failure - */ - void onFailure(IOException e); - - /** - * Callback received when the connection - * to the pod is terminated from the server-side - * @param code a valid http response code - * @param reason a reason for termination, may be null - */ - void onClose(int code, String reason); - } - - /** - * Options for exec - */ - class Options{ - - public static final String CONTAINER = "container"; - public static final String STDOUT = "stdout"; - public static final String STDERR = "stderr"; - private Map options = new HashMap<>(); - private Map secondaries = new HashMap<>(); - - private Options storeSecondary(String key, Object v ) { - secondaries.put( key, v.toString() ); - return this; - } - - /** - * The container from which to retrieve logs - * @param container - * @return - */ - public Options container(String container) { - return storeSecondary(CONTAINER, container); - } - - /** - * Enable stdout - * @param value - * @return - */ - public Options stdOut(boolean value) { - return storeSecondary(STDOUT, value); - } - - /** - * Enable stderr - * @param value - * @return - */ - public Options stdErr(boolean value) { - return storeSecondary(STDERR, value); - } - - /** - * Add an option that is not explicitly - * defined. These will override any - * explicit options if there are collisions - * - * @param name - * @param value - * @return - */ - public Options parameter(String name, String value) { - options.put(name, value); - return this; - } - - /** - * The collective options - * @return a map of all the options - */ - public Map getMap(){ - HashMap combined = new HashMap<>(secondaries); - combined.putAll(options); - return Collections.unmodifiableMap(combined); - } - } - - +public interface IPodExec extends ICapability { + + /** + * Execute a command on a named container in this pod + * + * @param listener + * Listener for command output + * @param options + * Options for the exec + * @param commands + * A command to run and any arguments + * @return A Handle to allow termination of the connection + */ + IStoppable start(IPodExecOutputListener listener, Options options, String... commands); + + /** + * A callback for exec output + * + */ + interface IPodExecOutputListener { + + /** + * Callback received on initial connection + */ + void onOpen(); + + /** + * Exec received stdout message + * + */ + void onStdOut(String message); + + /** + * Exec received stderr message + * + */ + void onStdErr(String message); + + /** + * Exec (channel 3) error message + * + */ + void onExecErr(String message); + + /** + * Called by lower level errors + * + * @param e + * Exception causing failure + */ + void onFailure(IOException e); + + /** + * Callback received when the connection to the pod is terminated from the + * server-side + * + * @param code + * a valid http response code + * @param reason + * a reason for termination, may be null + */ + void onClose(int code, String reason); + } + + /** + * Options for exec + */ + class Options { + + public static final String CONTAINER = "container"; + public static final String STDOUT = "stdout"; + public static final String STDERR = "stderr"; + private Map options = new HashMap<>(); + private Map secondaries = new HashMap<>(); + + private Options storeSecondary(String key, Object v) { + secondaries.put(key, v.toString()); + return this; + } + + /** + * The container from which to retrieve logs + * + */ + public Options container(String container) { + return storeSecondary(CONTAINER, container); + } + + /** + * Enable stdout + * + */ + public Options stdOut(boolean value) { + return storeSecondary(STDOUT, value); + } + + /** + * Enable stderr + * + */ + public Options stdErr(boolean value) { + return storeSecondary(STDERR, value); + } + + /** + * Add an option that is not explicitly defined. These will override any + * explicit options if there are collisions + * + */ + public Options parameter(String name, String value) { + options.put(name, value); + return this; + } + + /** + * The collective options + * + * @return a map of all the options + */ + public Map getMap() { + HashMap combined = new HashMap<>(secondaries); + combined.putAll(options); + return Collections.unmodifiableMap(combined); + } + } } diff --git a/src/main/java/com/openshift/restclient/api/capabilities/IScalable.java b/src/main/java/com/openshift/restclient/api/capabilities/IScalable.java index 81db7d43..49691597 100644 --- a/src/main/java/com/openshift/restclient/api/capabilities/IScalable.java +++ b/src/main/java/com/openshift/restclient/api/capabilities/IScalable.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.capabilities; import com.openshift.restclient.OpenShiftException; @@ -16,16 +17,15 @@ /** * Allow a resource to scale - * @author jeff.cantrill * */ public interface IScalable extends ICapability { - /** - * Scale to the desired replicas. Value - * less then 0 will scale to 0 - * @param replicas - * @throws OpenShiftException if there are errors - */ - IScale scaleTo(int replicas); + /** + * Scale to the desired replicas. Value less then 0 will scale to 0 + * + * @throws OpenShiftException + * if there are errors + */ + IScale scaleTo(int replicas); } diff --git a/src/main/java/com/openshift/restclient/api/models/IAnnotatable.java b/src/main/java/com/openshift/restclient/api/models/IAnnotatable.java index 16e8bfaf..87fefae9 100644 --- a/src/main/java/com/openshift/restclient/api/models/IAnnotatable.java +++ b/src/main/java/com/openshift/restclient/api/models/IAnnotatable.java @@ -8,44 +8,40 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; import java.util.Map; /** * A resource that can be annotated - * @author jeff.cantrill * */ -public interface IAnnotatable{ - - /** - * Returns true if the resource is annotated with - * the given key - * @param key - * @return true if the annotation key exists - */ - boolean isAnnotatedWith(String key); - - /** - * Retrieves the annotated value for the given key - * @param key - * @return - */ - String getAnnotation(String key); - - /** - * Set the resource annotation - * @param key - * @param value - */ - void setAnnotation(String key, String value); - - /** - * Retrieves the annotations associated with the resource - * @return - */ - Map getAnnotations(); +public interface IAnnotatable { + + /** + * Returns true if the resource is annotated with the given key + * + * @return true if the annotation key exists + */ + boolean isAnnotatedWith(String key); + + /** + * Retrieves the annotated value for the given key + * + */ + String getAnnotation(String key); + + /** + * Set the resource annotation + * + */ + void setAnnotation(String key, String value); + /** + * Retrieves the annotations associated with the resource + * + */ + Map getAnnotations(); } diff --git a/src/main/java/com/openshift/restclient/api/models/IApiVersionable.java b/src/main/java/com/openshift/restclient/api/models/IApiVersionable.java index 5db900d9..f13ae548 100644 --- a/src/main/java/com/openshift/restclient/api/models/IApiVersionable.java +++ b/src/main/java/com/openshift/restclient/api/models/IApiVersionable.java @@ -8,19 +8,18 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; /** * A model that can be versioned - * @author jeff.cantrill * */ public interface IApiVersionable { - /** - * The api version of the resource - * as found at apiVersion - * @return - */ - String getApiVersion(); + /** + * The api version of the resource as found at apiVersion + * + */ + String getApiVersion(); } diff --git a/src/main/java/com/openshift/restclient/api/models/IEndpoints.java b/src/main/java/com/openshift/restclient/api/models/IEndpoints.java index 55857b71..3e08ab6b 100644 --- a/src/main/java/com/openshift/restclient/api/models/IEndpoints.java +++ b/src/main/java/com/openshift/restclient/api/models/IEndpoints.java @@ -1,4 +1,3 @@ - /******************************************************************************* * Copyright (c) 2016 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. @@ -9,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; import java.util.List; @@ -18,34 +18,43 @@ /** * Endpoint representation 'api/Endpoint' + * * @author jeff.cantrill * */ -public interface IEndpoints extends IResource{ +public interface IEndpoints extends IResource { List getSubSets(); - + interface IEndpointSubset { - + List getAddresses(); + List getNotReadyAddresses(); + List getPorts(); } - - interface IEndpointAddress{ - + + interface IEndpointAddress { + String getIP(); + String getHostName(); + String getNodeName(); + String getName(); + IObjectReference getTargetRef(); } - - interface IEndpointPort{ - + + interface IEndpointPort { + String getName(); + int getPort(); + String getProtocol(); } - + } diff --git a/src/main/java/com/openshift/restclient/api/models/IKindable.java b/src/main/java/com/openshift/restclient/api/models/IKindable.java index 939ee58e..bdc55eb8 100644 --- a/src/main/java/com/openshift/restclient/api/models/IKindable.java +++ b/src/main/java/com/openshift/restclient/api/models/IKindable.java @@ -8,20 +8,20 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; /** - * A resource that can describe itself by - * the kind it is + * A resource that can describe itself by the kind it is + * * @author jeff.cantrill * */ public interface IKindable { - /** - * The kind of the resource as would be found - * at kind - * @return - */ - String getKind(); + /** + * The kind of the resource as would be found at kind + * + */ + String getKind(); } diff --git a/src/main/java/com/openshift/restclient/api/models/ILabelable.java b/src/main/java/com/openshift/restclient/api/models/ILabelable.java index e05e27de..18914a95 100644 --- a/src/main/java/com/openshift/restclient/api/models/ILabelable.java +++ b/src/main/java/com/openshift/restclient/api/models/ILabelable.java @@ -8,28 +8,27 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; import java.util.Map; /** * A resource that can be labeled - * @author jeff.cantrill * */ public interface ILabelable { - - /** - * Retrieves the labels associated with the resource - * @return - */ - Map getLabels(); - - /** - * Add or update a label; - * @param key - * @param value - */ - void addLabel(String key, String value); + + /** + * Retrieves the labels associated with the resource + * + */ + Map getLabels(); + + /** + * Add or update a label; + * + */ + void addLabel(String key, String value); } diff --git a/src/main/java/com/openshift/restclient/api/models/INameSetable.java b/src/main/java/com/openshift/restclient/api/models/INameSetable.java index 8c5a065f..df8a92f5 100644 --- a/src/main/java/com/openshift/restclient/api/models/INameSetable.java +++ b/src/main/java/com/openshift/restclient/api/models/INameSetable.java @@ -8,20 +8,19 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; /** - * A resource where the client can - * define the name on the object - * (e.g. ObjectRef) - * @author jeff.cantrill + * A resource where the client can define the name on the object (e.g. + * ObjectRef) * */ public interface INameSetable { - /** - * The name of the resource - * @param name - */ - void setName(String name); + /** + * The name of the resource + * + */ + void setName(String name); } diff --git a/src/main/java/com/openshift/restclient/api/models/INamespaceSetable.java b/src/main/java/com/openshift/restclient/api/models/INamespaceSetable.java index f8be2e8c..6b5bc4ea 100644 --- a/src/main/java/com/openshift/restclient/api/models/INamespaceSetable.java +++ b/src/main/java/com/openshift/restclient/api/models/INamespaceSetable.java @@ -8,20 +8,19 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; /** - * A resource where the client can - * define the namespace on the object - * (e.g. ObjectRef) - * @author jeff.cantrill + * A resource where the client can define the namespace on the object (e.g. + * ObjectRef) * */ public interface INamespaceSetable { - /** - * The namespace for the object ref - * @param namespace - */ - void setNamespace(String namespace); + /** + * The namespace for the object ref + * + */ + void setNamespace(String namespace); } diff --git a/src/main/java/com/openshift/restclient/api/models/IObjectMeta.java b/src/main/java/com/openshift/restclient/api/models/IObjectMeta.java index d5728e1f..b3ddaf92 100644 --- a/src/main/java/com/openshift/restclient/api/models/IObjectMeta.java +++ b/src/main/java/com/openshift/restclient/api/models/IObjectMeta.java @@ -8,37 +8,35 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; /** * ObjectMeta info as defined by the server - * @author jeff.cantrill - * */ public interface IObjectMeta extends ILabelable, IAnnotatable { - /** - * Returns the identifier for this resource - * @return - */ - String getName(); - - /** - * Returns the timestamp of when this resource - * was created - * @return - */ - String getCreationTimeStamp(); + /** + * Returns the identifier for this resource + * + */ + String getName(); + + /** + * Returns the timestamp of when this resource was created + * + */ + String getCreationTimeStamp(); - /** - * Returns the scope of this resource - * @return - */ - String getNamespace(); + /** + * Returns the scope of this resource + * + */ + String getNamespace(); - /** - * A value that represents the version of this resource - * @return - */ - String getResourceVersion(); + /** + * A value that represents the version of this resource + * + */ + String getResourceVersion(); } diff --git a/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java b/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java index 7590dbbd..c5e5f727 100644 --- a/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java +++ b/src/main/java/com/openshift/restclient/api/models/ITypeMeta.java @@ -8,13 +8,14 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.api.models; import com.openshift.restclient.model.JSONSerializeable; /** * Marker interface to kubernetes TypeMeta - * @author jeff.cantrill + * * */ public interface ITypeMeta extends IApiVersionable, IKindable, JSONSerializeable { diff --git a/src/main/java/com/openshift/restclient/apis/autoscaling/models/IScale.java b/src/main/java/com/openshift/restclient/apis/autoscaling/models/IScale.java index 3ecb02d3..4126ad0f 100644 --- a/src/main/java/com/openshift/restclient/apis/autoscaling/models/IScale.java +++ b/src/main/java/com/openshift/restclient/apis/autoscaling/models/IScale.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.apis.autoscaling.models; import com.openshift.restclient.api.models.INameSetable; @@ -17,20 +18,19 @@ /** * Scale object payload to scalable resources - * @author jeff.cantrill * */ public interface IScale extends ITypeMeta, IObjectMeta, INamespaceSetable, INameSetable { - /** - * The number of desired replicas - * @return - */ - int getSpecReplicas(); - - /** - * Set the number of desired replicas - * @param replicas - */ - void setSpecReplicas(int replicas); + /** + * The number of desired replicas + * + */ + int getSpecReplicas(); + + /** + * Set the number of desired replicas + * + */ + void setSpecReplicas(int replicas); } diff --git a/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java b/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java index 0154fbc3..c0be3a4f 100644 --- a/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java +++ b/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java @@ -6,89 +6,85 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.authorization; import com.openshift.restclient.model.user.IUser; -/** - * @author Jeff Cantrill - */ public interface IAuthorizationContext { - - public static final String AUTHSCHEME_BASIC = "Basic"; - public static final String AUTHSCHEME_OAUTH = "OAuth"; - - /** - * The authorized user if it can be found for this token - * @return return the user for the token or null if not authorized - */ - IUser getUser(); - - /** - * This can trigger a remote call if a user - * has not attempted to authorize previously - * - * @return true if authorized; false otherwise - */ - boolean isAuthorized(); - - /** - * The authorization scope if it can be determined. - * @return the scope or null if unknown - */ - String getAuthScheme(); - - /** - * Token to use for authentication. Will return non-null - * value if authorized - * @return - */ - String getToken(); - - /** - * The token to try and use for communication - * to the apiserver - * @param token - */ - void setToken(String token); - - /** - * A username to use for authenticating - * @param userName - */ - void setUserName(String userName); - - /** - * A username to use for authenticating - * @return userName - */ - String getUserName(); - - /** - * Password to use to authenticate to retrieve a - * token - * @param password - */ - void setPassword(String password); - - /** - * Password to use to authenticate to retrieve a - * token - * @return password - */ - String getPassword(); - /** - * Time in ?? when the token expires. Will return - * non-null value if authorized - * @return - */ - String getExpiresIn(); - - /** - * Retrieve the authorization details for a server - * - * @param baseURL - * @return - */ - IAuthorizationDetails getAuthorizationDetails(); + + public static final String AUTHSCHEME_BASIC = "Basic"; + public static final String AUTHSCHEME_OAUTH = "OAuth"; + + /** + * The authorized user if it can be found for this token + * + * @return return the user for the token or null if not authorized + */ + IUser getUser(); + + /** + * This can trigger a remote call if a user has not attempted to authorize + * previously + * + * @return true if authorized; false otherwise + */ + boolean isAuthorized(); + + /** + * The authorization scope if it can be determined. + * + * @return the scope or null if unknown + */ + String getAuthScheme(); + + /** + * Token to use for authentication. Will return non-null value if authorized + * + */ + String getToken(); + + /** + * The token to try and use for communication to the apiserver + * + */ + void setToken(String token); + + /** + * A username to use for authenticating + * + */ + void setUserName(String userName); + + /** + * A username to use for authenticating + * + * @return userName + */ + String getUserName(); + + /** + * Password to use to authenticate to retrieve a token + * + */ + void setPassword(String password); + + /** + * Password to use to authenticate to retrieve a token + * + * @return password + */ + String getPassword(); + + /** + * Time in ?? when the token expires. Will return non-null value if authorized + * + */ + String getExpiresIn(); + + /** + * Retrieve the authorization details for a server + * + */ + IAuthorizationDetails getAuthorizationDetails(); } diff --git a/src/main/java/com/openshift/restclient/authorization/IAuthorizationDetails.java b/src/main/java/com/openshift/restclient/authorization/IAuthorizationDetails.java index 4f233dad..3668202c 100644 --- a/src/main/java/com/openshift/restclient/authorization/IAuthorizationDetails.java +++ b/src/main/java/com/openshift/restclient/authorization/IAuthorizationDetails.java @@ -8,35 +8,34 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.authorization; /** - * The details about how to manually obtain - * a request token - * - * @author Jeff Cantrill + * The details about how to manually obtain a request token + * */ public interface IAuthorizationDetails { - - /** - * The message returned from the server - * for being unauthorized if provided - * @return the message or empty string - */ - String getMessage(); - - /** - * The link to visit to request a valid - * token that can be used to access - * the server if provided - * @return the link or null if not provided - */ - String getRequestTokenLink(); - - /** - * The authentication scheme - * @return - */ - String getScheme(); - + + /** + * The message returned from the server for being unauthorized if provided + * + * @return the message or empty string + */ + String getMessage(); + + /** + * The link to visit to request a valid token that can be used to access the + * server if provided + * + * @return the link or null if not provided + */ + String getRequestTokenLink(); + + /** + * The authentication scheme + * + */ + String getScheme(); + } diff --git a/src/main/java/com/openshift/restclient/authorization/ResourceForbiddenException.java b/src/main/java/com/openshift/restclient/authorization/ResourceForbiddenException.java index 12b8e039..2e81715e 100644 --- a/src/main/java/com/openshift/restclient/authorization/ResourceForbiddenException.java +++ b/src/main/java/com/openshift/restclient/authorization/ResourceForbiddenException.java @@ -6,26 +6,22 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.authorization; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.model.IStatus; -/** - * @author Jeff Cantrill - */ public class ResourceForbiddenException extends OpenShiftException { - private static final long serialVersionUID = 6998191096256199081L; + private static final long serialVersionUID = 6998191096256199081L; - public ResourceForbiddenException(String message, Throwable e) { - super(message, e); - } + public ResourceForbiddenException(String message, Throwable e) { + super(message, e); + } - public ResourceForbiddenException(String message, IStatus status, Throwable e) { - super(e, status, message); - } - - + public ResourceForbiddenException(String message, IStatus status, Throwable e) { + super(e, status, message); + } } diff --git a/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java b/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java index 1deff811..91989d8b 100644 --- a/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java +++ b/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.authorization; import org.apache.commons.lang.StringUtils; @@ -13,48 +14,48 @@ import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.model.IStatus; -/** - * @author Jeff Cantrill - */ public class UnauthorizedException extends OpenShiftException { - private static final long serialVersionUID = -3999801367045252906L; - private static final String MSG_BASE = "Unauthorized to access resource."; - private String message; - private IStatus status; - private IAuthorizationDetails details; - - public UnauthorizedException(IAuthorizationDetails details) { - this(details, null); - } - - public UnauthorizedException(IAuthorizationDetails details, IStatus status) { - super(String.format("%s See the authorization details for additional information or contact your system administrator.", MSG_BASE)); - this.status = status; - this.details = details; - if(details != null) { - if(StringUtils.isNotBlank(details.getScheme())){ - message = String.format("%s You can access the server using %s authentication.", MSG_BASE, details.getScheme()); - }else - message = details.getMessage(); - }else - message = super.getMessage(); - } - - public IAuthorizationDetails getAuthorizationDetails() { - return details; - } - - @Override - public String getMessage() { - return message; - } - - @Override - public IStatus getStatus() { - return this.status; - } - - + private static final long serialVersionUID = -3999801367045252906L; + private static final String MSG_BASE = "Unauthorized to access resource."; + private String message; + private IStatus status; + private IAuthorizationDetails details; + + public UnauthorizedException(IAuthorizationDetails details) { + this(details, null); + } + + public UnauthorizedException(IAuthorizationDetails details, IStatus status) { + super(String.format( + "%s See the authorization details for additional information or contact your system administrator.", + MSG_BASE)); + this.status = status; + this.details = details; + if (details != null) { + if (StringUtils.isNotBlank(details.getScheme())) { + message = String.format("%s You can access the server using %s authentication.", MSG_BASE, + details.getScheme()); + } else { + message = details.getMessage(); + } + } else { + message = super.getMessage(); + } + } + + public IAuthorizationDetails getAuthorizationDetails() { + return details; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public IStatus getStatus() { + return this.status; + } } diff --git a/src/main/java/com/openshift/restclient/capability/CapabilityVisitor.java b/src/main/java/com/openshift/restclient/capability/CapabilityVisitor.java index 2b7c26d9..c76d1c2b 100644 --- a/src/main/java/com/openshift/restclient/capability/CapabilityVisitor.java +++ b/src/main/java/com/openshift/restclient/capability/CapabilityVisitor.java @@ -6,42 +6,44 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability; -import java.lang.reflect.Type; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; /** * A visitor used to access a resources capability - * @param The capability type - * @param A context significant to the visitor * - * @author Jeff Cantrill + * @param + * The capability type + * @param + * A context significant to the visitor + * */ public abstract class CapabilityVisitor { - - private Type type; - - /** - * Visits the capability - * @param capability - * @return A return type that is significant to the caller - */ - public abstract R visit(T capability); - - /** - * Gets the Capability type - * @return - */ - public final Type getCapabilityType(){ - if(type == null) { - Type superclass = getClass().getGenericSuperclass(); - if (superclass instanceof Class) { - throw new RuntimeException("Missing type parameter."); - } - this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0]; - } + + private Type type; + + /** + * Visits the capability + * + */ + public abstract R visit(T capability); + + /** + * Gets the Capability type + * + */ + public final Type getCapabilityType() { + if (type == null) { + Type superclass = getClass().getGenericSuperclass(); + if (superclass instanceof Class) { + throw new RuntimeException("Missing type parameter."); + } + this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0]; + } return type; - } - + } + } diff --git a/src/main/java/com/openshift/restclient/capability/IBinaryCapability.java b/src/main/java/com/openshift/restclient/capability/IBinaryCapability.java index 31d33a1e..dbb7db74 100644 --- a/src/main/java/com/openshift/restclient/capability/IBinaryCapability.java +++ b/src/main/java/com/openshift/restclient/capability/IBinaryCapability.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability; /** @@ -13,23 +14,23 @@ */ public interface IBinaryCapability extends ICapability { - static final OpenShiftBinaryOption SKIP_TLS_VERIFY = new SkipTlsVerify(); + static final OpenShiftBinaryOption SKIP_TLS_VERIFY = new SkipTlsVerify(); + + /** + * Skips the SSL/TLS Verification when using a binary capability + */ + static class SkipTlsVerify implements OpenShiftBinaryOption { - /** - * Skips the SSL/TLS Verification when using a binary capability - */ - static class SkipTlsVerify implements OpenShiftBinaryOption { + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" --insecure-skip-tls-verify=true"); + } + } - @Override - public void append(StringBuilder commandLine) { - commandLine.append(" --insecure-skip-tls-verify=true"); - } - } - - static interface OpenShiftBinaryOption { - void append(StringBuilder builder); - } + static interface OpenShiftBinaryOption { + void append(StringBuilder builder); + } - static final String OPENSHIFT_BINARY_LOCATION = "openshift.restclient.oc.location"; + static final String OPENSHIFT_BINARY_LOCATION = "openshift.restclient.oc.location"; } diff --git a/src/main/java/com/openshift/restclient/capability/ICapability.java b/src/main/java/com/openshift/restclient/capability/ICapability.java index 8d467ab7..520a015b 100644 --- a/src/main/java/com/openshift/restclient/capability/ICapability.java +++ b/src/main/java/com/openshift/restclient/capability/ICapability.java @@ -6,25 +6,22 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability; -/** - * @author Jeff Cantrill - */ public interface ICapability { - - /** - * Allow the implementation of the capability to determine - * if it is supported on the OpenShift server. Implementations - * should return false if they can not - * - * @return true if the capability exists - */ - boolean isSupported(); - - /** - * Well known name of the capability - * @return - */ - String getName(); + + /** + * Allow the implementation of the capability to determine if it is supported on + * the OpenShift server. Implementations should return false if they can not + * + * @return true if the capability exists + */ + boolean isSupported(); + + /** + * Well known name of the capability + * + */ + String getName(); } diff --git a/src/main/java/com/openshift/restclient/capability/ICapable.java b/src/main/java/com/openshift/restclient/capability/ICapable.java index ff24d336..df3cf42b 100644 --- a/src/main/java/com/openshift/restclient/capability/ICapable.java +++ b/src/main/java/com/openshift/restclient/capability/ICapable.java @@ -6,40 +6,41 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability; /** - * ICapable allows a source to be queried and identify its - * capabilities + * ICapable allows a source to be queried and identify its capabilities * - * @author Jeff Cantrill */ public interface ICapable { - /** - * Gets the capability of the desired type - * - * @param capability - * @return an implementation of the given capability - */ - T getCapability(Class capability); - - /** - * Determines if the client supports the desired capability - * - * @param capability - * @return true if the client is able to offer this capability - */ - boolean supports(Class capability); - - /** - * Uses the given visitor to access the desired capability if it - * is supported - * - * @param visitor A visitor looking for a given Capability type - * @param visitor A capability visitor - * @param unsupportedCapabililityValue The value to return when the capability is not supported - * @return A type that is expected by the caller - */ - R accept(CapabilityVisitor visitor, R unsupportedCapabililityValue); + /** + * Gets the capability of the desired type + * + * @param capability + * @return an implementation of the given capability + */ + T getCapability(Class capability); + + /** + * Determines if the client supports the desired capability + * + * @return true if the client is able to offer this capability + */ + boolean supports(Class capability); + + /** + * Uses the given visitor to access the desired capability if it is supported + * + * @param visitor + * A visitor looking for a given Capability type + * @param + * visitor A capability visitor + * @param + * unsupportedCapabililityValue The value to return when the + * capability is not supported + * @return A type that is expected by the caller + */ + R accept(CapabilityVisitor visitor, R unsupportedCapabililityValue); } diff --git a/src/main/java/com/openshift/restclient/capability/IStoppable.java b/src/main/java/com/openshift/restclient/capability/IStoppable.java index ebdc900f..2556a31c 100644 --- a/src/main/java/com/openshift/restclient/capability/IStoppable.java +++ b/src/main/java/com/openshift/restclient/capability/IStoppable.java @@ -8,19 +8,18 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability; /** - * Handle to something that can be - * explicitly stopped or terminated + * Handle to something that can be explicitly stopped or terminated * - * @author jeff.cantrill * */ public interface IStoppable { - - /** - * Stop the process - */ - void stop(); + + /** + * Stop the process + */ + void stop(); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IBuildCancelable.java b/src/main/java/com/openshift/restclient/capability/resources/IBuildCancelable.java index ea1349e1..d2a70879 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IBuildCancelable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IBuildCancelable.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; @@ -15,15 +16,16 @@ /** * Capability to cancel a build that is running + * * @author jeff.cantrill * */ public interface IBuildCancelable extends ICapability { - - /** - * Cancel the build - * @return - */ - IBuild cancel(); + + /** + * Cancel the build + * + */ + IBuild cancel(); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java b/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java index 0caeb75f..3083300d 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IBuildTriggerable.java @@ -8,67 +8,77 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; +import java.util.List; + import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.model.IBuild; -import java.util.List; - /** * Capability to trigger a build based on the build configuration - * @author Jeff Cantrill * */ public interface IBuildTriggerable extends ICapability { - - /** - * Trigger a build based on a build config - * @return The build that was triggered - */ - IBuild trigger(); - - /** - * Trigger a build with the given source level commit id - * @param commitId - * @return The build that was triggered - * @deprecated - * Replaced by calling {@link #setCommitId(String)}, followed - * by {@link #trigger()}. - */ - IBuild trigger(String commitId); - - /** - * Set the commit level for the SCM extraction - * of the source code the build operates against - * @param commitId the specific hexadecimal commit ID associated with a SCM log level - */ - void setCommitId(String commitId); - - /** - * Get the commit level for the SCM extraction - * of the source code the build operates against - * @return the specific hexadecimal commit ID associated with a SCM log level - */ - String getCommitId(); - - /** - * Add a human readable short explanation of why this build request was issued - * @param cause the description to add to the list of causes for this request - */ - void addBuildCause(String cause); - - /** - * Get the list of human readable short explanations of why this build request was issued - * @return list of reasons for the build - */ - List getBuildCauses(); - /** - * Sets an environment variable for this build request - * @param name The name of the environment variable - * @param value The value of the environment variable - */ - void setEnvironmentVariable(String name, String value); + /** + * Trigger a build based on a build config + * + * @return The build that was triggered + */ + IBuild trigger(); + + /** + * Trigger a build with the given source level commit id + * + * @return The build that was triggered + * @deprecated Replaced by calling {@link #setCommitId(String)}, followed by + * {@link #trigger()}. + */ + IBuild trigger(String commitId); + + /** + * Set the commit level for the SCM extraction of the source code the build + * operates against + * + * @param commitId + * the specific hexadecimal commit ID associated with a SCM log level + */ + void setCommitId(String commitId); + + /** + * Get the commit level for the SCM extraction of the source code the build + * operates against + * + * @return the specific hexadecimal commit ID associated with a SCM log level + */ + String getCommitId(); + + /** + * Add a human readable short explanation of why this build request was issued + * + * @param cause + * the description to add to the list of causes for this request + */ + void addBuildCause(String cause); + + /** + * Get the list of human readable short explanations of why this build request + * was issued + * + * @return list of reasons for the build + */ + List getBuildCauses(); + + /** + * Sets an environment variable for this build request + * + * @param name + * The name of the environment variable + * @param value + * The value of the environment variable + */ + void setEnvironmentVariable(String name, String value); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IClientCapability.java b/src/main/java/com/openshift/restclient/capability/resources/IClientCapability.java index c48d6d2b..2653d524 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IClientCapability.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IClientCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.IClient; @@ -15,10 +16,9 @@ /** * The capability to retrieve the client from a resource - * @author Jeff Cantrill * */ public interface IClientCapability extends ICapability { - - IClient getClient(); + + IClient getClient(); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IDeployCapability.java b/src/main/java/com/openshift/restclient/capability/resources/IDeployCapability.java index 0a1b0d61..90a77449 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IDeployCapability.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IDeployCapability.java @@ -8,22 +8,24 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; /** - * Capability to trigger a new deployment of a deploymentconfig - * (e.g. oc deploy foo) - * @author jeff.cantrill + * Capability to trigger a new deployment of a deploymentconfig (e.g. oc deploy + * foo) * */ public interface IDeployCapability extends ICapability { - /** - * Deploy the latest deployment - * @throws an OpenShiftException if there is an error (e.g. 404) - */ - void deploy(); - + /** + * Deploy the latest deployment + * + * @throws an + * OpenShiftException if there is an error (e.g. 404) + */ + void deploy(); + } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IDeploymentConfigTraceability.java b/src/main/java/com/openshift/restclient/capability/resources/IDeploymentConfigTraceability.java index ce2fe06c..36fbb0a8 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IDeploymentConfigTraceability.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IDeploymentConfigTraceability.java @@ -6,20 +6,18 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.model.IDeploymentConfig; -/** - * @author Jeff Cantrill - */ public interface IDeploymentConfigTraceability extends ICapability { - - /** - * Get the deployment configuration for a resource - * @return - */ - IDeploymentConfig getDeploymentConfig(); + + /** + * Get the deployment configuration for a resource + * + */ + IDeploymentConfig getDeploymentConfig(); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTraceability.java b/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTraceability.java index ecd7a278..e2e1cba7 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTraceability.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTraceability.java @@ -6,24 +6,23 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; import com.openshift.restclient.model.IReplicationController; /** - * Trace the source of what caused a resource - * to be deployed + * Trace the source of what caused a resource to be deployed * - * @author Jeff Cantrill */ public interface IDeploymentTraceability extends ICapability { - /** - * Get the deployment of a resource. The value returned when - * the capability is not supported is not guaranteed. - * - * @return IReplicationController if the capability is supported. - */ - IReplicationController getDeployment(); + /** + * Get the deployment of a resource. The value returned when the capability is + * not supported is not guaranteed. + * + * @return IReplicationController if the capability is supported. + */ + IReplicationController getDeployment(); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTriggerable.java b/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTriggerable.java index fec93964..75a43eb0 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTriggerable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IDeploymentTriggerable.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; @@ -27,26 +28,22 @@ public interface IDeploymentTriggerable extends ICapability { /** * If set the true latest will update the deployment config with the latest state from all triggers. - * @param latest */ void setLatest(boolean latest); /** * Returns the current setting of the latest flag. - * @return */ boolean isLatest(); /** * If set to try force will try to force a new deployment to run. If the deployment config is paused, * then setting this to true will return an Invalid error. - * @param force */ void setForce(boolean force); /** * Returns the latest setting of the force flag. - * @return */ boolean isForce(); @@ -59,7 +56,6 @@ public interface IDeploymentTriggerable extends ICapability { /** * Returns the name of the deployment config seeded into the deployment request - * @return */ String getResourceName(); diff --git a/src/main/java/com/openshift/restclient/capability/resources/IImageStreamImportCapability.java b/src/main/java/com/openshift/restclient/capability/resources/IImageStreamImportCapability.java index 4b7655c9..a11acff4 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IImageStreamImportCapability.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IImageStreamImportCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; @@ -17,17 +18,14 @@ /** * Import tags from a repository for an image * - * @author jeff.cantrill * */ public interface IImageStreamImportCapability extends ICapability { - /** - * Import docker image metadata - * @param uri - * @return - * @throws OpenShiftException - */ - IImageStreamImport importImageMetadata(DockerImageURI uri); - + /** + * Import docker image metadata + * + */ + IImageStreamImport importImageMetadata(DockerImageURI uri); + } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrieval.java b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrieval.java index 970f87ff..c63b4640 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrieval.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrieval.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import java.io.InputStream; @@ -15,48 +16,44 @@ import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; import com.openshift.restclient.capability.ICapability; -/** - * - * @author Jeff Cantrill - * - */ public interface IPodLogRetrieval extends ICapability { - - - /** - * Return the logs from the pod, optionally following them. - * - * @param follow - * true if following. Default: false - * @param options - * the options to pass to the underlying {@code oc} command - * @return the log output stream - */ - InputStream getLogs(boolean follow, OpenShiftBinaryOption... options); - - /** - * Return the logs from the pod, optionally following them - * - * @param follow - * true; if following, Default: false - * @param container - * the name of the container in the pod to get logs uses the - * first container if empty - * @param options - * the options to pass to the underlying {@code oc} command - * @return the log output stream - */ - InputStream getLogs(boolean follow, String container, OpenShiftBinaryOption... options); - - /** - * Stop retrieving logs for all containers - */ - void stop(); - - /** - * Stop retrieving logs for a specific container - * @param container the name of the container - */ - void stop(String container); + + /** + * Return the logs from the pod, optionally following them. + * + * @param follow + * true if following. Default: false + * @param options + * the options to pass to the underlying {@code oc} command + * @return the log output stream + */ + InputStream getLogs(boolean follow, OpenShiftBinaryOption... options); + + /** + * Return the logs from the pod, optionally following them + * + * @param follow + * true; if following, Default: false + * @param container + * the name of the container in the pod to get logs uses the first + * container if empty + * @param options + * the options to pass to the underlying {@code oc} command + * @return the log output stream + */ + InputStream getLogs(boolean follow, String container, OpenShiftBinaryOption... options); + + /** + * Stop retrieving logs for all containers + */ + void stop(); + + /** + * Stop retrieving logs for a specific container + * + * @param container + * the name of the container + */ + void stop(String container); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java index 27ebbfc7..687191ac 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java @@ -8,144 +8,145 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.restclient.capability.resources; -import com.openshift.restclient.capability.ICapability; -import com.openshift.restclient.capability.IStoppable; -import org.apache.commons.lang.StringUtils; +package com.openshift.restclient.capability.resources; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import org.apache.commons.lang.StringUtils; + +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.capability.IStoppable; + /** * Retrieve logs in an async call - * @author jeff.cantrill + * * */ -public interface IPodLogRetrievalAsync extends ICapability{ - - /** - * Start retrieving logs using the given listener and options - * @param listener - * @return A Handle to allow termination of log streaming - */ - IStoppable start(IPodLogListener listener); - - /** - * Start retrieving logs using the given listener and options - * @param listener - * @param options options for retrieving logs - * @return A Handle to allow termination of log streaming - */ - IStoppable start(IPodLogListener listener, Options options); - - - /** - * A callback for log messages - * @author jeff.cantrill - * - */ - interface IPodLogListener{ - - /** - * Callback received on initial connection - */ - void onOpen(); - - /** - * A log message - * @param message - */ - void onMessage(String message); - - /** - * Callback received when the connection - * to the pod is terminated from the server-side - * @param code a valid http response code - * @param reason a reason for termination, may be null - */ - void onClose(int code, String reason); - - /** - * Callback received when the web socket connection - * fails - * @param e the exception which occurred - */ - void onFailure(IOException e); - - } - - /** - * Options for retrieving logs using a - * fluent builder style - * - * @author jeff.cantrill - * - */ - public static class Options{ - - private static final String CONTAINER = "container"; - private static final String FOLLOW = "follow"; - private boolean follow = false; - private String container = null; - private Map options = new HashMap<>(); - - /** - * The container from which to retrieve logs - * @param container - * @return - */ - public Options container(String container) { - this.container = container; - return this; - } - - /** - * follow the logs, defaults to false - * @return - */ - public Options follow() { - return follow(true); - } - - /** - * follow the logs - * @param value - * @return - */ - public Options follow(boolean value) { - this.follow = value; - return this; - } - - /** - * Add an option that is not explicitly - * defined. These will override any - * explicit options if there are collisions - * - * @param name - * @param value - * @return - */ - public Options parameter(String name, String value) { - options.put(name, value); - return this; - } - - /** - * The collective options - * @return a map of all the options - */ - public Map getMap(){ - if(!options.containsKey(FOLLOW) && follow) { - options.put(FOLLOW, "true"); - } - if(!options.containsKey(CONTAINER) && StringUtils.isNotBlank(container)) { - options.put(CONTAINER, container); - } - return Collections.unmodifiableMap(options); - } - } +public interface IPodLogRetrievalAsync extends ICapability { + + /** + * Start retrieving logs using the given listener and options + * + * @return A Handle to allow termination of log streaming + */ + IStoppable start(IPodLogListener listener); + + /** + * Start retrieving logs using the given listener and options + * + * @param options + * options for retrieving logs + * @return A Handle to allow termination of log streaming + */ + IStoppable start(IPodLogListener listener, Options options); + + /** + * A callback for log messages + * + * @author jeff.cantrill + * + */ + interface IPodLogListener { + + /** + * Callback received on initial connection + */ + void onOpen(); + + /** + * A log message + * + */ + void onMessage(String message); + + /** + * Callback received when the connection to the pod is terminated from the + * server-side + * + * @param code + * a valid http response code + * @param reason + * a reason for termination, may be null + */ + void onClose(int code, String reason); + + /** + * Callback received when the web socket connection fails + * + * @param e + * the exception which occurred + */ + void onFailure(IOException e); + + } + + /** + * Options for retrieving logs using a fluent builder style + * + * @author jeff.cantrill + * + */ + public static class Options { + + private static final String CONTAINER = "container"; + private static final String FOLLOW = "follow"; + private boolean follow = false; + private String container = null; + private Map options = new HashMap<>(); + + /** + * The container from which to retrieve logs + * + */ + public Options container(String container) { + this.container = container; + return this; + } + + /** + * follow the logs, defaults to false + * + */ + public Options follow() { + return follow(true); + } + + /** + * follow the logs + * + */ + public Options follow(boolean value) { + this.follow = value; + return this; + } + + /** + * Add an option that is not explicitly defined. These will override any + * explicit options if there are collisions + * + */ + public Options parameter(String name, String value) { + options.put(name, value); + return this; + } + + /** + * The collective options + * + * @return a map of all the options + */ + public Map getMap() { + if (!options.containsKey(FOLLOW) && follow) { + options.put(FOLLOW, "true"); + } + if (!options.containsKey(CONTAINER) && StringUtils.isNotBlank(container)) { + options.put(CONTAINER, container); + } + return Collections.unmodifiableMap(options); + } + } } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IPortForwardable.java b/src/main/java/com/openshift/restclient/capability/resources/IPortForwardable.java index 2f075ee7..62e3bbd4 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IPortForwardable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IPortForwardable.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import java.util.Collection; @@ -18,113 +19,120 @@ /** * Defines if a pod can support port forwarding - * @author Jeff Cantrill * */ public interface IPortForwardable extends IBinaryCapability { - /** - * Forward the ports to a pod. This is a non-blocking call - * @param pairs the pairs of local/remote ports to link together - * @param options - * the options to pass to the underlying {@code oc} command - * @throws OpenShiftException if unable to forward ports - */ - void forwardPorts(Collection pairs, OpenShiftBinaryOption...options); - - /** - * The port pairs. - * @return The pairs when forwarding or an empty array; - */ - Collection getPortPairs(); - - /** - * Stop forwarding ports, forcibly if necessary - */ - void stop(); - - /** - * - * @return true if forwarding; false otherwise - */ - boolean isForwarding(); - - /** - * Pairing a local port to the remote port of a container. - * - * @author Jeff Cantrill - */ - static class PortPair { - private int localPort = -1; - private IPort remotePort; - - /** - * Forward traffic to/from the specified port - * @param remotePort - */ - public PortPair(IPort remotePort) { - this(remotePort.getContainerPort(), remotePort); - } - - /** - * Forward traffic on the local port to the remote port. Set localPort - * to '0' to listen on a random local port - * @param localPort - * @param remotePort - */ - public PortPair(int localPort, IPort remotePort) { - this.localPort = localPort; - this.remotePort = remotePort; - } - - public int getLocalPort() { - return localPort; - } - - public void setLocalPort(int port) { - this.localPort = port; - } - - public int getRemotePort() { - return remotePort.getContainerPort(); - } - - public String getName() { - return remotePort.getName(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + localPort; - result = prime * result + ((remotePort == null) ? 0 : remotePort.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - PortPair other = (PortPair) obj; - if (localPort != other.localPort) - return false; - if (remotePort == null) { - if (other.remotePort != null) - return false; - } else if (!remotePort.equals(other.remotePort)) - return false; - return true; - } - - @Override - public String toString() { - return getName() + ": " + this.localPort + "->" + this.getRemotePort(); - } - - } + /** + * Forward the ports to a pod. This is a non-blocking call + * + * @param pairs + * the pairs of local/remote ports to link together + * @param options + * the options to pass to the underlying {@code oc} command + * @throws OpenShiftException + * if unable to forward ports + */ + void forwardPorts(Collection pairs, OpenShiftBinaryOption... options); + + /** + * The port pairs. + * + * @return The pairs when forwarding or an empty array; + */ + Collection getPortPairs(); + + /** + * Stop forwarding ports, forcibly if necessary + */ + void stop(); + + /** + * + * @return true if forwarding; false otherwise + */ + boolean isForwarding(); + + /** + * Pairing a local port to the remote port of a container. + * + */ + static class PortPair { + private int localPort = -1; + private IPort remotePort; + + /** + * Forward traffic to/from the specified port + * + */ + public PortPair(IPort remotePort) { + this(remotePort.getContainerPort(), remotePort); + } + + /** + * Forward traffic on the local port to the remote port. Set localPort to '0' to + * listen on a random local port + * + */ + public PortPair(int localPort, IPort remotePort) { + this.localPort = localPort; + this.remotePort = remotePort; + } + + public int getLocalPort() { + return localPort; + } + + public void setLocalPort(int port) { + this.localPort = port; + } + + public int getRemotePort() { + return remotePort.getContainerPort(); + } + + public String getName() { + return remotePort.getName(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + localPort; + result = prime * result + ((remotePort == null) ? 0 : remotePort.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PortPair other = (PortPair) obj; + if (localPort != other.localPort) { + return false; + } + if (remotePort == null) { + if (other.remotePort != null) { + return false; + } + } else if (!remotePort.equals(other.remotePort)) { + return false; + } + return true; + } + + @Override + public String toString() { + return getName() + ": " + this.localPort + "->" + this.getRemotePort(); + } + + } } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateList.java b/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateList.java index 29e1747b..491fc9de 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateList.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateList.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import java.util.Collection; @@ -14,26 +15,26 @@ import com.openshift.restclient.model.template.ITemplate; /** - * Get the list of templates available for this project. This list includes - * the templates from the default namespace "openshift" + * Get the list of templates available for this project. This list includes the + * templates from the default namespace "openshift" */ public interface IProjectTemplateList extends ICapability { - /** - * Retrieve the templates associated with a specific project - * @return - */ - Collection getTemplates(); - - /** - * Retrieve the common templates from the server (e.g. 'openshift' namespace) - * @return - */ - Collection getCommonTemplates(); + /** + * Retrieve the templates associated with a specific project + * + */ + Collection getTemplates(); + + /** + * Retrieve the common templates from the server (e.g. 'openshift' namespace) + * + */ + Collection getCommonTemplates(); - /** + /** * Retrieve the common templates from the server (e.g. 'openshift' namespace) - * @return + * */ default Collection getCommonTemplates(String clusterNamespace) { throw new UnsupportedOperationException(); diff --git a/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateProcessing.java b/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateProcessing.java index 20a0f9b9..20b7128c 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateProcessing.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IProjectTemplateProcessing.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import java.util.Collection; @@ -16,20 +17,19 @@ public interface IProjectTemplateProcessing extends ICapability { - /** - * Processes a template to substitute the parameters - * where necessary for project - * - * @param template The template to process - * @return a config of resources - */ - ITemplate process(ITemplate template); - - /** - * Apply the objects defined in the template to the server - * @param config - * @return - */ - Collection apply(ITemplate template); - + /** + * Processes a template to substitute the parameters where necessary for project + * + * @param template + * The template to process + * @return a config of resources + */ + ITemplate process(ITemplate template); + + /** + * Apply the objects defined in the template to the server + * + */ + Collection apply(ITemplate template); + } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IPropertyAccessCapability.java b/src/main/java/com/openshift/restclient/capability/resources/IPropertyAccessCapability.java index 7acada7c..82dbd2d6 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IPropertyAccessCapability.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IPropertyAccessCapability.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import java.util.Map; @@ -15,51 +16,46 @@ import com.openshift.restclient.capability.ICapability; /** - * A mechanism to access the underlying content of a json - * structure + * A mechanism to access the underlying content of a json structure * - * Relies on a dot delimited path to indentify the root of the entity - * being returned (e.g. 'metadata.labels'). This does not provide - * a mechanism to retrieve properties across an array kind. + * Relies on a dot delimited path to indentify the root of the entity being + * returned (e.g. 'metadata.labels'). This does not provide a mechanism to + * retrieve properties across an array kind. * - * @author jeff.cantrill * */ public interface IPropertyAccessCapability extends ICapability { - /** - * - * @param path - * @return - * - * @throws @{@link UnresolvablePathException} when the path - * does not resolve to an existing node - */ - Map asMap(String path); - - /** - * Return the string value to the path - * @param path - * @return - * @throws @{@link UnresolvablePathException} when the path - * does not resolve to an existing node - */ - String asString(String path); - - /** - * The exception thrown when a path given to the capability is - * unresolvable - * - * @author jeff.cantrill - * - */ - public static class UnresolvablePathException extends RuntimeException{ + /** + * + * + * @throws @{@link + * UnresolvablePathException} when the path does not resolve to an + * existing node + */ + Map asMap(String path); + + /** + * Return the string value to the path + * + * @throws @{@link + * UnresolvablePathException} when the path does not resolve to an + * existing node + */ + String asString(String path); + + /** + * The exception thrown when a path given to the capability is unresolvable + * + * @author jeff.cantrill + * + */ + public static class UnresolvablePathException extends RuntimeException { - /** - * - */ - private static final long serialVersionUID = 2422016683166925224L; + /** + * + */ + private static final long serialVersionUID = 2422016683166925224L; - - } + } } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java b/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java index 6c2ba9ae..56620313 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import java.io.InputStream; @@ -18,192 +19,190 @@ import com.openshift.restclient.model.IPod; public interface IRSyncable extends IBinaryCapability { - - /** option to skip verifying the certificates during TLS connection establishment. */ - static final OpenShiftBinaryOption EXCLUDE_GIT_FOLDER = new GitFolderExclude(); - - /** option to exclude files/folders that match the given expressions **/ - static OpenShiftBinaryOption exclude(String... expressions) { - return new Exclude(expressions); - } - - /** option to not transfer file permissions. */ - static final OpenShiftBinaryOption NO_PERMS = new NoPerms(); - - /** option to delete delete extraneous files from destination directories**/ - static final OpenShiftBinaryOption DELETE = new Delete(); - - /** - * Excludes some files/directories that match the given patterns when rsync'ing - * the remote pod and the local deployment directory. - * - * @see {@link https://github.com/openshift/origin/issues/8223} - */ - static class Exclude implements OpenShiftBinaryOption { - - private String[] expressions; - - public Exclude(String... expressions) { - this.expressions = expressions; - } - - @Override - public void append(StringBuilder arguments) { - if (ArrayUtils.isEmpty(expressions)) { - return; - } - for (String expression : expressions) { - arguments.append(" --exclude=").append(expression); - } - } - } - - /** - * Does not sync .git folders when rsync'ing - */ - static class GitFolderExclude extends Exclude { - - public GitFolderExclude() { - super(".git"); - } - } - - /** - * Avoids transferring file permissions when rsync'ing - */ - static class NoPerms implements OpenShiftBinaryOption { - - @Override - public void append(StringBuilder arguments) { - arguments.append(" --no-perms=true"); - } - } - - /** - * Deletes extraneous files from destination directories when rsync'ing. - */ - static class Delete implements OpenShiftBinaryOption { - - @Override - public void append(StringBuilder arguments) { - arguments.append(" --delete"); - } - } - - static class PodPeer extends Peer { - - private static final char POD_PATH_SEPARATOR = ':'; - - private IPod pod; - - public PodPeer(String location, IPod pod) { - super(location); - this.pod = pod; - } - - @Override - public boolean isPod() { - return true; - } - - public IPod getPod() { - return pod; - } - - @Override - protected String getParameter() { - return new StringBuilder() - .append('"') - .append(pod.getName()) - .append(POD_PATH_SEPARATOR) - .append(getLocation()) - .append('"') - .toString(); - } - } - - static class LocalPeer extends Peer { - - public LocalPeer(String location) { - super(location); - } - - @Override - public boolean isPod() { - return false; - } - - @Override - public IPod getPod() { - return null; - } - - protected String getParameter() { - return new StringBuilder() - .append('"') - .append(getLocation()) - .append('"') - .toString(); - } - } - - abstract static class Peer implements OpenShiftBinaryOption { - - private String location; - - private Peer(String path) { - this.location = path; - } - - protected String getLocation() { - return location; - } - - protected abstract String getParameter(); - - public abstract boolean isPod(); - - public abstract IPod getPod(); - - @Override - public void append(StringBuilder commandLine) { - commandLine.append(" ").append(getParameter()); - } - } - - /** - * Synchronizes the give {@code destination} with the given {@code source} - * @param source the source of the rsync - * @param destination the destination of the rsync - * @param options the options to pass to the underlying {@code oc rsync} command - * @return the underlying {@link Process} streams to be displayed in a console. - */ - InputStream sync(Peer source, Peer destination, OpenShiftBinaryOption... options); - - /** - * Stops rsync'ing, forcibly if necessary. - */ - void stop(); - - /** - * Indicates if the {@link Process} completed or not - * - * @return true if the {@link Process} completed, - * false otherwise. - */ - boolean isDone(); - - /** - * @return the {@link Process} exit value when it completed, {@code -1} if - * it's still running - */ - int exitValue(); - - /** - * Blocks until the process is done. - * - * @throws InterruptedException - * if the current thread is interrupted while waiting - */ - void await() throws InterruptedException; + + /** + * option to skip verifying the certificates during TLS connection + * establishment. + */ + static final OpenShiftBinaryOption EXCLUDE_GIT_FOLDER = new GitFolderExclude(); + + /** option to exclude files/folders that match the given expressions **/ + static OpenShiftBinaryOption exclude(String... expressions) { + return new Exclude(expressions); + } + + /** option to not transfer file permissions. */ + static final OpenShiftBinaryOption NO_PERMS = new NoPerms(); + + /** option to delete delete extraneous files from destination directories **/ + static final OpenShiftBinaryOption DELETE = new Delete(); + + /** + * Excludes some files/directories that match the given patterns when rsync'ing + * the remote pod and the local deployment directory. + * + * @see {@link https://github.com/openshift/origin/issues/8223} + */ + static class Exclude implements OpenShiftBinaryOption { + + private String[] expressions; + + public Exclude(String... expressions) { + this.expressions = expressions; + } + + @Override + public void append(StringBuilder arguments) { + if (ArrayUtils.isEmpty(expressions)) { + return; + } + for (String expression : expressions) { + arguments.append(" --exclude=").append(expression); + } + } + } + + /** + * Does not sync .git folders when rsync'ing + */ + static class GitFolderExclude extends Exclude { + + public GitFolderExclude() { + super(".git"); + } + } + + /** + * Avoids transferring file permissions when rsync'ing + */ + static class NoPerms implements OpenShiftBinaryOption { + + @Override + public void append(StringBuilder arguments) { + arguments.append(" --no-perms=true"); + } + } + + /** + * Deletes extraneous files from destination directories when rsync'ing. + */ + static class Delete implements OpenShiftBinaryOption { + + @Override + public void append(StringBuilder arguments) { + arguments.append(" --delete"); + } + } + + static class PodPeer extends Peer { + + private static final char POD_PATH_SEPARATOR = ':'; + + private IPod pod; + + public PodPeer(String location, IPod pod) { + super(location); + this.pod = pod; + } + + @Override + public boolean isPod() { + return true; + } + + public IPod getPod() { + return pod; + } + + @Override + protected String getParameter() { + return new StringBuilder().append('"').append(pod.getName()).append(POD_PATH_SEPARATOR) + .append(getLocation()).append('"').toString(); + } + } + + static class LocalPeer extends Peer { + + public LocalPeer(String location) { + super(location); + } + + @Override + public boolean isPod() { + return false; + } + + @Override + public IPod getPod() { + return null; + } + + protected String getParameter() { + return new StringBuilder().append('"').append(getLocation()).append('"').toString(); + } + } + + abstract static class Peer implements OpenShiftBinaryOption { + + private String location; + + private Peer(String path) { + this.location = path; + } + + protected String getLocation() { + return location; + } + + protected abstract String getParameter(); + + public abstract boolean isPod(); + + public abstract IPod getPod(); + + @Override + public void append(StringBuilder commandLine) { + commandLine.append(" ").append(getParameter()); + } + } + + /** + * Synchronizes the give {@code destination} with the given {@code source} + * + * @param source + * the source of the rsync + * @param destination + * the destination of the rsync + * @param options + * the options to pass to the underlying {@code oc rsync} command + * @return the underlying {@link Process} streams to be displayed in a console. + */ + InputStream sync(Peer source, Peer destination, OpenShiftBinaryOption... options); + + /** + * Stops rsync'ing, forcibly if necessary. + */ + void stop(); + + /** + * Indicates if the {@link Process} completed or not + * + * @return true if the {@link Process} completed, + * false otherwise. + */ + boolean isDone(); + + /** + * @return the {@link Process} exit value when it completed, {@code -1} if it's + * still running + */ + int exitValue(); + + /** + * Blocks until the process is done. + * + * @throws InterruptedException + * if the current thread is interrupted while waiting + */ + void await() throws InterruptedException; } diff --git a/src/main/java/com/openshift/restclient/capability/resources/ITags.java b/src/main/java/com/openshift/restclient/capability/resources/ITags.java index 83653e80..514e2d29 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/ITags.java +++ b/src/main/java/com/openshift/restclient/capability/resources/ITags.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability.resources; import java.util.Collection; @@ -13,15 +14,13 @@ import com.openshift.restclient.capability.ICapability; /** - * Determine if resource is tagged with categories - * of technologies it includes + * Determine if resource is tagged with categories of technologies it includes * - * @author Jeff Cantrill */ public interface ITags extends ICapability { - - /** - * The list of tags - */ - Collection getTags(); + + /** + * The list of tags + */ + Collection getTags(); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/ITemplateTraceability.java b/src/main/java/com/openshift/restclient/capability/resources/ITemplateTraceability.java index 23b225cc..0ad5c37a 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/ITemplateTraceability.java +++ b/src/main/java/com/openshift/restclient/capability/resources/ITemplateTraceability.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; @@ -13,15 +14,13 @@ /** * Trace the source template that defined the resource * - * @author Jeff Cantrill */ public interface ITemplateTraceability extends ICapability { - /** - * Get the name of the template if any associated - * with this resource - * @return - */ - String getTemplateName(); + /** + * Get the name of the template if any associated with this resource + * + */ + String getTemplateName(); } \ No newline at end of file diff --git a/src/main/java/com/openshift/restclient/capability/resources/IUpdatable.java b/src/main/java/com/openshift/restclient/capability/resources/IUpdatable.java index 0a8104da..182b80e6 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IUpdatable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IUpdatable.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.capability.ICapability; @@ -15,10 +16,9 @@ /** * Allow a resource to be updated from another - * @author jeff.cantrill - * + * */ public interface IUpdatable extends ICapability { - void updateFrom(IResource source); + void updateFrom(IResource source); } diff --git a/src/main/java/com/openshift/restclient/capability/resources/LocationNotFoundException.java b/src/main/java/com/openshift/restclient/capability/resources/LocationNotFoundException.java index d7df3cb9..71c952b2 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/LocationNotFoundException.java +++ b/src/main/java/com/openshift/restclient/capability/resources/LocationNotFoundException.java @@ -8,20 +8,16 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.capability.resources; import com.openshift.restclient.OpenShiftException; -/** - * @author Jeff Cantrill - * - */ @SuppressWarnings("serial") public class LocationNotFoundException extends OpenShiftException { - public LocationNotFoundException(String message) { - super(message, (Object [])null); - } + public LocationNotFoundException(String message) { + super(message, (Object[]) null); + } - } diff --git a/src/main/java/com/openshift/restclient/capability/server/IImageRegistryHosting.java b/src/main/java/com/openshift/restclient/capability/server/IImageRegistryHosting.java index 7db95315..43906942 100644 --- a/src/main/java/com/openshift/restclient/capability/server/IImageRegistryHosting.java +++ b/src/main/java/com/openshift/restclient/capability/server/IImageRegistryHosting.java @@ -6,21 +6,21 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability.server; import com.openshift.restclient.capability.ICapability; /** - * Identifies an OpenShift server as capable of - * hosting images via its own registry - * - * @author Jeff Cantrill + * Identifies an OpenShift server as capable of hosting images via its own + * registry */ -public interface IImageRegistryHosting extends ICapability{ - - /** - * Gets the Image Registry URI - * @return the registry URI (e.g. 172.121.17.212:5001) - */ - String getRegistryUri(); +public interface IImageRegistryHosting extends ICapability { + + /** + * Gets the Image Registry URI + * + * @return the registry URI (e.g. 172.121.17.212:5001) + */ + String getRegistryUri(); } diff --git a/src/main/java/com/openshift/restclient/capability/server/ITemplateProcessing.java b/src/main/java/com/openshift/restclient/capability/server/ITemplateProcessing.java index a7f00417..3be422b9 100644 --- a/src/main/java/com/openshift/restclient/capability/server/ITemplateProcessing.java +++ b/src/main/java/com/openshift/restclient/capability/server/ITemplateProcessing.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.capability.server; import com.openshift.restclient.capability.ICapability; @@ -14,17 +15,17 @@ /** * Add capability to process a template * - * @author Jeff Cantrill */ public interface ITemplateProcessing extends ICapability { - - /** - * Processes the template to substitute the parameters - * where necessary - * - * @param template The template to process - * @param namespace The namespace to use when processing the template - * @return ITemplate - */ - ITemplate process(ITemplate template, String namespace); + + /** + * Processes the template to substitute the parameters where necessary + * + * @param template + * The template to process + * @param namespace + * The namespace to use when processing the template + * @return ITemplate + */ + ITemplate process(ITemplate template, String namespace); } diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index edc7cb94..3b714971 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.http; /** @@ -17,51 +18,51 @@ */ public interface IHttpConstants { - public static final int STATUS_UPGRADE_PROTOCOL = 101; - public static final int STATUS_OK = 200; - public static final int STATUS_MOVED_PERMANENTLY = 301; - public static final int STATUS_MOVED_TEMPORARILY = 302; - public static final int STATUS_INTERNAL_SERVER_ERROR = 500; - public static final int STATUS_BAD_REQUEST = 400; - public static final int STATUS_UNAUTHORIZED = 401; - public static final int STATUS_FORBIDDEN = 403; - public static final int STATUS_NOT_FOUND = 404; - - public static final int STATUS_NORMAL_STOP = 1000; + public static final int STATUS_UPGRADE_PROTOCOL = 101; + public static final int STATUS_OK = 200; + public static final int STATUS_MOVED_PERMANENTLY = 301; + public static final int STATUS_MOVED_TEMPORARILY = 302; + public static final int STATUS_INTERNAL_SERVER_ERROR = 500; + public static final int STATUS_BAD_REQUEST = 400; + public static final int STATUS_UNAUTHORIZED = 401; + public static final int STATUS_FORBIDDEN = 403; + public static final int STATUS_NOT_FOUND = 404; + + public static final int STATUS_NORMAL_STOP = 1000; + + public static final String PROPERTY_CONTENT_TYPE = "Content-Type"; + public static final String PROPERTY_AUTHORIZATION = "Authorization"; + public static final String PROPERTY_ACCEPT = "Accept"; + public static final String PROPERTY_ORIGIN = "Origin"; + public static final String PROPERTY_LOCATION = "Location"; + public static final String PROPERTY_USER_AGENT = "User-Agent"; + public static final String PROPERTY_WWW_AUTHENTICATE = "Www-Authenticate"; + + public static final String PROPERTY_AUTHKEY = "broker_auth_key"; + public static final String PROPERTY_AUTHIV = "broker_auth_iv"; + + public static final String MEDIATYPE_ANY = "*/*"; + public static final String MEDIATYPE_APPLICATION_JSON = "application/json"; + public static final String MEDIATYPE_APPLICATION_XML = "application/xml"; + public static final String MEDIATYPE_APPLICATION_FORMURLENCODED = "application/x-www-form-urlencoded"; - public static final String PROPERTY_CONTENT_TYPE = "Content-Type"; - public static final String PROPERTY_AUTHORIZATION = "Authorization"; - public static final String PROPERTY_ACCEPT = "Accept"; - public static final String PROPERTY_ORIGIN = "Origin"; - public static final String PROPERTY_LOCATION = "Location"; - public static final String PROPERTY_USER_AGENT = "User-Agent"; - public static final String PROPERTY_WWW_AUTHENTICATE = "Www-Authenticate"; - - public static final String PROPERTY_AUTHKEY = "broker_auth_key"; - public static final String PROPERTY_AUTHIV = "broker_auth_iv"; + public static final String AUTHORIZATION_BASIC = "Basic"; + public static final String AUTHORIZATION_BEARER = "Bearer"; - public static final String MEDIATYPE_ANY = "*/*"; - public static final String MEDIATYPE_APPLICATION_JSON = "application/json"; - public static final String MEDIATYPE_APPLICATION_XML = "application/xml"; - public static final String MEDIATYPE_APPLICATION_FORMURLENCODED = "application/x-www-form-urlencoded"; + public static final String VERSION = "version"; - public static final String AUTHORIZATION_BASIC = "Basic"; - public static final String AUTHORIZATION_BEARER = "Bearer"; - - public static final String VERSION = "version"; + public static final char SPACE = ' '; + public static final char COLON = ':'; + public static final char COMMA = ','; + public static final char SEMICOLON = ';'; + public static final char AMPERSAND = '&'; + public static final char EQUALS = '='; + public static final char SLASH = '/'; + public static final char QUESTION_MARK = '?'; - public static final char SPACE = ' '; - public static final char COLON = ':'; - public static final char COMMA = ','; - public static final char SEMICOLON = ';'; - public static final char AMPERSAND = '&'; - public static final char EQUALS = '='; - public static final char SLASH = '/'; - public static final char QUESTION_MARK = '?'; - public static final int DEFAULT_READ_TIMEOUT = 2 * 60 * 1000; - public static final int NO_TIMEOUT = -1; + public static final int NO_TIMEOUT = -1; - static final String PUT = "PUT"; - static final String POST = "POST"; + static final String PUT = "PUT"; + static final String POST = "POST"; } diff --git a/src/main/java/com/openshift/restclient/images/DockerImageDescriptor.java b/src/main/java/com/openshift/restclient/images/DockerImageDescriptor.java index 5328f55c..4cf3d328 100644 --- a/src/main/java/com/openshift/restclient/images/DockerImageDescriptor.java +++ b/src/main/java/com/openshift/restclient/images/DockerImageDescriptor.java @@ -6,27 +6,25 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.images; -/** - * @author Jeff Cantrill - */ -public class DockerImageDescriptor{ - - private final String description; - private final DockerImageURI name; +public class DockerImageDescriptor { + + private final String description; + private final DockerImageURI name; + + public DockerImageDescriptor(DockerImageURI name, String description) { + this.name = name; + this.description = description; + } + + public String getDescription() { + return description; + } - public DockerImageDescriptor(DockerImageURI name, String description){ - this.name = name; - this.description = description; - } + public DockerImageURI getImageUri() { + return name; + } - public String getDescription() { - return description; - } - - public DockerImageURI getImageUri() { - return name; - } - } \ No newline at end of file diff --git a/src/main/java/com/openshift/restclient/images/DockerImageURI.java b/src/main/java/com/openshift/restclient/images/DockerImageURI.java index 0c46b3d0..fd0c7a00 100644 --- a/src/main/java/com/openshift/restclient/images/DockerImageURI.java +++ b/src/main/java/com/openshift/restclient/images/DockerImageURI.java @@ -6,186 +6,199 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.images; /** - * ImageUri is an immutable representation of a full image tag in accordance with - * with Docker conventions [REGISTRYHOST/][USERNAME/]NAME[:TAG] - * - * @author Jeff Cantrill + * ImageUri is an immutable representation of a full image tag in accordance + * with with Docker conventions [REGISTRYHOST/][USERNAME/]NAME[:TAG] */ public class DockerImageURI { - - public static final String LATEST = "latest"; - private String registryHost; - private String userName; - private String name; - private String tag; - - public DockerImageURI(String registryHost, String userName, String name){ - this(registryHost, userName, name, LATEST); - } - public DockerImageURI(String registryHost, String userName, String name, String imageTag){ - this.registryHost = registryHost; - this.userName = userName; - this.name = name; - this.tag = imageTag; - } - - public DockerImageURI(String tag){ - if(tag != null) { - String[] segments = tag.split("/"); - switch (segments.length) { - case 3: - registryHost = segments[0]; - userName = segments[1]; - setNameAndTag(segments[2]); - break; - case 2: - userName = segments[0]; - setNameAndTag(segments[1]); - break; - default: - setNameAndTag(segments[0]); - break; - } - } - } - - private void setNameAndTag(String nameAndTag){ - String [] nameTag = nameAndTag.split(":"); - if(nameTag.length == 2){ - name = nameTag[0]; - tag = nameTag[1]; - } - else{ - name =nameTag[0]; - tag = LATEST; - } - } - - @Override - public String toString() { - return getAbsoluteUri(); - } - - public String getName() { - return this.name; - } - - public String getTag() { - return this.tag; - } - - public String getUserName() { - return this.userName; - } - - public String getRepositoryHost() { - return this.registryHost; - } - - /** - * Get the docker tag as repo:9999/username/name:tag - * @return - */ - public String getAbsoluteUri() { - return buildUri(registryHost, userName, name, tag); - } - - /** - * Get the docker tag as username/name:tag only - * @return - */ - public String getBaseUri() { - return buildUri(null, userName, name, tag); - } - - /** - * Get the docker tag as username/name only - * @return - */ - public String getUriUserNameAndName() { - return buildUri(null, userName, name, null); - } - - /** - * Get the docker tag as repo:9999/username/name only - * @return - */ - public String getUriWithoutTag() { - return buildUri(registryHost, userName, name, null); - } - - /** - * Get the docker tag as username/name:tag only - * @return - */ - public String getUriWithoutHost() { - return buildUri(null, userName, name, tag); - } - - /** - * Get the docker tag as name:tag only - * @return - */ - public String getNameAndTag() { - return buildUri(null, null, name, tag); - } - - private String buildUri(String host, String user, String name, String tag){ - StringBuilder b = new StringBuilder(); - if(host != null) b.append(host).append("/"); - if(user != null) b.append(user).append("/"); - b.append(name); - if(tag != null)b.append(":").append(tag); - return b.toString(); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result - + ((registryHost == null) ? 0 : registryHost.hashCode()); - result = prime * result + ((tag == null) ? 0 : tag.hashCode()); - result = prime * result - + ((userName == null) ? 0 : userName.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DockerImageURI other = (DockerImageURI) obj; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (registryHost == null) { - if (other.registryHost != null) - return false; - } else if (!registryHost.equals(other.registryHost)) - return false; - if (tag == null) { - if (other.tag != null) - return false; - } else if (!tag.equals(other.tag)) - return false; - if (userName == null) { - if (other.userName != null) - return false; - } else if (!userName.equals(other.userName)) - return false; - return true; - } - - + + public static final String LATEST = "latest"; + private String registryHost; + private String userName; + private String name; + private String tag; + + public DockerImageURI(String registryHost, String userName, String name) { + this(registryHost, userName, name, LATEST); + } + + public DockerImageURI(String registryHost, String userName, String name, String imageTag) { + this.registryHost = registryHost; + this.userName = userName; + this.name = name; + this.tag = imageTag; + } + + public DockerImageURI(String tag) { + if (tag != null) { + String[] segments = tag.split("/"); + switch (segments.length) { + case 3: + registryHost = segments[0]; + userName = segments[1]; + setNameAndTag(segments[2]); + break; + case 2: + userName = segments[0]; + setNameAndTag(segments[1]); + break; + default: + setNameAndTag(segments[0]); + break; + } + } + } + + private void setNameAndTag(String nameAndTag) { + String[] nameTag = nameAndTag.split(":"); + if (nameTag.length == 2) { + name = nameTag[0]; + tag = nameTag[1]; + } else { + name = nameTag[0]; + tag = LATEST; + } + } + + @Override + public String toString() { + return getAbsoluteUri(); + } + + public String getName() { + return this.name; + } + + public String getTag() { + return this.tag; + } + + public String getUserName() { + return this.userName; + } + + public String getRepositoryHost() { + return this.registryHost; + } + + /** + * Get the docker tag as repo:9999/username/name:tag + * + */ + public String getAbsoluteUri() { + return buildUri(registryHost, userName, name, tag); + } + + /** + * Get the docker tag as username/name:tag only + * + */ + public String getBaseUri() { + return buildUri(null, userName, name, tag); + } + + /** + * Get the docker tag as username/name only + * + */ + public String getUriUserNameAndName() { + return buildUri(null, userName, name, null); + } + + /** + * Get the docker tag as repo:9999/username/name only + * + */ + public String getUriWithoutTag() { + return buildUri(registryHost, userName, name, null); + } + + /** + * Get the docker tag as username/name:tag only + * + */ + public String getUriWithoutHost() { + return buildUri(null, userName, name, tag); + } + + /** + * Get the docker tag as name:tag only + * + */ + public String getNameAndTag() { + return buildUri(null, null, name, tag); + } + + private String buildUri(String host, String user, String name, String tag) { + StringBuilder b = new StringBuilder(); + if (host != null) { + b.append(host).append("/"); + } + if (user != null) { + b.append(user).append("/"); + } + b.append(name); + if (tag != null) { + b.append(":").append(tag); + } + return b.toString(); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((registryHost == null) ? 0 : registryHost.hashCode()); + result = prime * result + ((tag == null) ? 0 : tag.hashCode()); + result = prime * result + ((userName == null) ? 0 : userName.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + DockerImageURI other = (DockerImageURI) obj; + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + if (registryHost == null) { + if (other.registryHost != null) { + return false; + } + } else if (!registryHost.equals(other.registryHost)) { + return false; + } + if (tag == null) { + if (other.tag != null) { + return false; + } + } else if (!tag.equals(other.tag)) { + return false; + } + if (userName == null) { + if (other.userName != null) { + return false; + } + } else if (!userName.equals(other.userName)) { + return false; + } + return true; + } + } diff --git a/src/main/java/com/openshift/restclient/model/Annotatable.java b/src/main/java/com/openshift/restclient/model/Annotatable.java index c664cd6b..2b3a996c 100644 --- a/src/main/java/com/openshift/restclient/model/Annotatable.java +++ b/src/main/java/com/openshift/restclient/model/Annotatable.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import com.openshift.restclient.api.models.IAnnotatable; diff --git a/src/main/java/com/openshift/restclient/model/IBuild.java b/src/main/java/com/openshift/restclient/model/IBuild.java index b5029e16..0c1dd4ba 100644 --- a/src/main/java/com/openshift/restclient/model/IBuild.java +++ b/src/main/java/com/openshift/restclient/model/IBuild.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import com.openshift.restclient.images.DockerImageURI; @@ -13,46 +14,43 @@ import com.openshift.restclient.model.build.IBuildStatus; import com.openshift.restclient.model.build.IBuildStrategy; -/** - * @author Jeff Cantrill - */ public interface IBuild extends IResource { - /** - * Returns the status of the buld - * @return - */ - String getStatus(); - - /** - * Returns the details about the status of this build - * @return - */ - String getMessage(); - - /** - * Returns the name of the pod running the build - * @return - */ - @Deprecated - String getPodName(); - - /** - * Cancels a build if its status is not "Complete", - * "Failed", or "Cancelled" - * @return if the build state was in fact changed - */ - boolean cancel(); - - DockerImageURI getOutputTo(); - - String getOutputKind(); - - T getBuildSource(); - - T getBuildStrategy(); - - String getPushSecret(); - - IBuildStatus getBuildStatus(); + /** + * Returns the status of the buld + * + */ + String getStatus(); + + /** + * Returns the details about the status of this build + * + */ + String getMessage(); + + /** + * Returns the name of the pod running the build + * + */ + @Deprecated + String getPodName(); + + /** + * Cancels a build if its status is not "Complete", "Failed", or "Cancelled" + * + * @return if the build state was in fact changed + */ + boolean cancel(); + + DockerImageURI getOutputTo(); + + String getOutputKind(); + + T getBuildSource(); + + T getBuildStrategy(); + + String getPushSecret(); + + IBuildStatus getBuildStatus(); } diff --git a/src/main/java/com/openshift/restclient/model/IBuildConfig.java b/src/main/java/com/openshift/restclient/model/IBuildConfig.java index 3336e10b..8cf6feca 100644 --- a/src/main/java/com/openshift/restclient/model/IBuildConfig.java +++ b/src/main/java/com/openshift/restclient/model/IBuildConfig.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.List; @@ -14,69 +15,66 @@ import com.openshift.restclient.model.build.IBuildStrategy; import com.openshift.restclient.model.build.IBuildTrigger; -/** - * @author Jeff Cantrill - */ -public interface IBuildConfig extends IResource{ - - /** - * To defines an optional location to push the output of this build to. - * Kind must be one of 'ImageStreamTag' or 'DockerImage'. - * @return a mutable object reference - */ - IObjectReference getBuildOutputReference(); - - /** - * Returns the source URL for a build - * @return - */ - String getSourceURI(); - - /** - * Returns the policies which will trigger a build - * @return - */ - List getBuildTriggers(); - - /** - * Add a trigger to the list of triggers for this build. - * - * @param trigger - */ - void addBuildTrigger(IBuildTrigger trigger); +public interface IBuildConfig extends IResource { + + /** + * To defines an optional location to push the output of this build to. Kind + * must be one of 'ImageStreamTag' or 'DockerImage'. + * + * @return a mutable object reference + */ + IObjectReference getBuildOutputReference(); + + /** + * Returns the source URL for a build + * + */ + String getSourceURI(); + + /** + * Returns the policies which will trigger a build + * + */ + List getBuildTriggers(); + + /** + * Add a trigger to the list of triggers for this build. + * + */ + void addBuildTrigger(IBuildTrigger trigger); + + /** + * Returns the source info of the build + * + * @return + */ + T getBuildSource(); - /** - * Returns the source info of the build - * @return - */ - T getBuildSource(); + /** + * Set the source for the build. + * + */ + void setBuildSource(IBuildSource source); - /** - * Set the source for the build. - * - * @param source - */ - void setBuildSource(IBuildSource source); + /** + * Returns the strategy to for building the source + * + * @return + */ + T getBuildStrategy(); - /** - * Returns the strategy to for building the source - * @return - */ - T getBuildStrategy(); + /** + * Set the strategy for how the build should be built.
+ * Depending on the strategies available on the server this could be 'source', + * 'docker' or 'custom'. + * + */ + void setBuildStrategy(IBuildStrategy strategy); - /** - * Set the strategy for how the build should be built.
- * Depending on the strategies available on the server this - * could be 'source', 'docker' or 'custom'. - * - * @param strategy - */ - void setBuildStrategy(IBuildStrategy strategy); - - /** - * Retrieves the name of the repository where the - * resulting build image will be pushed - * @return - */ - String getOutputRepositoryName(); + /** + * Retrieves the name of the repository where the resulting build image will be + * pushed + * + */ + String getOutputRepositoryName(); } diff --git a/src/main/java/com/openshift/restclient/model/IConfig.java b/src/main/java/com/openshift/restclient/model/IConfig.java index 3e1ca01d..42a8589e 100644 --- a/src/main/java/com/openshift/restclient/model/IConfig.java +++ b/src/main/java/com/openshift/restclient/model/IConfig.java @@ -6,12 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; /** * A Config which is a list of resources. * - * @author Jeff Cantrill * @deprecated ??? in later model versions in favor of List? */ @Deprecated diff --git a/src/main/java/com/openshift/restclient/model/IConfigMapKeySelector.java b/src/main/java/com/openshift/restclient/model/IConfigMapKeySelector.java index e1a86bc6..bd5d198a 100644 --- a/src/main/java/com/openshift/restclient/model/IConfigMapKeySelector.java +++ b/src/main/java/com/openshift/restclient/model/IConfigMapKeySelector.java @@ -8,14 +8,15 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import com.openshift.restclient.model.IEnvironmentVariable.IEnvVarSource; public interface IConfigMapKeySelector extends IEnvVarSource { - - String getName(); - - String getKey(); + + String getName(); + + String getKey(); } diff --git a/src/main/java/com/openshift/restclient/model/IContainer.java b/src/main/java/com/openshift/restclient/model/IContainer.java index 81790d31..89023ee3 100644 --- a/src/main/java/com/openshift/restclient/model/IContainer.java +++ b/src/main/java/com/openshift/restclient/model/IContainer.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import java.util.List; @@ -20,79 +21,91 @@ import com.openshift.restclient.model.volume.IVolume; import com.openshift.restclient.model.volume.IVolumeMount; -public interface IContainer extends INameSetable{ - - String getName(); - - void setImage(DockerImageURI tag); - DockerImageURI getImage(); - - /** - * replace the env vars - * @param vars - */ - void setEnvVars(Map vars); - /** - * - * @return an unmodifiable map of env vars - */ - Map getEnvVars(); - - void addEnvVar(String key, String value); - - /** - * replaces the set of ports - * @param ports - */ - void setPorts(Set ports); - - /** - * - * @return an unmodifiable set of the container ports - */ - Set getPorts(); - - void setImagePullPolicy(String policy); - String getImagePullPolicy(); - - void setLifecycle(ILifecycle lifecycle); - ILifecycle getLifecycle(); - +public interface IContainer extends INameSetable, JSONSerializeable { + + String getName(); + + void setImage(DockerImageURI tag); + + DockerImageURI getImage(); + + /** + * replace the env vars + * + */ + void setEnvVars(Map vars); + + /** + * + * @return an unmodifiable map of env vars + */ + Map getEnvVars(); + + void addEnvVar(String key, String value); + + /** + * replaces the set of ports + * + */ + void setPorts(Set ports); + + /** + * + * @return an unmodifiable set of the container ports + */ + Set getPorts(); + + void setImagePullPolicy(String policy); + + String getImagePullPolicy(); + + void setLifecycle(ILifecycle lifecycle); + + ILifecycle getLifecycle(); + void setCommand(List command); + List getCommand(); void setCommandArgs(List args); + List getCommandArgs(); - - @Deprecated - void setVolumes(Set volumes); - @Deprecated - Set getVolumes(); - - void setVolumeMounts(Set volumes); - Set getVolumeMounts(); - - /** - * Add a volumemount with the given name - * @param name - * @return IVolumeMount - */ - IVolumeMount addVolumeMount(String name); - - String getRequestsCPU(); - void setRequestsCPU(String requestsCPU); - - String getRequestsMemory(); - void setRequestsMemory(String requestsMemory); - - String getLimitsCPU(); - void setLimitsCPU(String limitsCPU); - - String getLimitsMemory(); - void setLimitsMemory(String limitsMemory); + + @Deprecated + void setVolumes(Set volumes); + + @Deprecated + Set getVolumes(); + + void setVolumeMounts(Set volumes); + + Set getVolumeMounts(); + + /** + * Add a volumemount with the given name + * + * @return IVolumeMount + */ + IVolumeMount addVolumeMount(String name); + + String getRequestsCPU(); + + void setRequestsCPU(String requestsCPU); + + String getRequestsMemory(); + + void setRequestsMemory(String requestsMemory); + + String getLimitsCPU(); + + void setLimitsCPU(String limitsCPU); + + String getLimitsMemory(); + + void setLimitsMemory(String limitsMemory); IProbe getReadinessProbe(); + IProbe getLivenessProbe(); - - String toJSONString(); + } diff --git a/src/main/java/com/openshift/restclient/model/IDeploymentConfig.java b/src/main/java/com/openshift/restclient/model/IDeploymentConfig.java index 740fc973..1265f3be 100644 --- a/src/main/java/com/openshift/restclient/model/IDeploymentConfig.java +++ b/src/main/java/com/openshift/restclient/model/IDeploymentConfig.java @@ -6,86 +6,83 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.Collection; import com.openshift.restclient.model.deploy.IDeploymentTrigger; -/** - * @author Jeff Cantrill - */ public interface IDeploymentConfig extends IReplicationController { - - - /** - * Get the list of deployment triggers - * @return a collection of trigger types - */ - Collection getTriggerTypes(); - /** - * Returns the trigger of the given type - * or null if it doesn not exist - * @param type - * @return - */ - Collection getTriggers(); - - /** - * Convenience method to get the deployment - * strategy type - * @return the type as a string - */ - String getDeploymentStrategyType(); - - /** - * Add a trigger of the given type - * or null if the type is unrecognized - * - * @param type - * @return - */ - IDeploymentTrigger addTrigger(String type); - - /** - * Get the latest version number - * @return - */ - int getLatestVersionNumber(); - - /** - * Set the latest version number - * @param new version number - * - */ - void setLatestVersionNumber(int newVersionNumber); - - /** - * Return whether deployments have fired because of triggers - * @return - */ - boolean haveTriggersFired(); - - /** - * Return whether deployments have fired based on an image trigger - * for a particular image - * @param imageNameTag the image name:tag associated with an image trigger - * @return - */ - boolean didImageTrigger(String imageNameTag); - - /** - * Get the image hexadecimal ID for the image tag used with the - * latest image change trigger - * @param imageNameTag the image name:tag associated with an image trigger - * @return - */ - String getImageHexIDForImageNameAndTag(String imageNameTag); - - /** - * Get the image name:tag from a image change trigger firing - * @return - */ - String getImageNameAndTagForTriggeredDeployment(); + /** + * Get the list of deployment triggers + * + * @return a collection of trigger types + */ + Collection getTriggerTypes(); + + /** + * Returns the trigger of the given type or null if it doesn not exist + * + */ + Collection getTriggers(); + + /** + * Convenience method to get the deployment strategy type + * + * @return the type as a string + */ + String getDeploymentStrategyType(); + + /** + * Add a trigger of the given type or null if the type is unrecognized + * + */ + IDeploymentTrigger addTrigger(String type); + + /** + * Get the latest version number + * + */ + int getLatestVersionNumber(); + + /** + * Set the latest version number + * + * @param new + * version number + * + */ + void setLatestVersionNumber(int newVersionNumber); + + /** + * Return whether deployments have fired because of triggers + * + */ + boolean haveTriggersFired(); + + /** + * Return whether deployments have fired based on an image trigger for a + * particular image + * + * @param imageNameTag + * the image name:tag associated with an image trigger + */ + boolean didImageTrigger(String imageNameTag); + + /** + * Get the image hexadecimal ID for the image tag used with the latest image + * change trigger + * + * @param imageNameTag + * the image name:tag associated with an image trigger + */ + String getImageHexIDForImageNameAndTag(String imageNameTag); + + /** + * Get the image name:tag from a image change trigger firing + * + */ + String getImageNameAndTagForTriggeredDeployment(); } diff --git a/src/main/java/com/openshift/restclient/model/IEnvironmentVariable.java b/src/main/java/com/openshift/restclient/model/IEnvironmentVariable.java index 7cdbc01f..22fdc56d 100644 --- a/src/main/java/com/openshift/restclient/model/IEnvironmentVariable.java +++ b/src/main/java/com/openshift/restclient/model/IEnvironmentVariable.java @@ -8,49 +8,46 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; /** - * Environment variable representation to - * allow more complex values then - * name/value pairs. An environmentVariable - * will have either a value or valueFrom - * but not both. + * Environment variable representation to allow more complex values then + * name/value pairs. An environmentVariable will have either a value or + * valueFrom but not both. * - * @author jeff.cantrill * */ -public interface IEnvironmentVariable extends JSONSerializeable{ - - /** - * The name of the env var - * @return - */ - String getName(); - - /** - * The value of the environment variable or null if not - * defined. - * @return - */ - String getValue(); - - /** - * The ref value or null if not defined - * @return - */ - IEnvVarSource getValueFrom(); - - /** - * Marker interface for sources of environment variables - * @author jeff.cantrill - * - */ - static interface IEnvVarSource{ - - } - - @Override - String toJson(); - +public interface IEnvironmentVariable extends JSONSerializeable { + + /** + * The name of the env var + * + */ + String getName(); + + /** + * The value of the environment variable or null if not defined. + * + */ + String getValue(); + + /** + * The ref value or null if not defined + * + */ + IEnvVarSource getValueFrom(); + + /** + * Marker interface for sources of environment variables + * + * + */ + static interface IEnvVarSource { + + } + + @Override + String toJson(); + } diff --git a/src/main/java/com/openshift/restclient/model/IEvent.java b/src/main/java/com/openshift/restclient/model/IEvent.java index 8c53dfcb..b6dc805e 100644 --- a/src/main/java/com/openshift/restclient/model/IEvent.java +++ b/src/main/java/com/openshift/restclient/model/IEvent.java @@ -8,82 +8,79 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IEvent extends IResource { - - /** - * The reason for the event - * @return - */ - String getReason(); - - /** - * The additional message associated with the event - * @return - */ - String getMessage(); - - /** - * A reference to the Object that was involved in - * this event - * - * @return - */ - IObjectReference getInvolvedObject(); - - /** - * The first time this event was recorded - * @return - */ - String getFirstSeenTimestamp(); - - /** - * The last time this event was recorded - * @return - */ - String getLastSeenTimestamp(); - - /** - * The number of times this event has occured - * @return - */ - int getCount(); - - /** - * The type of this event (e.g. Normal, Warning) - * @return - */ - String getType(); - - /** - * Optional information of the component reporting this event - * @return - */ - IEventSource getEventSource(); - - /** - * Event source information - * @author jeff.cantrill - * - */ - static interface IEventSource{ - - /** - * The component from which this event was generated - * @return - */ - String getComponent(); - - /** - * The host name on which this event was generated - * @return - */ - String getHost(); - } + + /** + * The reason for the event + * + */ + String getReason(); + + /** + * The additional message associated with the event + * + */ + String getMessage(); + + /** + * A reference to the Object that was involved in this event + * + */ + IObjectReference getInvolvedObject(); + + /** + * The first time this event was recorded + * + */ + String getFirstSeenTimestamp(); + + /** + * The last time this event was recorded + * + */ + String getLastSeenTimestamp(); + + /** + * The number of times this event has occured + * + */ + int getCount(); + + /** + * The type of this event (e.g. Normal, Warning) + * + */ + String getType(); + + /** + * Optional information of the component reporting this event + * + */ + IEventSource getEventSource(); + + /** + * Event source information + * + * @author jeff.cantrill + * + */ + static interface IEventSource { + + /** + * The component from which this event was generated + * + */ + String getComponent(); + + /** + * The host name on which this event was generated + * + */ + String getHost(); + } } diff --git a/src/main/java/com/openshift/restclient/model/IExecAction.java b/src/main/java/com/openshift/restclient/model/IExecAction.java index c4b9ed13..ec462f00 100644 --- a/src/main/java/com/openshift/restclient/model/IExecAction.java +++ b/src/main/java/com/openshift/restclient/model/IExecAction.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; /** @@ -18,6 +19,7 @@ public interface IExecAction extends IHandler { interface IBuilder { IBuilder command(String command); + IExecAction build(); } } diff --git a/src/main/java/com/openshift/restclient/model/IHandler.java b/src/main/java/com/openshift/restclient/model/IHandler.java index d5bacb61..e3a546de 100644 --- a/src/main/java/com/openshift/restclient/model/IHandler.java +++ b/src/main/java/com/openshift/restclient/model/IHandler.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; /** diff --git a/src/main/java/com/openshift/restclient/model/IImageStream.java b/src/main/java/com/openshift/restclient/model/IImageStream.java index b8f18cc1..36af3340 100644 --- a/src/main/java/com/openshift/restclient/model/IImageStream.java +++ b/src/main/java/com/openshift/restclient/model/IImageStream.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.Collection; @@ -13,78 +14,67 @@ import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.image.ITagReference; -/** - * @author Jeff Cantrill - */ -public interface IImageStream extends IResource{ +public interface IImageStream extends IResource { + + /** + * Get the image repository uri abstracted by this image stream + * + */ + DockerImageURI getDockerImageRepository(); + + /** + * Set the image repository uri abstracted by this image stream + * + */ + void setDockerImageRepository(DockerImageURI imageUri); + + /** + * Set the image repository uri abstracted by this image stream + * + */ + void setDockerImageRepository(String imageUri); + + /** + * Sets a new tag in an image stream + * + * @param newTag + * the new tag to create + * @param fromTag + * existing tag the new tag is based from + */ + void setTag(String newTag, String fromTag); + + /** + * Add a tag to the list with the given name, and reference to the given kind + * and name. + * + */ + ITagReference addTag(String name, String fromKind, String fromName); + + /** + * Add a tag to the list with the given name, namespace, and reference to the + * given kind, namespace, and name. + * + */ + ITagReference addTag(String name, String fromKind, String fromName, String fromNamespace); - /** - * Get the image repository uri abstracted by this - * image stream - * @return - */ - DockerImageURI getDockerImageRepository(); - - /** - * Set the image repository uri abstracted by this - * image stream - * @return - */ - void setDockerImageRepository(DockerImageURI imageUri); - - /** - * Set the image repository uri abstracted by this - * image stream - * @return - */ - void setDockerImageRepository(String imageUri); + /** + * Gets the long imagae id for the provided tag + * + * @param tagName + * name of the image stream tag to interrogate + */ + String getImageId(String tagName); - /** - * Sets a new tag in an image stream - * - * @param newTag the new tag to create - * @param fromTag existing tag the new tag is based from - */ - void setTag(String newTag, String fromTag); - - /** - * Add a tag to the list with the given name, and reference - * to the given kind and name. - * @param name - * @param fromKind - * @param fromName - * @return - */ - ITagReference addTag(String name, String fromKind, String fromName); - - /** - * Add a tag to the list with the given name, namespace, and reference - * to the given kind, namespace, and name. - * @param name - * @param fromKind - * @param fromName - * @param fromNamespace - * @return - */ - ITagReference addTag(String name, String fromKind, String fromName, String fromNamespace); - - /** - * Gets the long imagae id for the provided tag - * @param tagName name of the image stream tag to interrogate - * @return - */ - String getImageId(String tagName); + /** + * The collection of tag references for this imagestream + * + */ + Collection getTags(); - /** - * The collection of tag references for this imagestream - * @return - */ - Collection getTags(); - - /** - * The collection of tag names as listed - * in status.tags - * @return - */ - Collection getTagNames(); + /** + * The collection of tag names as listed in status.tags + * + */ + Collection getTagNames(); } diff --git a/src/main/java/com/openshift/restclient/model/ILifecycle.java b/src/main/java/com/openshift/restclient/model/ILifecycle.java index fd65831e..34a0e7d1 100644 --- a/src/main/java/com/openshift/restclient/model/ILifecycle.java +++ b/src/main/java/com/openshift/restclient/model/ILifecycle.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import java.util.Optional; @@ -17,11 +18,14 @@ */ public interface ILifecycle extends JSONSerializeable { Optional getPostStart(); + Optional getPreStop(); interface IBuilder { IBuilder preStop(IHandler handler); + IBuilder postStart(IHandler handler); + ILifecycle build(); } } diff --git a/src/main/java/com/openshift/restclient/model/ILimitRange.java b/src/main/java/com/openshift/restclient/model/ILimitRange.java index cb899cb5..5fbac77d 100644 --- a/src/main/java/com/openshift/restclient/model/ILimitRange.java +++ b/src/main/java/com/openshift/restclient/model/ILimitRange.java @@ -8,13 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface ILimitRange extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/IList.java b/src/main/java/com/openshift/restclient/model/IList.java index 5f54f46e..a9f62794 100644 --- a/src/main/java/com/openshift/restclient/model/IList.java +++ b/src/main/java/com/openshift/restclient/model/IList.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.Collection; @@ -13,18 +14,17 @@ /** * A list of resources. * - * @author Jeff Cantrill */ -public interface IList extends IResource{ - /** - * Retrieve the list of resources for this config - * @return - */ - Collection getItems(); +public interface IList extends IResource { + /** + * Retrieve the list of resources for this config + * + */ + Collection getItems(); - /** - * Add all of the given resources to the list - * @param items - */ - void addAll(Collection items); + /** + * Add all of the given resources to the list + * + */ + void addAll(Collection items); } diff --git a/src/main/java/com/openshift/restclient/model/INamespace.java b/src/main/java/com/openshift/restclient/model/INamespace.java index abcb90a6..bb0e97a1 100644 --- a/src/main/java/com/openshift/restclient/model/INamespace.java +++ b/src/main/java/com/openshift/restclient/model/INamespace.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.List; @@ -17,7 +18,9 @@ public interface INamespace extends IResource { /** * Retrieves resource of the given kind that are scoped to this project - * @param kind the resource kind to retrieve + * + * @param kind + * the resource kind to retrieve * @return a list of {@link INamespace}s */ List getResources(String kind); diff --git a/src/main/java/com/openshift/restclient/model/IObjectFieldSelector.java b/src/main/java/com/openshift/restclient/model/IObjectFieldSelector.java index afb33039..fa931d0d 100644 --- a/src/main/java/com/openshift/restclient/model/IObjectFieldSelector.java +++ b/src/main/java/com/openshift/restclient/model/IObjectFieldSelector.java @@ -8,13 +8,14 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import com.openshift.restclient.model.IEnvironmentVariable.IEnvVarSource; public interface IObjectFieldSelector extends IEnvVarSource { - - String getApiVersion(); - - String getFieldPath(); + + String getApiVersion(); + + String getFieldPath(); } diff --git a/src/main/java/com/openshift/restclient/model/IObjectReference.java b/src/main/java/com/openshift/restclient/model/IObjectReference.java index a0399af7..4cea9c9d 100644 --- a/src/main/java/com/openshift/restclient/model/IObjectReference.java +++ b/src/main/java/com/openshift/restclient/model/IObjectReference.java @@ -8,67 +8,66 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; /** - * An OpenShift object reference to an - * OpenShift object - * @author Jeff Cantrill + * An OpenShift object reference to an OpenShift object * */ public interface IObjectReference { - /** - * Returns the resource kind - * @return - */ - String getKind(); - - /** - * The obj ref kind - * @param kind - */ - void setKind(String kind); + /** + * Returns the resource kind + * + */ + String getKind(); + + /** + * The obj ref kind + * + */ + void setKind(String kind); + + /** + * returns the api version of this resource + * + */ + String getApiVersion(); + + /** + * returns the resource version of this resource + * + */ + String getResourceVersion(); + + /** + * Returns the identifier for this resource + * + */ + String getName(); - /** - * returns the api version of this resource - * @return - */ - String getApiVersion(); - - /** - * returns the resource version of this resource - * @return - */ - String getResourceVersion(); + /** + * The name of the obj ref + * + */ + void setName(String name); - /** - * Returns the identifier for this resource - * @return - */ - String getName(); - - /** - * The name of the obj ref - * @param name - */ - void setName(String name); + /** + * Returns the scope of this resource + * + */ + String getNamespace(); - /** - * Returns the scope of this resource - * @return - */ - String getNamespace(); - - /** - * The namespace for the object ref - * @param namespace - */ - void setNamespace(String namespace); + /** + * The namespace for the object ref + * + */ + void setNamespace(String namespace); - String getFieldPath(); + String getFieldPath(); - String getUID(); + String getUID(); - String toJson(); + String toJson(); } diff --git a/src/main/java/com/openshift/restclient/model/IPod.java b/src/main/java/com/openshift/restclient/model/IPod.java index a4026090..10e1a8ea 100644 --- a/src/main/java/com/openshift/restclient/model/IPod.java +++ b/src/main/java/com/openshift/restclient/model/IPod.java @@ -6,62 +6,54 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.Collection; import java.util.Set; -/** - * @author Jeff Cantrill - */ public interface IPod extends IResource { - /** - * Gets the IP of the Pod - * @return - */ - String getIP(); - - /** - * Gets the name of the host on which - * the pod is running - * @return - */ - String getHost(); - - /** - * Gets the collection of image names - * for the pod containers - * @return - */ - Collection getImages(); - - /** - * Gets the status of the pod - * @return - */ - String getStatus(); - - /** - * Retrieve the set of ports that the - * containers are using - */ - Set getContainerPorts(); - - /** - * Add a container with the given name. This is - * useful if creating a pod directly without a - * resource controller - * - * @param name - * @return - */ - IContainer addContainer(String name); - - /** - * Retrieve all the containers spec'd - * for the pod - * @return collection of containers - */ - Collection getContainers(); + /** + * Gets the IP of the Pod + * + */ + String getIP(); + + /** + * Gets the name of the host on which the pod is running + * + */ + String getHost(); + + /** + * Gets the collection of image names for the pod containers + * + */ + Collection getImages(); + + /** + * Gets the status of the pod + * + */ + String getStatus(); + + /** + * Retrieve the set of ports that the containers are using + */ + Set getContainerPorts(); + + /** + * Add a container with the given name. This is useful if creating a pod + * directly without a resource controller + * + */ + IContainer addContainer(String name); + + /** + * Retrieve all the containers spec'd for the pod + * + * @return collection of containers + */ + Collection getContainers(); } diff --git a/src/main/java/com/openshift/restclient/model/IPort.java b/src/main/java/com/openshift/restclient/model/IPort.java index 37c43655..fd107f21 100644 --- a/src/main/java/com/openshift/restclient/model/IPort.java +++ b/src/main/java/com/openshift/restclient/model/IPort.java @@ -8,23 +8,23 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; /** * Port details. - * @author Jeff Cantrill * */ public interface IPort { - - /** - * The name of the port - * - * @return the name or null if undefined. - */ - String getName(); - - int getContainerPort(); - - String getProtocol(); + + /** + * The name of the port + * + * @return the name or null if undefined. + */ + String getName(); + + int getContainerPort(); + + String getProtocol(); } diff --git a/src/main/java/com/openshift/restclient/model/IProject.java b/src/main/java/com/openshift/restclient/model/IProject.java index 1f27f41a..bcf036ee 100644 --- a/src/main/java/com/openshift/restclient/model/IProject.java +++ b/src/main/java/com/openshift/restclient/model/IProject.java @@ -6,29 +6,27 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.List; -/** - * @author Jeff Cantrill - */ public interface IProject extends IResource { - /** - * Retrieves resource of the given kind that are scoped to - * this project - * @param kind - * @return List - */ - List getResources(String kind); - - String getDisplayName(); - - void setDisplayName(String name); - - String getDescription(); - - void setDescription(String value); - + /** + * Retrieves resource of the given kind that are scoped to this project + * + * @param kind + * @return List + */ + List getResources(String kind); + + String getDisplayName(); + + void setDisplayName(String name); + + String getDescription(); + + void setDescription(String value); + } diff --git a/src/main/java/com/openshift/restclient/model/IReplicationController.java b/src/main/java/com/openshift/restclient/model/IReplicationController.java index d41f027a..019ab852 100644 --- a/src/main/java/com/openshift/restclient/model/IReplicationController.java +++ b/src/main/java/com/openshift/restclient/model/IReplicationController.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.Collection; @@ -17,207 +18,208 @@ import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.model.volume.IVolumeSource; -/** - * @author Jeff Cantrill - */ -public interface IReplicationController extends IResource{ - - static final String DEPLOYMENT_PHASE = "openshift.io/deployment.phase"; - - /** - * Set an environment variable to the given name and - * value on the first container in the list of containers - * - * @param name - * @param value - */ - void setEnvironmentVariable(String name, String value); - - /** - * Set an environment variable to the given name and - * value on the given container. Returns silently - * if the containerName is not found - * - * @param containerName - * @param name - * @param value - */ - void setEnvironmentVariable(String containerName, String name, String value); - - /** - * Removes an environment variable with the given name. - * Returns silently if the name is not found - * - * @throws IllegalArgumentException if name is null - * - * @param name - */ - public void removeEnvironmentVariable(String name); - - /** - * Removes an environment variable with the given name and - * value on the given container. Returns silently - * if the containerName or the name is not found - * - * @throws IllegalArgumentException if name is null - * - * @param containerName - * @param name - */ - public void removeEnvironmentVariable(String containerName, String name); - - /** - * Return the list of env vars of the first container - * @return - */ - Collection getEnvironmentVariables(); - - /** - * Return the list of env vars for the given container or an empty list - * if the container is not found - * @param containerName - * @return - */ - Collection getEnvironmentVariables(String containerName); - - /** - * Returns the desired number of replicas - * @return - */ - int getDesiredReplicaCount(); - int getReplicas(); - - void setReplicas(int count); - - /** - * Sets a new desired number of replicas - * @param new number of replicas - */ - void setDesiredReplicaCount(int numOfReplicas); - - /** - * Returns the current number of replicas - * @return - */ - int getCurrentReplicaCount(); - - /** - * Returns the selector used by the controller - * @return - */ - Map getReplicaSelector(); - - /** - * Set the selector using the map of values - * @param selector - */ - void setReplicaSelector(Map selector); - void setReplicaSelector(String key, String value); - - /** - * Retrieves the list of images deployed in the - * pod containers from this controller - * @return - */ - Collection getImages(); - - /** - * Add a container to the pod that will be spun up as - * part of this deployment. - * - * @param name the name of the container - * @param tag the docker uri - * @param containerPorts the container ports - * @param volumes the set of emptyDir volumes to add to the config - */ - IContainer addContainer(String name, DockerImageURI tag, Set containerPorts, Map envVars, List volumes); - - /** - * Add a container to the pod that will be spun up as - * part of this deployment, defaulting the name to the image name - * - * @param tag the docker uri - * @param containerPorts the container ports - */ - IContainer addContainer(DockerImageURI tag, Set containerPorts, Map envVars); - - /** - * Add a container with the given name - * @param name - * @return - */ - IContainer addContainer(String name); - - /** - * Retrieve a container by name or null if it is not found - * @param name - * @return the container or null if not found - */ - IContainer getContainer(String name); - - /** - * Retrieve the containers defined in spec - * @param name - * @return collection of containers or empty collection - */ - Collection getContainers(); - - /** - * Returns the labels for the template in this replication controller - * @return - */ - Map getTemplateLabels(); - - /** - * Add or update a label to the template spec; - * @param key - * @param value - */ - void addTemplateLabel(String key, String value); - - /** - * The volumes associated with the pod spec - * @return - */ - Set getVolumes(); - - /** - * Adds a volume to the pod spec. If a volume with the same name already exists, the volume is not added. - * - * @param volumeSource The volume to add to the pod spec - */ - void addVolume(IVolumeSource volumeSource); - - /** - * Add a volume source of the given type with the given name. Unimplemented types - * will return a generic volumesource impl - * - * @param volumetype - * @param name - * @return - */ - T addVolume(String volumetype, String name); - - /** - * Sets the volumes associated with the pod spec. Existing volumes will be overwritten. - * - * @param volumes The volumes to assign to the pod spec. - */ - void setVolumes(Set volumes); - - void setContainers(Collection containers); - - /** - * Sets the service account to run this replication controller under. +public interface IReplicationController extends IResource { + + static final String DEPLOYMENT_PHASE = "openshift.io/deployment.phase"; + + /** + * Set an environment variable to the given name and value on the first + * container in the list of containers + * + */ + void setEnvironmentVariable(String name, String value); + + /** + * Set an environment variable to the given name and value on the given + * container. Returns silently if the containerName is not found + * + */ + void setEnvironmentVariable(String containerName, String name, String value); + + /** + * Removes an environment variable with the given name. Returns silently if the + * name is not found + * + * @throws IllegalArgumentException + * if name is null + * + */ + public void removeEnvironmentVariable(String name); + + /** + * Removes an environment variable with the given name and value on the given + * container. Returns silently if the containerName or the name is not found + * + * @throws IllegalArgumentException + * if name is null + * + */ + public void removeEnvironmentVariable(String containerName, String name); + + /** + * Return the list of env vars of the first container + * + */ + Collection getEnvironmentVariables(); + + /** + * Return the list of env vars for the given container or an empty list if the + * container is not found + * + */ + Collection getEnvironmentVariables(String containerName); + + /** + * Returns the desired number of replicas + * + */ + int getDesiredReplicaCount(); + + int getReplicas(); + + void setReplicas(int count); + + /** + * Sets a new desired number of replicas + * + * @param new + * number of replicas + */ + void setDesiredReplicaCount(int numOfReplicas); + + /** + * Returns the current number of replicas + * + */ + int getCurrentReplicaCount(); + + /** + * Returns the selector used by the controller + * + */ + Map getReplicaSelector(); + + /** + * Set the selector using the map of values + * + */ + void setReplicaSelector(Map selector); + + void setReplicaSelector(String key, String value); + + /** + * Retrieves the list of images deployed in the pod containers from this + * controller + * + */ + Collection getImages(); + + /** + * Add a container to the pod that will be spun up as part of this deployment. + * + * @param name + * the name of the container + * @param tag + * the docker uri + * @param containerPorts + * the container ports + * @param volumes + * the set of emptyDir volumes to add to the config + */ + IContainer addContainer(String name, DockerImageURI tag, Set containerPorts, Map envVars, + List volumes); + + /** + * Add a container to the pod that will be spun up as part of this deployment, + * defaulting the name to the image name + * + * @param tag + * the docker uri + * @param containerPorts + * the container ports + */ + IContainer addContainer(DockerImageURI tag, Set containerPorts, Map envVars); + + /** + * Add a container with the given name + * + */ + IContainer addContainer(String name); + + /** + * Retrieve a container by name or null if it is not found + * + * @return the container or null if not found + */ + IContainer getContainer(String name); + + /** + * Retrieve the containers defined in spec + * + * @return collection of containers or empty collection + */ + Collection getContainers(); + + /** + * Returns the labels for the template in this replication controller + * + */ + Map getTemplateLabels(); + + /** + * Add or update a label to the template spec; + * + */ + void addTemplateLabel(String key, String value); + + /** + * The volumes associated with the pod spec + * + */ + Set getVolumes(); + + /** + * Adds a volume to the pod spec. If a volume with the same name already exists, + * the volume is not added. * - * @param volumes The service account to assign to the spec. + * @param volumeSource + * The volume to add to the pod spec */ - void setServiceAccountName(String serviceAccount); - + void addVolume(IVolumeSource volumeSource); + /** - * Retrieves the service account used by the controller + * Add a volume source of the given type with the given name. Unimplemented + * types will return a generic volumesource impl + * + * @param volumetype + * @param name * @return */ + T addVolume(String volumetype, String name); + + /** + * Sets the volumes associated with the pod spec. Existing volumes will be + * overwritten. + * + * @param volumes + * The volumes to assign to the pod spec. + */ + void setVolumes(Set volumes); + + void setContainers(Collection containers); + + /** + * Sets the service account to run this replication controller under. + * + * @param volumes + * The service account to assign to the spec. + */ + void setServiceAccountName(String serviceAccount); + + /** + * Retrieves the service account used by the controller + * + */ String getServiceAccountName(); } diff --git a/src/main/java/com/openshift/restclient/model/IResource.java b/src/main/java/com/openshift/restclient/model/IResource.java index 9743945a..2c0bd789 100644 --- a/src/main/java/com/openshift/restclient/model/IResource.java +++ b/src/main/java/com/openshift/restclient/model/IResource.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.Map; @@ -17,97 +18,92 @@ import com.openshift.restclient.capability.ICapable; /** - * IResource is a representation of a Kubernetes resource (e.g. Service, Pod, ReplicationController) + * IResource is a representation of a Kubernetes resource (e.g. Service, Pod, + * ReplicationController) * - * @author Jeff Cantrill */ public interface IResource extends ICapable, Annotatable, IAnnotatable, JSONSerializeable, ITypeMeta { - - Map getMetadata(); - - /** - * @return the list of capabilities supported by this resource - */ - Set> getCapabilities(); - - /** - * Returns the timestamp of when this resource - * was created - * @return - */ - String getCreationTimeStamp(); - - /** - * Returns the identifier for this resource - * @return - */ - String getName(); - - /** - * Returns the scope of this resource - * @return - */ - String getNamespaceName(); - - /** - * Return the project of the resource - * @return - */ - IProject getProject(); - - /** - * Return the namespace of the resource - * @return - */ - INamespace getNamespace(); - - /** - * Retrieves the labels associated with the resource - * @return - */ - Map getLabels(); - - /** - * Add or update a label; - * @param key - * @param value - */ - void addLabel(String key, String value); - - /** - * Returns true if the resource is annotated with - * the given key - * @param key - * @return true if the annotation key exists - */ - boolean isAnnotatedWith(String key); - - /** - * Retrieves the annotated value for the given key - * @param key - * @return - */ - String getAnnotation(String key); - - /** - * Set the resource annotation - * @param key - * @param value - */ - void setAnnotation(String key, String value); - - /** - * Removes the resource annotation - * @param key - */ - void removeAnnotation(String key); - - /** - * Retrieves the annotations associated with the resource - * @return - */ - Map getAnnotations(); - - String getResourceVersion(); + + Map getMetadata(); + + /** + * @return the list of capabilities supported by this resource + */ + Set> getCapabilities(); + + /** + * Returns the timestamp of when this resource was created + * + */ + String getCreationTimeStamp(); + + /** + * Returns the identifier for this resource + * + */ + String getName(); + + /** + * Returns the scope of this resource + * + */ + String getNamespaceName(); + + /** + * Return the project of the resource + * + */ + IProject getProject(); + + /** + * Return the namespace of the resource + * + */ + INamespace getNamespace(); + + /** + * Retrieves the labels associated with the resource + * + */ + Map getLabels(); + + /** + * Add or update a label; + * + */ + void addLabel(String key, String value); + + /** + * Returns true if the resource is annotated with the given key + * + * @return true if the annotation key exists + */ + boolean isAnnotatedWith(String key); + + /** + * Retrieves the annotated value for the given key + * + */ + String getAnnotation(String key); + + /** + * Set the resource annotation + * + */ + void setAnnotation(String key, String value); + + /** + * Removes the resource annotation + * + */ + void removeAnnotation(String key); + + /** + * Retrieves the annotations associated with the resource + * + */ + Map getAnnotations(); + + String getResourceVersion(); } diff --git a/src/main/java/com/openshift/restclient/model/IResourceBuilder.java b/src/main/java/com/openshift/restclient/model/IResourceBuilder.java index 52b4b541..1a43732c 100644 --- a/src/main/java/com/openshift/restclient/model/IResourceBuilder.java +++ b/src/main/java/com/openshift/restclient/model/IResourceBuilder.java @@ -8,28 +8,28 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import java.util.Map; /** * A builder for building up resources - * @author jeff.cantrill * - * @param */ @SuppressWarnings("rawtypes") public interface IResourceBuilder { - - B named(String name); - B inNamespace(String name); - - B withLabels(Map labels); - - T build(); - - interface Endable{ - - IResourceBuilder end(); - } + + B named(String name); + + B inNamespace(String name); + + B withLabels(Map labels); + + T build(); + + interface Endable { + + IResourceBuilder end(); + } } diff --git a/src/main/java/com/openshift/restclient/model/IResourceQuota.java b/src/main/java/com/openshift/restclient/model/IResourceQuota.java index 4806dcfc..d8b28bde 100644 --- a/src/main/java/com/openshift/restclient/model/IResourceQuota.java +++ b/src/main/java/com/openshift/restclient/model/IResourceQuota.java @@ -8,13 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IResourceQuota extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/ISecretKeySelector.java b/src/main/java/com/openshift/restclient/model/ISecretKeySelector.java index 6a2c2373..db0e817f 100644 --- a/src/main/java/com/openshift/restclient/model/ISecretKeySelector.java +++ b/src/main/java/com/openshift/restclient/model/ISecretKeySelector.java @@ -8,14 +8,15 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import com.openshift.restclient.model.IEnvironmentVariable.IEnvVarSource; public interface ISecretKeySelector extends IEnvVarSource { - String getName(); - - String getKey(); + String getName(); + + String getKey(); } diff --git a/src/main/java/com/openshift/restclient/model/IService.java b/src/main/java/com/openshift/restclient/model/IService.java index b3587ad9..cae6c189 100644 --- a/src/main/java/com/openshift/restclient/model/IService.java +++ b/src/main/java/com/openshift/restclient/model/IService.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; import java.util.List; @@ -14,101 +15,93 @@ /** * Kubernetes Service to access a Pod * - * @author Jeff Cantrill */ -public interface IService extends IResource{ - - /** - * Sets the container port exposed by the image - * @param port - */ - void setTargetPort(int port); - - /** - * Sets the exposed port that is mapped to a - * running image - * @param port - */ - void setPort(int port); - - /** - * Returns the first exposed port that is mapped to - * a running image - * @return - */ - int getPort(); - - IServicePort addPort(int port, int targetPort); - - IServicePort addPort(int port, int targetPort, String name); - - /** - * Sets the container name that the service - * routes traffic to. - * @param selector - */ - void setSelector(Map selector); - - /** - * Convenience method for setting a selector that has - * a singular key/value pair. - * @param key - * @param value - */ - void setSelector(String key, String value); - - /** - * Returns the selector used to find the Pod - * to which this service is routing - * @return - */ - Map getSelector(); - - /** - * The port this service targets on the - * pod - * @return - */ - String getTargetPort(); - - /** - * Returns the IP of the service. - * @return - */ - @Deprecated - String getPortalIP(); - - /** - * Returns the IP of the service. - * @return - */ - String getClusterIP(); - - /** - * Retrieves the pods for this service - * @return - */ - List getPods(); - - /** - * Get the collection of ports for the service - * @return - */ - List getPorts(); - - /** - * Set the collection of ports for the service - */ - void setPorts(List ports); - - /** - * Returns the type of the service. - * @return - */ - String getType(); - - /** - * Sets the type of the service. - */ - void setType(String type); +public interface IService extends IResource { + + /** + * Sets the container port exposed by the image + * + */ + void setTargetPort(int port); + + /** + * Sets the exposed port that is mapped to a running image + * + */ + void setPort(int port); + + /** + * Returns the first exposed port that is mapped to a running image + * + */ + int getPort(); + + IServicePort addPort(int port, int targetPort); + + IServicePort addPort(int port, int targetPort, String name); + + /** + * Sets the container name that the service routes traffic to. + * + */ + void setSelector(Map selector); + + /** + * Convenience method for setting a selector that has a singular key/value pair. + * + */ + void setSelector(String key, String value); + + /** + * Returns the selector used to find the Pod to which this service is routing + * + */ + Map getSelector(); + + /** + * The port this service targets on the pod + * + */ + String getTargetPort(); + + /** + * Returns the IP of the service. + * + */ + @Deprecated + String getPortalIP(); + + /** + * Returns the IP of the service. + * + */ + String getClusterIP(); + + /** + * Retrieves the pods for this service + * + */ + List getPods(); + + /** + * Get the collection of ports for the service + * + */ + List getPorts(); + + /** + * Set the collection of ports for the service + */ + void setPorts(List ports); + + /** + * Returns the type of the service. + * + */ + String getType(); + + /** + * Sets the type of the service. + */ + void setType(String type); } diff --git a/src/main/java/com/openshift/restclient/model/IServicePort.java b/src/main/java/com/openshift/restclient/model/IServicePort.java index e87a6cef..6e39cb07 100644 --- a/src/main/java/com/openshift/restclient/model/IServicePort.java +++ b/src/main/java/com/openshift/restclient/model/IServicePort.java @@ -8,38 +8,44 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; public interface IServicePort { - /** - * The name of the port - * - * @return the name or null if undefined. - */ - String getName(); - void setName(String name); - - /** - * Port exposed by the service - * @return - */ - int getPort(); - void setPort(int port); - - /** - * The target port on the pod it services. An integer - * or named port on the pod spec - * @return - */ - String getTargetPort(); - void setTargetPort(int port); - void setTargetPort(String name); - - /** - * IP protocol (TCP, UDP) - * @return - */ - String getProtocol(); - void setProtocol(String proto); + /** + * The name of the port + * + * @return the name or null if undefined. + */ + String getName(); + + void setName(String name); + + /** + * Port exposed by the service + * + */ + int getPort(); + + void setPort(int port); + + /** + * The target port on the pod it services. An integer or named port on the pod + * spec + * + */ + String getTargetPort(); + + void setTargetPort(int port); + + void setTargetPort(String name); + + /** + * IP protocol (TCP, UDP) + * + */ + String getProtocol(); + + void setProtocol(String proto); } diff --git a/src/main/java/com/openshift/restclient/model/IStatus.java b/src/main/java/com/openshift/restclient/model/IStatus.java index 596f28d0..c00a0bed 100644 --- a/src/main/java/com/openshift/restclient/model/IStatus.java +++ b/src/main/java/com/openshift/restclient/model/IStatus.java @@ -6,47 +6,47 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model; /** - * Status message resulting from trying to manipulate an - * OpenShift resource and an error occurs + * Status message resulting from trying to manipulate an OpenShift resource and + * an error occurs * - * @author Jeff Cantrill */ public interface IStatus extends IResource { - public static final String SUCCESS = "Success"; - public static final String FAILURE = "Failure"; - - /** - * Returns the status message - * @return - */ - String getMessage(); - - /** - * The HTTP status code - * @return an int - */ - int getCode(); - - /** - * The status info of the status - * @return - */ - String getStatus(); - - /** - * Determine if this status is indicates - * a failure - * @return - */ - boolean isFailure(); - - /** - * Returns {@code true} if this status represent success} - * @return - */ - boolean isSuccess(); + public static final String SUCCESS = "Success"; + public static final String FAILURE = "Failure"; + + /** + * Returns the status message + * + */ + String getMessage(); + + /** + * The HTTP status code + * + * @return an int + */ + int getCode(); + + /** + * The status info of the status + * + */ + String getStatus(); + + /** + * Determine if this status is indicates a failure + * + */ + boolean isFailure(); + + /** + * Returns {@code true} if this status represent success} + * + */ + boolean isSuccess(); } diff --git a/src/main/java/com/openshift/restclient/model/JSONSerializeable.java b/src/main/java/com/openshift/restclient/model/JSONSerializeable.java index 6a280afa..90193365 100644 --- a/src/main/java/com/openshift/restclient/model/JSONSerializeable.java +++ b/src/main/java/com/openshift/restclient/model/JSONSerializeable.java @@ -8,27 +8,28 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; /** * Something that can be serialized to JSON - * @author jeff.cantrill * */ public interface JSONSerializeable { - - /** - * The JSON representation - * @return - */ - String toJson(); - - /** - * The JSON representation - * @param compact true if it should be compact; false otherwise - * @return - */ - default String toJson(boolean compact) { - return toJson(); - } + + /** + * The JSON representation + * + */ + String toJson(); + + /** + * The JSON representation + * + * @param compact + * true if it should be compact; false otherwise + */ + default String toJson(boolean compact) { + return toJson(); + } } diff --git a/src/main/java/com/openshift/restclient/model/authorization/IPolicy.java b/src/main/java/com/openshift/restclient/model/authorization/IPolicy.java index 442f36c0..85040026 100644 --- a/src/main/java/com/openshift/restclient/model/authorization/IPolicy.java +++ b/src/main/java/com/openshift/restclient/model/authorization/IPolicy.java @@ -8,13 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.authorization; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IPolicy extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/authorization/IPolicyBinding.java b/src/main/java/com/openshift/restclient/model/authorization/IPolicyBinding.java index c55fae2a..19014405 100644 --- a/src/main/java/com/openshift/restclient/model/authorization/IPolicyBinding.java +++ b/src/main/java/com/openshift/restclient/model/authorization/IPolicyBinding.java @@ -8,13 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.authorization; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ + public interface IPolicyBinding extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/authorization/IRole.java b/src/main/java/com/openshift/restclient/model/authorization/IRole.java index 2bfd4e45..098f7418 100644 --- a/src/main/java/com/openshift/restclient/model/authorization/IRole.java +++ b/src/main/java/com/openshift/restclient/model/authorization/IRole.java @@ -8,13 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.authorization; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IRole extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/authorization/IRoleBinding.java b/src/main/java/com/openshift/restclient/model/authorization/IRoleBinding.java index d11097f5..005dcf03 100644 --- a/src/main/java/com/openshift/restclient/model/authorization/IRoleBinding.java +++ b/src/main/java/com/openshift/restclient/model/authorization/IRoleBinding.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.authorization; import java.util.Set; @@ -15,22 +16,25 @@ import com.openshift.restclient.model.IObjectReference; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IRoleBinding extends IResource { - void setUserNames(Set names); - Set getUserNames(); - void addUserName(String name); - - void setGroupNames(Set names); - Set getGroupNames(); - void addGroupName(String name); - - void setSubjects(Set subjects); - Set getSubjects(); - - IObjectReference getRoleRef(); - void setRoleRef(IObjectReference roleRef); + void setUserNames(Set names); + + Set getUserNames(); + + void addUserName(String name); + + void setGroupNames(Set names); + + Set getGroupNames(); + + void addGroupName(String name); + + void setSubjects(Set subjects); + + Set getSubjects(); + + IObjectReference getRoleRef(); + + void setRoleRef(IObjectReference roleRef); } diff --git a/src/main/java/com/openshift/restclient/model/build/BuildSourceType.java b/src/main/java/com/openshift/restclient/model/build/BuildSourceType.java index dbbff607..9ef68bf3 100644 --- a/src/main/java/com/openshift/restclient/model/build/BuildSourceType.java +++ b/src/main/java/com/openshift/restclient/model/build/BuildSourceType.java @@ -6,13 +6,11 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; -/** - * @author Jeff Cantrill - */ public interface BuildSourceType { - - static final String GIT = "Git"; - + + static final String GIT = "Git"; + } diff --git a/src/main/java/com/openshift/restclient/model/build/BuildStrategyType.java b/src/main/java/com/openshift/restclient/model/build/BuildStrategyType.java index a3b02316..29a73abb 100644 --- a/src/main/java/com/openshift/restclient/model/build/BuildStrategyType.java +++ b/src/main/java/com/openshift/restclient/model/build/BuildStrategyType.java @@ -6,22 +6,22 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; /** - * The build strategies supported - * by OpenShift + * The build strategies supported by OpenShift */ public interface BuildStrategyType { - - static final String DOCKER = "Docker"; - - @Deprecated - static final String STI = "STI"; - - static final String SOURCE = "Source"; - static final String CUSTOM = "Custom"; - static final String JENKINS_PIPELINE = "JenkinsPipeline"; + + static final String DOCKER = "Docker"; + + @Deprecated + static final String STI = "STI"; + + static final String SOURCE = "Source"; + static final String CUSTOM = "Custom"; + static final String JENKINS_PIPELINE = "JenkinsPipeline"; } diff --git a/src/main/java/com/openshift/restclient/model/build/BuildTriggerType.java b/src/main/java/com/openshift/restclient/model/build/BuildTriggerType.java index 6d318243..eb7d2e35 100644 --- a/src/main/java/com/openshift/restclient/model/build/BuildTriggerType.java +++ b/src/main/java/com/openshift/restclient/model/build/BuildTriggerType.java @@ -6,24 +6,22 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; -/** - * @author Jeff Cantrill - */ public interface BuildTriggerType { - @Deprecated - static final String generic = "generic"; - - @Deprecated - static final String github = "github"; - - @Deprecated - static final String imageChange = "imageChange"; + @Deprecated + static final String generic = "generic"; + + @Deprecated + static final String github = "github"; + + @Deprecated + static final String imageChange = "imageChange"; + + static final String CONFIG_CHANGE = "ConfigChange"; + static final String GENERIC = "Generic"; + static final String GITHUB = "GitHub"; + static final String IMAGE_CHANGE = "ImageChange"; - static final String CONFIG_CHANGE = "ConfigChange"; - static final String GENERIC = "Generic"; - static final String GITHUB = "GitHub"; - static final String IMAGE_CHANGE = "ImageChange"; - } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java index ac8966a5..41a4f4ee 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.build; import java.util.List; @@ -19,53 +20,63 @@ public interface IBuildConfigBuilder extends IResourceBuilder, ICapability { - ISourceStrategyBuilder usingSourceStrategy(); - IJenkinsPipelineStrategyBuilder usingJenkinsPipelineStrategy(); - IGitSourceBuilder fromGitSource(); - IBuildConfigBuilder toImageStreamTag(String tag); - IBuildConfigBuilder buildOnSourceChange(boolean onSourceChange); - IBuildConfigBuilder buildOnImageChange(boolean onImageChange); - IBuildConfigBuilder buildOnConfigChange(boolean onConfigChange); - - interface IGitSourceBuilder extends Endable{ - - IBuildConfigBuilder end(); - - IGitSourceBuilder fromGitUrl(String url); - IGitSourceBuilder usingGitReference(String ref); - IGitSourceBuilder inContextDir(String contextDir); - - } - - interface ISourceStrategyBuilder extends Endable{ - - IBuildConfigBuilder end(); - - /** - * The imagestream tag in form of 'name:tag" - * @param tag 'name:tag' - * @return - */ - ISourceStrategyBuilder fromImageStreamTag(String tag); - - ISourceStrategyBuilder inNamespace(String namespace); - - ISourceStrategyBuilder withEnvVars(List envVars); - - /** - * @param tag docker pullspec - * @return - */ - ISourceStrategyBuilder fromDockerImage(String tag); - - } - - interface IJenkinsPipelineStrategyBuilder extends Endable { - - IBuildConfigBuilder end(); - - IJenkinsPipelineStrategyBuilder usingFile(String file); - IJenkinsPipelineStrategyBuilder usingFilePath(String filePath); - } + ISourceStrategyBuilder usingSourceStrategy(); + + IJenkinsPipelineStrategyBuilder usingJenkinsPipelineStrategy(); + + IGitSourceBuilder fromGitSource(); + + IBuildConfigBuilder toImageStreamTag(String tag); + + IBuildConfigBuilder buildOnSourceChange(boolean onSourceChange); + + IBuildConfigBuilder buildOnImageChange(boolean onImageChange); + + IBuildConfigBuilder buildOnConfigChange(boolean onConfigChange); + + interface IGitSourceBuilder extends Endable { + + IBuildConfigBuilder end(); + + IGitSourceBuilder fromGitUrl(String url); + + IGitSourceBuilder usingGitReference(String ref); + + IGitSourceBuilder inContextDir(String contextDir); + + } + + interface ISourceStrategyBuilder extends Endable { + + IBuildConfigBuilder end(); + + /** + * The imagestream tag in form of 'name:tag" + * + * @param tag + * 'name:tag' + */ + ISourceStrategyBuilder fromImageStreamTag(String tag); + + ISourceStrategyBuilder inNamespace(String namespace); + + ISourceStrategyBuilder withEnvVars(List envVars); + + /** + * @param tag + * docker pullspec + */ + ISourceStrategyBuilder fromDockerImage(String tag); + + } + + interface IJenkinsPipelineStrategyBuilder extends Endable { + + IBuildConfigBuilder end(); + + IJenkinsPipelineStrategyBuilder usingFile(String file); + + IJenkinsPipelineStrategyBuilder usingFilePath(String filePath); + } } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java b/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java index afefd555..d6e82f52 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildRequest.java @@ -8,8 +8,8 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.restclient.model.build; +package com.openshift.restclient.model.build; import java.util.List; @@ -17,41 +17,50 @@ /** * Resource payload for triggering a build - * @author Jeff Cantrill * */ public interface IBuildRequest extends IResource { - /** - * Set the commit level for the git clone extraction - * of the source code the build operates against - * @param commitId the specific hexadecimal commit ID associated with a git log level - */ - void setCommitId(String commitId); - - /** - * Get the commit level for the git clone extraction - * of the source code the build operates against - * @return the specific hexadecimal commit ID associated with a git log level - */ - String getCommitId(); - - /** - * Add a human readable short explanation of why this build request was issued - * @param cause the description to add to the list of causes for this request - */ - void addBuildCause(String cause); - - /** - * Get the list of human readable short explanations of why this build request was issued - * @return list of reasons for the build - */ - List getBuildCauses(); - - /** - * Sets an environment variable in this build request - * @param name The name of the environment variable to set - * @param value The value of the variable - */ - void setEnvironmentVariable(String name, String value); + /** + * Set the commit level for the git clone extraction of the source code the + * build operates against + * + * @param commitId + * the specific hexadecimal commit ID associated with a git log level + */ + void setCommitId(String commitId); + + /** + * Get the commit level for the git clone extraction of the source code the + * build operates against + * + * @return the specific hexadecimal commit ID associated with a git log level + */ + String getCommitId(); + + /** + * Add a human readable short explanation of why this build request was issued + * + * @param cause + * the description to add to the list of causes for this request + */ + void addBuildCause(String cause); + + /** + * Get the list of human readable short explanations of why this build request + * was issued + * + * @return list of reasons for the build + */ + List getBuildCauses(); + + /** + * Sets an environment variable in this build request + * + * @param name + * The name of the environment variable to set + * @param value + * The value of the variable + */ + void setEnvironmentVariable(String name, String value); } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildSource.java b/src/main/java/com/openshift/restclient/model/build/IBuildSource.java index 3bfb621a..b9551d93 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildSource.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildSource.java @@ -6,30 +6,29 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; -/** - * @author Jeff Cantrill - */ public interface IBuildSource { - - /** - * The BuildSourceType - * @return {@link BuildSourceType} - */ - String getType(); - - /** - * The URI to the source repo - * @return - */ - String getURI(); - /** - * The sub-directory relative to the repo root where the source code for the application exists. - * This allows to have buildable sources in directory other than root of repository. - * - * @return - */ - String getContextDir(); + /** + * The BuildSourceType + * + * @return {@link BuildSourceType} + */ + String getType(); + + /** + * The URI to the source repo + * + */ + String getURI(); + + /** + * The sub-directory relative to the repo root where the source code for the + * application exists. This allows to have buildable sources in directory other + * than root of repository. + * + */ + String getContextDir(); } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildStatus.java b/src/main/java/com/openshift/restclient/model/build/IBuildStatus.java index e4f184e0..52f832dc 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildStatus.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildStatus.java @@ -8,21 +8,22 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.build; import com.openshift.restclient.images.DockerImageURI; public interface IBuildStatus { - - String getPhase(); - - String getStartTime(); - - /** - * The duration of the build in nanoseconds - * @return - */ - long getDuration(); - - DockerImageURI getOutputDockerImage(); + + String getPhase(); + + String getStartTime(); + + /** + * The duration of the build in nanoseconds + * + */ + long getDuration(); + + DockerImageURI getOutputDockerImage(); } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildStrategy.java b/src/main/java/com/openshift/restclient/model/build/IBuildStrategy.java index 6c48f77c..41643f8a 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildStrategy.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildStrategy.java @@ -6,16 +6,15 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; -/** - * @author Jeff Cantrill - */ public interface IBuildStrategy { - - /** - * The type of build Strategy - * @return {@link BuildStrategyType} - */ - String getType(); + + /** + * The type of build Strategy + * + * @return {@link BuildStrategyType} + */ + String getType(); } diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildTrigger.java b/src/main/java/com/openshift/restclient/model/build/IBuildTrigger.java index 1ebded57..b513a941 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildTrigger.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildTrigger.java @@ -6,12 +6,10 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; -/** - * @author Jeff Cantrill - */ public interface IBuildTrigger { - - String getType(); + + String getType(); } diff --git a/src/main/java/com/openshift/restclient/model/build/ICustomBuildStrategy.java b/src/main/java/com/openshift/restclient/model/build/ICustomBuildStrategy.java index 6dab8dbf..1120766a 100644 --- a/src/main/java/com/openshift/restclient/model/build/ICustomBuildStrategy.java +++ b/src/main/java/com/openshift/restclient/model/build/ICustomBuildStrategy.java @@ -6,20 +6,18 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; import java.util.Map; import com.openshift.restclient.images.DockerImageURI; -/** - * @author Jeff Cantrill - */ public interface ICustomBuildStrategy extends IBuildStrategy { - - Map getEnvironmentVariables(); - - boolean exposeDockerSocket(); - - DockerImageURI getImage(); + + Map getEnvironmentVariables(); + + boolean exposeDockerSocket(); + + DockerImageURI getImage(); } diff --git a/src/main/java/com/openshift/restclient/model/build/IDockerBuildStrategy.java b/src/main/java/com/openshift/restclient/model/build/IDockerBuildStrategy.java index d4f29a07..447610c0 100644 --- a/src/main/java/com/openshift/restclient/model/build/IDockerBuildStrategy.java +++ b/src/main/java/com/openshift/restclient/model/build/IDockerBuildStrategy.java @@ -6,18 +6,16 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; import com.openshift.restclient.images.DockerImageURI; -/** - * @author Jeff Cantrill - */ public interface IDockerBuildStrategy extends IBuildStrategy { - - String getContextDir(); - - boolean isNoCache(); - - DockerImageURI getBaseImage(); + + String getContextDir(); + + boolean isNoCache(); + + DockerImageURI getBaseImage(); } diff --git a/src/main/java/com/openshift/restclient/model/build/IGitBuildSource.java b/src/main/java/com/openshift/restclient/model/build/IGitBuildSource.java index fdef9e1b..dc898710 100644 --- a/src/main/java/com/openshift/restclient/model/build/IGitBuildSource.java +++ b/src/main/java/com/openshift/restclient/model/build/IGitBuildSource.java @@ -6,16 +6,14 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; -/** - * @author Jeff Cantrill - */ public interface IGitBuildSource extends IBuildSource { - - /** - * The branch/tag/ref to build - * @return - */ - String getRef(); + + /** + * The branch/tag/ref to build + * + */ + String getRef(); } diff --git a/src/main/java/com/openshift/restclient/model/build/IImageChangeTrigger.java b/src/main/java/com/openshift/restclient/model/build/IImageChangeTrigger.java index 2c97ada9..802f421a 100644 --- a/src/main/java/com/openshift/restclient/model/build/IImageChangeTrigger.java +++ b/src/main/java/com/openshift/restclient/model/build/IImageChangeTrigger.java @@ -6,28 +6,25 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; import com.openshift.restclient.images.DockerImageURI; -/** - * @author Jeff Cantrill - */ public interface IImageChangeTrigger extends IBuildTrigger { - - - DockerImageURI getImage(); - - /** - * Returns the name of the docker image repo to watch - * @return - */ - DockerImageURI getFrom(); - - /** - * Returns the tag to watch in the image repository - * @return - */ - String getTag(); - + + DockerImageURI getImage(); + + /** + * Returns the name of the docker image repo to watch + * + */ + DockerImageURI getFrom(); + + /** + * Returns the tag to watch in the image repository + * + */ + String getTag(); + } diff --git a/src/main/java/com/openshift/restclient/model/build/IJenkinsPipelineStrategy.java b/src/main/java/com/openshift/restclient/model/build/IJenkinsPipelineStrategy.java index 819c886d..13c94dcc 100644 --- a/src/main/java/com/openshift/restclient/model/build/IJenkinsPipelineStrategy.java +++ b/src/main/java/com/openshift/restclient/model/build/IJenkinsPipelineStrategy.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; import java.util.Collection; @@ -16,17 +17,20 @@ * @author Andre Dietisheim */ public interface IJenkinsPipelineStrategy extends IBuildStrategy { - - static final String JENKINS_FILE = "jenkinsPipelineStrategy.jenkinsfile"; - static final String JENKINS_FILE_PATH = "jenkinsPipelineStrategy.jenkinsfilePath"; - static final String ENV = "jenkinsPipelineStrategy.env"; - void setJenkinsfilePath(String filePath); - String getJenkinsfilePath(); + static final String JENKINS_FILE = "jenkinsPipelineStrategy.jenkinsfile"; + static final String JENKINS_FILE_PATH = "jenkinsPipelineStrategy.jenkinsfilePath"; + static final String ENV = "jenkinsPipelineStrategy.env"; + + void setJenkinsfilePath(String filePath); + + String getJenkinsfilePath(); + + void setJenkinsfile(String jenkinsFile); + + String getJenkinsfile(); - void setJenkinsfile(String jenkinsFile); - String getJenkinsfile(); + Collection getEnvVars(); - Collection getEnvVars(); - void setEnvVars(Collection envVars); + void setEnvVars(Collection envVars); } diff --git a/src/main/java/com/openshift/restclient/model/build/ISTIBuildStrategy.java b/src/main/java/com/openshift/restclient/model/build/ISTIBuildStrategy.java index 2ac2f001..090208ab 100644 --- a/src/main/java/com/openshift/restclient/model/build/ISTIBuildStrategy.java +++ b/src/main/java/com/openshift/restclient/model/build/ISTIBuildStrategy.java @@ -6,31 +6,28 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; import java.util.Map; import com.openshift.restclient.images.DockerImageURI; -/** - * @author Jeff Cantrill - */ @Deprecated public interface ISTIBuildStrategy extends IBuildStrategy { - - /** - * Returns the Builder Image used to execute the build - */ - DockerImageURI getImage(); - - String getScriptsLocation(); - - Map getEnvironmentVariables(); - - boolean incremental(); - - @Deprecated - boolean forceClean(); - - + + /** + * Returns the Builder Image used to execute the build + */ + DockerImageURI getImage(); + + String getScriptsLocation(); + + Map getEnvironmentVariables(); + + boolean incremental(); + + @Deprecated + boolean forceClean(); + } diff --git a/src/main/java/com/openshift/restclient/model/build/ISourceBuildStrategy.java b/src/main/java/com/openshift/restclient/model/build/ISourceBuildStrategy.java index 50861d46..402a672b 100644 --- a/src/main/java/com/openshift/restclient/model/build/ISourceBuildStrategy.java +++ b/src/main/java/com/openshift/restclient/model/build/ISourceBuildStrategy.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.build; import java.util.Collection; @@ -16,41 +17,42 @@ import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IEnvironmentVariable; -/** - * - * @author Jeff Cantrill - * - */ -public interface ISourceBuildStrategy extends IBuildStrategy{ - - /** - * Returns the Builder Image used to execute the build - */ - DockerImageURI getImage(); - void setImage(DockerImageURI image); - - String getFromKind(); - void setFromKind(String kind); - - String getFromNamespace(); - void setFromNamespace(String namespace); - - String getScriptsLocation(); - void setScriptsLocation(String location); - - Map getEnvironmentVariables(); - void setEnvironmentVariables(Map envVars); - - Collection getEnvVars(); - - /** - * Setting using a null collection will early return without - * modification to the strategy - * @param envVars - */ - void setEnvVars(Collection envVars); - - boolean incremental(); - void setIncremental(boolean isIncremental); +public interface ISourceBuildStrategy extends IBuildStrategy { + + /** + * Returns the Builder Image used to execute the build + */ + DockerImageURI getImage(); + + void setImage(DockerImageURI image); + + String getFromKind(); + + void setFromKind(String kind); + + String getFromNamespace(); + + void setFromNamespace(String namespace); + + String getScriptsLocation(); + + void setScriptsLocation(String location); + + Map getEnvironmentVariables(); + + void setEnvironmentVariables(Map envVars); + + Collection getEnvVars(); + + /** + * Setting using a null collection will early return without modification to the + * strategy + * + */ + void setEnvVars(Collection envVars); + + boolean incremental(); + + void setIncremental(boolean isIncremental); } diff --git a/src/main/java/com/openshift/restclient/model/build/IWebhookTrigger.java b/src/main/java/com/openshift/restclient/model/build/IWebhookTrigger.java index e7dc7d78..bb56d743 100644 --- a/src/main/java/com/openshift/restclient/model/build/IWebhookTrigger.java +++ b/src/main/java/com/openshift/restclient/model/build/IWebhookTrigger.java @@ -6,18 +6,17 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.build; -/** - * @author Jeff Cantrill - */ public interface IWebhookTrigger extends IBuildTrigger { - - String getSecret(); - - /** - * Returns the URL to trigger the build for the resource - * @return the URL or empty if the resource is not configured with an IClient - */ - String getWebhookURL(); + + String getSecret(); + + /** + * Returns the URL to trigger the build for the resource + * + * @return the URL or empty if the resource is not configured with an IClient + */ + String getWebhookURL(); } diff --git a/src/main/java/com/openshift/restclient/model/deploy/DeploymentTriggerType.java b/src/main/java/com/openshift/restclient/model/deploy/DeploymentTriggerType.java index 0925437e..ee02c585 100644 --- a/src/main/java/com/openshift/restclient/model/deploy/DeploymentTriggerType.java +++ b/src/main/java/com/openshift/restclient/model/deploy/DeploymentTriggerType.java @@ -8,14 +8,10 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.deploy; -/** - * - * @author Jeff Cantrill - * - */ public interface DeploymentTriggerType { - static final String CONFIG_CHANGE = "ConfigChange"; - static final String IMAGE_CHANGE = "ImageChange"; + static final String CONFIG_CHANGE = "ConfigChange"; + static final String IMAGE_CHANGE = "ImageChange"; } diff --git a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentConfigChangeTrigger.java b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentConfigChangeTrigger.java index 2c0749c3..61adb2f9 100644 --- a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentConfigChangeTrigger.java +++ b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentConfigChangeTrigger.java @@ -8,13 +8,9 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.deploy; -/** - * - * @author Jeff Cantrill - * - */ public interface IDeploymentConfigChangeTrigger extends IDeploymentTrigger { } diff --git a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentImageChangeTrigger.java b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentImageChangeTrigger.java index 2e865230..9274b700 100644 --- a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentImageChangeTrigger.java +++ b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentImageChangeTrigger.java @@ -8,63 +8,58 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.deploy; import java.util.Collection; import com.openshift.restclient.images.DockerImageURI; -/** - * - * @author Jeff Cantrill - * - */ public interface IDeploymentImageChangeTrigger extends IDeploymentTrigger { - /** - * Returns the name of the docker image repo to watch - * @return - */ - DockerImageURI getFrom(); + /** + * Returns the name of the docker image repo to watch + * + */ + DockerImageURI getFrom(); + + /** + * Automatically sets kind to "ImageStreamTag" if kind is empty + * + */ + void setFrom(DockerImageURI fromImage); + + /** + * The namespace of the ImageStreamTag + * + */ + void setNamespace(String namespace); + + /** + * @return The namespace of the ImageStreamTag + * + */ + String getNamespace(); + + void setKind(String kind); + + String getKind(); + + boolean isAutomatic(); - /** - * Automatically sets kind to "ImageStreamTag" if kind is empty - * @param fromImage - */ - void setFrom(DockerImageURI fromImage); - - /** - * The namespace of the ImageStreamTag - * @param namespace - */ - void setNamespace(String namespace); + void setAutomatic(boolean auto); - /** - * @return The namespace of the ImageStreamTag - * - */ - String getNamespace(); + /** + * The container names for this trigger + * + */ + Collection getContainerNames(); - void setKind(String kind); - - String getKind(); - - boolean isAutomatic(); - - void setAutomatic(boolean auto); - - /** - * The container names for this trigger - * @return - */ - Collection getContainerNames(); - - void setContainerNames(Collection names); + void setContainerNames(Collection names); - /** - * Convenience method for setting - * a single container name - * @param names - */ - void setContainerName(String names); + /** + * Convenience method for setting a single container name + * + */ + void setContainerName(String names); } diff --git a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentRequest.java b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentRequest.java index 6df02761..b9a59205 100644 --- a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentRequest.java +++ b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentRequest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.deploy; import com.openshift.restclient.api.models.INameSetable; @@ -22,26 +23,22 @@ public interface IDeploymentRequest extends ITypeMeta, INameSetable { /** * If set the true latest will update the deployment config with the latest state from all triggers. - * @param latest */ void setLatest(boolean latest); /** * Returns the current setting of the latest flag. - * @return */ boolean isLatest(); /** * If set to try force will try to force a new deployment to run. If the deployment config is paused, * then setting this to true will return an Invalid error. - * @param force */ void setForce(boolean force); /** * Returns the latest setting of the force flag. - * @return */ boolean isForce(); @@ -54,7 +51,6 @@ public interface IDeploymentRequest extends ITypeMeta, INameSetable { /** * Returns the name of the deployment config seeded into the deployment request - * @return */ String getName(); diff --git a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentTrigger.java b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentTrigger.java index 3417c3d2..4996bed3 100644 --- a/src/main/java/com/openshift/restclient/model/deploy/IDeploymentTrigger.java +++ b/src/main/java/com/openshift/restclient/model/deploy/IDeploymentTrigger.java @@ -8,18 +8,14 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.deploy; -/** - * - * @author Jeff Cantrill - * - */ public interface IDeploymentTrigger { - - /** - * - * @return {@link DeploymentTriggerType} - */ - String getType(); + + /** + * + * @return {@link DeploymentTriggerType} + */ + String getType(); } diff --git a/src/main/java/com/openshift/restclient/model/image/IImageStreamImport.java b/src/main/java/com/openshift/restclient/model/image/IImageStreamImport.java index 757b4596..4dedd2bf 100644 --- a/src/main/java/com/openshift/restclient/model/image/IImageStreamImport.java +++ b/src/main/java/com/openshift/restclient/model/image/IImageStreamImport.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.image; import java.util.Collection; @@ -16,57 +17,52 @@ import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.IStatus; -/** - * - * @author jeff.cantrill - * - */ public interface IImageStreamImport extends IResource { - /** - * Set to true to import tags for the imagestream; false to just retrieve - * @param importTags - */ - void setImport(boolean importTags); - - /** - * Are the tags to be imported for the imagestream - * @return true if import; false otherwise - */ - boolean isImport(); + /** + * Set to true to import tags for the imagestream; false to just retrieve + * + */ + void setImport(boolean importTags); + + /** + * Are the tags to be imported for the imagestream + * + * @return true if import; false otherwise + */ + boolean isImport(); + + /** + * Add image info those being imorted + * + * @param fromKind + * The indirection of where to find the image. Typically is + * DockerImage, ImageStreamTag + */ + void addImage(String fromKind, DockerImageURI imageUri); - /** - * Add image info those being imorted - * @param fromKind The indirection of where to find the image. - * Typically is DockerImage, ImageStreamTag - * @param uriWithoutTag - */ - void addImage(String fromKind, DockerImageURI imageUri); + /** + * The status of the image retrieval + * + */ + Collection getImageStatus(); - /** - * The status of the image retrieval - * @return - */ - Collection getImageStatus(); - - /** - * Get the raw json docker metadata for - * the given uir. Tries to match uri without tag - * to the beginning of image.dockerImageReference - * - * @param uri - * @return json string or null if not matched. - */ - @Deprecated - String getImageJsonFor(DockerImageURI uri); + /** + * Get the raw json docker metadata for the given uir. Tries to match uri + * without tag to the beginning of image.dockerImageReference + * + * @return json string or null if not matched. + */ + @Deprecated + String getImageJsonFor(DockerImageURI uri); - /** - * Get the raw json docker metadata for - * the given tag. Assumes the result was - * success - * - * @param tag a tag for the image - * @return json string or null if not matched. - */ - String getImageJsonFor(String tag); + /** + * Get the raw json docker metadata for the given tag. Assumes the result was + * success + * + * @param tag + * a tag for the image + * @return json string or null if not matched. + */ + String getImageJsonFor(String tag); } diff --git a/src/main/java/com/openshift/restclient/model/image/ITagReference.java b/src/main/java/com/openshift/restclient/model/image/ITagReference.java index 41490743..c6135451 100644 --- a/src/main/java/com/openshift/restclient/model/image/ITagReference.java +++ b/src/main/java/com/openshift/restclient/model/image/ITagReference.java @@ -8,25 +8,26 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.image; import com.openshift.restclient.model.Annotatable; import com.openshift.restclient.model.IObjectReference; public interface ITagReference extends Annotatable { - - /** - * Returns the identifier for this reference - * @return - */ - String getName(); - - /** - * if specified, a reference to another image that this tag should point to. - * Valid values are ImageStreamTag, ImageStreamImage, and DockerImage. - * @return - */ - IObjectReference getFrom(); - - String toJson(); + + /** + * Returns the identifier for this reference + * + */ + String getName(); + + /** + * if specified, a reference to another image that this tag should point to. + * Valid values are ImageStreamTag, ImageStreamImage, and DockerImage. + * + */ + IObjectReference getFrom(); + + String toJson(); } diff --git a/src/main/java/com/openshift/restclient/model/kubeclient/ICluster.java b/src/main/java/com/openshift/restclient/model/kubeclient/ICluster.java index 2ea4c9e8..c63c3933 100644 --- a/src/main/java/com/openshift/restclient/model/kubeclient/ICluster.java +++ b/src/main/java/com/openshift/restclient/model/kubeclient/ICluster.java @@ -8,17 +8,19 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.kubeclient; public interface ICluster { - - String getName(); - /** - * The server url - * @return - */ - String getServer(); - - boolean isInsecureSkipTLSVerify(); - + + String getName(); + + /** + * The server url + * + */ + String getServer(); + + boolean isInsecureSkipTLSVerify(); + } \ No newline at end of file diff --git a/src/main/java/com/openshift/restclient/model/kubeclient/IContext.java b/src/main/java/com/openshift/restclient/model/kubeclient/IContext.java index 70676025..a4b031cb 100644 --- a/src/main/java/com/openshift/restclient/model/kubeclient/IContext.java +++ b/src/main/java/com/openshift/restclient/model/kubeclient/IContext.java @@ -8,34 +8,34 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.kubeclient; public interface IContext { - - /** - * The name of the cluster - * @return - */ - String getCluster(); - /** - * Returns the user info in the form of: - * / - * @return the user info - */ - String getUser(); - - /** - * default namespace to use - * on unspecified requests - * @return - */ - String getNamespace(); + /** + * The name of the cluster + * + */ + String getCluster(); + + /** + * Returns the user info in the form of: USERNAME/URL + * + * @return the user info + */ + String getUser(); + + /** + * default namespace to use on unspecified requests + * + */ + String getNamespace(); + + /** + * The name of the context + * + */ + String getName(); - /** - * The name of the context - * @return - */ - String getName(); - } \ No newline at end of file diff --git a/src/main/java/com/openshift/restclient/model/kubeclient/IKubeClientConfig.java b/src/main/java/com/openshift/restclient/model/kubeclient/IKubeClientConfig.java index 9dd94c91..8d5c4463 100644 --- a/src/main/java/com/openshift/restclient/model/kubeclient/IKubeClientConfig.java +++ b/src/main/java/com/openshift/restclient/model/kubeclient/IKubeClientConfig.java @@ -8,33 +8,33 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.kubeclient; import java.util.Collection; /** - * Configuration type for connecting to a Kubernetes client config - * ref: client/unversioned/clientcmd/api/types.go + * Configuration type for connecting to a Kubernetes client config ref: + * client/unversioned/clientcmd/api/types.go * - * @author jeff.cantrill * */ public interface IKubeClientConfig { - - /** - * A map of userinfo to cluster info where the key - * is // - * @return - */ - Collection getClusters(); - Collection getContexts(); - - /** - * The name of the current cluster context - * @return - */ - String getCurrentContext(); - - Collection getUsers(); + /** + * A map of userinfo to cluster info where the key is + * NAMESPACE/URL/USERNAME + * + */ + Collection getClusters(); + + Collection getContexts(); + + /** + * The name of the current cluster context + * + */ + String getCurrentContext(); + + Collection getUsers(); } diff --git a/src/main/java/com/openshift/restclient/model/kubeclient/IUser.java b/src/main/java/com/openshift/restclient/model/kubeclient/IUser.java index bf72914e..07230acc 100644 --- a/src/main/java/com/openshift/restclient/model/kubeclient/IUser.java +++ b/src/main/java/com/openshift/restclient/model/kubeclient/IUser.java @@ -8,11 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.kubeclient; public interface IUser { - - String getToken(); - - String getName(); + + String getToken(); + + String getName(); } \ No newline at end of file diff --git a/src/main/java/com/openshift/restclient/model/kubeclient/KubeClientConfigSerializer.java b/src/main/java/com/openshift/restclient/model/kubeclient/KubeClientConfigSerializer.java index 0a5aa8a9..27552f85 100644 --- a/src/main/java/com/openshift/restclient/model/kubeclient/KubeClientConfigSerializer.java +++ b/src/main/java/com/openshift/restclient/model/kubeclient/KubeClientConfigSerializer.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.kubeclient; import java.beans.IntrospectionException; @@ -22,27 +23,22 @@ import com.openshift.internal.restclient.model.kubeclient.KubeClientConfigConstructor; import com.openshift.restclient.utils.BeanUtils; -/** - * - * @author jeff.cantrill - * - */ public class KubeClientConfigSerializer { - public IKubeClientConfig loadKubeClientConfig(Reader reader) { - Representer representer = new Representer(); - Yaml parser = new Yaml(new KubeClientConfigConstructor(new YamlPropertyUtils()), representer); - representer.getPropertyUtils().setSkipMissingProperties(true); - return parser.loadAs(reader, KubeClientConfig.class); - } - - private static class YamlPropertyUtils extends PropertyUtils { - @Override - public Property getProperty(Class type, String name) throws IntrospectionException { - if (name.indexOf('-') > -1) { - name = BeanUtils.toCamelCase(name, "-"); - } - return super.getProperty(type, name); - } - } + public IKubeClientConfig loadKubeClientConfig(Reader reader) { + Representer representer = new Representer(); + Yaml parser = new Yaml(new KubeClientConfigConstructor(new YamlPropertyUtils()), representer); + representer.getPropertyUtils().setSkipMissingProperties(true); + return parser.loadAs(reader, KubeClientConfig.class); + } + + private static class YamlPropertyUtils extends PropertyUtils { + @Override + public Property getProperty(Class type, String name) throws IntrospectionException { + if (name.indexOf('-') > -1) { + name = BeanUtils.toCamelCase(name, "-"); + } + return super.getProperty(type, name); + } + } } diff --git a/src/main/java/com/openshift/restclient/model/oauth/IOAuthAccessToken.java b/src/main/java/com/openshift/restclient/model/oauth/IOAuthAccessToken.java index a099884e..a3f5de79 100644 --- a/src/main/java/com/openshift/restclient/model/oauth/IOAuthAccessToken.java +++ b/src/main/java/com/openshift/restclient/model/oauth/IOAuthAccessToken.java @@ -8,13 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.oauth; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IOAuthAccessToken extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/oauth/IOAuthAuthorizeToken.java b/src/main/java/com/openshift/restclient/model/oauth/IOAuthAuthorizeToken.java index 79a5d339..b9407a8f 100644 --- a/src/main/java/com/openshift/restclient/model/oauth/IOAuthAuthorizeToken.java +++ b/src/main/java/com/openshift/restclient/model/oauth/IOAuthAuthorizeToken.java @@ -8,13 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.oauth; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IOAuthAuthorizeToken extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/oauth/IOAuthClient.java b/src/main/java/com/openshift/restclient/model/oauth/IOAuthClient.java index 8877943e..79ee17ea 100644 --- a/src/main/java/com/openshift/restclient/model/oauth/IOAuthClient.java +++ b/src/main/java/com/openshift/restclient/model/oauth/IOAuthClient.java @@ -8,13 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.oauth; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IOAuthClient extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/oauth/IOAuthClientAuthorization.java b/src/main/java/com/openshift/restclient/model/oauth/IOAuthClientAuthorization.java index 1952b4ec..ae457e18 100644 --- a/src/main/java/com/openshift/restclient/model/oauth/IOAuthClientAuthorization.java +++ b/src/main/java/com/openshift/restclient/model/oauth/IOAuthClientAuthorization.java @@ -8,13 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.oauth; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IOAuthClientAuthorization extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/probe/IProbe.java b/src/main/java/com/openshift/restclient/model/probe/IProbe.java index 8e9633f1..a42473e6 100644 --- a/src/main/java/com/openshift/restclient/model/probe/IProbe.java +++ b/src/main/java/com/openshift/restclient/model/probe/IProbe.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.probe; /** @@ -15,18 +16,23 @@ */ public interface IProbe { - void setInitialDelaySeconds(int delay); - int getInitialDelaySeconds(); + void setInitialDelaySeconds(int delay); + + int getInitialDelaySeconds(); + + void setPeriodSeconds(int period); + + int getPeriodSeconds(); + + void setSuccessThreshold(int threshold); + + int getSuccessThreshold(); - void setPeriodSeconds(int period); - int getPeriodSeconds(); + void setFailureThreshold(int failureThreshold); - void setSuccessThreshold(int threshold); - int getSuccessThreshold(); + int getFailureThreshold(); - void setFailureThreshold(int failureThreshold); - int getFailureThreshold(); + void setTimeoutSeconds(int timeout); - void setTimeoutSeconds(int timeout); - int getTimeoutSeconds(); + int getTimeoutSeconds(); } diff --git a/src/main/java/com/openshift/restclient/model/project/IProjectRequest.java b/src/main/java/com/openshift/restclient/model/project/IProjectRequest.java index 68bae29e..0dc794ee 100644 --- a/src/main/java/com/openshift/restclient/model/project/IProjectRequest.java +++ b/src/main/java/com/openshift/restclient/model/project/IProjectRequest.java @@ -8,21 +8,19 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.project; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IProjectRequest extends IResource { - - void setDisplayName(String name); - - String getDisplayName(); - - void setDescription(String name); - - String getDescription(); + + void setDisplayName(String name); + + String getDisplayName(); + + void setDescription(String name); + + String getDescription(); } diff --git a/src/main/java/com/openshift/restclient/model/route/IRoute.java b/src/main/java/com/openshift/restclient/model/route/IRoute.java index d4498a88..34d499c6 100644 --- a/src/main/java/com/openshift/restclient/model/route/IRoute.java +++ b/src/main/java/com/openshift/restclient/model/route/IRoute.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.route; import com.openshift.restclient.model.IResource; @@ -13,92 +14,88 @@ /** * OpenShift route to Service * - * @author Jeff Cantrill */ public interface IRoute extends IResource { - /** - * Retrieves the externally available hostname that can be used to access - * service. - * - * @return Route hostname. - */ - String getHost(); + /** + * Retrieves the externally available hostname that can be used to access + * service. + * + * @return Route hostname. + */ + String getHost(); - /** - * Sets the externally available hostname that can be used to access - * service. - * - * @param host - * hostname to use - */ - void setHost(String host); + /** + * Sets the externally available hostname that can be used to access service. + * + * @param host + * hostname to use + */ + void setHost(String host); - /** - * Retrieves the path that the router watches for, to route traffic for to - * the service. - * - * @return Route path. - */ - String getPath(); + /** + * Retrieves the path that the router watches for, to route traffic for to the + * service. + * + * @return Route path. + */ + String getPath(); - /** - * Sets the path that the router watches for, to route traffic for to the - * service. - * - * @param path - * route path - */ - void setPath(String path); + /** + * Sets the path that the router watches for, to route traffic for to the + * service. + * + * @param path + * route path + */ + void setPath(String path); - /** - * Retrieves the name of the service this route leads to. - * - * @return Name of the service for this route. - */ - String getServiceName(); + /** + * Retrieves the name of the service this route leads to. + * + * @return Name of the service for this route. + */ + String getServiceName(); - /** - * Sets the name of the service this route should lead to. - * - * @param serviceName - * Name of the service this route should lead to. - */ - void setServiceName(String serviceName); + /** + * Sets the name of the service this route should lead to. + * + * @param serviceName + * Name of the service this route should lead to. + */ + void setServiceName(String serviceName); + + /** + * Retrieves the TLS configuration of this route. + * + * @return TLS configuration or null if there is not one + */ + ITLSConfig getTLSConfig(); + + /** + * Create a tls config if one is not defined or return the existing one + * + */ + ITLSConfig createTLSConfig(); + + /** + * Return a URL representation of this route. Assumes the protocol is https if + * the route includes TLS Config + * + * @return java.lang.String The route url + */ + String getURL(); - /** - * Retrieves the TLS configuration of this route. - * - * @return TLS configuration or null if there is not one - */ - ITLSConfig getTLSConfig(); - - /** - * Create a tls config if one is not defined or return - * the existing one - * @return - */ - ITLSConfig createTLSConfig(); - - - /** - * Return a URL representation of this route. Assumes - * the protocol is https if the route includes TLS Config - * @return java.lang.String The route url - */ - String getURL(); - /** * Retrieves the target port of this route. * * @return target port or null if there is not one */ ITargetPort getPort(); - + /** - * Create a target port if one is not defined or return - * the existing one - * @return + * Create a target port if one is not defined or return the existing one + * */ ITargetPort createPort(); } diff --git a/src/main/java/com/openshift/restclient/model/route/ITLSConfig.java b/src/main/java/com/openshift/restclient/model/route/ITLSConfig.java index 5e54e144..e99f31f8 100644 --- a/src/main/java/com/openshift/restclient/model/route/ITLSConfig.java +++ b/src/main/java/com/openshift/restclient/model/route/ITLSConfig.java @@ -6,111 +6,110 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.route; /** * TLS configuration for routes. * - * @author Jeff Cantrill */ public interface ITLSConfig { - - /** - * Returns the termination type. If termination type is not set, - * any termination config will be ignored. - * - * @return Termination type. - */ - String getTerminationType(); - /** - * Sets the termination type to this config. - * Termination indicates termination type. If termination type is not set, - * any termination config will be ignored. - * - * @param type - * termination type - */ - void setTerminationType(String type); + /** + * Returns the termination type. If termination type is not set, any termination + * config will be ignored. + * + * @return Termination type. + */ + String getTerminationType(); + + /** + * Sets the termination type to this config. Termination indicates termination + * type. If termination type is not set, any termination config will be ignored. + * + * @param type + * termination type + */ + void setTerminationType(String type); - /** - * Retrieves the certificate contents. - * - * @return Certificate contents. - */ - String getCertificate(); + /** + * Retrieves the certificate contents. + * + * @return Certificate contents. + */ + String getCertificate(); - /** - * Sets the certificate contents. - * - * @param certificate - * certificate contents - */ - void setCertificate(String certificate); + /** + * Sets the certificate contents. + * + * @param certificate + * certificate contents + */ + void setCertificate(String certificate); - /** - * Retrieves the key file contents. - * - * @return Key file contents. - */ - String getKey(); + /** + * Retrieves the key file contents. + * + * @return Key file contents. + */ + String getKey(); - /** - * Sets the key file contents. - * - * @param key - * key file contents - */ - void setKey(String key); + /** + * Sets the key file contents. + * + * @param key + * key file contents + */ + void setKey(String key); - /** - * Retrieves the certification authority certificate contents. - * - * @return CA certificate contents. - */ - String getCACertificate(); + /** + * Retrieves the certification authority certificate contents. + * + * @return CA certificate contents. + */ + String getCACertificate(); - /** - * Sets the certification authority certificate contents. - * - * @param caCertificate - * CA certificate contents - */ - void setCACertificate(String caCertificate); + /** + * Sets the certification authority certificate contents. + * + * @param caCertificate + * CA certificate contents + */ + void setCACertificate(String caCertificate); - /** - * DestinationCACertificate provides the contents of the CA certificate of - * the final destination. When using reencrypt termination this file should - * be provided in order to have routers use it for health checks on the - * secure connection. - * - * @return Contents of CA certificate of the final destination. - */ - String getDestinationCertificate(); + /** + * DestinationCACertificate provides the contents of the CA certificate of the + * final destination. When using reencrypt termination this file should be + * provided in order to have routers use it for health checks on the secure + * connection. + * + * @return Contents of CA certificate of the final destination. + */ + String getDestinationCertificate(); - /** - * DestinationCACertificate provides the contents of the CA certificate of - * the final destination. When using reencrypt termination this file should - * be provided in order to have routers use it for health checks on the - * secure connection. - * - * @param destinationCertificate - * contents of CA certificate of the final destination - */ - void setDestinationCertificate(String destinationCertificate); + /** + * DestinationCACertificate provides the contents of the CA certificate of the + * final destination. When using reencrypt termination this file should be + * provided in order to have routers use it for health checks on the secure + * connection. + * + * @param destinationCertificate + * contents of CA certificate of the final destination + */ + void setDestinationCertificate(String destinationCertificate); - /** - * Retrieves InsecureEdgeTerminationPolicy - * - * @return InsecureEdgeTerminationPolicy - */ - String getInsecureEdgeTerminationPolicy(); + /** + * Retrieves InsecureEdgeTerminationPolicy + * + * @return InsecureEdgeTerminationPolicy + */ + String getInsecureEdgeTerminationPolicy(); - /** - * Sets insecureEdgeTerminationPolicy - * - * @param insecureEdgeTerminationPolicy - * insecureEdgeTerminationPolicy - */ - void setInsecureEdgeTerminationPolicy(String insecureEdgeTerminationPolicy); + /** + * Sets insecureEdgeTerminationPolicy + * + * @param insecureEdgeTerminationPolicy + * insecureEdgeTerminationPolicy + */ + void setInsecureEdgeTerminationPolicy(String insecureEdgeTerminationPolicy); } diff --git a/src/main/java/com/openshift/restclient/model/route/ITargetPort.java b/src/main/java/com/openshift/restclient/model/route/ITargetPort.java index 4b086322..7b625a92 100644 --- a/src/main/java/com/openshift/restclient/model/route/ITargetPort.java +++ b/src/main/java/com/openshift/restclient/model/route/ITargetPort.java @@ -6,30 +6,33 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.route; /** - * Target port for routes. If both attributes are present, then name is preferred. + * Target port for routes. If both attributes are present, then name is + * preferred. * * @author Jeff Maury */ public interface ITargetPort { - - /** - * Returns the target port name. - * - * @return target port name. - */ - String getTargetPortName(); - /** - * Sets the target port name. - * - * @param portName target port name - */ - void setTargetPortName(String portName); + /** + * Returns the target port name. + * + * @return target port name. + */ + String getTargetPortName(); - /** + /** + * Sets the target port name. + * + * @param portName + * target port name + */ + void setTargetPortName(String portName); + + /** * Returns the target port value. * * @return target port value. @@ -39,7 +42,8 @@ public interface ITargetPort { /** * Sets the target port value. * - * @param portName target port value + * @param portName + * target port value */ void setTargetPort(Integer port); } diff --git a/src/main/java/com/openshift/restclient/model/route/TLSTerminationType.java b/src/main/java/com/openshift/restclient/model/route/TLSTerminationType.java index fa089392..fd83f555 100644 --- a/src/main/java/com/openshift/restclient/model/route/TLSTerminationType.java +++ b/src/main/java/com/openshift/restclient/model/route/TLSTerminationType.java @@ -8,15 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.route; -/** - * - * @author Jeff Cantrill - * - */ public interface TLSTerminationType { - static final String EDGE = "edge"; - static final String PASSTHROUGH = "passthrough"; - static final String REENCRYPT = "reencrypt"; + static final String EDGE = "edge"; + static final String PASSTHROUGH = "passthrough"; + static final String REENCRYPT = "reencrypt"; } \ No newline at end of file diff --git a/src/main/java/com/openshift/restclient/model/secret/ISecret.java b/src/main/java/com/openshift/restclient/model/secret/ISecret.java index 4f8331dc..93bf457f 100644 --- a/src/main/java/com/openshift/restclient/model/secret/ISecret.java +++ b/src/main/java/com/openshift/restclient/model/secret/ISecret.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.secret; import java.io.InputStream; @@ -13,42 +14,44 @@ import com.openshift.restclient.model.IResource; /** - * Kubernetes Secret object to inject/mount sensitive data into containers + * Kubernetes Secret object to inject/mount sensitive data into containers * * @author Jiri Pechanec */ public interface ISecret extends IResource { - /** - * Sets the container port exposed by the image - * @param key - the name under which the data are mount in container - * @param data - */ - void addData(String key, InputStream data); - - /** - * Sets the container port exposed by the image - * @param key - the name under which the data are mount in container - * @param data - */ - void addData(String key, byte[] data); - - /** - * Get the data stored under the key - * @param key - * @return byte representation of the stored data - */ - byte[] getData(String key); - - /** - * Sets the type of Secrete - default Opaque - * @param type - */ - void setType(String type); - - /** - * Returns the type of Secrete - default Opaque - * return - */ - String getType(); + /** + * Sets the container port exposed by the image + * + * @param key + * - the name under which the data are mount in container + */ + void addData(String key, InputStream data); + + /** + * Sets the container port exposed by the image + * + * @param key + * - the name under which the data are mount in container + */ + void addData(String key, byte[] data); + + /** + * Get the data stored under the key + * + * @param key + * @return byte representation of the stored data + */ + byte[] getData(String key); + + /** + * Sets the type of Secrete - default Opaque + * + */ + void setType(String type); + + /** + * Returns the type of Secrete - default Opaque return + */ + String getType(); } diff --git a/src/main/java/com/openshift/restclient/model/serviceaccount/IServiceAccount.java b/src/main/java/com/openshift/restclient/model/serviceaccount/IServiceAccount.java index e1358717..69a18088 100644 --- a/src/main/java/com/openshift/restclient/model/serviceaccount/IServiceAccount.java +++ b/src/main/java/com/openshift/restclient/model/serviceaccount/IServiceAccount.java @@ -1,36 +1,40 @@ package com.openshift.restclient.model.serviceaccount; -import com.openshift.restclient.model.IResource; - import java.util.Collection; +import com.openshift.restclient.model.IResource; + /** * @author David Simansky | dsimansk@redhat.com */ public interface IServiceAccount extends IResource { - /** - * Get the collection of all secrets - * @return - */ - Collection getSecrets(); - - /** - * Add new secret name - * @param secret - secret name - */ - void addSecret(String secret); - - /** - * Get the collection of all imagePullSecrets - * @return - */ - Collection getImagePullSecrets(); - - /** - * Add new imagePullSecret name - * @param imagePullSecret - imagePullSecretName - */ - void addImagePullSecret(String imagePullSecret); + /** + * Get the collection of all secrets + * + */ + Collection getSecrets(); + + /** + * Add new secret name + * + * @param secret + * - secret name + */ + void addSecret(String secret); + + /** + * Get the collection of all imagePullSecrets + * + */ + Collection getImagePullSecrets(); + + /** + * Add new imagePullSecret name + * + * @param imagePullSecret + * - imagePullSecretName + */ + void addImagePullSecret(String imagePullSecret); } diff --git a/src/main/java/com/openshift/restclient/model/template/IParameter.java b/src/main/java/com/openshift/restclient/model/template/IParameter.java index b7055c02..5bedaac3 100644 --- a/src/main/java/com/openshift/restclient/model/template/IParameter.java +++ b/src/main/java/com/openshift/restclient/model/template/IParameter.java @@ -6,59 +6,57 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.template; /** * A parameter for a template * - * @author Jeff Cantrill */ public interface IParameter extends Cloneable { - - /** - * Returns the name of the parameter that is substituted - * in the template - * @return - */ - String getName(); - - /** - * Returns the description - * @return - */ - String getDescription(); - - /** - * Returns the value to use - * @return - */ - String getValue(); - - /** - * Sets the value to use - * @param value - */ - void setValue(String value); - - /** - * Returns the generator name which will use the value - * from 'getFrom' if set - * @return - */ - String getGeneratorName(); - - /** - * Returns the input to the generator - * @return - */ - String getFrom(); - - /** - * Returns true if parameter is required; false otherwise - * @return - */ - boolean isRequired(); - - IParameter clone(); - + + /** + * Returns the name of the parameter that is substituted in the template + * + */ + String getName(); + + /** + * Returns the description + * + */ + String getDescription(); + + /** + * Returns the value to use + * + */ + String getValue(); + + /** + * Sets the value to use + * + */ + void setValue(String value); + + /** + * Returns the generator name which will use the value from 'getFrom' if set + * + */ + String getGeneratorName(); + + /** + * Returns the input to the generator + * + */ + String getFrom(); + + /** + * Returns true if parameter is required; false otherwise + * + */ + boolean isRequired(); + + IParameter clone(); + } diff --git a/src/main/java/com/openshift/restclient/model/template/ITemplate.java b/src/main/java/com/openshift/restclient/model/template/ITemplate.java index 9fcb472b..e0537f4b 100644 --- a/src/main/java/com/openshift/restclient/model/template/ITemplate.java +++ b/src/main/java/com/openshift/restclient/model/template/ITemplate.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.model.template; import java.util.Collection; @@ -16,63 +17,53 @@ /** * Representation of a set of pre-configured parameterized set of resources * - * @author Jeff Cantrill */ public interface ITemplate extends IResource { - - /** - * Retrieves the list of resources this template - * creates - * @return - */ - Collection getObjects(); - - /** - * Returns a map of parameter names to parameters. - * @return - */ - Map getParameters(); - - /** - * Update the template's parameter values, with the values from the - * collection if a parameter with the same name is found - * - * @param parameters - */ - void updateParameterValues(Collection parameters); - - - /** - * Update a parameter if it exists - * @param key - * @param value - */ - void updateParameter(String key, String value); - - /** - * Retrieves the labels that are applied to the objects of the - * template when it is processed. - * - * @return Unmodifiable map of the item labels - */ - Map getObjectLabels(); - - /** - * Add or update a label that is applied to the objects of the - * template when it is processed - * - * @param key - * @param value - */ - void addObjectLabel(String key, String value); - /** - * Returns true if the given resource contains the given text - * in name or tags. - * - * @param filterText - * @param template - * @return - */ - public boolean isMatching(final String filterText); + /** + * Retrieves the list of resources this template creates + * + */ + Collection getObjects(); + + /** + * Returns a map of parameter names to parameters. + * + */ + Map getParameters(); + + /** + * Update the template's parameter values, with the values from the collection + * if a parameter with the same name is found + * + */ + void updateParameterValues(Collection parameters); + + /** + * Update a parameter if it exists + * + */ + void updateParameter(String key, String value); + + /** + * Retrieves the labels that are applied to the objects of the template when it + * is processed. + * + * @return Unmodifiable map of the item labels + */ + Map getObjectLabels(); + + /** + * Add or update a label that is applied to the objects of the template when it + * is processed + * + */ + void addObjectLabel(String key, String value); + + /** + * Returns true if the given resource contains the given text in + * name or tags. + * + */ + public boolean isMatching(final String filterText); } diff --git a/src/main/java/com/openshift/restclient/model/user/IUser.java b/src/main/java/com/openshift/restclient/model/user/IUser.java index 48bd0d2e..bd5d3711 100644 --- a/src/main/java/com/openshift/restclient/model/user/IUser.java +++ b/src/main/java/com/openshift/restclient/model/user/IUser.java @@ -8,24 +8,22 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.user; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ public interface IUser extends IResource { - /** - * The full name of this user - * @return - */ - String getFullName(); + /** + * The full name of this user + * + */ + String getFullName(); - /** - * Returns the user uid as specified in the metadata - * @return - */ - String getUID(); + /** + * Returns the user uid as specified in the metadata + * + */ + String getUID(); } diff --git a/src/main/java/com/openshift/restclient/model/volume/IEmptyDirVolumeSource.java b/src/main/java/com/openshift/restclient/model/volume/IEmptyDirVolumeSource.java index 3e747e63..7b13429e 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IEmptyDirVolumeSource.java +++ b/src/main/java/com/openshift/restclient/model/volume/IEmptyDirVolumeSource.java @@ -5,5 +5,6 @@ */ public interface IEmptyDirVolumeSource extends IVolumeSource { String getMedium(); + void setMedium(String medium); } diff --git a/src/main/java/com/openshift/restclient/model/volume/IHostPathVolumeSource.java b/src/main/java/com/openshift/restclient/model/volume/IHostPathVolumeSource.java index de363915..142a5125 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IHostPathVolumeSource.java +++ b/src/main/java/com/openshift/restclient/model/volume/IHostPathVolumeSource.java @@ -8,20 +8,21 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume; /** * VolumeSource for hostpath volumes of a pod - * @author jeff.cantrill + * * */ public interface IHostPathVolumeSource extends IVolumeSource { - /** - * Host path mapped into a pod - * @return - */ - String getPath(); - - void setPath(String path); + /** + * Host path mapped into a pod + * + */ + String getPath(); + + void setPath(String path); } diff --git a/src/main/java/com/openshift/restclient/model/volume/IPersistentVolume.java b/src/main/java/com/openshift/restclient/model/volume/IPersistentVolume.java index 1e56661d..2cc4c440 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IPersistentVolume.java +++ b/src/main/java/com/openshift/restclient/model/volume/IPersistentVolume.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume; import java.util.Set; @@ -17,77 +18,90 @@ import com.openshift.restclient.model.volume.property.IPersistentVolumeProperties; import com.openshift.restclient.utils.MemoryUnit; - public interface IPersistentVolume extends IResource { - /** - * @param unit the designated unit. One of "Ki", "Mi", "Gi", "Ti", "Pi", "Ei". - * @return 0, if conversion not possible. Otherwise the capacity in given units. - * @see {@link PersistentVolume#convert(String, MemoryUnit)} - * @throws IllegalArgumentException if not supported {@code unit} given. - */ - long getCapacity(String unit); - - /** - * @param unit the designated unit. One of {@link MemoryUnit}'s Ki, Mi, Gi, Ti, Pi, Ei. - * @return 0, if conversion not possible. Otherwise the capacity in given units. - * @see {@link PersistentVolume#convert(String, MemoryUnit)} - * @throws IllegalArgumentException if not supported {@code unit} given. - */ - long getCapacity(MemoryUnit unit); - - /** - * @return the capacity in bytes. - */ - long getCapacity(); - - /** - * @return the unit in which the capacity is represent. - * @see {@link MemoryUnit} - */ - MemoryUnit getCapacityUnit(); - - /** - * Sets the capacity. There is no conversion between units. - * @param capacity the capacity - * @param unit the unit - */ - void setCapacity(long capacity, MemoryUnit unit); - - /** - * @return access modes - * @see {@link com.openshift.restclient.model.volume.PVCAccessModes} - * @see - */ - Set getAccessModes(); - - /** - * Sets the access modes. - * If there are any modes present, they are overridden by the {@code modes} parameter. - * @param modes the access modes - */ - void setAccessModes(String... modes); - - /** - * @return the value of 'spec.persistentVolumeReclaimPolicy' - */ - String getReclaimPolicy(); - - /** - * Sets the 'spec.persistentVolumeReclaimPolicy' value - * @param policy the policy string - */ - void setReclaimPolicy(String policy); - - /** - * @return specific persistent volume type properties - */ - IPersistentVolumeProperties getPersistentVolumeProperties(); - - /** - * Sets the volume type properties. - * @param properties the properties - */ - void setPersistentVolumeProperties(IPersistentVolumeProperties properties); + /** + * @param unit + * the designated unit. One of "Ki", "Mi", "Gi", "Ti", "Pi", "Ei". + * @return 0, if conversion not possible. Otherwise the capacity in given units. + * @see {@link PersistentVolume#convert(String, MemoryUnit)} + * @throws IllegalArgumentException + * if not supported {@code unit} given. + */ + long getCapacity(String unit); + + /** + * @param unit + * the designated unit. One of {@link MemoryUnit}'s Ki, Mi, Gi, Ti, + * Pi, Ei. + * @return 0, if conversion not possible. Otherwise the capacity in given units. + * @see {@link PersistentVolume#convert(String, MemoryUnit)} + * @throws IllegalArgumentException + * if not supported {@code unit} given. + */ + long getCapacity(MemoryUnit unit); + + /** + * @return the capacity in bytes. + */ + long getCapacity(); + + /** + * @return the unit in which the capacity is represent. + * @see {@link MemoryUnit} + */ + MemoryUnit getCapacityUnit(); + + /** + * Sets the capacity. There is no conversion between units. + * + * @param capacity + * the capacity + * @param unit + * the unit + */ + void setCapacity(long capacity, MemoryUnit unit); + + /** + * @return access modes + * @see {@link com.openshift.restclient.model.volume.PVCAccessModes} + * @see + */ + Set getAccessModes(); + + /** + * Sets the access modes. If there are any modes present, they are overridden by + * the {@code modes} parameter. + * + * @param modes + * the access modes + */ + void setAccessModes(String... modes); + + /** + * @return the value of 'spec.persistentVolumeReclaimPolicy' + */ + String getReclaimPolicy(); + + /** + * Sets the 'spec.persistentVolumeReclaimPolicy' value + * + * @param policy + * the policy string + */ + void setReclaimPolicy(String policy); + + /** + * @return specific persistent volume type properties + */ + IPersistentVolumeProperties getPersistentVolumeProperties(); + + /** + * Sets the volume type properties. + * + * @param properties + * the properties + */ + void setPersistentVolumeProperties(IPersistentVolumeProperties properties); } diff --git a/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaim.java b/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaim.java index e16c8c5d..82749c36 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaim.java +++ b/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaim.java @@ -8,53 +8,51 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume; import java.util.Set; import com.openshift.restclient.model.IResource; -/** - * - * @author Jeff Cantrill - * - */ public interface IPersistentVolumeClaim extends IResource { - /** - * - * @return the {@link PVCAccessModes} - */ - Set getAccessModes(); + /** + * + * @return the {@link PVCAccessModes} + */ + Set getAccessModes(); + + /** + * Set the access modes for this claim. + * + * @param accessModes + * The access modes to set + */ + void setAccessModes(Set accessModes); + + /** + * The requested storage + * + */ + String getRequestedStorage(); - /** - * Set the access modes for this claim. - * - * @param accessModes The access modes to set + /** + * Set the requested storage of the claim + * + * @param requestedStorage + * The requested storage capacity */ - void setAccessModes(Set accessModes); - - /** - * The requested storage - * @return - */ - String getRequestedStorage(); - - /** - * Set the requested storage of the claim - * - * @param requestedStorage The requested storage capacity + void setRequestedStorage(String requestedStorage); + + /** + * The status of the claim + * + */ + String getStatus(); + + /** + * The volume name */ - void setRequestedStorage(String requestedStorage); - - /** - * The status of the claim - * @return - */ - String getStatus(); - - /** - * The volume name - */ - String getVolumeName(); + String getVolumeName(); } diff --git a/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaimVolumeSource.java b/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaimVolumeSource.java index 08c5f159..37ff5bb9 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaimVolumeSource.java +++ b/src/main/java/com/openshift/restclient/model/volume/IPersistentVolumeClaimVolumeSource.java @@ -5,7 +5,10 @@ */ public interface IPersistentVolumeClaimVolumeSource extends IVolumeSource { String getClaimName(); + void setClaimName(String claimName); + boolean isReadOnly(); + void setReadOnly(boolean readOnly); } diff --git a/src/main/java/com/openshift/restclient/model/volume/ISecretVolumeSource.java b/src/main/java/com/openshift/restclient/model/volume/ISecretVolumeSource.java index c50e8692..4be2cf4c 100644 --- a/src/main/java/com/openshift/restclient/model/volume/ISecretVolumeSource.java +++ b/src/main/java/com/openshift/restclient/model/volume/ISecretVolumeSource.java @@ -5,5 +5,6 @@ */ public interface ISecretVolumeSource extends IVolumeSource { String getSecretName(); + void setSecretName(String secretName); } diff --git a/src/main/java/com/openshift/restclient/model/volume/IVolume.java b/src/main/java/com/openshift/restclient/model/volume/IVolume.java index 54c886e0..45135713 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IVolume.java +++ b/src/main/java/com/openshift/restclient/model/volume/IVolume.java @@ -8,23 +8,26 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume; /** * - * @author Jeff Cantrill * @deprecated see {@link IVolumeMount} * */ @Deprecated public interface IVolume { - String getName(); - void setName(String name); - - void setMountPath(String path); - String getMountPath(); - - void setReadOnly(boolean readonly); - boolean isReadOnly(); + String getName(); + + void setName(String name); + + void setMountPath(String path); + + String getMountPath(); + + void setReadOnly(boolean readonly); + + boolean isReadOnly(); } diff --git a/src/main/java/com/openshift/restclient/model/volume/IVolumeMount.java b/src/main/java/com/openshift/restclient/model/volume/IVolumeMount.java index 168a971b..2c50ec9a 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IVolumeMount.java +++ b/src/main/java/com/openshift/restclient/model/volume/IVolumeMount.java @@ -8,22 +8,24 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume; /** - * The volumes that are mounted - * in a container - * @author jeff.cantrill + * The volumes that are mounted in a container * */ public interface IVolumeMount { - String getName(); - void setName(String name); - - void setMountPath(String path); - String getMountPath(); - - void setReadOnly(boolean readonly); - boolean isReadOnly(); + String getName(); + + void setName(String name); + + void setMountPath(String path); + + String getMountPath(); + + void setReadOnly(boolean readonly); + + boolean isReadOnly(); } diff --git a/src/main/java/com/openshift/restclient/model/volume/IVolumeSource.java b/src/main/java/com/openshift/restclient/model/volume/IVolumeSource.java index 94e60c17..d3211553 100644 --- a/src/main/java/com/openshift/restclient/model/volume/IVolumeSource.java +++ b/src/main/java/com/openshift/restclient/model/volume/IVolumeSource.java @@ -8,17 +8,17 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume; /** * Persisent storage found on a pod - * @author jeff.cantrill * */ public interface IVolumeSource { - String getName(); + String getName(); - void setName(String name); + void setName(String name); - String toJSONString(); + String toJSONString(); } diff --git a/src/main/java/com/openshift/restclient/model/volume/PVCAccessModes.java b/src/main/java/com/openshift/restclient/model/volume/PVCAccessModes.java index 67da5a80..7f2cff28 100644 --- a/src/main/java/com/openshift/restclient/model/volume/PVCAccessModes.java +++ b/src/main/java/com/openshift/restclient/model/volume/PVCAccessModes.java @@ -8,12 +8,13 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume; public interface PVCAccessModes { - static final String READ_WRITE_ONCE = "ReadWriteOnce"; - static final String READ_ONLY_MANY = "ReadOnlyMany"; - static final String READ_WRITE_MANY = "ReadWriteMany"; + static final String READ_WRITE_ONCE = "ReadWriteOnce"; + static final String READ_ONLY_MANY = "ReadOnlyMany"; + static final String READ_WRITE_MANY = "ReadWriteMany"; } diff --git a/src/main/java/com/openshift/restclient/model/volume/VolumeType.java b/src/main/java/com/openshift/restclient/model/volume/VolumeType.java index 07b65532..6a9e4d39 100644 --- a/src/main/java/com/openshift/restclient/model/volume/VolumeType.java +++ b/src/main/java/com/openshift/restclient/model/volume/VolumeType.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume; import java.util.Arrays; @@ -15,33 +16,28 @@ /** * - * @author Jeff Cantrill * - * @see Persistent volume types + * @see Persistent + * volume types * */ public interface VolumeType { - static final String EMPTY_DIR = "emptyDir"; - static final String HOST_PATH = "hostPath"; - static final String NFS = "nfs"; - static final String GCE_PERSISTENT_DISK = "gcePersistentDisk"; - static final String AWS_ELASTIC_BLOCK_STORAGE = "awsElasticBlockStore"; - static final String GLUSTERFS = "glusterfs"; - static final String ISCSI = "iscsi"; - static final String RBD = "rbd"; - static final String SECRET = "secret"; - static final String PERSISTENT_VOLUME_CLAIM = "persistentVolumeClaim"; + static final String EMPTY_DIR = "emptyDir"; + static final String HOST_PATH = "hostPath"; + static final String NFS = "nfs"; + static final String GCE_PERSISTENT_DISK = "gcePersistentDisk"; + static final String AWS_ELASTIC_BLOCK_STORAGE = "awsElasticBlockStore"; + static final String GLUSTERFS = "glusterfs"; + static final String ISCSI = "iscsi"; + static final String RBD = "rbd"; + static final String SECRET = "secret"; + static final String PERSISTENT_VOLUME_CLAIM = "persistentVolumeClaim"; - static List getTypes() { - return Arrays.asList(EMPTY_DIR, - HOST_PATH, - NFS, - GCE_PERSISTENT_DISK, - AWS_ELASTIC_BLOCK_STORAGE, - GLUSTERFS, - ISCSI, - RBD); - } + static List getTypes() { + return Arrays.asList(EMPTY_DIR, HOST_PATH, NFS, GCE_PERSISTENT_DISK, AWS_ELASTIC_BLOCK_STORAGE, GLUSTERFS, + ISCSI, RBD); + } } diff --git a/src/main/java/com/openshift/restclient/model/volume/property/IHostPathVolumeProperties.java b/src/main/java/com/openshift/restclient/model/volume/property/IHostPathVolumeProperties.java index 8a04c3ea..b84d24d0 100644 --- a/src/main/java/com/openshift/restclient/model/volume/property/IHostPathVolumeProperties.java +++ b/src/main/java/com/openshift/restclient/model/volume/property/IHostPathVolumeProperties.java @@ -8,12 +8,13 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.restclient.model.volume.property; +package com.openshift.restclient.model.volume.property; public interface IHostPathVolumeProperties extends IPersistentVolumeProperties { - String getPath(); - void setPath(String path); + String getPath(); + + void setPath(String path); } diff --git a/src/main/java/com/openshift/restclient/model/volume/property/INfsVolumeProperties.java b/src/main/java/com/openshift/restclient/model/volume/property/INfsVolumeProperties.java index f7562aa6..b15fd7d6 100644 --- a/src/main/java/com/openshift/restclient/model/volume/property/INfsVolumeProperties.java +++ b/src/main/java/com/openshift/restclient/model/volume/property/INfsVolumeProperties.java @@ -8,17 +8,21 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.restclient.model.volume.property; +package com.openshift.restclient.model.volume.property; public interface INfsVolumeProperties extends IPersistentVolumeProperties { - String getPath(); - String getServer(); - boolean isReadOnly(); + String getPath(); + + String getServer(); + + boolean isReadOnly(); + + void setPath(String path); + + void setServer(String path); - void setPath(String path); - void setServer(String path); - void setReadOnly(boolean isReadOnly); + void setReadOnly(boolean isReadOnly); } diff --git a/src/main/java/com/openshift/restclient/model/volume/property/IPersistentVolumeProperties.java b/src/main/java/com/openshift/restclient/model/volume/property/IPersistentVolumeProperties.java index 1eec0603..dac42e21 100644 --- a/src/main/java/com/openshift/restclient/model/volume/property/IPersistentVolumeProperties.java +++ b/src/main/java/com/openshift/restclient/model/volume/property/IPersistentVolumeProperties.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model.volume.property; diff --git a/src/main/java/com/openshift/restclient/utils/Base64Coder.java b/src/main/java/com/openshift/restclient/utils/Base64Coder.java index efb62c25..d605b28f 100644 --- a/src/main/java/com/openshift/restclient/utils/Base64Coder.java +++ b/src/main/java/com/openshift/restclient/utils/Base64Coder.java @@ -8,9 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.utils; import javax.xml.bind.DatatypeConverter; + import org.apache.commons.lang.StringUtils; /** @@ -21,73 +23,70 @@ */ public class Base64Coder { - private Base64Coder() { - // inhibit instantiation - } + private Base64Coder() { + // inhibit instantiation + } - /** - * Encodes the given byte array to a base64 encoded String - * - * @param unencoded - * the array of unencoded bytes that shall get encoded - * @return the encoded string - */ - public static String encode(byte[] unencoded) { - if (unencoded == null) { - return null; - } else if (unencoded.length == 0) { - return new String(); - } - return DatatypeConverter.printBase64Binary(unencoded); - } + /** + * Encodes the given byte array to a base64 encoded String + * + * @param unencoded + * the array of unencoded bytes that shall get encoded + * @return the encoded string + */ + public static String encode(byte[] unencoded) { + if (unencoded == null) { + return null; + } else if (unencoded.length == 0) { + return new String(); + } + return DatatypeConverter.printBase64Binary(unencoded); + } - /** - * Encodes the given string to a base64 encoded string. Returns - * null if the given string is null. - * - * @param unencoded - * @return - */ - public static String encode(String unencoded) { - if (StringUtils.isEmpty(unencoded)) { - return unencoded; - } - return encode(unencoded.getBytes()); - } + /** + * Encodes the given string to a base64 encoded string. Returns + * null if the given string is null. + * + */ + public static String encode(String unencoded) { + if (StringUtils.isEmpty(unencoded)) { + return unencoded; + } + return encode(unencoded.getBytes()); + } - public static String decode(byte[] encoded) { - if (encoded == null - || encoded.length == 0) { - return new String(); - } - return decode(new String(encoded)); - } + public static String decode(byte[] encoded) { + if (encoded == null || encoded.length == 0) { + return new String(); + } + return decode(new String(encoded)); + } - /** - * Decodes the given base64 encoded string. Returns null if the - * given string is null. - * - * @param encoded - * the base64 encoded string - * @return the decoded string - */ - public static String decode(String encoded) { - byte[] encodedBytes = decodeBinary(encoded); - return (encodedBytes == null) ? encoded : new String(DatatypeConverter.parseBase64Binary(encoded)); - } + /** + * Decodes the given base64 encoded string. Returns null if the + * given string is null. + * + * @param encoded + * the base64 encoded string + * @return the decoded string + */ + public static String decode(String encoded) { + byte[] encodedBytes = decodeBinary(encoded); + return (encodedBytes == null) ? encoded : new String(DatatypeConverter.parseBase64Binary(encoded)); + } - /** - * Decodes the given base64 encoded string. Returns null if the - * given string is null. - * - * @param encoded - * the base64 encoded string - * @return the decoded binary data - */ - public static byte[] decodeBinary(String encoded) { - if (StringUtils.isEmpty(encoded)) { - return null; - } - return DatatypeConverter.parseBase64Binary(encoded); - } + /** + * Decodes the given base64 encoded string. Returns null if the + * given string is null. + * + * @param encoded + * the base64 encoded string + * @return the decoded binary data + */ + public static byte[] decodeBinary(String encoded) { + if (StringUtils.isEmpty(encoded)) { + return null; + } + return DatatypeConverter.parseBase64Binary(encoded); + } } diff --git a/src/main/java/com/openshift/restclient/utils/BeanUtils.java b/src/main/java/com/openshift/restclient/utils/BeanUtils.java index 08342725..af12579f 100644 --- a/src/main/java/com/openshift/restclient/utils/BeanUtils.java +++ b/src/main/java/com/openshift/restclient/utils/BeanUtils.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.utils; import java.util.List; @@ -18,18 +19,21 @@ public class BeanUtils { - private BeanUtils() { - } - - /** - * Convert a delimited string to camelcase (e.g. foo-bar -> fooBar) - * @param name the string to convert - * @param delimiter the delimiter to use - * @return the delimited string camelcased - */ - public static String toCamelCase(String name, String delimiter) { - String[] parts = name.split("-"); - List capitalized = Stream.of(parts).map(p->StringUtils.capitalize(p)).collect(Collectors.toList()); - return StringUtils.uncapitalize(StringUtils.join(capitalized, "")); - } + private BeanUtils() { + } + + /** + * Convert a delimited string to camelcase (e.g. foo-bar -> fooBar) + * + * @param name + * the string to convert + * @param delimiter + * the delimiter to use + * @return the delimited string camelcased + */ + public static String toCamelCase(String name, String delimiter) { + String[] parts = name.split("-"); + List capitalized = Stream.of(parts).map(p -> StringUtils.capitalize(p)).collect(Collectors.toList()); + return StringUtils.uncapitalize(StringUtils.join(capitalized, "")); + } } diff --git a/src/main/java/com/openshift/restclient/utils/EnvironmentVariableUtils.java b/src/main/java/com/openshift/restclient/utils/EnvironmentVariableUtils.java index 32ac5f31..80d17668 100644 --- a/src/main/java/com/openshift/restclient/utils/EnvironmentVariableUtils.java +++ b/src/main/java/com/openshift/restclient/utils/EnvironmentVariableUtils.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.utils; import java.util.Collection; @@ -15,24 +16,22 @@ import com.openshift.restclient.model.IEnvironmentVariable; - /** * @author Andre Dietisheim */ public class EnvironmentVariableUtils { - - private EnvironmentVariableUtils(){ - } - - public static Map toMapOfStrings(Collection envVars){ - if (envVars == null) { - return null; - } - if (envVars.isEmpty()) { - return Collections.emptyMap(); - } - return envVars.stream() - .collect(Collectors.toMap(envVar -> envVar.getName(), envVar -> envVar.getValue())); - } + private EnvironmentVariableUtils() { + } + + public static Map toMapOfStrings(Collection envVars) { + if (envVars == null) { + return null; + } + if (envVars.isEmpty()) { + return Collections.emptyMap(); + } + + return envVars.stream().collect(Collectors.toMap(envVar -> envVar.getName(), envVar -> envVar.getValue())); + } } diff --git a/src/main/java/com/openshift/restclient/utils/MemoryUnit.java b/src/main/java/com/openshift/restclient/utils/MemoryUnit.java index 0b520d00..fd6c0809 100644 --- a/src/main/java/com/openshift/restclient/utils/MemoryUnit.java +++ b/src/main/java/com/openshift/restclient/utils/MemoryUnit.java @@ -8,10 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.utils; public enum MemoryUnit { - Ki, Mi, Gi, Ti, Pi, Ei; + Ki, Mi, Gi, Ti, Pi, Ei; } diff --git a/src/main/java/com/openshift/restclient/utils/SSLUtils.java b/src/main/java/com/openshift/restclient/utils/SSLUtils.java index d9c88c48..247f11ee 100644 --- a/src/main/java/com/openshift/restclient/utils/SSLUtils.java +++ b/src/main/java/com/openshift/restclient/utils/SSLUtils.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.utils; import java.security.AlgorithmParameterGenerator; @@ -25,71 +26,69 @@ */ public class SSLUtils { - private static final String SSL_CONTEXT_NAME = "SSL"; - public static final String CIPHER_DHE_REGEX = ".*_DHE_.*"; - private static final String CIPHER_DHE_NAME = "DiffieHellman"; - private static final int CIPHER_DHE_MINSIZE = 512; - private static final int CIPHER_DHE_MAXSIZE = 16384; - private static final int CIPHER_DHE_MODULO = 64; + private static final String SSL_CONTEXT_NAME = "SSL"; + public static final String CIPHER_DHE_REGEX = ".*_DHE_.*"; + private static final String CIPHER_DHE_NAME = "DiffieHellman"; + private static final int CIPHER_DHE_MINSIZE = 512; + private static final int CIPHER_DHE_MAXSIZE = 16384; + private static final int CIPHER_DHE_MODULO = 64; - private SSLUtils() { - // inhibit instantiation - } + private SSLUtils() { + // inhibit instantiation + } - /** - * Returns true if the jdk supports DEH cipher keys in the - * given length. - * inspired by http://stackoverflow.com/a/18254095/231357 - * - * @param length - * @return - * - */ - public static boolean supportsDHECipherKeysOf(int length) { - try { - return isMaxKeysize(length, CIPHER_DHE_MINSIZE, CIPHER_DHE_MAXSIZE, CIPHER_DHE_MODULO, - AlgorithmParameterGenerator.getInstance(CIPHER_DHE_NAME)); - } catch (NoSuchAlgorithmException e1) { - return false; - } - } + /** + * Returns true if the jdk supports DEH cipher keys in the given + * length. inspired by http://stackoverflow.com/a/18254095/231357 + * + * @return + * + */ + public static boolean supportsDHECipherKeysOf(int length) { + try { + return isMaxKeysize(length, CIPHER_DHE_MINSIZE, CIPHER_DHE_MAXSIZE, CIPHER_DHE_MODULO, + AlgorithmParameterGenerator.getInstance(CIPHER_DHE_NAME)); + } catch (NoSuchAlgorithmException e1) { + return false; + } + } - private static boolean isMaxKeysize(int length, int minSize, int maxSize, int modulo, - AlgorithmParameterGenerator algorithmParamGen) { - int maxLength = 0; - for (int i = minSize; i <= maxSize; i += modulo) { - try { - algorithmParamGen.init(i); - } catch (InvalidParameterException e) { - break; - } - maxLength = i; - } - return maxLength >= length; - } + private static boolean isMaxKeysize(int length, int minSize, int maxSize, int modulo, + AlgorithmParameterGenerator algorithmParamGen) { + int maxLength = 0; + for (int i = minSize; i <= maxSize; i += modulo) { + try { + algorithmParamGen.init(i); + } catch (InvalidParameterException e) { + break; + } + maxLength = i; + } + return maxLength >= length; + } - public static final String[] filterCiphers(String excludedCipherRegex, String[] ciphers) { - if (excludedCipherRegex == null - || ciphers == null) { - return ciphers; - } + public static final String[] filterCiphers(String excludedCipherRegex, String[] ciphers) { + if (excludedCipherRegex == null || ciphers == null) { + return ciphers; + } - List filteredCiphers = new ArrayList(); - for (String cipher : ciphers) { - if (!cipher.matches(excludedCipherRegex)) { - filteredCiphers.add(cipher); - } - } - return filteredCiphers.toArray(new String[filteredCiphers.size()]); - } + List filteredCiphers = new ArrayList(); + for (String cipher : ciphers) { + if (!cipher.matches(excludedCipherRegex)) { + filteredCiphers.add(cipher); + } + } + return filteredCiphers.toArray(new String[filteredCiphers.size()]); + } - public static SSLContext getSSLContext(TrustManager trustManager) throws NoSuchAlgorithmException, KeyManagementException { - TrustManager[] trustManagers = null; - if (trustManager != null) { - trustManagers = new TrustManager[] { trustManager }; - } - SSLContext sslContext = SSLContext.getInstance(SSL_CONTEXT_NAME); - sslContext.init(null, trustManagers, null); - return sslContext; - } + public static SSLContext getSSLContext(TrustManager trustManager) + throws NoSuchAlgorithmException, KeyManagementException { + TrustManager[] trustManagers = null; + if (trustManager != null) { + trustManagers = new TrustManager[] { trustManager }; + } + SSLContext sslContext = SSLContext.getInstance(SSL_CONTEXT_NAME); + sslContext.init(null, trustManagers, null); + return sslContext; + } } diff --git a/src/test/java/com/openshift/internal/restclient/APIModelVersionTest.java b/src/test/java/com/openshift/internal/restclient/APIModelVersionTest.java index fac44c86..cb84f23f 100644 --- a/src/test/java/com/openshift/internal/restclient/APIModelVersionTest.java +++ b/src/test/java/com/openshift/internal/restclient/APIModelVersionTest.java @@ -8,26 +8,22 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Test; import com.openshift.internal.restclient.APIModelVersion.VersionComparitor; -/** - * - * @author Jeff Cantrill - * - */ public class APIModelVersionTest { - @Test - public void testVersionComparitor() { - VersionComparitor comparitor = new APIModelVersion.VersionComparitor(); - int result = comparitor.compare(OpenShiftAPIVersion.v1, OpenShiftAPIVersion.v1beta3); - assertEquals("Exp. v1 to be greater then v1beta3", 1,result); - } + @Test + public void testVersionComparitor() { + VersionComparitor comparitor = new APIModelVersion.VersionComparitor(); + int result = comparitor.compare(OpenShiftAPIVersion.v1, OpenShiftAPIVersion.v1beta3); + assertEquals("Exp. v1 to be greater then v1beta3", 1, result); + } } diff --git a/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java b/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java index e758d279..c6fe5fd7 100644 --- a/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java +++ b/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java @@ -8,10 +8,14 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import org.junit.Test; import org.junit.runner.RunWith; @@ -24,61 +28,61 @@ import com.openshift.restclient.model.IService; import com.openshift.restclient.model.MocksFactory; - @RunWith(MockitoJUnitRunner.class) public class ApiTypeMapperTest extends TypeMapperFixture { - private MocksFactory factory = new MocksFactory(); - - @Test - public void testKubernetesResourceIsSupportedAfterInitiallyErrorIsThrown() throws Exception { - IService resource = factory.stub(ResourceKind.SERVICE); - try { - getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api").thenThrow(new RuntimeException()); - assertTrue("Exp. Kube support", mapper.isSupported(resource)); - }catch(RuntimeException e) { - getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api").thenReturn(responseOf(TypeMapperFixture.VERSIONS)); - assertTrue("Exp. Kube support", mapper.isSupported(resource)); - } - } - - @Test - public void testKubernetesResourceIsSupported() { - IService resource = factory.stub(ResourceKind.SERVICE); - assertTrue("Exp. Kube support", mapper.isSupported(resource)); - - IVersionedApiResource endpoint = mapper.getEndpointFor("v1", ResourceKind.SERVICE); - assertTrue("Exp. services to be namespaces", endpoint.isNamespaced()); - } - - @Test - public void testOpenShiftResourceIsSupported() { - IBuildConfig resource = factory.mock(IBuildConfig.class); - //check subresource or action first - when(resource.getKind()).thenReturn("buildconfigs/webhooks"); - assertFalse("Exp. ApiGroups to not recognize 'action' as a resource", mapper.isSupported(resource)); - - resource = factory.stub(IBuildConfig.class); - assertTrue("Exp. OpenShift support", mapper.isSupported(resource)); - } + private MocksFactory factory = new MocksFactory(); + + @Test + public void testKubernetesResourceIsSupportedAfterInitiallyErrorIsThrown() throws Exception { + IService resource = factory.stub(ResourceKind.SERVICE); + try { + getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api").thenThrow(new RuntimeException()); + assertTrue("Exp. Kube support", mapper.isSupported(resource)); + } catch (RuntimeException e) { + getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api") + .thenReturn(responseOf(TypeMapperFixture.VERSIONS)); + assertTrue("Exp. Kube support", mapper.isSupported(resource)); + } + } + + @Test + public void testKubernetesResourceIsSupported() { + IService resource = factory.stub(ResourceKind.SERVICE); + assertTrue("Exp. Kube support", mapper.isSupported(resource)); + + IVersionedApiResource endpoint = mapper.getEndpointFor("v1", ResourceKind.SERVICE); + assertTrue("Exp. services to be namespaces", endpoint.isNamespaced()); + } + + @Test + public void testOpenShiftResourceIsSupported() { + IBuildConfig resource = factory.mock(IBuildConfig.class); + // check subresource or action first + when(resource.getKind()).thenReturn("buildconfigs/webhooks"); + assertFalse("Exp. ApiGroups to not recognize 'action' as a resource", mapper.isSupported(resource)); + + resource = factory.stub(IBuildConfig.class); + assertTrue("Exp. OpenShift support", mapper.isSupported(resource)); + } + + @Test + public void testRandomResourceIsNotSupported() { + IResource resource = factory.mock(IResource.class); + assertFalse("Exp. no random supported kinds", mapper.isSupported(resource)); + } - @Test - public void testRandomResourceIsNotSupported() { - IResource resource = factory.mock(IResource.class); - assertFalse("Exp. no random supported kinds",mapper.isSupported(resource)); - } + @Test + public void testApiGroupResourceIsSupported() { + IResource resource = mock(IResource.class); + when(resource.getKind()).thenReturn("DaemonSet"); + when(resource.getApiVersion()).thenReturn("extensions/v1beta1"); + assertTrue("Exp. extension to be supported", mapper.isSupported(resource)); - @Test - public void testApiGroupResourceIsSupported() { - IResource resource = mock(IResource.class); - when(resource.getKind()).thenReturn("DaemonSet"); - when(resource.getApiVersion()).thenReturn("extensions/v1beta1"); - assertTrue("Exp. extension to be supported",mapper.isSupported(resource)); - - IVersionedApiResource endpoint = mapper.getEndpointFor("extensions/v1beta1", "DaemonSet"); - assertEquals("daemonsets", endpoint.getName()); - assertTrue(endpoint.isNamespaced()); - assertTrue(endpoint.isSupported("status")); - } + IVersionedApiResource endpoint = mapper.getEndpointFor("extensions/v1beta1", "DaemonSet"); + assertEquals("daemonsets", endpoint.getName()); + assertTrue(endpoint.isNamespaced()); + assertTrue(endpoint.isSupported("status")); + } } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java index 5410df7f..57d70939 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java @@ -1,5 +1,21 @@ package com.openshift.internal.restclient; +import static com.openshift.internal.restclient.IntegrationTestHelper.cleanUpResource; +import static com.openshift.restclient.ResourceKind.BUILD_CONFIG; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.openshift.internal.restclient.model.build.BuildConfigBuilder; import com.openshift.internal.restclient.model.project.OpenshiftProjectRequest; import com.openshift.restclient.IClient; @@ -8,148 +24,140 @@ import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IResource; -import org.junit.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.*; -import java.util.stream.Collectors; - -import static com.openshift.internal.restclient.IntegrationTestHelper.*; -import static com.openshift.restclient.ResourceKind.BUILD_CONFIG; -import static org.junit.Assert.*; public class DefaultClientFilterIntegrationTest { - private static final String VERSION = "v1"; - - private static final Logger LOG = LoggerFactory.getLogger(DefaultClientFilterIntegrationTest.class); - - private static IClient client; - - private static IResourceFactory factory; - - private static IProject project; - - private static IntegrationTestHelper helper = new IntegrationTestHelper(); - - @BeforeClass - public static void setup() { - - client = helper.createClientForBasicAuth(); - factory = new ResourceFactory(client); - OpenshiftProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); - projectRequest.setName(helper.generateNamespace()); - project = (IProject) client.create(projectRequest); - - createBuildConfigWithLabels(project, "build1", new HashMap() {{ - put("foo", "yes"); - put("bar", "no"); - put("baz", "no"); - }}); - - createBuildConfigWithLabels(project, "build2", new HashMap() {{ - put("foo", "no"); - put("bar", "yes"); - - }}); + private static final String VERSION = "v1"; - createBuildConfigWithLabels(project, "build3", new HashMap() {{ - put("foo", "yes"); - put("bar", "yes"); - }}); + private static final Logger LOG = LoggerFactory.getLogger(DefaultClientFilterIntegrationTest.class); - createBuildConfigWithLabels(project, "build4", new HashMap<>()); + private static IClient client; - } + private static IResourceFactory factory; - @AfterClass - public static void cleanup() { - cleanUpResource(client, project); - } + private static IProject project; - @Test - public void testFilteringWithOneLabel() { - List list = client.list(BUILD_CONFIG, project.getNamespaceName(), new HashMap() {{ - put("foo", "yes"); - }}); + private static IntegrationTestHelper helper = new IntegrationTestHelper(); - assertEquals(2, list.size()); - Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); - assertTrue("Should contain build1", names.contains("build1")); - assertTrue("Should contain build3", names.contains("build3")); + @BeforeClass + public static void setup() { - } + client = helper.createClientForBasicAuth(); + factory = new ResourceFactory(client); + OpenshiftProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); + projectRequest.setName(helper.generateNamespace()); + project = (IProject) client.create(projectRequest); - @Test - public void testFilteringWithTwoLabel() { - List list = client.list(BUILD_CONFIG, project.getNamespaceName(), new HashMap() {{ - put("foo", "yes"); - put("bar", "no"); - }}); + createBuildConfigWithLabels(project, "build1", new HashMap() { + { + put("foo", "yes"); + put("bar", "no"); + put("baz", "no"); + } + }); - assertEquals(1, list.size()); - IBuildConfig bc = list.get(0); - assertEquals("build1", bc.getName()); - } + createBuildConfigWithLabels(project, "build2", new HashMap() { + { + put("foo", "no"); + put("bar", "yes"); - @Test - public void testFilteringWithLabelExist() { - List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "baz"); + } + }); - assertEquals(1, list.size()); - IBuildConfig bc = list.get(0); - assertEquals("build1", bc.getName()); - } + createBuildConfigWithLabels(project, "build3", new HashMap() { + { + put("foo", "yes"); + put("bar", "yes"); + } + }); - @Test - public void testFilteringWithLabelNotExist() { - List list = - client.list(BUILD_CONFIG, project.getNamespaceName(), "!baz"); + createBuildConfigWithLabels(project, "build4", new HashMap<>()); - Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); + } - assertEquals(3, list.size()); - assertTrue("Should contain build2", names.contains("build2")); - assertTrue("Should contain build3", names.contains("build3")); - assertTrue("Should contain build4", names.contains("build4")); + @AfterClass + public static void cleanup() { + cleanUpResource(client, project); + } - } + @Test + public void testFilteringWithOneLabel() { + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), new HashMap() { + { + put("foo", "yes"); + } + }); - @Test - public void testFilteringWithLabelNotEqualTo() { - List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "foo != yes"); + assertEquals(2, list.size()); + Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); + assertTrue("Should contain build1", names.contains("build1")); + assertTrue("Should contain build3", names.contains("build3")); + } - Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); + @Test + public void testFilteringWithTwoLabel() { + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), new HashMap() { + { + put("foo", "yes"); + put("bar", "no"); + } + }); - assertEquals(2, list.size()); - assertTrue("Should contain build2", names.contains("build2")); - assertTrue("Should contain build4", names.contains("build4")); } + assertEquals(1, list.size()); + IBuildConfig bc = list.get(0); + assertEquals("build1", bc.getName()); + } - @Test - public void testFilteringWithLabelCombinedLabelQuery() { - List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "foo,bar=no"); + @Test + public void testFilteringWithLabelExist() { + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "baz"); - assertEquals(1, list.size()); - IBuildConfig bc = list.get(0); - assertEquals("build1", bc.getName()); - } + assertEquals(1, list.size()); + IBuildConfig bc = list.get(0); + assertEquals("build1", bc.getName()); + } + @Test + public void testFilteringWithLabelNotExist() { + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "!baz"); + Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); - private static IBuildConfig createBuildConfigWithLabels(IProject project, String name, HashMap labelFilter) { + assertEquals(3, list.size()); + assertTrue("Should contain build2", names.contains("build2")); + assertTrue("Should contain build3", names.contains("build3")); + assertTrue("Should contain build4", names.contains("build4")); - IBuildConfig bc = new BuildConfigBuilder(client) - .named(name) - .inNamespace(project.getNamespaceName()) - .usingSourceStrategy() - .fromDockerImage("centos/ruby-22-centos7:latest") - .end() - .toImageStreamTag("ruby-hello-world:latest") - .withLabels(labelFilter) - .build(); - return client.create(bc); - } + } + + @Test + public void testFilteringWithLabelNotEqualTo() { + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "foo != yes"); + + Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); + + assertEquals(2, list.size()); + assertTrue("Should contain build2", names.contains("build2")); + assertTrue("Should contain build4", names.contains("build4")); + } + + @Test + public void testFilteringWithLabelCombinedLabelQuery() { + List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "foo,bar=no"); + + assertEquals(1, list.size()); + IBuildConfig bc = list.get(0); + assertEquals("build1", bc.getName()); + } + + private static IBuildConfig createBuildConfigWithLabels(IProject project, String name, + HashMap labelFilter) { + + IBuildConfig bc = new BuildConfigBuilder(client).named(name).inNamespace(project.getNamespaceName()) + .usingSourceStrategy().fromDockerImage("centos/ruby-22-centos7:latest").end() + .toImageStreamTag("ruby-hello-world:latest").withLabels(labelFilter).build(); + return client.create(bc); + } } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index 8ba8f1fb..045db75a 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -1,17 +1,20 @@ - /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. +* All rights reserved. This program is 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: Red Hat, Inc. +******************************************************************************/ + package com.openshift.internal.restclient; +import static com.openshift.internal.restclient.IntegrationTestHelper.MILLISECONDS_PER_SECOND; +import static com.openshift.internal.restclient.IntegrationTestHelper.cleanUpResource; +import static com.openshift.internal.restclient.IntegrationTestHelper.waitForResource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static com.openshift.internal.restclient.IntegrationTestHelper.*; import java.util.List; @@ -34,158 +37,151 @@ import com.openshift.restclient.model.project.IProjectRequest; import com.openshift.restclient.model.template.ITemplate; -/** - * @author Jeff Cantrill - */ public class DefaultClientIntegrationTest { - private static final String VERSION = "v1"; - - private static final Logger LOG = LoggerFactory.getLogger(DefaultClientIntegrationTest.class); - - private IClient client; - private IntegrationTestHelper helper = new IntegrationTestHelper(); - - private IResourceFactory factory; - - @Before - public void setup () { - client = helper.createClientForBasicAuth(); - factory = new ResourceFactory(client); - } - - @Test - public void testAuthContextIsAuthorizedWithValidUserNameAndPassword() { - client = helper.createClient(); - client.getAuthorizationContext().setUserName(helper.getDefaultClusterAdminUser()); - client.getAuthorizationContext().setPassword(helper.getDefaultClusterAdminPassword()); - client.getAuthorizationContext().isAuthorized(); - } - @Test(expected=UnauthorizedException.class) - public void testAuthContextIsAuthorizedWithoutPasswordThrows() { - client = helper.createClient(); - client.getAuthorizationContext().setUserName(helper.getDefaultClusterAdminUser()); - client.getAuthorizationContext().isAuthorized(); - } - - public void testListprojects() { - assertTrue(client.list(ResourceKind.PROJECT, "default").size() > 0); - } - - @Test - public void testReady() { - client.getServerReadyStatus(); - } - - @Test - public void testListTemplates(){ - Template template = null; - IProject project = null; - - try { - OpenshiftProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); - projectRequest.setName(helper.generateNamespace()); - template = factory.stub(ResourceKind.TEMPLATE, "mytemplate"); - - project = (IProject) client.create(projectRequest); - template = client.create(template, project.getNamespaceName()); - - assertNotNull("Exp. the template to be found but was not", waitForResource(client, ResourceKind.TEMPLATE, project.getName(), template.getName(), 5 * MILLISECONDS_PER_SECOND)); - - List list = client.list(ResourceKind.TEMPLATE, project.getName()); - assertEquals(1, list.size()); - for (ITemplate t : list) { - LOG.debug(t.toString()); - } - } finally { - cleanUpResource(client, template); - cleanUpResource(client, project); - } - } - - @Test - public void testResourceLifeCycle() { - - - IProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); - ((OpenshiftProjectRequest) projectRequest).setName(helper.generateNamespace()); - LOG.debug(String.format("Stubbing project request: %s", projectRequest)); - - IProjectRequest otherProjectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); - ((OpenshiftProjectRequest) otherProjectRequest).setName(helper.generateNamespace()); - LOG.debug(String.format("Stubbing project request: %s", otherProjectRequest)); - - Service service = factory.create(VERSION, ResourceKind.SERVICE); - service.setNamespace(projectRequest.getName()); //this will be the project's namespace - service.setName("some-service"); - service.setTargetPort(6767); - service.setPort(6767); - service.setSelector("name", "barpod"); - LOG.debug(String.format("Stubbing service: %s", service)); - - Service otherService = factory.create(VERSION, ResourceKind.SERVICE); - otherService.setNamespace(otherProjectRequest.getName()); //this will be the project's namespace - otherService.setName("some-other-service"); - otherService.setTargetPort(8787); - otherService.setPort(8787); - otherService.setSelector("name", "foopod"); - - LOG.debug(String.format("Stubbing service: %s", otherService)); - - IProject project = null; - IProject other = null; - try{ - project = (IProject) client.create(projectRequest); - LOG.debug(String.format("Created project: %s", project)); - - other = (IProject) client.create(otherProjectRequest); - LOG.debug(String.format("Created project: %s", project)); - - LOG.debug(String.format("Creating service: %s", service)); - service = client.create(service); - LOG.debug(String.format("Created service: %s", service)); - - LOG.debug(String.format("Creating service: %s", otherService)); - otherService = client.create(otherService); - LOG.debug(String.format("Created service: %s", otherService)); - - LOG.debug("Listing projects"); - List projects = client.list(ResourceKind.PROJECT); - LOG.debug(String.format("Listed projects: %s", projects)); - - LOG.debug(String.format("Listing services with namespace: %s", project.getNamespaceName())); - List services = client.list(ResourceKind.SERVICE, project.getNamespaceName()); - LOG.debug(String.format("Listed services: %s", services)); - - LOG.debug(String.format("Getting service: %s", otherService.getName())); - Service s = client.get(ResourceKind.SERVICE, otherService.getName(), otherService.getNamespaceName()); - LOG.debug(String.format("Retrieved service: %s", s.getName())); - - assertEquals("Expected there to be only one service returned", 1, services.size()); - assertEquals("Expected to get the service with the correct name", service.getName(), services.get(0).getName()); - - IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); - IBuildConfig bc = builder.named("test") - .fromGitSource() - .fromGitUrl("https://github.com/openshift/origin.git") - .inContextDir("examples/hello-openshift") - .end() - .usingSourceStrategy() - .fromDockerImage("foo/bar") - .end() - .toImageStreamTag("foo/bar:latest") - .build(); - bc = client.create(bc, project.getNamespaceName()); - LOG.debug(String.format("Created bc: %s", bc.getName())); - LOG.debug(String.format("Trying to delete bc: %s", bc.getName())); - client.delete(bc); - }finally{ - cleanUpResource(client, project); - cleanUpResource(client, other); - cleanUpResource(client, service); - cleanUpResource(client, otherService); - } - - } + private static final String VERSION = "v1"; + + private static final Logger LOG = LoggerFactory.getLogger(DefaultClientIntegrationTest.class); + + private IClient client; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + + private IResourceFactory factory; + + @Before + public void setup() { + client = helper.createClientForBasicAuth(); + factory = new ResourceFactory(client); + } + + @Test + public void testAuthContextIsAuthorizedWithValidUserNameAndPassword() { + client = helper.createClient(); + client.getAuthorizationContext().setUserName(helper.getDefaultClusterAdminUser()); + client.getAuthorizationContext().setPassword(helper.getDefaultClusterAdminPassword()); + client.getAuthorizationContext().isAuthorized(); + } + + @Test(expected = UnauthorizedException.class) + public void testAuthContextIsAuthorizedWithoutPasswordThrows() { + client = helper.createClient(); + client.getAuthorizationContext().setUserName(helper.getDefaultClusterAdminUser()); + client.getAuthorizationContext().isAuthorized(); + } + + public void testListprojects() { + assertTrue(client.list(ResourceKind.PROJECT, "default").size() > 0); + } + + @Test + public void testReady() { + client.getServerReadyStatus(); + } + + @Test + public void testListTemplates() { + Template template = null; + IProject project = null; + + try { + OpenshiftProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); + projectRequest.setName(helper.generateNamespace()); + template = factory.stub(ResourceKind.TEMPLATE, "mytemplate"); + + project = (IProject) client.create(projectRequest); + template = client.create(template, project.getNamespaceName()); + + assertNotNull("Exp. the template to be found but was not", waitForResource(client, ResourceKind.TEMPLATE, + project.getName(), template.getName(), 5 * MILLISECONDS_PER_SECOND)); + + List list = client.list(ResourceKind.TEMPLATE, project.getName()); + assertEquals(1, list.size()); + for (ITemplate t : list) { + LOG.debug(t.toString()); + } + } finally { + cleanUpResource(client, template); + cleanUpResource(client, project); + } + } + + @Test + public void testResourceLifeCycle() { + + IProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); + ((OpenshiftProjectRequest) projectRequest).setName(helper.generateNamespace()); + LOG.debug(String.format("Stubbing project request: %s", projectRequest)); + + IProjectRequest otherProjectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); + ((OpenshiftProjectRequest) otherProjectRequest).setName(helper.generateNamespace()); + LOG.debug(String.format("Stubbing project request: %s", otherProjectRequest)); + + Service service = factory.create(VERSION, ResourceKind.SERVICE); + service.setNamespace(projectRequest.getName()); // this will be the project's namespace + service.setName("some-service"); + service.setTargetPort(6767); + service.setPort(6767); + service.setSelector("name", "barpod"); + LOG.debug(String.format("Stubbing service: %s", service)); + + Service otherService = factory.create(VERSION, ResourceKind.SERVICE); + otherService.setNamespace(otherProjectRequest.getName()); // this will be the project's namespace + otherService.setName("some-other-service"); + otherService.setTargetPort(8787); + otherService.setPort(8787); + otherService.setSelector("name", "foopod"); + + LOG.debug(String.format("Stubbing service: %s", otherService)); + + IProject project = null; + IProject other = null; + try { + project = (IProject) client.create(projectRequest); + LOG.debug(String.format("Created project: %s", project)); + + other = (IProject) client.create(otherProjectRequest); + LOG.debug(String.format("Created project: %s", project)); + + LOG.debug(String.format("Creating service: %s", service)); + service = client.create(service); + LOG.debug(String.format("Created service: %s", service)); + + LOG.debug(String.format("Creating service: %s", otherService)); + otherService = client.create(otherService); + LOG.debug(String.format("Created service: %s", otherService)); + + LOG.debug("Listing projects"); + List projects = client.list(ResourceKind.PROJECT); + LOG.debug(String.format("Listed projects: %s", projects)); + + LOG.debug(String.format("Listing services with namespace: %s", project.getNamespaceName())); + List services = client.list(ResourceKind.SERVICE, project.getNamespaceName()); + LOG.debug(String.format("Listed services: %s", services)); + + LOG.debug(String.format("Getting service: %s", otherService.getName())); + Service s = client.get(ResourceKind.SERVICE, otherService.getName(), otherService.getNamespaceName()); + LOG.debug(String.format("Retrieved service: %s", s.getName())); + + assertEquals("Expected there to be only one service returned", 1, services.size()); + assertEquals("Expected to get the service with the correct name", service.getName(), + services.get(0).getName()); + + IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); + IBuildConfig bc = builder.named("test").fromGitSource() + .fromGitUrl("https://github.com/openshift/origin.git").inContextDir("examples/hello-openshift") + .end().usingSourceStrategy().fromDockerImage("foo/bar").end().toImageStreamTag("foo/bar:latest") + .build(); + bc = client.create(bc, project.getNamespaceName()); + LOG.debug(String.format("Created bc: %s", bc.getName())); + LOG.debug(String.format("Trying to delete bc: %s", bc.getName())); + client.delete(bc); + } finally { + cleanUpResource(client, project); + cleanUpResource(client, other); + cleanUpResource(client, service); + cleanUpResource(client, otherService); + } + + } } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index f9124fea..937b026c 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -8,10 +8,13 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient; import static org.fest.assertions.Assertions.assertThat; + import java.net.URL; + import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; @@ -28,95 +31,92 @@ * @author Andre Dietisheim */ @RunWith(MockitoJUnitRunner.class) -public class DefaultClientTest extends TypeMapperFixture{ - - private static final String VERSION = "v1"; - - private DefaultClient client; - private ModelNode response; - private Pod podFrontEnd; - private Pod podBackEnd; - private IResourceFactory factory; - private URL baseUrl; - - - @Before - public void setUp() throws Exception{ - super.setUp(); - this.baseUrl = new URL("http://myopenshift"); - givenAClient(); - givenAPodList(); - getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api/v1/namespaces/aNamespace/pods").thenReturn(responseOf(response.toJSONString(false))); - } - - private void givenAClient() throws Exception{ - factory = new ResourceFactory(null); - client = (DefaultClient) getIClient();//new DefaultClient(baseUrl, getHttpClient(), factory, getApiTypeMapper(), new AuthorizationContext(null)); - factory = client.getResourceFactory(); - } - - private void givenAPodList(){ - this.podFrontEnd = factory.create(VERSION, ResourceKind.POD); - podFrontEnd.setName("frontend"); - podFrontEnd.setNamespace("aNamespace"); - podFrontEnd.addLabel("name", "frontend"); - podFrontEnd.addLabel("env", "production"); - - this.podBackEnd = factory.create(VERSION, ResourceKind.POD); - podBackEnd.setName("backend"); - podBackEnd.setNamespace("aNamespace"); - podBackEnd.addLabel("name", "backend"); - podBackEnd.addLabel("env", "production"); - - Pod otherPod = factory.create(VERSION, ResourceKind.POD); - otherPod.setName("other"); - otherPod.setNamespace("aNamespace"); - otherPod.addLabel("env", "production"); - - this.response = new ModelNode(); - response.get("apiVersion").set(VERSION); - response.get("kind").set("PodList"); - ModelNode items = response.get("items"); - items.add(podFrontEnd.getNode()); - items.add(otherPod.getNode()); - items.add(podBackEnd.getNode()); - } - - - private DefaultClient givenClient(URL baseUrl, String token, String user) { - DefaultClient client = new DefaultClient(baseUrl, getHttpClient(), null, null, new AuthorizationContext(token,user,null)); - return client; - } - - - @Test - public void clientShouldEqualClientWithSameUrl() throws Exception { - assertThat(givenClient(baseUrl,null,null)) - .isEqualTo(givenClient(baseUrl,null,null)); - } - - @Test - public void clientShouldNotEqualClientWithDifferentUrl() throws Exception { - assertThat(givenClient(baseUrl,null,null)) - .isNotEqualTo(givenClient(new URL("http://localhost:8443"),null,null)); - } - - public void client_should_equal_client_with_same_user_with_different_token() throws Exception { - DefaultClient tokenClientOne = givenClient(baseUrl, "tokenOne", "aUser"); - - DefaultClient tokenClientTwo = givenClient(baseUrl,"tokenTwo", "aUser"); - - assertThat(tokenClientOne).isEqualTo(tokenClientTwo); - } - - - @Test - public void client_should_not_equal_client_with_different_username() throws Exception { - DefaultClient tokenClientOne = givenClient(baseUrl,"aToken", "aUser"); - - DefaultClient tokenClientTwo = givenClient(baseUrl, "aToken", "differentUser"); - - assertThat(tokenClientOne).isNotEqualTo(tokenClientTwo); - } +public class DefaultClientTest extends TypeMapperFixture { + + private static final String VERSION = "v1"; + + private DefaultClient client; + private ModelNode response; + private Pod podFrontEnd; + private Pod podBackEnd; + private IResourceFactory factory; + private URL baseUrl; + + @Before + public void setUp() throws Exception { + super.setUp(); + this.baseUrl = new URL("http://myopenshift"); + givenAClient(); + givenAPodList(); + getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api/v1/namespaces/aNamespace/pods") + .thenReturn(responseOf(response.toJSONString(false))); + } + + private void givenAClient() throws Exception { + factory = new ResourceFactory(null); + client = (DefaultClient) getIClient(); + factory = client.getResourceFactory(); + } + + private void givenAPodList() { + this.podFrontEnd = factory.create(VERSION, ResourceKind.POD); + podFrontEnd.setName("frontend"); + podFrontEnd.setNamespace("aNamespace"); + podFrontEnd.addLabel("name", "frontend"); + podFrontEnd.addLabel("env", "production"); + + this.podBackEnd = factory.create(VERSION, ResourceKind.POD); + podBackEnd.setName("backend"); + podBackEnd.setNamespace("aNamespace"); + podBackEnd.addLabel("name", "backend"); + podBackEnd.addLabel("env", "production"); + + Pod otherPod = factory.create(VERSION, ResourceKind.POD); + otherPod.setName("other"); + otherPod.setNamespace("aNamespace"); + otherPod.addLabel("env", "production"); + + this.response = new ModelNode(); + response.get("apiVersion").set(VERSION); + response.get("kind").set("PodList"); + ModelNode items = response.get("items"); + items.add(podFrontEnd.getNode()); + items.add(otherPod.getNode()); + items.add(podBackEnd.getNode()); + } + + private DefaultClient givenClient(URL baseUrl, String token, String user) { + DefaultClient client = new DefaultClient(baseUrl, getHttpClient(), null, null, + new AuthorizationContext(token, user, null)); + return client; + } + + @Test + public void clientShouldEqualClientWithSameUrl() throws Exception { + assertThat(givenClient(baseUrl, null, null)).isEqualTo(givenClient(baseUrl, null, null)); + } + + @Test + public void clientShouldNotEqualClientWithDifferentUrl() throws Exception { + assertThat(givenClient(baseUrl, null, null)) + .isNotEqualTo(givenClient(new URL("http://localhost:8443"), null, null)); + } + + public void client_should_equal_client_with_same_user_with_different_token() throws Exception { + DefaultClient tokenClientOne = givenClient(baseUrl, "tokenOne", "aUser"); + + DefaultClient tokenClientTwo = givenClient(baseUrl, "tokenTwo", "aUser"); + + assertThat(tokenClientOne).isEqualTo(tokenClientTwo); + } + + @Test + public void client_should_not_equal_client_with_different_username() throws Exception { + DefaultClient tokenClientOne = givenClient(baseUrl, "aToken", "aUser"); + + DefaultClient tokenClientTwo = givenClient(baseUrl, "aToken", "differentUser"); + + assertThat(tokenClientOne).isNotEqualTo(tokenClientTwo); + } } diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index 1793ae35..622e553b 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -6,8 +6,11 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient; +import static org.junit.Assert.fail; + import java.io.IOException; import java.util.Collections; import java.util.HashMap; @@ -36,233 +39,212 @@ import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.deploy.DeploymentTriggerType; -import static org.junit.Assert.fail; - -/** - * @author Jeff Cantrill - */ public class IntegrationTestHelper implements ResourcePropertyKeys { - public static final long MILLISECONDS_PER_SECOND = 1000; - public static final long MILLISECONDS_PER_MIN = MILLISECONDS_PER_SECOND * 60; - - private static final String KEY_DEFAULT_PROJECT = "default.project"; - private static final String KEY_SERVER_URL = "serverURL"; - private static final String KEY_PASSWORD = "default.clusteradmin.password"; - private static final String KEY_USER = "default.clusteradmin.user"; - private static final String KEY_OPENSHIFT_LOCATION = "default.openshift.location"; - - private static final String INTEGRATIONTEST_PROPERTIES = "/openshiftv3IntegrationTest.properties"; - - private static final Logger LOG = LoggerFactory.getLogger(IntegrationTestHelper.class); - - private final Properties prop; - - public IntegrationTestHelper() { - this.prop = loadProperties(INTEGRATIONTEST_PROPERTIES); - } - - public IClient createClient(){ - return new ClientBuilder(prop.getProperty(KEY_SERVER_URL)).build(); - } - - public IClient createClientForBasicAuth() { - IClient client = new ClientBuilder(prop.getProperty(KEY_SERVER_URL)) - .withUserName(getDefaultClusterAdminUser()) - .withPassword(getDefaultClusterAdminPassword()) - .build(); - return client; - } - - public String getDefaultNamespace(){ - return prop.getProperty(KEY_DEFAULT_PROJECT); - } - - public String generateNamespace() { - return String.format("%s-%s",getDefaultNamespace(), new Random().nextInt(9999)); - } - - public IProject generateProject(IClient client) { - IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, generateNamespace()); - return (IProject) client.create(request); - } - - /** - * Stub a pod definition to the openshift/hello-openshift - * image for purposes of testing. - * @param client - * @param project - * @return a pod definition that needs to be further created using the client - */ - public static IPod stubPod(IClient client, IProject project) { - //cluster shouldnt allow us to create pods directly - ModelNode builder = new ModelNodeBuilder() - .set(ResourcePropertyKeys.KIND, ResourceKind.POD) - .set(ResourcePropertyKeys.METADATA_NAME, "hello-openshift") - .set(ResourcePropertyKeys.METADATA_NAMESPACE, project.getName()) - .add("spec.containers", new ModelNodeBuilder() - .set(ResourcePropertyKeys.NAME, "hello-openshift") - .set("image", "openshift/hello-openshift") - .add("ports", new ModelNodeBuilder() - .set("containerPort", 8080) - .set("protocol", "TCP") - ) - ) - .build(); - return new Pod(builder, client, new HashMap<>()); - } - - public static IDeploymentConfig stubDeploymentConfig(IClient client, IProject project) { - IDeploymentConfig dc = new ResourceFactory(client).create("v1", ResourceKind.DEPLOYMENT_CONFIG); - ((DeploymentConfig)dc).setName("hello-openshift"); - ((DeploymentConfig)dc).setNamespace(project.getName()); - dc.setReplicas(1); - dc.setReplicaSelector("foo","bar"); - dc.addContainer(dc.getName(), new DockerImageURI("openshift/hello-openshift"), new HashSet<>(), Collections.emptyMap(), Collections.emptyList()); - dc.addTrigger(DeploymentTriggerType.CONFIG_CHANGE); - return dc; - } - - public static IReplicationController stubReplicationController(IClient client, IProject project) { - IReplicationController rc = new ResourceFactory(client).create("v1", ResourceKind.REPLICATION_CONTROLLER); - ((ReplicationController)rc).setName("hello-openshift-rc"); - ((ReplicationController)rc).setNamespace(project.getName()); - rc.setReplicas(1); - rc.setReplicaSelector("foo","bar"); - rc.addContainer(rc.getName(), new DockerImageURI("openshift/hello-openshift"), new HashSet<>(), Collections.emptyMap(), Collections.emptyList()); - return rc; - } - - /** - * Loads the properties from the given {@code propertyFileName}, then - * overrides from the System properties if any was given (this is a convenient way to - * override the default settings and avoid conflicting with the properties file in git) - * - * @return the properties to use in the test - * @throws IOException - */ - private static Properties loadProperties(final String propertyFileName) { - final Properties properties = new Properties(); - try { - properties.load(IntegrationTestHelper.class.getResourceAsStream(propertyFileName)); - } catch (IOException e) { - e.printStackTrace(); - fail("Failed to load properties from file " + INTEGRATIONTEST_PROPERTIES + ": " + e.getMessage()); - } - overrideIfExists(properties, KEY_SERVER_URL); - overrideIfExists(properties, KEY_DEFAULT_PROJECT); - overrideIfExists(properties, KEY_OPENSHIFT_LOCATION); - overrideIfExists(properties, KEY_USER); - overrideIfExists(properties, KEY_PASSWORD); - return properties; - } - - - private static void overrideIfExists(final Properties properties, final String propertyName){ - // then override with the VM arguments (if any) - final String propertyValue = System.getProperty(propertyName); - if (propertyValue != null) { - properties.setProperty(propertyName, propertyValue); - } - } - - public String getOpenShiftLocation() { - return prop.getProperty(KEY_OPENSHIFT_LOCATION); - } - - public String getDefaultClusterAdminUser() { - return prop.getProperty(KEY_USER); - } - - public String getDefaultClusterAdminPassword() { - return prop.getProperty(KEY_PASSWORD); - } - - public String getServerUrl() { - return prop.getProperty(KEY_SERVER_URL); - } - - public static void cleanUpResource(IClient client, IResource resource) { - if(client == null || resource == null) { - LOG.debug("Skipping cleanup as client %s or resource %s is null", client, resource); - } - try { - Thread.sleep(1000); - LOG.debug(String.format("Deleting resource: %s", resource)); - client.delete(resource); - } catch (Exception e) { - LOG.warn("Exception deleting", e); - } - } - - /** - * Wait for the resource to exist for cases where the test is faster - * then the server in reconciling its existence; - * @param client - * @param kind - * @param namespace - * @param name - * @param maxWaitMillis - * @return The resource or null if the maxWaitMillis was exceeded or the resource doesnt exist - */ - public static IResource waitForResource(IClient client, String kind, String namespace, String name, long maxWaitMillis) { - return waitForResource(client, kind, namespace, name, maxWaitMillis, new ReadyConditional() { - @Override - public boolean isReady(IResource resource) { - return resource != null; - } - - }); - } - /** - * Wait for the resource to exist for cases where the test is faster - * then the server in reconciling its existence; - * - * @param client - * @param kind - * @param namespace - * @param name - * @param maxWaitMillis - * @param conditional - * @return - */ - public static IResource waitForResource(IClient client, String kind, String namespace, String name, long maxWaitMillis, ReadyConditional conditional) { - IResource resource = null; - final long timeout = System.currentTimeMillis() + maxWaitMillis; - do { - try { - resource = client.get(kind, name, namespace); - if(resource != null && conditional != null) { - if(conditional.isReady(resource)) { - return resource; - } - resource = null; - } - }catch(NotFoundException e) { - try { - Thread.sleep(1000); - } catch (InterruptedException e1) { - throw new RuntimeException(e1); - } - } - }while(resource == null && System.currentTimeMillis() <= timeout); - return resource; - } - - /** - * Interface that can evaluate a resource to determine if its ready - * @author jeff.cantrill - * - */ - public static interface ReadyConditional { - - /** - * - * @param resource - * @return true if the resource is 'ready' - */ - boolean isReady(IResource resource); - } - - + public static final long MILLISECONDS_PER_SECOND = 1000; + public static final long MILLISECONDS_PER_MIN = MILLISECONDS_PER_SECOND * 60; + + private static final String KEY_DEFAULT_PROJECT = "default.project"; + private static final String KEY_SERVER_URL = "serverURL"; + private static final String KEY_PASSWORD = "default.clusteradmin.password"; + private static final String KEY_USER = "default.clusteradmin.user"; + private static final String KEY_OPENSHIFT_LOCATION = "default.openshift.location"; + + private static final String INTEGRATIONTEST_PROPERTIES = "/openshiftv3IntegrationTest.properties"; + + private static final Logger LOG = LoggerFactory.getLogger(IntegrationTestHelper.class); + + private final Properties prop; + + public IntegrationTestHelper() { + this.prop = loadProperties(INTEGRATIONTEST_PROPERTIES); + } + + public IClient createClient() { + return new ClientBuilder(prop.getProperty(KEY_SERVER_URL)).build(); + } + + public IClient createClientForBasicAuth() { + IClient client = new ClientBuilder(prop.getProperty(KEY_SERVER_URL)).withUserName(getDefaultClusterAdminUser()) + .withPassword(getDefaultClusterAdminPassword()).build(); + return client; + } + + public String getDefaultNamespace() { + return prop.getProperty(KEY_DEFAULT_PROJECT); + } + + public String generateNamespace() { + return String.format("%s-%s", getDefaultNamespace(), new Random().nextInt(9999)); + } + + public IProject generateProject(IClient client) { + IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, generateNamespace()); + return (IProject) client.create(request); + } + + /** + * Stub a pod definition to the openshift/hello-openshift image for purposes of + * testing. + * + * @return a pod definition that needs to be further created using the client + */ + public static IPod stubPod(IClient client, IProject project) { + // cluster shouldnt allow us to create pods directly + ModelNode builder = new ModelNodeBuilder().set(ResourcePropertyKeys.KIND, ResourceKind.POD) + .set(ResourcePropertyKeys.METADATA_NAME, "hello-openshift") + .set(ResourcePropertyKeys.METADATA_NAMESPACE, project.getName()) + .add("spec.containers", + new ModelNodeBuilder().set(ResourcePropertyKeys.NAME, "hello-openshift") + .set("image", "openshift/hello-openshift") + .add("ports", new ModelNodeBuilder().set("containerPort", 8080).set("protocol", "TCP"))) + .build(); + return new Pod(builder, client, new HashMap<>()); + } + + public static IDeploymentConfig stubDeploymentConfig(IClient client, IProject project) { + IDeploymentConfig dc = new ResourceFactory(client).create("v1", ResourceKind.DEPLOYMENT_CONFIG); + ((DeploymentConfig) dc).setName("hello-openshift"); + ((DeploymentConfig) dc).setNamespace(project.getName()); + dc.setReplicas(1); + dc.setReplicaSelector("foo", "bar"); + dc.addContainer(dc.getName(), new DockerImageURI("openshift/hello-openshift"), new HashSet<>(), + Collections.emptyMap(), Collections.emptyList()); + dc.addTrigger(DeploymentTriggerType.CONFIG_CHANGE); + return dc; + } + + public static IReplicationController stubReplicationController(IClient client, IProject project) { + IReplicationController rc = new ResourceFactory(client).create("v1", ResourceKind.REPLICATION_CONTROLLER); + ((ReplicationController) rc).setName("hello-openshift-rc"); + ((ReplicationController) rc).setNamespace(project.getName()); + rc.setReplicas(1); + rc.setReplicaSelector("foo", "bar"); + rc.addContainer(rc.getName(), new DockerImageURI("openshift/hello-openshift"), new HashSet<>(), + Collections.emptyMap(), Collections.emptyList()); + return rc; + } + + /** + * Loads the properties from the given {@code propertyFileName}, then overrides + * from the System properties if any was given (this is a convenient way to + * override the default settings and avoid conflicting with the properties file + * in git) + * + * @return the properties to use in the test + * @throws IOException an io exception + */ + private static Properties loadProperties(final String propertyFileName) { + final Properties properties = new Properties(); + try { + properties.load(IntegrationTestHelper.class.getResourceAsStream(propertyFileName)); + } catch (IOException e) { + e.printStackTrace(); + fail("Failed to load properties from file " + INTEGRATIONTEST_PROPERTIES + ": " + e.getMessage()); + } + overrideIfExists(properties, KEY_SERVER_URL); + overrideIfExists(properties, KEY_DEFAULT_PROJECT); + overrideIfExists(properties, KEY_OPENSHIFT_LOCATION); + overrideIfExists(properties, KEY_USER); + overrideIfExists(properties, KEY_PASSWORD); + return properties; + } + + private static void overrideIfExists(final Properties properties, final String propertyName) { + // then override with the VM arguments (if any) + final String propertyValue = System.getProperty(propertyName); + if (propertyValue != null) { + properties.setProperty(propertyName, propertyValue); + } + } + + public String getOpenShiftLocation() { + return prop.getProperty(KEY_OPENSHIFT_LOCATION); + } + + public String getDefaultClusterAdminUser() { + return prop.getProperty(KEY_USER); + } + + public String getDefaultClusterAdminPassword() { + return prop.getProperty(KEY_PASSWORD); + } + + public String getServerUrl() { + return prop.getProperty(KEY_SERVER_URL); + } + + public static void cleanUpResource(IClient client, IResource resource) { + if (client == null || resource == null) { + LOG.debug("Skipping cleanup as client %s or resource %s is null", client, resource); + } + try { + Thread.sleep(1000); + LOG.debug(String.format("Deleting resource: %s", resource)); + client.delete(resource); + } catch (Exception e) { + LOG.warn("Exception deleting", e); + } + } + + /** + * Wait for the resource to exist for cases where the test is faster then the + * server in reconciling its existence; + * + * @return The resource or null if the maxWaitMillis was exceeded or the + * resource doesnt exist + */ + public static IResource waitForResource(IClient client, String kind, String namespace, String name, + long maxWaitMillis) { + return waitForResource(client, kind, namespace, name, maxWaitMillis, new ReadyConditional() { + @Override + public boolean isReady(IResource resource) { + return resource != null; + } + + }); + } + + /** + * Wait for the resource to exist for cases where the test is faster then the + * server in reconciling its existence; + * + */ + public static IResource waitForResource(IClient client, String kind, String namespace, String name, + long maxWaitMillis, ReadyConditional conditional) { + IResource resource = null; + final long timeout = System.currentTimeMillis() + maxWaitMillis; + do { + try { + resource = client.get(kind, name, namespace); + if (resource != null && conditional != null) { + if (conditional.isReady(resource)) { + return resource; + } + resource = null; + } + } catch (NotFoundException e) { + try { + Thread.sleep(1000); + } catch (InterruptedException e1) { + throw new RuntimeException(e1); + } + } + } while (resource == null && System.currentTimeMillis() <= timeout); + return resource; + } + + /** + * Interface that can evaluate a resource to determine if its ready + * + */ + public static interface ReadyConditional { + + /** + * + * @return true if the resource is 'ready' + */ + boolean isReady(IResource resource); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/PodStatusRunningConditional.java b/src/test/java/com/openshift/internal/restclient/PodStatusRunningConditional.java index 2358fdc1..3d05e13f 100644 --- a/src/test/java/com/openshift/internal/restclient/PodStatusRunningConditional.java +++ b/src/test/java/com/openshift/internal/restclient/PodStatusRunningConditional.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient; import com.openshift.internal.restclient.IntegrationTestHelper.ReadyConditional; @@ -16,16 +17,19 @@ /** * Conditional to determin if a pod has acheived Running Status - * @author jeff.cantrill * */ public class PodStatusRunningConditional implements ReadyConditional { - @Override - public boolean isReady(IResource resource) { - if(resource == null) return false; - if(!(resource instanceof IPod)) return false; - IPod pod = (IPod) resource; - return "Running".equals(pod.getStatus()); - } + @Override + public boolean isReady(IResource resource) { + if (resource == null) { + return false; + } + if (!(resource instanceof IPod)) { + return false; + } + IPod pod = (IPod) resource; + return "Running".equals(pod.getStatus()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java index a3afe045..45349687 100644 --- a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java +++ b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java @@ -8,10 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient; -import static org.mockito.Mockito.*; -import static junit.framework.Assert.*; +import static junit.framework.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.List; @@ -23,48 +25,43 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IService; -/** - * @author Jeff Cantrill - */ public class ResourceFactoryTest { - private ResourceFactory factory; + private ResourceFactory factory; + + @Before + public void setup() { + IClient client = mock(IClient.class); + when(client.getOpenShiftAPIVersion()).thenReturn(OpenShiftAPIVersion.v1.toString()); + factory = new ResourceFactory(client); + } + + /* + * Validate the implementation classes implemented the expected constructor + */ + @Test + public void testV1Beta3Implementations() { + List v1beta3Exlusions = Arrays + .asList(new String[] { ResourceKind.CONFIG, ResourceKind.PROCESSED_TEMPLATES }); + final String version = OpenShiftAPIVersion.v1beta3.toString(); + for (String kind : ResourceKind.values()) { + if (!v1beta3Exlusions.contains(kind)) { + factory.create(version, kind); + } + } + } - @Before - public void setup() { - IClient client = mock(IClient.class); - when(client.getOpenShiftAPIVersion()).thenReturn(OpenShiftAPIVersion.v1.toString()); - factory = new ResourceFactory(client); - } - - /* - * Validate the implementation classes implemented the expected constructor - */ - @Test - public void testV1Beta3Implementations() { - List v1beta3Exlusions = Arrays.asList(new String [] { - ResourceKind.CONFIG, - ResourceKind.PROCESSED_TEMPLATES - }); - final String version = OpenShiftAPIVersion.v1beta3.toString(); - for (String kind : ResourceKind.values()) { - if(!v1beta3Exlusions.contains(kind)) { - factory.create(version, kind); - } - } - } - - @Test - public void testStubWithNamespace() { - IService service = factory.stub(ResourceKind.SERVICE, "foo", "bar"); - assertEquals("foo", service.getName()); - assertEquals("bar", service.getNamespaceName()); - } + @Test + public void testStubWithNamespace() { + IService service = factory.stub(ResourceKind.SERVICE, "foo", "bar"); + assertEquals("foo", service.getName()); + assertEquals("bar", service.getNamespaceName()); + } - @Test - public void testCreateWithKindAndName() { - IService service = factory.create("v1", ResourceKind.SERVICE, "foo"); - assertEquals("foo", service.getName()); - } + @Test + public void testCreateWithKindAndName() { + IService service = factory.create("v1", ResourceKind.SERVICE, "foo"); + assertEquals("foo", service.getName()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 567cf3a9..2aa6b309 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -8,10 +8,14 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient; import static org.mockito.Matchers.argThat; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import java.io.IOException; import java.net.URL; @@ -33,78 +37,82 @@ import okhttp3.ResponseBody; public class TypeMapperFixture { - - protected static final String VERSIONS = "{ \"versions\": [\"v1\"]}"; - protected static final String base = "https://localhost:8443"; - private static final String ANY = "--any--"; - private TestOkHttpClient client = spy(new TestOkHttpClient()); - - protected IApiTypeMapper mapper; - - protected IApiTypeMapper getApiTypeMapper() { - return mapper; - } - - protected TestOkHttpClient getHttpClient() { - return client; - } - - protected IClient getIClient() throws Exception { - return new DefaultClient(new URL(base), client, new ResourceFactory(null), mapper, null); - } - - @Before - public void setUp() throws Exception { - client.whenRequestTo(ANY).thenReturn(responseOf("")); - client.whenRequestTo(base + "/api").thenReturn(responseOf(VERSIONS)); - client.whenRequestTo(base + "/oapi").thenReturn(responseOf(VERSIONS)); - client.whenRequestTo(base + "/apis").thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS.getContentAsString())); - client.whenRequestTo(base + "/api/v1").thenReturn(responseOf(Samples.GROUP_ENDPONT_API_V1.getContentAsString())); - client.whenRequestTo(base + "/oapi/v1").thenReturn(responseOf(Samples.GROUP_ENDPONT_OAPI_V1.getContentAsString())); - client.whenRequestTo(base + "/apis/extensions/v1beta1").thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS_EXTENSIONS.getContentAsString())); - client.whenRequestTo(base + "/version").thenReturn(responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); - client.whenRequestTo(base + "/version/openshift").thenReturn(responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); - mapper = new ApiTypeMapper(base, client); - } - - static class TestOkHttpClient extends OkHttpClient{ - - OngoingStubbing whenRequestTo(String url) throws IOException{ - Call call = mock(Call.class); - doReturn(call).when(this).newCall(requestTo(url)); - return when(call.execute()); - } - - } - - static Request requestTo(String url) { - return argThat(new RequestMatcher(url)); - } - - protected static Response responseOf(String response) { - return new Response.Builder() - .request(new Request.Builder().url("https://someurlfortesting").build()) - .protocol(Protocol.HTTP_1_1) - .code(IHttpConstants.STATUS_OK) - .body(ResponseBody.create(null, response)) - .build(); - } - - static class RequestMatcher extends ArgumentMatcher{ - - private final String url; - - public RequestMatcher(String url) { - this.url = url; - } - - @Override - public boolean matches(Object argument) { - if(ANY.equals(this.url)) return true; - if(argument == null || !(argument instanceof Request)) - return false; - return ((Request)argument).url().toString().equals(url); - } - - } + + protected static final String VERSIONS = "{ \"versions\": [\"v1\"]}"; + protected static final String base = "https://localhost:8443"; + private static final String ANY = "--any--"; + private TestOkHttpClient client = spy(new TestOkHttpClient()); + + protected IApiTypeMapper mapper; + + protected IApiTypeMapper getApiTypeMapper() { + return mapper; + } + + protected TestOkHttpClient getHttpClient() { + return client; + } + + protected IClient getIClient() throws Exception { + return new DefaultClient(new URL(base), client, new ResourceFactory(null), mapper, null); + } + + @Before + public void setUp() throws Exception { + client.whenRequestTo(ANY).thenReturn(responseOf("")); + client.whenRequestTo(base + "/api").thenReturn(responseOf(VERSIONS)); + client.whenRequestTo(base + "/oapi").thenReturn(responseOf(VERSIONS)); + client.whenRequestTo(base + "/apis").thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS.getContentAsString())); + client.whenRequestTo(base + "/api/v1") + .thenReturn(responseOf(Samples.GROUP_ENDPONT_API_V1.getContentAsString())); + client.whenRequestTo(base + "/oapi/v1") + .thenReturn(responseOf(Samples.GROUP_ENDPONT_OAPI_V1.getContentAsString())); + client.whenRequestTo(base + "/apis/extensions/v1beta1") + .thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS_EXTENSIONS.getContentAsString())); + client.whenRequestTo(base + "/version").thenReturn(responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); + client.whenRequestTo(base + "/version/openshift") + .thenReturn(responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); + mapper = new ApiTypeMapper(base, client); + } + + static class TestOkHttpClient extends OkHttpClient { + + OngoingStubbing whenRequestTo(String url) throws IOException { + Call call = mock(Call.class); + doReturn(call).when(this).newCall(requestTo(url)); + return when(call.execute()); + } + + } + + static Request requestTo(String url) { + return argThat(new RequestMatcher(url)); + } + + protected static Response responseOf(String response) { + return new Response.Builder().request(new Request.Builder().url("https://someurlfortesting").build()) + .protocol(Protocol.HTTP_1_1).code(IHttpConstants.STATUS_OK).body(ResponseBody.create(null, response)) + .build(); + } + + static class RequestMatcher extends ArgumentMatcher { + + private final String url; + + public RequestMatcher(String url) { + this.url = url; + } + + @Override + public boolean matches(Object argument) { + if (ANY.equals(this.url)) { + return true; + } + if (argument == null || !(argument instanceof Request)) { + return false; + } + return ((Request) argument).url().toString().equals(url); + } + + } } diff --git a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java index b16b4c94..16a66972 100644 --- a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java @@ -8,123 +8,105 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient; -import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.model.IResource; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ @RunWith(MockitoJUnitRunner.class) -public class URLBuilderTest extends TypeMapperFixture{ - - private static final String BASE_URL = "https://localhost:8443"; - private URLBuilder builder; - - @Before - public void setup() throws MalformedURLException { - builder = new URLBuilder(new URL(BASE_URL), mapper); - } - - @Test - public void testBuildingURLForAWatchService() throws Exception { - IResource resource = givenAResource(ResourceKind.SERVICE, KubernetesAPIVersion.v1,"foo"); - - Map params = new HashMap<>(); - params.put("foo", "bar"); - - String url = builder. - resource(resource) - .watch() - .addParmeter("resourceVersion", "123") - .addParameters(params) - .build().toString(); - assertEquals(String.format("%s/api/v1/namespaces/foo/services?watch=true&resourceVersion=123&foo=bar", BASE_URL),url.toString()); - } - - @Test - public void testDuplicateParameters() throws Exception { - IResource resource = givenAResource(ResourceKind.SERVICE, KubernetesAPIVersion.v1,"foo"); - String url = builder. - resource(resource) - .watch() - .addParmeter("resourceVersion", "123") - .addParmeter("x", "1") - .addParmeter("x", "2") - .build().toString(); - assertEquals(String.format("%s/api/v1/namespaces/foo/services?watch=true&resourceVersion=123&x=1&x=2", BASE_URL),url.toString()); - } - - @Test - public void testBuildingURLForAProjectUsingResource() throws Exception { - IResource resource = givenAResource(ResourceKind.PROJECT, KubernetesAPIVersion.v1,"foo"); - - String url = builder. - resource(resource) - .name("foo") - .build().toString(); - assertEquals(String.format("%s/oapi/v1/projects/foo", BASE_URL),url.toString()); - } - - @Test - public void testBaseURLWithTrailingSlash() throws Exception { - builder = new URLBuilder(new URL(BASE_URL + "///"), mapper); - IResource resource = givenAResource(ResourceKind.SERVICE, KubernetesAPIVersion.v1,"foo"); - - String url = whenBuildingTheURLFor(resource, "foo"); - assertEquals(String.format("%s/api/v1/namespaces/foo/services/bar", BASE_URL),url.toString()); - } - - @Test - public void testAddingASubResource() { - IResource resource = givenAResource(ResourceKind.REPLICATION_CONTROLLER, KubernetesAPIVersion.v1, "foo"); - String url = builder. - resource(resource) - .name("bar") - .subresource("status") - .build().toString(); - assertEquals(String.format("%s/api/v1/namespaces/foo/replicationcontrollers/bar/status", BASE_URL),url.toString()); - } - - @Test - public void testAddingASubContext() { - IResource resource = givenAResource(ResourceKind.POD, KubernetesAPIVersion.v1, "https:demo-app-8-3gehi:8778"); - String url = builder. - resource(resource) - .name("bar") - .subresource("proxy") - .subContext("jolokia/exec/java.util.logging:type=Logging/getLoggerLevel/abc") - .build().toString(); - assertEquals(String.format("%s/api/v1/namespaces/https:demo-app-8-3gehi:8778/pods/bar/proxy/jolokia/exec/java.util.logging:type=Logging/getLoggerLevel/abc", BASE_URL),url.toString()); - } - - private String whenBuildingTheURLFor(IResource resource, String namespace) { - return builder. - resource(resource) - .namespace(namespace) - .name("bar") - .build().toString(); - } - - private IResource givenAResource(String kind, KubernetesAPIVersion version, String namespace) { - IResource resource = mock(IResource.class); - when(resource.getApiVersion()).thenReturn(version.toString()); - when(resource.getKind()).thenReturn(kind); - when(resource.getNamespaceName()).thenReturn(namespace); - return resource; - } +public class URLBuilderTest extends TypeMapperFixture { + + private static final String BASE_URL = "https://localhost:8443"; + private URLBuilder builder; + + @Before + public void setup() throws MalformedURLException { + builder = new URLBuilder(new URL(BASE_URL), mapper); + } + + @Test + public void testBuildingURLForAWatchService() throws Exception { + IResource resource = givenAResource(ResourceKind.SERVICE, KubernetesAPIVersion.v1, "foo"); + + Map params = new HashMap<>(); + params.put("foo", "bar"); + + String url = builder.resource(resource).watch().addParmeter("resourceVersion", "123").addParameters(params) + .build().toString(); + assertEquals( + String.format("%s/api/v1/namespaces/foo/services?watch=true&resourceVersion=123&foo=bar", BASE_URL), + url.toString()); + } + + @Test + public void testDuplicateParameters() throws Exception { + IResource resource = givenAResource(ResourceKind.SERVICE, KubernetesAPIVersion.v1, "foo"); + String url = builder.resource(resource).watch().addParmeter("resourceVersion", "123").addParmeter("x", "1") + .addParmeter("x", "2").build().toString(); + assertEquals( + String.format("%s/api/v1/namespaces/foo/services?watch=true&resourceVersion=123&x=1&x=2", BASE_URL), + url.toString()); + } + + @Test + public void testBuildingURLForAProjectUsingResource() throws Exception { + IResource resource = givenAResource(ResourceKind.PROJECT, KubernetesAPIVersion.v1, "foo"); + + String url = builder.resource(resource).name("foo").build().toString(); + assertEquals(String.format("%s/oapi/v1/projects/foo", BASE_URL), url.toString()); + } + + @Test + public void testBaseURLWithTrailingSlash() throws Exception { + builder = new URLBuilder(new URL(BASE_URL + "///"), mapper); + IResource resource = givenAResource(ResourceKind.SERVICE, KubernetesAPIVersion.v1, "foo"); + + String url = whenBuildingTheURLFor(resource, "foo"); + assertEquals(String.format("%s/api/v1/namespaces/foo/services/bar", BASE_URL), url.toString()); + } + + @Test + public void testAddingASubResource() { + IResource resource = givenAResource(ResourceKind.REPLICATION_CONTROLLER, KubernetesAPIVersion.v1, "foo"); + String url = builder.resource(resource).name("bar").subresource("status").build().toString(); + assertEquals(String.format("%s/api/v1/namespaces/foo/replicationcontrollers/bar/status", BASE_URL), + url.toString()); + } + + @Test + public void testAddingASubContext() { + IResource resource = givenAResource(ResourceKind.POD, KubernetesAPIVersion.v1, "https:demo-app-8-3gehi:8778"); + String url = builder.resource(resource).name("bar").subresource("proxy") + .subContext("jolokia/exec/java.util.logging:type=Logging/getLoggerLevel/abc").build().toString(); + assertEquals(String.format( + "%s/api/v1/namespaces/https:demo-app-8-3gehi:8778/pods/bar/proxy/jolokia/exec/java.util.logging:type=Logging/getLoggerLevel/abc", + BASE_URL), url.toString()); + } + + private String whenBuildingTheURLFor(IResource resource, String namespace) { + return builder.resource(resource).namespace(namespace).name("bar").build().toString(); + } + + private IResource givenAResource(String kind, KubernetesAPIVersion version, String namespace) { + IResource resource = mock(IResource.class); + when(resource.getApiVersion()).thenReturn(version.toString()); + when(resource.getKind()).thenReturn(kind); + when(resource.getNamespaceName()).thenReturn(namespace); + return resource; + } } diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java index 9ec552db..f42f1e51 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java @@ -8,20 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.api.capabilities; -import com.openshift.internal.restclient.IntegrationTestHelper; -import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.api.capabilities.IPodExec; -import com.openshift.restclient.capability.CapabilityVisitor; -import com.openshift.restclient.capability.IStoppable; -import com.openshift.restclient.model.IPod; -import com.openshift.restclient.model.IResource; -import org.junit.Before; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.util.ArrayList; @@ -31,180 +23,189 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; -import static org.junit.Assert.*; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.api.capabilities.IPodExec; +import com.openshift.restclient.capability.CapabilityVisitor; +import com.openshift.restclient.capability.IStoppable; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IResource; public class PodExecIntegrationTest { - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private Exception ex; - private IPod pod; - - public static class TestExecListener implements IPodExec.IPodExecOutputListener { - - private static final Logger LOG = LoggerFactory.getLogger(PodExecIntegrationTest.class); - - - public final CountDownLatch testDone = new CountDownLatch(1); - public final AtomicBoolean openCalled = new AtomicBoolean(false); - public final AtomicBoolean closeCalled = new AtomicBoolean(false); - public final AtomicBoolean failureCalled = new AtomicBoolean(false); - public final AtomicBoolean execErrCalled = new AtomicBoolean(false); - public final List messages = Collections.synchronizedList( new ArrayList() ); - - @Override - public void onOpen() { - assertTrue(openCalled.compareAndSet(false,true)); - } - - @Override - public void onStdOut(String message) { - LOG.debug( "onStdOut: " + message ); - message = message.trim(); - if ( message.isEmpty() == false ) { // Observing that actual output appears after empty newline - messages.add( PodExec.CHANNEL_STDOUT+message ); - } - } - - @Override - public void onStdErr(String message) { - LOG.debug( "onStdErr: " + message ); - message = message.trim(); - messages.add( PodExec.CHANNEL_STDERR+message ); - } - - @Override - public void onExecErr(String message) { - LOG.debug( "onExecError: " + message ); - execErrCalled.set(true); - message = message.trim(); - messages.add( PodExec.CHANNEL_EXECERR+message ); - } - - @Override - public void onClose(int code, String reason) { - assertTrue(closeCalled.compareAndSet(false,true)); - testDone.countDown(); - } - - @Override - public void onFailure(IOException e) { - failureCalled.set(true); - LOG.error( "Potentially expected error occurred", e ); - testDone.countDown(); - } - - } - - @Before - public void setUp() throws Exception { - IClient client = helper.createClientForBasicAuth(); - List pods = client.list(ResourceKind.POD, "default"); - pod = (IPod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); - assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); - } - - @Test - public void testPodExec() throws Exception { - String[] echoCommand = { "echo", "a", "b", "c" }; - TestExecListener echoListener = new TestExecListener(); - - pod.accept(new CapabilityVisitor() { - @Override - public IStoppable visit(IPodExec capability) { - return capability.start( echoListener, null, echoCommand ); - } - }, null); - - echoListener.testDone.await( 60, TimeUnit.SECONDS ); - assertTrue( echoListener.openCalled.get() ); - assertTrue( echoListener.closeCalled.get() ); - assertTrue( !echoListener.failureCalled.get() ); - assertTrue( !echoListener.execErrCalled.get() ); - assertEquals( 1, echoListener.messages.size() ); - assertEquals( "1a b c", echoListener.messages.get(0)); - } - - @Test - public void testPodExecWithContainerSpecified() throws Exception { - String[] echoCommand = { "echo", "a", "b", "c" }; - TestExecListener echoListener = new TestExecListener(); - - final String container = pod.getContainers().iterator().next().getName(); - IPodExec.Options options = new IPodExec.Options(); - options.container( container ); - - pod.accept(new CapabilityVisitor() { - @Override - public IStoppable visit(IPodExec capability) { - return capability.start( echoListener, options, echoCommand ); - } - }, null); - - echoListener.testDone.await( 60, TimeUnit.SECONDS ); - assertTrue( echoListener.openCalled.get() ); - assertTrue( echoListener.closeCalled.get() ); - assertTrue( !echoListener.failureCalled.get() ); - assertTrue( !echoListener.execErrCalled.get() ); - assertEquals( 1, echoListener.messages.size() ); - assertEquals( "1a b c", echoListener.messages.get(0)); - } - - @Test - public void testCommandNotFound() throws Exception { - String[] badCommand = { "/bin/doesnotexist" }; - TestExecListener badListener = new TestExecListener(); - - pod.accept(new CapabilityVisitor() { - @Override - public IStoppable visit(IPodExec capability) { - return capability.start( badListener, null, badCommand ); - } - }, null); - - badListener.testDone.await( 60, TimeUnit.SECONDS ); - assertTrue( badListener.openCalled.get() ); - assertTrue( badListener.closeCalled.get() ); - assertTrue( badListener.execErrCalled.get() ); - // both execErr and stdErr will be called - assertEquals( 2, badListener.messages.size() ); - } - - @Test - public void testPodExecStop() throws Exception { - String[] longCommand = { "sleep", "500" }; - TestExecListener longListener = new TestExecListener(); - - IStoppable stopLong = pod.accept(new CapabilityVisitor() { - @Override - public IStoppable visit(IPodExec capability) { - return capability.start( longListener, null, longCommand ); - } - }, null); - - // Trigger a cancel on the web socket before long delay can complete - stopLong.stop(); - longListener.testDone.await( 60, TimeUnit.SECONDS ); - assertTrue( longListener.failureCalled.get() ); - } - - @Test - public void testContainerDoesNotExist() throws Exception { - String[] dateCommand = { "date" }; - TestExecListener dateListener = new TestExecListener(); - IPodExec.Options options = new IPodExec.Options(); - options.container( "will-not-exist-in-docker-registry-pod" ); - - pod.accept(new CapabilityVisitor() { - @Override - public IStoppable visit(IPodExec capability) { - return capability.start( dateListener, options, dateCommand ); - } - }, null); - - dateListener.testDone.await( 60, TimeUnit.SECONDS ); - assertTrue( dateListener.failureCalled.get() ); - } - + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private Exception ex; + private IPod pod; + + public static class TestExecListener implements IPodExec.IPodExecOutputListener { + + private static final Logger LOG = LoggerFactory.getLogger(PodExecIntegrationTest.class); + + public final CountDownLatch testDone = new CountDownLatch(1); + public final AtomicBoolean openCalled = new AtomicBoolean(false); + public final AtomicBoolean closeCalled = new AtomicBoolean(false); + public final AtomicBoolean failureCalled = new AtomicBoolean(false); + public final AtomicBoolean execErrCalled = new AtomicBoolean(false); + public final List messages = Collections.synchronizedList(new ArrayList()); + + @Override + public void onOpen() { + assertTrue(openCalled.compareAndSet(false, true)); + } + + @Override + public void onStdOut(String message) { + LOG.debug("onStdOut: " + message); + message = message.trim(); + if (message.isEmpty() == false) { // Observing that actual output appears after empty newline + messages.add(PodExec.CHANNEL_STDOUT + message); + } + } + + @Override + public void onStdErr(String message) { + LOG.debug("onStdErr: " + message); + message = message.trim(); + messages.add(PodExec.CHANNEL_STDERR + message); + } + + @Override + public void onExecErr(String message) { + LOG.debug("onExecError: " + message); + execErrCalled.set(true); + message = message.trim(); + messages.add(PodExec.CHANNEL_EXECERR + message); + } + + @Override + public void onClose(int code, String reason) { + assertTrue(closeCalled.compareAndSet(false, true)); + testDone.countDown(); + } + + @Override + public void onFailure(IOException e) { + failureCalled.set(true); + LOG.error("Potentially expected error occurred", e); + testDone.countDown(); + } + + } + + @Before + public void setUp() throws Exception { + IClient client = helper.createClientForBasicAuth(); + List pods = client.list(ResourceKind.POD, "default"); + pod = (IPod) pods.stream().filter(p -> p.getName().startsWith("docker-registry")).findFirst().orElse(null); + assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); + } + + @Test + public void testPodExec() throws Exception { + String[] echoCommand = { "echo", "a", "b", "c" }; + TestExecListener echoListener = new TestExecListener(); + + pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start(echoListener, null, echoCommand); + } + }, null); + + echoListener.testDone.await(60, TimeUnit.SECONDS); + assertTrue(echoListener.openCalled.get()); + assertTrue(echoListener.closeCalled.get()); + assertTrue(!echoListener.failureCalled.get()); + assertTrue(!echoListener.execErrCalled.get()); + assertEquals(1, echoListener.messages.size()); + assertEquals("1a b c", echoListener.messages.get(0)); + } + + @Test + public void testPodExecWithContainerSpecified() throws Exception { + String[] echoCommand = { "echo", "a", "b", "c" }; + TestExecListener echoListener = new TestExecListener(); + + final String container = pod.getContainers().iterator().next().getName(); + IPodExec.Options options = new IPodExec.Options(); + options.container(container); + + pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start(echoListener, options, echoCommand); + } + }, null); + + echoListener.testDone.await(60, TimeUnit.SECONDS); + assertTrue(echoListener.openCalled.get()); + assertTrue(echoListener.closeCalled.get()); + assertTrue(!echoListener.failureCalled.get()); + assertTrue(!echoListener.execErrCalled.get()); + assertEquals(1, echoListener.messages.size()); + assertEquals("1a b c", echoListener.messages.get(0)); + } + + @Test + public void testCommandNotFound() throws Exception { + String[] badCommand = { "/bin/doesnotexist" }; + TestExecListener badListener = new TestExecListener(); + + pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start(badListener, null, badCommand); + } + }, null); + + badListener.testDone.await(60, TimeUnit.SECONDS); + assertTrue(badListener.openCalled.get()); + assertTrue(badListener.closeCalled.get()); + assertTrue(badListener.execErrCalled.get()); + // both execErr and stdErr will be called + assertEquals(2, badListener.messages.size()); + } + + @Test + public void testPodExecStop() throws Exception { + String[] longCommand = { "sleep", "500" }; + TestExecListener longListener = new TestExecListener(); + + IStoppable stopLong = pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start(longListener, null, longCommand); + } + }, null); + + // Trigger a cancel on the web socket before long delay can complete + stopLong.stop(); + longListener.testDone.await(60, TimeUnit.SECONDS); + assertTrue(longListener.failureCalled.get()); + } + + @Test + public void testContainerDoesNotExist() throws Exception { + String[] dateCommand = { "date" }; + TestExecListener dateListener = new TestExecListener(); + IPodExec.Options options = new IPodExec.Options(); + options.container("will-not-exist-in-docker-registry-pod"); + + pod.accept(new CapabilityVisitor() { + @Override + public IStoppable visit(IPodExec capability) { + return capability.start(dateListener, options, dateCommand); + } + }, null); + + dateListener.testDone.await(60, TimeUnit.SECONDS); + assertTrue(dateListener.failureCalled.get()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java index 2bcde2d3..86dfb6f9 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java @@ -8,8 +8,21 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.api.capabilities; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.TypeMapperFixture; import com.openshift.internal.restclient.capability.resources.PodLogRetrievalAsync; @@ -17,99 +30,88 @@ import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.MocksFactory; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class PodExecTest extends TypeMapperFixture { - private DefaultClient client; - @Mock - private IApiTypeMapper mapper; - private PodLogRetrievalAsync capability; - private IPod pod; - private PodExec.ExecOutputListenerAdapter adapter; - - @Mock - private IPodExec.IPodExecOutputListener listener; - - @Before - public void setUp() throws Exception { - super.setUp(); - client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); - pod = new MocksFactory().mock(IPod.class); - capability = new PodLogRetrievalAsync(pod, client); - adapter = new PodExec.ExecOutputListenerAdapter(null, listener); - } - - @Test - public void testIsSupported() { - assertTrue("Exp. capability to be supported because the pod endpoint exists", capability.isSupported()); - } - - @Test - public void testIsNotSupportedWhenEndpointDoesNotExist() { - when(pod.getApiVersion()).thenReturn("somenoneexitentversion"); - assertFalse("Exp. capability to not be supported because the pod endpoint does not exist exists", capability.isSupported()); - } - - @Test - public void testAdapterCallsListenerCycle() throws Exception { - adapter.onOpen(null, null); - adapter.onOpen(null, null); - verify(listener).onOpen(); - - - adapter.deliver(PodExec.CHANNEL_STDOUT, "ImStdOut"); - adapter.deliver(PodExec.CHANNEL_STDERR, "ImStdErr"); - adapter.deliver(PodExec.CHANNEL_EXECERR, "ImExecErr"); - - verify(listener).onStdOut("ImStdOut"); - verify(listener).onStdErr("ImStdErr"); - verify(listener).onExecErr("ImExecErr"); - - adapter.onClose(1986, "the reason"); - adapter.onClose(1986, "the reason"); - verify(listener).onClose(1986, "the reason"); - } - - @Test - public void testExecOptions() throws Exception { - IPodExec.Options options = new IPodExec.Options(); - assertEquals( 0, options.getMap().size() ); - - options.stdErr( false ); - options.stdOut( false ); - options.container( "test" ); - - assertEquals( 3, options.getMap().size() ); - - assertEquals( "false", options.getMap().get(IPodExec.Options.STDERR) ); - assertEquals( "false", options.getMap().get(IPodExec.Options.STDOUT) ); - assertEquals( "test", options.getMap().get(IPodExec.Options.CONTAINER) ); - - options.parameter( IPodExec.Options.STDERR, "true" ); - options.parameter( IPodExec.Options.STDOUT, "true" ); - options.parameter( IPodExec.Options.CONTAINER, "override" ); - - // Re-set these options to ensure they do not override parameter API - options.stdErr( false ); - options.stdOut( false ); - options.container( "test" ); - - assertEquals( "true", options.getMap().get(IPodExec.Options.STDERR) ); - assertEquals( "true", options.getMap().get(IPodExec.Options.STDOUT) ); - assertEquals( "override", options.getMap().get(IPodExec.Options.CONTAINER) ); - - } + private DefaultClient client; + @Mock + private IApiTypeMapper mapper; + private PodLogRetrievalAsync capability; + private IPod pod; + private PodExec.ExecOutputListenerAdapter adapter; + + @Mock + private IPodExec.IPodExecOutputListener listener; + + @Before + public void setUp() throws Exception { + super.setUp(); + client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); + pod = new MocksFactory().mock(IPod.class); + capability = new PodLogRetrievalAsync(pod, client); + adapter = new PodExec.ExecOutputListenerAdapter(null, listener); + } + + @Test + public void testIsSupported() { + assertTrue("Exp. capability to be supported because the pod endpoint exists", capability.isSupported()); + } + + @Test + public void testIsNotSupportedWhenEndpointDoesNotExist() { + when(pod.getApiVersion()).thenReturn("somenoneexitentversion"); + assertFalse("Exp. capability to not be supported because the pod endpoint does not exist exists", + capability.isSupported()); + } + + @Test + public void testAdapterCallsListenerCycle() throws Exception { + adapter.onOpen(null, null); + adapter.onOpen(null, null); + verify(listener).onOpen(); + + adapter.deliver(PodExec.CHANNEL_STDOUT, "ImStdOut"); + adapter.deliver(PodExec.CHANNEL_STDERR, "ImStdErr"); + adapter.deliver(PodExec.CHANNEL_EXECERR, "ImExecErr"); + + verify(listener).onStdOut("ImStdOut"); + verify(listener).onStdErr("ImStdErr"); + verify(listener).onExecErr("ImExecErr"); + + adapter.onClose(1986, "the reason"); + adapter.onClose(1986, "the reason"); + verify(listener).onClose(1986, "the reason"); + } + + @Test + public void testExecOptions() throws Exception { + IPodExec.Options options = new IPodExec.Options(); + assertEquals(0, options.getMap().size()); + + options.stdErr(false); + options.stdOut(false); + options.container("test"); + + assertEquals(3, options.getMap().size()); + + assertEquals("false", options.getMap().get(IPodExec.Options.STDERR)); + assertEquals("false", options.getMap().get(IPodExec.Options.STDOUT)); + assertEquals("test", options.getMap().get(IPodExec.Options.CONTAINER)); + + options.parameter(IPodExec.Options.STDERR, "true"); + options.parameter(IPodExec.Options.STDOUT, "true"); + options.parameter(IPodExec.Options.CONTAINER, "override"); + + // Re-set these options to ensure they do not override parameter API + options.stdErr(false); + options.stdOut(false); + options.container("test"); + + assertEquals("true", options.getMap().get(IPodExec.Options.STDERR)); + assertEquals("true", options.getMap().get(IPodExec.Options.STDOUT)); + assertEquals("override", options.getMap().get(IPodExec.Options.CONTAINER)); + + } } \ No newline at end of file diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java index c741550e..910aa652 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java @@ -8,9 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.api.capabilities; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.util.List; import java.util.concurrent.CountDownLatch; @@ -36,92 +38,97 @@ public class ScaleCapabilityIntegrationTest { - private static final int REPLICAS = 2; - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private IClient client; - private IProject project; - private IWatcher watch; - private CountDownLatch initializationLatch = new CountDownLatch(2); - private CountDownLatch replicaLatch = new CountDownLatch(1); - private IReplicationController dc; - private AtomicBoolean foundFirstPod = new AtomicBoolean(false); - private PodStatusRunningConditional conditional = new PodStatusRunningConditional(); - - @Before - public void setUp() throws Exception { - client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); - } - - @After - public void teardown() throws Exception{ - if(watch != null) { - try { - watch.stop(); - }catch(Exception e) { - } - } - IntegrationTestHelper.cleanUpResource(client, project); - } - @Test(timeout=3*1000*60) - public void testScalingReplicationController() throws Exception { - dc = client.create(IntegrationTestHelper.stubReplicationController(client, project)); - runTest(); - } - - @Test(timeout=3*1000*60) - public void testScalingDeploymentConfig() throws Exception { - dc = client.create(IntegrationTestHelper.stubDeploymentConfig(client, project)); - runTest(); - } - - private void runTest() throws Exception { - watch = client.watch(project.getName(), new IOpenShiftWatchListener() { - - @Override - public void connected(List resources) { - initializationLatch.countDown(); - } - - @Override - public void disconnected() { - - } - - @Override - public void received(IResource resource, ChangeType change) { - if(ChangeType.MODIFIED.equals(change) && !resource.getName().endsWith("deploy") && conditional.isReady(resource)) { - if(foundFirstPod.get()){ - replicaLatch.countDown(); - }else { - foundFirstPod.set(true); - initializationLatch.countDown(); - } - } - } - - @Override - public void error(Throwable err) { - - } - - }, ResourceKind.POD); - - if(initializationLatch.await(1, TimeUnit.MINUTES)){ - scaleTo(REPLICAS); - assertTrue("The pods either did not scale as expected or the test timed out", replicaLatch.await(2, TimeUnit.MINUTES)); - }; - - } - - private void scaleTo(int replicas) { - IScale result = dc.accept(new CapabilityVisitor() { - - @Override - public IScale visit(IScalable capability) { - return capability.scaleTo(replicas); - } - }, null); - assertNotNull("Exp. to receive a non-null result", result); - } + private static final int REPLICAS = 2; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IClient client; + private IProject project; + private IWatcher watch; + private CountDownLatch initializationLatch = new CountDownLatch(2); + private CountDownLatch replicaLatch = new CountDownLatch(1); + private IReplicationController dc; + private AtomicBoolean foundFirstPod = new AtomicBoolean(false); + private PodStatusRunningConditional conditional = new PodStatusRunningConditional(); + + @Before + public void setUp() throws Exception { + client = helper.createClientForBasicAuth(); + project = helper.generateProject(client); + } + + @After + public void teardown() throws Exception { + if (watch != null) { + try { + watch.stop(); + } catch (Exception e) { + // swallow + } + } + IntegrationTestHelper.cleanUpResource(client, project); + } + + @Test(timeout = 3 * 1000 * 60) + public void testScalingReplicationController() throws Exception { + dc = client.create(IntegrationTestHelper.stubReplicationController(client, project)); + runTest(); + } + + @Test(timeout = 3 * 1000 * 60) + public void testScalingDeploymentConfig() throws Exception { + dc = client.create(IntegrationTestHelper.stubDeploymentConfig(client, project)); + runTest(); + } + + private void runTest() throws Exception { + watch = client.watch(project.getName(), new IOpenShiftWatchListener() { + + @Override + public void connected(List resources) { + initializationLatch.countDown(); + } + + @Override + public void disconnected() { + + } + + @Override + public void received(IResource resource, ChangeType change) { + if (ChangeType.MODIFIED.equals(change) && !resource.getName().endsWith("deploy") + && conditional.isReady(resource)) { + if (foundFirstPod.get()) { + replicaLatch.countDown(); + } else { + foundFirstPod.set(true); + initializationLatch.countDown(); + } + } + } + + @Override + public void error(Throwable err) { + + } + + }, ResourceKind.POD); + + if (initializationLatch.await(1, TimeUnit.MINUTES)) { + scaleTo(REPLICAS); + assertTrue("The pods either did not scale as expected or the test timed out", + replicaLatch.await(2, TimeUnit.MINUTES)); + } + ; + + } + + private void scaleTo(int replicas) { + IScale result = dc.accept(new CapabilityVisitor() { + + @Override + public IScale visit(IScalable capability) { + return capability.scaleTo(replicas); + } + }, null); + assertNotNull("Exp. to receive a non-null result", result); + } } diff --git a/src/test/java/com/openshift/internal/restclient/apis/TypeMetaFactoryTest.java b/src/test/java/com/openshift/internal/restclient/apis/TypeMetaFactoryTest.java index 198221c5..b7188979 100644 --- a/src/test/java/com/openshift/internal/restclient/apis/TypeMetaFactoryTest.java +++ b/src/test/java/com/openshift/internal/restclient/apis/TypeMetaFactoryTest.java @@ -8,15 +8,17 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ -package com.openshift.internal.restclient.apis; -import static org.junit.Assert.*; +package com.openshift.internal.restclient.apis; -import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import java.util.Optional; -import com.openshift.internal.restclient.apis.TypeMetaFactory; +import org.junit.Test; + import com.openshift.restclient.api.ITypeFactory; import com.openshift.restclient.api.models.ITypeMeta; import com.openshift.restclient.apis.autoscaling.models.IScale; @@ -24,31 +26,31 @@ import com.openshift.restclient.utils.Samples; public class TypeMetaFactoryTest { - - private final ITypeFactory factory = new TypeMetaFactory(); - - @Test - public void testStubKind() { - Object obj = factory.stubKind("extensions/v1beta1.Scale", Optional.of("foo"), Optional.of("bar")); - assertTrue(obj instanceof IScale); - IScale scale = (IScale) obj; - assertEquals("foo", scale.getName()); - assertEquals("bar", scale.getNamespace()); - assertEquals("Scale", scale.getKind()); - assertEquals("extensions/v1beta1", scale.getApiVersion()); - } - - @Test - public void testExtensionScale() { - Object response = factory.createInstanceFrom(Samples.V1BETA1_API_EXT_SCALE.getContentAsString()); - assertTrue(response instanceof IScale); - } - - @Test - public void testUnrecognized() { - Object response = factory.createInstanceFrom(Samples.V1_BUILD.getContentAsString()); - assertFalse(response instanceof IBuild); - assertTrue(response instanceof ITypeMeta); - } + + private final ITypeFactory factory = new TypeMetaFactory(); + + @Test + public void testStubKind() { + Object obj = factory.stubKind("extensions/v1beta1.Scale", Optional.of("foo"), Optional.of("bar")); + assertTrue(obj instanceof IScale); + IScale scale = (IScale) obj; + assertEquals("foo", scale.getName()); + assertEquals("bar", scale.getNamespace()); + assertEquals("Scale", scale.getKind()); + assertEquals("extensions/v1beta1", scale.getApiVersion()); + } + + @Test + public void testExtensionScale() { + Object response = factory.createInstanceFrom(Samples.V1BETA1_API_EXT_SCALE.getContentAsString()); + assertTrue(response instanceof IScale); + } + + @Test + public void testUnrecognized() { + Object response = factory.createInstanceFrom(Samples.V1_BUILD.getContentAsString()); + assertFalse(response instanceof IBuild); + assertTrue(response instanceof ITypeMeta); + } } diff --git a/src/test/java/com/openshift/internal/restclient/apis/extensions/model/v1beta1/ScaleTest.java b/src/test/java/com/openshift/internal/restclient/apis/extensions/model/v1beta1/ScaleTest.java index f675ec1c..83c30d9b 100644 --- a/src/test/java/com/openshift/internal/restclient/apis/extensions/model/v1beta1/ScaleTest.java +++ b/src/test/java/com/openshift/internal/restclient/apis/extensions/model/v1beta1/ScaleTest.java @@ -8,9 +8,10 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.apis.extensions.model.v1beta1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.util.Collections; @@ -23,45 +24,45 @@ import com.openshift.restclient.utils.Samples; public class ScaleTest { - - private static final String JSON = Samples.V1BETA1_API_EXT_SCALE.getContentAsString(); - IScale scale; - - @Before - public void setUp() throws Exception { - ModelNode node = ModelNode.fromJSONString(JSON); - scale = new Scale(node, Collections.emptyMap()); - } - - @Test - public void testGetSetName() { - assertEquals("logging-kibana", scale.getName()); - scale.setName("other"); - assertEquals("other", scale.getName()); - } - - @Test - public void testGetSetNamespace() { - assertEquals("logging", scale.getNamespace()); - scale.setNamespace("other-ns"); - assertEquals("other-ns", scale.getNamespace()); - } - - @Test - public void testGetApiVersion() { - assertEquals("extensions/v1beta1", scale.getApiVersion()); - } - @Test - public void testGetKind() { - assertEquals("Scale", scale.getKind()); - } - - @Test - public void testSetGetSpecReplicas() { - assertEquals(2, scale.getSpecReplicas()); - scale.setSpecReplicas(30); - assertEquals(30, scale.getSpecReplicas()); - } + private static final String JSON = Samples.V1BETA1_API_EXT_SCALE.getContentAsString(); + IScale scale; + + @Before + public void setUp() throws Exception { + ModelNode node = ModelNode.fromJSONString(JSON); + scale = new Scale(node, Collections.emptyMap()); + } + + @Test + public void testGetSetName() { + assertEquals("logging-kibana", scale.getName()); + scale.setName("other"); + assertEquals("other", scale.getName()); + } + + @Test + public void testGetSetNamespace() { + assertEquals("logging", scale.getNamespace()); + scale.setNamespace("other-ns"); + assertEquals("other-ns", scale.getNamespace()); + } + + @Test + public void testGetApiVersion() { + assertEquals("extensions/v1beta1", scale.getApiVersion()); + } + + @Test + public void testGetKind() { + assertEquals("Scale", scale.getKind()); + } + + @Test + public void testSetGetSpecReplicas() { + assertEquals(2, scale.getSpecReplicas()); + scale.setSpecReplicas(30); + assertEquals(30, scale.getSpecReplicas()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationDetailsTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationDetailsTest.java index 49f0f77d..8d37bcdc 100644 --- a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationDetailsTest.java +++ b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationDetailsTest.java @@ -8,56 +8,57 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.authorization; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; import okhttp3.Headers; -/** - * @author Jeff Cantrill - */ public class AuthorizationDetailsTest { - /* - * WWW-Authenticate: OAuth realm= - * WWW-Authenticate: Basic - * Link: ; rel="related" - * Warning: 199 OpenShift "You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request" - * code 401 - */ - private Headers.Builder builder = new Headers.Builder(); - - @Before - public void setUp() { - - } - - @Test - public void testMessageDetailsWithoutAuthorizationHeader() { - givenHeader("Link", "; rel=\"related\""); - givenHeader("Warning", "199 OpenShift \"You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request\""); - AuthorizationDetails details = whenCreatingAnAuthorizationScheme(); - assertEquals("https://127.0.0.1:8443/oauth/token/request", details.getRequestTokenLink()); - assertEquals("\"You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request\"", details.getMessage()); - } - - @Test - public void testMessageDetailsWithAuthorizationHeader() { - givenHeader("WWW-Authenticate", "Basic realm=\"openshift\""); - givenHeader("Warning", "199 OpenShift \"You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request\""); - AuthorizationDetails details = whenCreatingAnAuthorizationScheme(); - assertEquals("Basic", details.getScheme()); - } - - private AuthorizationDetails whenCreatingAnAuthorizationScheme() { - return new AuthorizationDetails(builder.build()); - } - - private void givenHeader(String name, String value) { - builder.add(name, value); - } + /* + * WWW-Authenticate: OAuth realm= WWW-Authenticate: Basic Link: + * ; rel="related" Warning: 199 + * OpenShift + * "You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request" + * code 401 + */ + private Headers.Builder builder = new Headers.Builder(); + + @Before + public void setUp() { + + } + + @Test + public void testMessageDetailsWithoutAuthorizationHeader() { + givenHeader("Link", "; rel=\"related\""); + givenHeader("Warning", + "199 OpenShift \"You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request\""); + AuthorizationDetails details = whenCreatingAnAuthorizationScheme(); + assertEquals("https://127.0.0.1:8443/oauth/token/request", details.getRequestTokenLink()); + assertEquals("\"You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request\"", + details.getMessage()); + } + + @Test + public void testMessageDetailsWithAuthorizationHeader() { + givenHeader("WWW-Authenticate", "Basic realm=\"openshift\""); + givenHeader("Warning", + "199 OpenShift \"You must obtain an API token by visiting https://127.0.0.1:8443/oauth/token/request\""); + AuthorizationDetails details = whenCreatingAnAuthorizationScheme(); + assertEquals("Basic", details.getScheme()); + } + + private AuthorizationDetails whenCreatingAnAuthorizationScheme() { + return new AuthorizationDetails(builder.build()); + } + + private void givenHeader(String name, String value) { + builder.add(name, value); + } } diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java index 1bdc1040..07c43140 100644 --- a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java @@ -1,11 +1,12 @@ - /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. Distributed under license by Red Hat, Inc. - * All rights reserved. This program is 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: Red Hat, Inc. - ******************************************************************************/ +/******************************************************************************* +* Copyright (c) 2016 Red Hat, Inc. Distributed under license by Red Hat, Inc. +* All rights reserved. This program is 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: Red Hat, Inc. +******************************************************************************/ + package com.openshift.internal.restclient.authorization; import static org.fest.assertions.Assertions.assertThat; @@ -20,33 +21,30 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.authorization.IRole; -/** - * @author Jeff Cantrill - */ public class AuthorizationKindsIntegrationTest { - private IClient client; - private IntegrationTestHelper helper = new IntegrationTestHelper(); - - @Before - public void setup () { - client = helper.createClientForBasicAuth(); - } - - @Test - public void testListRolesAssumingClusterAdmin(){ - List roles= client.list(ResourceKind.ROLE, "default"); - assertThat(roles).isNotEmpty(); - } - - @Test - public void testListPoliciesAssumingClusterAdmin(){ - client.list(ResourceKind.POLICY, "default"); - } - - @Test - public void testListPolicyBindingsAssumingClusterAdmin(){ - client.list(ResourceKind.POLICY_BINDING, "default"); - } + private IClient client; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + + @Before + public void setup() { + client = helper.createClientForBasicAuth(); + } + + @Test + public void testListRolesAssumingClusterAdmin() { + List roles = client.list(ResourceKind.ROLE, "default"); + assertThat(roles).isNotEmpty(); + } + + @Test + public void testListPoliciesAssumingClusterAdmin() { + client.list(ResourceKind.POLICY, "default"); + } + + @Test + public void testListPolicyBindingsAssumingClusterAdmin() { + client.list(ResourceKind.POLICY_BINDING, "default"); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java index 59dcc428..90533658 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java @@ -6,11 +6,13 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -18,40 +20,39 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import com.openshift.internal.restclient.capability.resources.AnnotationCapability; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ @RunWith(MockitoJUnitRunner.class) public class AnnotationCapabilityTest { - - private AnnotationCapability capability; - @Mock private IResource resource; - - @Before - public void setUp(){ - capability = newCapability(); - } - - private AnnotationCapability newCapability(){ - return new AnnotationCapability("MyCapability", resource) { - @Override - protected String getAnnotationKey() { - return "foobar"; - } - }; - - } - @Test - public void supportedWhenAnnotationsHasKey(){ - when(resource.isAnnotatedWith(eq("foobar"))).thenReturn(true); - assertTrue("Exp. the capability to be supported when the annotation key exists", capability.isSupported()); - } - - @Test - public void unsupportedWhenAnnotationsDoNotHaveADeploymentKey(){ - assertFalse("Exp. the capability to not be supported when annotation key does not exists", capability.isSupported()); - } + + private AnnotationCapability capability; + @Mock + private IResource resource; + + @Before + public void setUp() { + capability = newCapability(); + } + + private AnnotationCapability newCapability() { + return new AnnotationCapability("MyCapability", resource) { + @Override + protected String getAnnotationKey() { + return "foobar"; + } + }; + + } + + @Test + public void supportedWhenAnnotationsHasKey() { + when(resource.isAnnotatedWith(eq("foobar"))).thenReturn(true); + assertTrue("Exp. the capability to be supported when the annotation key exists", capability.isSupported()); + } + + @Test + public void unsupportedWhenAnnotationsDoNotHaveADeploymentKey() { + assertFalse("Exp. the capability to not be supported when annotation key does not exists", + capability.isSupported()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/AssociationCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/AssociationCapabilityTest.java index 29b52af6..62d9176c 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/AssociationCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/AssociationCapabilityTest.java @@ -6,27 +6,23 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; +import static org.junit.Assert.assertFalse; import org.junit.Test; -import com.openshift.internal.restclient.capability.resources.AssociationCapability; - -/** - * @author Jeff Cantrill - */ public class AssociationCapabilityTest { - @Test - public void unsupportedWhenTheClientIsNull(){ - AssociationCapability capability = new AssociationCapability("MyCapability", null, null) { - @Override - protected String getAnnotationKey() { - return "foobar"; - } - }; - assertFalse("Exp. the capability to be unsupported because the IClient is null", capability.isSupported()); - } + @Test + public void unsupportedWhenTheClientIsNull() { + AssociationCapability capability = new AssociationCapability("MyCapability", null, null) { + @Override + protected String getAnnotationKey() { + return "foobar"; + } + }; + assertFalse("Exp. the capability to be unsupported because the IClient is null", capability.isSupported()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java index 9c34a26d..04867cd0 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java @@ -8,9 +8,10 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; import org.junit.After; import org.junit.Before; @@ -30,102 +31,92 @@ import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.build.IBuildConfigBuilder; -/** - * - * @author Jeff Cantrill - * - */ public class BuildCapabilitiesIntegrationTest { - private static final Logger LOG = LoggerFactory.getLogger(BuildCapabilitiesIntegrationTest.class); - private IBuildConfig config; - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private IProject project; - private IClient client; - - @Before - public void setUp() throws Exception { - client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); - - //an output imagestream - IImageStream is = client.getResourceFactory().stub(ResourceKind.IMAGE_STREAM, "ruby-hello-world", project.getName()); - LOG.debug("Creating imagestream {}", is); - is = client.create(is); - LOG.debug("Generated imagestream {}", is); - - //a buildconfig - IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); - assertNotNull("Exp. the client to be able to use a buildconfigbuilder", builder); - config = builder.named("hello-openshift") - .inNamespace(project.getName()) - .fromGitSource() - .fromGitUrl("https://github.com/openshift/ruby-hello-world.git") - .end() - .usingSourceStrategy() - .fromDockerImage("centos/ruby-22-centos7:latest") - .end() - .toImageStreamTag("ruby-hello-world:latest") - .build(); - LOG.debug("Creating BuildConfig {}", config); - config = client.create(config); - LOG.debug("Created BuildConfig {}", config); - assertNotNull(config); - } - - @Test - public void testBuildActions() { - - //trigger the build - LOG.debug("Triggering build from the buildconfig..."); - IBuild build = config.accept(new CapabilityVisitor() { - @Override - public IBuild visit(IBuildTriggerable capability) { - return capability.trigger(); - } - }, null); - assertNotNull("Exp. to be able to trigger a build from a buildconfig", build); - LOG.debug("Triggered build {}", build); - - LOG.debug("Canceling the build..."); - //cancel the build - build = build.accept(new CapabilityVisitor() { - - @Override - public IBuild visit(IBuildCancelable cap) { - return cap.cancel(); - } - }, null); - assertNotNull("Exp. to be able to cancel a build", build); - LOG.debug("Canceled build {}", build); - - //trigger the build from a build - LOG.debug("Triggering build from a build..."); - build = build.accept(new CapabilityVisitor() { - @Override - public IBuild visit(IBuildTriggerable capability) { - return capability.trigger(); - } - }, null); - assertNotNull("Exp. to be able to trigger a build from a build", build); - LOG.debug("Triggered build {}", build); - - //add a build cause - LOG.debug("Triggering build with build cause..."); - build = build.accept(new CapabilityVisitor() { - @Override - public IBuild visit(IBuildTriggerable capability) { - capability.addBuildCause("test cause"); - return capability.trigger(); - } - }, null); - assertNotNull("Exp. to be able to add a build cause for a build", build); - LOG.debug("Triggered build {}", build); - } - - @After - public void tearDown() { - IntegrationTestHelper.cleanUpResource(client, project); - } + private static final Logger LOG = LoggerFactory.getLogger(BuildCapabilitiesIntegrationTest.class); + private IBuildConfig config; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IProject project; + private IClient client; + + @Before + public void setUp() throws Exception { + client = helper.createClientForBasicAuth(); + project = helper.generateProject(client); + + // an output imagestream + IImageStream is = client.getResourceFactory().stub(ResourceKind.IMAGE_STREAM, "ruby-hello-world", + project.getName()); + LOG.debug("Creating imagestream {}", is); + is = client.create(is); + LOG.debug("Generated imagestream {}", is); + + // a buildconfig + IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); + assertNotNull("Exp. the client to be able to use a buildconfigbuilder", builder); + config = builder.named("hello-openshift").inNamespace(project.getName()).fromGitSource() + .fromGitUrl("https://github.com/openshift/ruby-hello-world.git").end().usingSourceStrategy() + .fromDockerImage("centos/ruby-22-centos7:latest").end().toImageStreamTag("ruby-hello-world:latest") + .build(); + LOG.debug("Creating BuildConfig {}", config); + config = client.create(config); + LOG.debug("Created BuildConfig {}", config); + assertNotNull(config); + } + + @Test + public void testBuildActions() { + + // trigger the build + LOG.debug("Triggering build from the buildconfig..."); + IBuild build = config.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBuildTriggerable capability) { + return capability.trigger(); + } + }, null); + assertNotNull("Exp. to be able to trigger a build from a buildconfig", build); + LOG.debug("Triggered build {}", build); + + LOG.debug("Canceling the build..."); + // cancel the build + build = build.accept(new CapabilityVisitor() { + + @Override + public IBuild visit(IBuildCancelable cap) { + return cap.cancel(); + } + }, null); + assertNotNull("Exp. to be able to cancel a build", build); + LOG.debug("Canceled build {}", build); + + // trigger the build from a build + LOG.debug("Triggering build from a build..."); + build = build.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBuildTriggerable capability) { + return capability.trigger(); + } + }, null); + assertNotNull("Exp. to be able to trigger a build from a build", build); + LOG.debug("Triggered build {}", build); + + // add a build cause + LOG.debug("Triggering build with build cause..."); + build = build.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBuildTriggerable capability) { + capability.addBuildCause("test cause"); + return capability.trigger(); + } + }, null); + assertNotNull("Exp. to be able to add a build cause for a build", build); + LOG.debug("Triggered build {}", build); + } + + @After + public void tearDown() { + IntegrationTestHelper.cleanUpResource(client, project); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java index 37dd74a1..2c453a87 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java @@ -8,11 +8,19 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; +import static com.openshift.restclient.utils.ResourceTestHelper.givenDeployConfigIsVersion; +import static com.openshift.restclient.utils.ResourceTestHelper.givenResourceIsAnnotatedWith; +import static com.openshift.restclient.utils.ResourceTestHelper.thenResourceShouldBeUpdated; +import static com.openshift.restclient.utils.ResourceTestHelper.thenResourceShouldNotBeUpdated; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.*; -import static com.openshift.restclient.utils.ResourceTestHelper.*; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -32,97 +40,100 @@ @RunWith(MockitoJUnitRunner.class) public class DeployCapabilityTest { - private static final String NAMESPACE = "aNamespace"; - private static final int VERSION = 1986; - private static final String NAME = "aDCName"; - - private IDeployCapability cap; - @Mock private IDeploymentConfig config; - @Mock private IReplicationController deployment; - @Mock private IClient client; - - @Before - public void setUp() throws Exception { - cap = new DeployCapability(config, client); - when(config.getNamespaceName()).thenReturn(NAMESPACE); - when(config.getName()).thenReturn(NAME); - - givenDeployConfigIsVersion(config, VERSION); - } - - @Test - public void testIsSupported() { - assertTrue("Exp. the capability to be supported", cap.isSupported()); - } - - @SuppressWarnings("unchecked") - @Test(expected=OpenShiftException.class) - public void testThrowsErrorWhenUnableToFindLatestDeployment() { - when(client.get(anyString(), anyString(), anyString())).thenThrow(OpenShiftException.class); - whenDeploying(); - } - - @Test - public void testWhenLatestDeploymentNotFound() { - givenTheLatestDeploymentIsNotFound(); - whenDeploying(); - thenVersionShouldIncrease(config); - thenResourceShouldBeUpdated(client, config); - } - - @Test - public void testConfigNotUpdatedWhenAlreadyInProgress() { - givenTheDeploymentIsRetrieved(); - givenDeploymentStatusIs("New"); - whenDeploying(); - thenResourceShouldNotBeUpdated(client, config); - thenVersionShouldNotBeIncreased(config); - } - - @Test - public void testStartsNewDeploymentWhenPreviousFailed() { - givenTheDeploymentIsRetrieved(); - givenDeploymentStatusIs("Failed"); - whenDeploying(); - thenVersionShouldIncrease(config); - thenResourceShouldBeUpdated(client, config); - } - - @Test - public void testStartsNewDeploymentWhenPreviousComplete() { - givenTheDeploymentIsRetrieved(); - givenDeploymentStatusIs("Complete"); - whenDeploying(); - thenVersionShouldIncrease(config); - thenResourceShouldBeUpdated(client, config); - } - - private void thenVersionShouldIncrease(IDeploymentConfig config) { - int newVersion = config.getLatestVersionNumber()+1; - verify(config, times(1)).setLatestVersionNumber(newVersion); - } - - private void thenVersionShouldNotBeIncreased(IDeploymentConfig config) { - int newVersion = config.getLatestVersionNumber()+1; - verify(config, times(0)).setLatestVersionNumber(newVersion); - } - - private void whenDeploying() { - cap.deploy(); - } - - private void givenDeploymentStatusIs(String status) { - givenResourceIsAnnotatedWith(deployment, IReplicationController.DEPLOYMENT_PHASE, status); - } - - private void givenTheDeploymentIsRetrieved() { - when(client.get(anyString(),anyString(),anyString())).thenReturn(deployment); - } - - private void givenTheLatestDeploymentIsNotFound() { - IStatus status = mock(IStatus.class); - when(status.getCode()).thenReturn(IHttpConstants.STATUS_NOT_FOUND); - NotFoundException e = new NotFoundException(null, status, "Not Found"); - when(client.get(anyString(),anyString(),anyString())).thenThrow(e); - } + private static final String NAMESPACE = "aNamespace"; + private static final int VERSION = 1986; + private static final String NAME = "aDCName"; + + private IDeployCapability cap; + @Mock + private IDeploymentConfig config; + @Mock + private IReplicationController deployment; + @Mock + private IClient client; + + @Before + public void setUp() throws Exception { + cap = new DeployCapability(config, client); + when(config.getNamespaceName()).thenReturn(NAMESPACE); + when(config.getName()).thenReturn(NAME); + + givenDeployConfigIsVersion(config, VERSION); + } + + @Test + public void testIsSupported() { + assertTrue("Exp. the capability to be supported", cap.isSupported()); + } + + @SuppressWarnings("unchecked") + @Test(expected = OpenShiftException.class) + public void testThrowsErrorWhenUnableToFindLatestDeployment() { + when(client.get(anyString(), anyString(), anyString())).thenThrow(OpenShiftException.class); + whenDeploying(); + } + + @Test + public void testWhenLatestDeploymentNotFound() { + givenTheLatestDeploymentIsNotFound(); + whenDeploying(); + thenVersionShouldIncrease(config); + thenResourceShouldBeUpdated(client, config); + } + + @Test + public void testConfigNotUpdatedWhenAlreadyInProgress() { + givenTheDeploymentIsRetrieved(); + givenDeploymentStatusIs("New"); + whenDeploying(); + thenResourceShouldNotBeUpdated(client, config); + thenVersionShouldNotBeIncreased(config); + } + + @Test + public void testStartsNewDeploymentWhenPreviousFailed() { + givenTheDeploymentIsRetrieved(); + givenDeploymentStatusIs("Failed"); + whenDeploying(); + thenVersionShouldIncrease(config); + thenResourceShouldBeUpdated(client, config); + } + + @Test + public void testStartsNewDeploymentWhenPreviousComplete() { + givenTheDeploymentIsRetrieved(); + givenDeploymentStatusIs("Complete"); + whenDeploying(); + thenVersionShouldIncrease(config); + thenResourceShouldBeUpdated(client, config); + } + + private void thenVersionShouldIncrease(IDeploymentConfig config) { + int newVersion = config.getLatestVersionNumber() + 1; + verify(config, times(1)).setLatestVersionNumber(newVersion); + } + + private void thenVersionShouldNotBeIncreased(IDeploymentConfig config) { + int newVersion = config.getLatestVersionNumber() + 1; + verify(config, times(0)).setLatestVersionNumber(newVersion); + } + + private void whenDeploying() { + cap.deploy(); + } + + private void givenDeploymentStatusIs(String status) { + givenResourceIsAnnotatedWith(deployment, IReplicationController.DEPLOYMENT_PHASE, status); + } + + private void givenTheDeploymentIsRetrieved() { + when(client.get(anyString(), anyString(), anyString())).thenReturn(deployment); + } + + private void givenTheLatestDeploymentIsNotFound() { + IStatus status = mock(IStatus.class); + when(status.getCode()).thenReturn(IHttpConstants.STATUS_NOT_FOUND); + NotFoundException e = new NotFoundException(null, status, "Not Found"); + when(client.get(anyString(), anyString(), anyString())).thenThrow(e); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java index 66578460..f184d614 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java @@ -6,11 +6,14 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -23,41 +26,40 @@ import com.openshift.restclient.model.IDeploymentConfig; import com.openshift.restclient.model.IPod; -/** - * @author Jeff Cantrill - */ @RunWith(MockitoJUnitRunner.class) public class DeploymentConfigTraceabilityTest { - private DeploymentConfigTraceability capability; - - @Mock private IDeploymentConfig config; - @Mock private IPod resource; - @Mock private IClient client; - - @Before - public void setUp(){ - capability = new DeploymentConfigTraceability(resource, client); - - when(resource.getNamespaceName()).thenReturn("mynamespace"); - - when(client.get(eq(ResourceKind.DEPLOYMENT_CONFIG), eq("foobar"), eq("mynamespace"))) - .thenReturn(config); - } - - @Test - public void supportedWhenAnnotationsHaveADeploymentKey(){ - when(resource.isAnnotatedWith(eq("deploymentconfig"))).thenReturn(true); - when(resource.getAnnotation("deploymentconfig")).thenReturn("foobar"); - - assertEquals("Exp. to get the deploymentConfig", config, capability.getDeploymentConfig()); - - verify(client).get(eq(ResourceKind.DEPLOYMENT_CONFIG), eq("foobar"), eq("mynamespace")); - } - - @Test - public void unsupportedWhenAnnotationsDoNotHaveADeploymentKey(){ - assertNull("Exp. to get the deploymentConfig", capability.getDeploymentConfig()); - } + private DeploymentConfigTraceability capability; + + @Mock + private IDeploymentConfig config; + @Mock + private IPod resource; + @Mock + private IClient client; + + @Before + public void setUp() { + capability = new DeploymentConfigTraceability(resource, client); + + when(resource.getNamespaceName()).thenReturn("mynamespace"); + + when(client.get(eq(ResourceKind.DEPLOYMENT_CONFIG), eq("foobar"), eq("mynamespace"))).thenReturn(config); + } + + @Test + public void supportedWhenAnnotationsHaveADeploymentKey() { + when(resource.isAnnotatedWith(eq("deploymentconfig"))).thenReturn(true); + when(resource.getAnnotation("deploymentconfig")).thenReturn("foobar"); + + assertEquals("Exp. to get the deploymentConfig", config, capability.getDeploymentConfig()); + + verify(client).get(eq(ResourceKind.DEPLOYMENT_CONFIG), eq("foobar"), eq("mynamespace")); + } + + @Test + public void unsupportedWhenAnnotationsDoNotHaveADeploymentKey() { + assertNull("Exp. to get the deploymentConfig", capability.getDeploymentConfig()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java index 4461f1cf..5145aa9e 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java @@ -6,10 +6,14 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -22,41 +26,41 @@ import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IReplicationController; -/** - * @author Jeff Cantrill - */ @RunWith(MockitoJUnitRunner.class) public class DeploymentTraceabilityTest { - private DeploymentTraceability capability; - - @Mock private IReplicationController deployment; - @Mock private IPod resource; - @Mock private IClient client; - - @Before - public void setUp(){ - capability = new DeploymentTraceability(resource, client); - - when(resource.getNamespaceName()).thenReturn("mynamespace"); - - when(client.get(eq(ResourceKind.REPLICATION_CONTROLLER), eq("foobar"), eq("mynamespace"))) - .thenReturn(deployment); - } - - @Test - public void supportedWhenAnnotationsHaveADeploymentKey(){ - when(resource.isAnnotatedWith(eq("deployment"))).thenReturn(true); - when(resource.getAnnotation("deployment")).thenReturn("foobar"); - - assertEquals("Exp. to get the deployment", deployment, capability.getDeployment()); - - verify(client).get(eq(ResourceKind.REPLICATION_CONTROLLER), eq("foobar"), eq("mynamespace")); - } - - @Test - public void unsupportedWhenAnnotationsDoNotHaveADeploymentKey(){ - assertNull("Exp. to get the deployment", capability.getDeployment()); - } - + private DeploymentTraceability capability; + + @Mock + private IReplicationController deployment; + @Mock + private IPod resource; + @Mock + private IClient client; + + @Before + public void setUp() { + capability = new DeploymentTraceability(resource, client); + + when(resource.getNamespaceName()).thenReturn("mynamespace"); + + when(client.get(eq(ResourceKind.REPLICATION_CONTROLLER), eq("foobar"), eq("mynamespace"))) + .thenReturn(deployment); + } + + @Test + public void supportedWhenAnnotationsHaveADeploymentKey() { + when(resource.isAnnotatedWith(eq("deployment"))).thenReturn(true); + when(resource.getAnnotation("deployment")).thenReturn("foobar"); + + assertEquals("Exp. to get the deployment", deployment, capability.getDeployment()); + + verify(client).get(eq(ResourceKind.REPLICATION_CONTROLLER), eq("foobar"), eq("mynamespace")); + } + + @Test + public void unsupportedWhenAnnotationsDoNotHaveADeploymentKey() { + assertNull("Exp. to get the deployment", capability.getDeployment()); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DockerManifestComparatorTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DockerManifestComparatorTest.java index 3f33f110..57e900df 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DockerManifestComparatorTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DockerManifestComparatorTest.java @@ -8,9 +8,10 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.util.List; import java.util.stream.Collectors; @@ -24,22 +25,24 @@ public class DockerManifestComparatorTest { - private ModelNode root; - private ManifestComparator comparator = new ManifestComparator(); - - @Before - public void setUp() throws Exception { - root = ModelNode.fromJSONString(Samples.V1_DOCKER_IMAGE_MANIFEST.getContentAsString()); - } - - @Test - public void testCompareWithMultipleHistoryEntries() { - ModelNode history = root.get("history"); - List entries = history.asList().stream().map(n->ModelNode.fromJSONString(n.get("v1Compatibility").asString())).collect(Collectors.toList()); - entries.sort(comparator); - - ModelNode last = entries.get(entries.size()-1); - assertEquals("Exp. to retrieve the 'newest' entry with a non-null parent","5f162644b2633962f753b9a09c7783d342c8aaebccaf6270fde68404d2af7a8c",last.get("id").asString()); - } + private ModelNode root; + private ManifestComparator comparator = new ManifestComparator(); + + @Before + public void setUp() throws Exception { + root = ModelNode.fromJSONString(Samples.V1_DOCKER_IMAGE_MANIFEST.getContentAsString()); + } + + @Test + public void testCompareWithMultipleHistoryEntries() { + ModelNode history = root.get("history"); + List entries = history.asList().stream() + .map(n -> ModelNode.fromJSONString(n.get("v1Compatibility").asString())).collect(Collectors.toList()); + entries.sort(comparator); + + ModelNode last = entries.get(entries.size() - 1); + assertEquals("Exp. to retrieve the 'newest' entry with a non-null parent", + "5f162644b2633962f753b9a09c7783d342c8aaebccaf6270fde68404d2af7a8c", last.get("id").asString()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/IPodLogRetrievalAsyncOptionsTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/IPodLogRetrievalAsyncOptionsTest.java index a383af91..e375cbdb 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/IPodLogRetrievalAsyncOptionsTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/IPodLogRetrievalAsyncOptionsTest.java @@ -8,9 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import org.junit.Before; import org.junit.Test; @@ -19,51 +21,43 @@ public class IPodLogRetrievalAsyncOptionsTest { - private Options options = new Options(); - @Before - public void setUp() throws Exception { - } - - @Test - public void testFollowDoesNotOverrideParameter() { - assertEquals("false", options - .follow() - .parameter("follow", "false") - .getMap().get("follow")); - - } - - @Test - public void testFollowIsAddedWhenTrue() { - assertEquals("true", options.follow().getMap().get("follow")); - } - - @Test - public void testFollowIsNotAddedWhenFalse() { - assertNull(options.follow(false).getMap().get("follow")); - } - - @Test - public void testContainerDoesNotOverrideParameter() { - assertEquals("foo", options - .container("bar") - .parameter("container", "foo") - .getMap().get("container")); - - } - - @Test - public void testContainerAddedWhenNotEmpty() { - assertEquals("bar", options - .container("bar") - .getMap().get("container")); - - } - @Test - public void testContainerNotAddedWhenEmpty() { - assertNull(options - .container(" ") - .getMap().get("container")); - - } + private Options options = new Options(); + + @Before + public void setUp() throws Exception { + } + + @Test + public void testFollowDoesNotOverrideParameter() { + assertEquals("false", options.follow().parameter("follow", "false").getMap().get("follow")); + + } + + @Test + public void testFollowIsAddedWhenTrue() { + assertEquals("true", options.follow().getMap().get("follow")); + } + + @Test + public void testFollowIsNotAddedWhenFalse() { + assertNull(options.follow(false).getMap().get("follow")); + } + + @Test + public void testContainerDoesNotOverrideParameter() { + assertEquals("foo", options.container("bar").parameter("container", "foo").getMap().get("container")); + + } + + @Test + public void testContainerAddedWhenNotEmpty() { + assertEquals("bar", options.container("bar").getMap().get("container")); + + } + + @Test + public void testContainerNotAddedWhenEmpty() { + assertNull(options.container(" ").getMap().get("container")); + + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java index 2eaff04d..53a53791 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java @@ -8,9 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import org.junit.After; import org.junit.Before; @@ -27,46 +30,41 @@ import junit.framework.Assert; -/** - * - * @author jeff.cantrill - * - */ public class ImageStreamImportCapabilityIntegrationTest { - private IImageStreamImportCapability cap; - private IProject project; - private IClient client; - private IntegrationTestHelper helper = new IntegrationTestHelper(); - - @Before - public void setUp() throws Exception { - client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); - cap = new ImageStreamImportCapability(project, client); - } - - @After - public void tearDown() { - IntegrationTestHelper.cleanUpResource(client, project); - } + private IImageStreamImportCapability cap; + private IProject project; + private IClient client; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + + @Before + public void setUp() throws Exception { + client = helper.createClientForBasicAuth(); + project = helper.generateProject(client); + cap = new ImageStreamImportCapability(project, client); + } + + @After + public void tearDown() { + IntegrationTestHelper.cleanUpResource(client, project); + } - @Test - public void testImportImageForExistingImage() { - DockerImageURI image = new DockerImageURI("openshift/hello-openshift"); - IImageStreamImport imported = cap.importImageMetadata(image); - assertNotNull(imported); - IStatus status = imported.getImageStatus().iterator().next(); - assertTrue(status.isSuccess()); - } + @Test + public void testImportImageForExistingImage() { + DockerImageURI image = new DockerImageURI("openshift/hello-openshift"); + IImageStreamImport imported = cap.importImageMetadata(image); + assertNotNull(imported); + IStatus status = imported.getImageStatus().iterator().next(); + assertTrue(status.isSuccess()); + } - @Test - public void testImportImageForUnknownImage() { - DockerImageURI image = new DockerImageURI("openshift/hello-openshifts"); - IImageStreamImport imported = cap.importImageMetadata(image); - Assert.assertNotNull(imported); - IStatus status = imported.getImageStatus().iterator().next(); - assertEquals(IHttpConstants.STATUS_UNAUTHORIZED, status.getCode()); //exp code when image does not exist - } + @Test + public void testImportImageForUnknownImage() { + DockerImageURI image = new DockerImageURI("openshift/hello-openshifts"); + IImageStreamImport imported = cap.importImageMetadata(image); + Assert.assertNotNull(imported); + IStatus status = imported.getImageStatus().iterator().next(); + assertEquals(IHttpConstants.STATUS_UNAUTHORIZED, status.getCode()); // exp code when image does not exist + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java index e2b2504d..2d61a760 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java @@ -8,10 +8,14 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.util.Arrays; @@ -29,49 +33,43 @@ import com.openshift.restclient.model.IStatus; import com.openshift.restclient.model.image.IImageStreamImport; -/** - * - * @author jeff.cantrill - * - */ @RunWith(MockitoJUnitRunner.class) public class ImageStreamImportCapabilityTest { - private IImageStreamImportCapability cap; - @Mock - private IProject project; - @Mock - private IClient client; - @Mock - private IResourceFactory factory; - @Mock - private IImageStreamImport streamImport; - @Mock - private IStatus status; - - @Before - public void setUp() throws Exception { - when(project.getName()).thenReturn("aProjectName"); - when(client.getResourceFactory()).thenReturn(factory); - when(factory.stub(anyString(), anyString(), anyString())).thenReturn(streamImport); - when(client.create(any(IImageStreamImport.class))).thenReturn(streamImport); - - when(status.getStatus()).thenReturn("Success"); - when(streamImport.getImageStatus()).thenReturn(Arrays.asList(status)); - - cap = new ImageStreamImportCapability(project, client); - } + private IImageStreamImportCapability cap; + @Mock + private IProject project; + @Mock + private IClient client; + @Mock + private IResourceFactory factory; + @Mock + private IImageStreamImport streamImport; + @Mock + private IStatus status; + + @Before + public void setUp() throws Exception { + when(project.getName()).thenReturn("aProjectName"); + when(client.getResourceFactory()).thenReturn(factory); + when(factory.stub(anyString(), anyString(), anyString())).thenReturn(streamImport); + when(client.create(any(IImageStreamImport.class))).thenReturn(streamImport); + + when(status.getStatus()).thenReturn("Success"); + when(streamImport.getImageStatus()).thenReturn(Arrays.asList(status)); + + cap = new ImageStreamImportCapability(project, client); + } + + @Test + public void testImportImageInfo() { + DockerImageURI image = new DockerImageURI("foo/hello-world"); + IImageStreamImport imported = cap.importImageMetadata(image); + assertEquals(imported, streamImport); - @Test - public void testImportImageInfo() { - DockerImageURI image = new DockerImageURI("foo/hello-world"); - IImageStreamImport imported = cap.importImageMetadata(image); - assertEquals(imported, streamImport); - - verify(client).create(streamImport); - verify(streamImport).addImage("DockerImage", image); - + verify(client).create(streamImport); + verify(streamImport).addImage("DockerImage", image); - } + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java index 2289377c..8e1c2687 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.OC_LOCATION; @@ -38,70 +39,53 @@ public class OpenShiftBinaryPodLogRetrievalTest { - private static final String CONTAINER_NAME = "smurfland"; + private static final String CONTAINER_NAME = "smurfland"; - private IClient client; - private IPod pod; + private IClient client; + private IPod pod; - @Before - public void before() throws MalformedURLException { - this.client = mockClient(); - this.pod = mockPod(); - } + @Before + public void before() throws MalformedURLException { + this.client = mockClient(); + this.pod = mockPod(); + } - private OpenShiftBinaryPodLogRetrieval.PodLogs createPodLogs(boolean follow, IPod pod, IClient client, OpenShiftBinaryOption... options) { - OpenShiftBinaryPodLogRetrieval.PodLogs podLogs = spy( - new OpenShiftBinaryPodLogRetrieval(pod, client).new PodLogs(client, true, CONTAINER_NAME, options)); - doReturn(OC_LOCATION).when(podLogs).getOpenShiftBinaryLocation(); - doReturn(null).when(podLogs).startProcess(any(ProcessBuilder.class)); - return podLogs; - } + private OpenShiftBinaryPodLogRetrieval.PodLogs createPodLogs(boolean follow, IPod pod, IClient client, + OpenShiftBinaryOption... options) { + OpenShiftBinaryPodLogRetrieval.PodLogs podLogs = spy( + new OpenShiftBinaryPodLogRetrieval(pod, client).new PodLogs(client, true, CONTAINER_NAME, options)); + doReturn(OC_LOCATION).when(podLogs).getOpenShiftBinaryLocation(); + doReturn(null).when(podLogs).startProcess(any(ProcessBuilder.class)); + return podLogs; + } - @Test - public void shouldBuildCommandLineWithoutSkipTlsVerify() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - PodLogs podLogs = createPodLogs(false, pod, client); - // when - podLogs.getLogs(); - // then - verify(podLogs).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList( - OC_LOCATION, - PodLogs.LOGS_COMMAND, - "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), - POD_NAME, - "-n", - POD_NAMESPACE, - "-f", - "-c", - CONTAINER_NAME)); - } + @Test + public void shouldBuildCommandLineWithoutSkipTlsVerify() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + PodLogs podLogs = createPodLogs(false, pod, client); + // when + podLogs.getLogs(); + // then + verify(podLogs).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList(OC_LOCATION, PodLogs.LOGS_COMMAND, "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), POD_NAME, "-n", POD_NAMESPACE, "-f", "-c", CONTAINER_NAME)); + } - @Test - public void shouldBuildCommandLineWithSkipTlsVerify() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - PodLogs podLogs = createPodLogs(false, pod, client, IBinaryCapability.SKIP_TLS_VERIFY); - // when - podLogs.getLogs(); - // then - verify(podLogs).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList( - OC_LOCATION, - PodLogs.LOGS_COMMAND, - "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), - "--insecure-skip-tls-verify=true", - POD_NAME, - "-n", - POD_NAMESPACE, - "-f", - "-c", - CONTAINER_NAME)); - } + @Test + public void shouldBuildCommandLineWithSkipTlsVerify() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + PodLogs podLogs = createPodLogs(false, pod, client, IBinaryCapability.SKIP_TLS_VERIFY); + // when + podLogs.getLogs(); + // then + verify(podLogs).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList(OC_LOCATION, PodLogs.LOGS_COMMAND, "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), "--insecure-skip-tls-verify=true", POD_NAME, "-n", POD_NAMESPACE, + "-f", "-c", CONTAINER_NAME)); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java index 32982895..8c7ca84d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.OC_LOCATION; @@ -39,76 +40,60 @@ public class OpenShiftBinaryPortForwardingTest { - private static final int LOCAL_PORT1 = 8080; - private static final int REMOTE_PORT1 = 80; + private static final int LOCAL_PORT1 = 8080; + private static final int REMOTE_PORT1 = 80; - private static final int LOCAL_PORT2 = 8443; - private static final int REMOTE_PORT2 = 43; + private static final int LOCAL_PORT2 = 8443; + private static final int REMOTE_PORT2 = 43; - private IPod pod; + private IPod pod; - private OpenShiftBinaryPortForwarding binaryPortForwarding; + private OpenShiftBinaryPortForwarding binaryPortForwarding; - @Before - public void before() throws MalformedURLException { - IClient client = mockClient(); - this.pod = mockPod(); - this.binaryPortForwarding = createBinaryPortForwarding(pod, client); - } + @Before + public void before() throws MalformedURLException { + IClient client = mockClient(); + this.pod = mockPod(); + this.binaryPortForwarding = createBinaryPortForwarding(pod, client); + } - private OpenShiftBinaryPortForwarding createBinaryPortForwarding(IPod pod, IClient client) { - OpenShiftBinaryPortForwarding portForwarding = spy(new OpenShiftBinaryPortForwarding(pod, client)); - doReturn(OC_LOCATION).when(portForwarding).getOpenShiftBinaryLocation(); - doReturn(null).when(portForwarding).startProcess(any(ProcessBuilder.class)); - return portForwarding; - } + private OpenShiftBinaryPortForwarding createBinaryPortForwarding(IPod pod, IClient client) { + OpenShiftBinaryPortForwarding portForwarding = spy(new OpenShiftBinaryPortForwarding(pod, client)); + doReturn(OC_LOCATION).when(portForwarding).getOpenShiftBinaryLocation(); + doReturn(null).when(portForwarding).startProcess(any(ProcessBuilder.class)); + return portForwarding; + } - @Test - public void shouldBuildCommandLineWithoutSkipSSL() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - List ports = Arrays.asList( - mockPortPair(LOCAL_PORT2, REMOTE_PORT2)); - // when - binaryPortForwarding.forwardPorts(ports); - // then - verify(binaryPortForwarding).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList( - OC_LOCATION, - OpenShiftBinaryPortForwarding.PORT_FORWARD_COMMAND, - "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), - "-n", - POD_NAMESPACE, - "-p", - POD_NAME, - LOCAL_PORT2 + ":" + REMOTE_PORT2)); - } + @Test + public void shouldBuildCommandLineWithoutSkipSSL() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + List ports = Arrays.asList(mockPortPair(LOCAL_PORT2, REMOTE_PORT2)); + // when + binaryPortForwarding.forwardPorts(ports); + // then + verify(binaryPortForwarding).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()) + .isEqualTo(Arrays.asList(OC_LOCATION, OpenShiftBinaryPortForwarding.PORT_FORWARD_COMMAND, + "--token=" + TOKEN, "--server=" + SERVER_URL.toString(), "-n", POD_NAMESPACE, "-p", POD_NAME, + LOCAL_PORT2 + ":" + REMOTE_PORT2)); + } - @Test - public void shouldBuildCommandLineWith2PortsSkipSSL() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - List ports = Arrays.asList( - mockPortPair(LOCAL_PORT1, REMOTE_PORT1), - mockPortPair(LOCAL_PORT2, REMOTE_PORT2)); - // when - binaryPortForwarding.forwardPorts(ports, new SkipTlsVerify()); - // then - verify(binaryPortForwarding).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList( - OC_LOCATION, - OpenShiftBinaryPortForwarding.PORT_FORWARD_COMMAND, - "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), - "--insecure-skip-tls-verify=true", - "-n", - POD_NAMESPACE, - "-p", - POD_NAME, - LOCAL_PORT1 + ":" + REMOTE_PORT1, - LOCAL_PORT2 + ":" + REMOTE_PORT2)); - } + @Test + public void shouldBuildCommandLineWith2PortsSkipSSL() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + List ports = Arrays.asList(mockPortPair(LOCAL_PORT1, REMOTE_PORT1), + mockPortPair(LOCAL_PORT2, REMOTE_PORT2)); + // when + binaryPortForwarding.forwardPorts(ports, new SkipTlsVerify()); + // then + verify(binaryPortForwarding).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo( + Arrays.asList(OC_LOCATION, OpenShiftBinaryPortForwarding.PORT_FORWARD_COMMAND, "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), "--insecure-skip-tls-verify=true", "-n", POD_NAMESPACE, + "-p", POD_NAME, LOCAL_PORT1 + ":" + REMOTE_PORT1, LOCAL_PORT2 + ":" + REMOTE_PORT2)); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java index be9ffa44..85106a0d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.OC_LOCATION; @@ -42,98 +43,73 @@ public class OpenShiftBinaryRSyncTest { - private static final String LOCAL_PATH = "/local/42"; - private static final String POD_PATH = "/deployment/42"; - - private IPod pod; + private static final String LOCAL_PATH = "/local/42"; + private static final String POD_PATH = "/deployment/42"; - private OpenShiftBinaryRSync binaryRsync; + private IPod pod; - @Before - public void before() throws MalformedURLException { - IClient client = mockClient(); - this.pod = mockPod(); - this.binaryRsync = createBinaryRSync(client); - } + private OpenShiftBinaryRSync binaryRsync; - private OpenShiftBinaryRSync createBinaryRSync(IClient client) { - OpenShiftBinaryRSync binaryRsync = spy(new OpenShiftBinaryRSync(client)); - doReturn(OC_LOCATION).when(binaryRsync).getOpenShiftBinaryLocation(); - doReturn(null).when(binaryRsync).startProcess(any(ProcessBuilder.class)); - return binaryRsync; - } + @Before + public void before() throws MalformedURLException { + IClient client = mockClient(); + this.pod = mockPod(); + this.binaryRsync = createBinaryRSync(client); + } + private OpenShiftBinaryRSync createBinaryRSync(IClient client) { + OpenShiftBinaryRSync binaryRsync = spy(new OpenShiftBinaryRSync(client)); + doReturn(OC_LOCATION).when(binaryRsync).getOpenShiftBinaryLocation(); + doReturn(null).when(binaryRsync).startProcess(any(ProcessBuilder.class)); + return binaryRsync; + } - @Test - public void shouldBuildCommandLineWithoutSkipSSL() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - Peer localPeer = new LocalPeer(LOCAL_PATH); - PodPeer podPeer = new PodPeer(POD_PATH, pod); - // when - binaryRsync.sync(localPeer, podPeer); - // then - verify(binaryRsync).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList( - OC_LOCATION, - OpenShiftBinaryRSync.RSYNC_COMMAND, - "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), - "-n", - POD_NAMESPACE, - LOCAL_PATH, - POD_NAME + ":" + POD_PATH)); - } + @Test + public void shouldBuildCommandLineWithoutSkipSSL() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + Peer localPeer = new LocalPeer(LOCAL_PATH); + PodPeer podPeer = new PodPeer(POD_PATH, pod); + // when + binaryRsync.sync(localPeer, podPeer); + // then + verify(binaryRsync).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList(OC_LOCATION, OpenShiftBinaryRSync.RSYNC_COMMAND, + "--token=" + TOKEN, "--server=" + SERVER_URL.toString(), "-n", POD_NAMESPACE, LOCAL_PATH, + POD_NAME + ":" + POD_PATH)); + } - @Test - public void shouldBuildCommandLineWithSkipSSLNoPermsGitExclude() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - Peer localPeer = new LocalPeer(LOCAL_PATH); - PodPeer podPeer = new PodPeer(POD_PATH, pod); - // when - binaryRsync.sync(localPeer, podPeer, - new SkipTlsVerify(), new NoPerms(), new GitFolderExclude()); - // then - verify(binaryRsync).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList( - OC_LOCATION, - OpenShiftBinaryRSync.RSYNC_COMMAND, - "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), - "-n", - POD_NAMESPACE, - "--insecure-skip-tls-verify=true", - "--no-perms=true", - "--exclude=.git", - LOCAL_PATH, - POD_NAME + ":" + POD_PATH)); - } + @Test + public void shouldBuildCommandLineWithSkipSSLNoPermsGitExclude() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + Peer localPeer = new LocalPeer(LOCAL_PATH); + PodPeer podPeer = new PodPeer(POD_PATH, pod); + // when + binaryRsync.sync(localPeer, podPeer, new SkipTlsVerify(), new NoPerms(), new GitFolderExclude()); + // then + verify(binaryRsync).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()) + .isEqualTo(Arrays.asList(OC_LOCATION, OpenShiftBinaryRSync.RSYNC_COMMAND, "--token=" + TOKEN, + "--server=" + SERVER_URL.toString(), "-n", POD_NAMESPACE, "--insecure-skip-tls-verify=true", + "--no-perms=true", "--exclude=.git", LOCAL_PATH, POD_NAME + ":" + POD_PATH)); + } - @Test - public void shouldBuildCommandLineWithExcludeDotGitDotNpm() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - Peer localPeer = new LocalPeer(LOCAL_PATH); - PodPeer podPeer = new PodPeer(POD_PATH, pod); - // when - binaryRsync.sync(localPeer, podPeer, - new Exclude(".git", ".npm")); - // then - verify(binaryRsync).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList( - OC_LOCATION, - OpenShiftBinaryRSync.RSYNC_COMMAND, - "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), - "-n", - POD_NAMESPACE, - "--exclude=.git", - "--exclude=.npm", - LOCAL_PATH, - POD_NAME + ":" + POD_PATH)); - } + @Test + public void shouldBuildCommandLineWithExcludeDotGitDotNpm() { + // given + ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); + Peer localPeer = new LocalPeer(LOCAL_PATH); + PodPeer podPeer = new PodPeer(POD_PATH, pod); + // when + binaryRsync.sync(localPeer, podPeer, new Exclude(".git", ".npm")); + // then + verify(binaryRsync).startProcess(processBuilderArgument.capture()); + ProcessBuilder builder = processBuilderArgument.getValue(); + assertThat(builder.command()).isEqualTo(Arrays.asList(OC_LOCATION, OpenShiftBinaryRSync.RSYNC_COMMAND, + "--token=" + TOKEN, "--server=" + SERVER_URL.toString(), "-n", POD_NAMESPACE, "--exclude=.git", + "--exclude=.npm", LOCAL_PATH, POD_NAME + ":" + POD_PATH)); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java index 92e4e74f..59235e06 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import static org.junit.Assert.assertNotNull; @@ -30,46 +31,41 @@ import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IResource; -/** - * - * @author Jeff Cantrill - * - */ public class OpenshiftBinaryPodLogRetrievalIntegrationTest { private static final Logger LOG = LoggerFactory.getLogger(OpenshiftBinaryPodLogRetrievalIntegrationTest.class); - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private Exception ex; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private Exception ex; - @Test - public void testLogRetrieval() { - System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - IClient client = helper.createClientForBasicAuth(); - List pods = client.list(ResourceKind.POD, "default"); - IPod pod = (IPod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); - assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); + @Test + public void testLogRetrieval() { + System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); + IClient client = helper.createClientForBasicAuth(); + List pods = client.list(ResourceKind.POD, "default"); + IPod pod = (IPod) pods.stream().filter(p -> p.getName().startsWith("docker-registry")).findFirst().orElse(null); + assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); - ex = pod.accept(new CapabilityVisitor() { + ex = pod.accept(new CapabilityVisitor() { - @Override - public Exception visit(IPodLogRetrieval cap) { - StringBuilder builder = new StringBuilder(); - try { - BufferedInputStream os = new BufferedInputStream(cap.getLogs(false, new SkipTlsVerify())); - int c; - while((c = os.read()) != -1) { - builder.append((char)c); - } - } catch (Exception e) { - LOG.error("There was an error:", e); - return e; - }finally { - LOG.info(builder.toString()); - cap.stop(); - } - return null; - } + @Override + public Exception visit(IPodLogRetrieval cap) { + StringBuilder builder = new StringBuilder(); + try { + BufferedInputStream os = new BufferedInputStream(cap.getLogs(false, new SkipTlsVerify())); + int c; + while ((c = os.read()) != -1) { + builder.append((char) c); + } + } catch (Exception e) { + LOG.error("There was an error:", e); + return e; + } finally { + LOG.info(builder.toString()); + cap.stop(); + } + return null; + } - }, null); - assertNull("Expected no exception", ex); - } + }, null); + assertNull("Expected no exception", ex); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java index 5f6e6e52..e712d37d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; import static org.junit.Assert.assertNotNull; @@ -35,67 +36,60 @@ import com.openshift.restclient.capability.resources.IPortForwardable.PortPair; import com.openshift.restclient.model.IProject; -/** - * - * @author Jeff Cantrill - * - */ -public class OpenshiftBinaryPortForwardingIntegrationTest implements ResourcePropertyKeys{ +public class OpenshiftBinaryPortForwardingIntegrationTest implements ResourcePropertyKeys { + + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IClient client; + private IProject project; + + @Before + public void setUp() throws Exception { + System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); + client = helper.createClientForBasicAuth(); + project = helper.generateProject(client); + } + + @After + public void teardown() throws Exception { + IntegrationTestHelper.cleanUpResource(client, project); + } + + @Test + public void testPortForwarding() { + Pod pod = (Pod) IntegrationTestHelper.stubPod(client, project); + pod = (Pod) client.create(pod); + pod = (Pod) IntegrationTestHelper.waitForResource(client, pod.getKind(), pod.getNamespaceName(), pod.getName(), + 5 * IntegrationTestHelper.MILLISECONDS_PER_MIN, new PodStatusRunningConditional()); + + assertNotNull("The test timed out before the pod was in a running state", pod); - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private IClient client; - private IProject project; - - @Before - public void setUp() throws Exception { - System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); - } - - @After - public void teardown() throws Exception{ - IntegrationTestHelper.cleanUpResource(client, project); - } + final Port port = new Port(new ModelNode()); + port.setProtocol("tcp"); + port.setContainerPort(8080); + pod.accept(new CapabilityVisitor() { - @Test - public void testPortForwarding() { - Pod pod = (Pod) IntegrationTestHelper.stubPod(client, project); - pod = (Pod) client.create(pod); - pod = (Pod) IntegrationTestHelper.waitForResource(client, - pod.getKind(), - pod.getNamespaceName(), - pod.getName(), 5 * IntegrationTestHelper.MILLISECONDS_PER_MIN, new PodStatusRunningConditional()); - - assertNotNull("The test timed out before the pod was in a running state", pod); - - final Port port = new Port(new ModelNode()); - port.setProtocol("tcp"); - port.setContainerPort(8080); - pod.accept(new CapabilityVisitor() { + @Override + public Object visit(IPortForwardable capability) { + capability.forwardPorts(Arrays.asList(new PortPair(8181, port)), new SkipTlsVerify()); + try { + Thread.sleep(5 * IntegrationTestHelper.MILLISECONDS_PER_SECOND); + curl(); + } catch (Exception e) { + e.printStackTrace(); + } + capability.stop(); + return null; + } + }, new Object()); + } - @Override - public Object visit(IPortForwardable capability) { - capability.forwardPorts(Arrays.asList(new PortPair(8181, port)), new SkipTlsVerify()); - try { - Thread.sleep(5 * IntegrationTestHelper.MILLISECONDS_PER_SECOND); - curl(); - } catch (Exception e) { - e.printStackTrace(); - } - capability.stop(); - return null; - } - }, new Object()); - } - - private void curl() throws Exception { - URL url = new URL("http://localhost:8181"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("GET"); - con.setDoInput(true); - con.connect(); - System.out.println(IOUtils.toString(con.getInputStream())); - con.disconnect(); - } + private void curl() throws Exception { + URL url = new URL("http://localhost:8181"); + HttpURLConnection con = (HttpURLConnection) url.openConnection(); + con.setRequestMethod("GET"); + con.setDoInput(true); + con.connect(); + System.out.println(IOUtils.toString(con.getInputStream())); + con.disconnect(); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java index c92a65fb..de49e7fb 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java @@ -53,136 +53,140 @@ * */ public class OpenshiftBinaryRSyncRetrievalIntegrationTest { - private static final String TARGET_FOLDER_WITH_SPECIAL_CHARS = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/with sp@cé/"; - private static final String FILE_NAME_SPECIAL_CHARS = "test with spéci@l characters and spaces"; - private static final String SOURCE_FOLDER_WITH_SPECIAL_CHARS = "with sp@cé in path"; - - private static final String NORMAL_TARGET_TMP = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/withoutspace/"; - private static final String NORMAL_FILE_NAME = "normalFileName"; - private static final String NORMAL_FOLDER_NAME = "normalFolderName"; - - private static final Logger LOG = LoggerFactory.getLogger(OpenshiftBinaryRSyncRetrievalIntegrationTest.class); - - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private IClient client; - - @Rule - public TemporaryFolder tmpFolder = new TemporaryFolder(); - - private Pod pod; - private String podFolderToClean = null; - - @Before - public void setUp() throws Exception { - // given - System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - client = helper.createClientForBasicAuth(); - - List pods = client.list(ResourceKind.POD, "default"); - pod = (Pod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); - assertNotNull("Did not find the registry pod to which to rsync", pod); - } - - @After - public void tearDown() throws Exception { - if(podFolderToClean != null) { - execOnPod(new String[] {"rm", "-r",podFolderToClean}); - } - } - - @Test - public void testRSyncLogRetrieval() throws IOException, InterruptedException { - testRsyncLogRetrieval(NORMAL_FOLDER_NAME, NORMAL_FILE_NAME, NORMAL_TARGET_TMP); - } - - @Test - public void testRSyncLogRetrievalWithSpaceInFolderToSynchronize() throws Exception { - testRsyncLogRetrieval(SOURCE_FOLDER_WITH_SPECIAL_CHARS, NORMAL_FILE_NAME, NORMAL_TARGET_TMP); - } - - @Test - public void testRSyncLogRetrievalWithSpaceInFileToSynchronize() throws Exception { - testRsyncLogRetrieval(NORMAL_FOLDER_NAME, FILE_NAME_SPECIAL_CHARS, NORMAL_TARGET_TMP); - } - - @Test - public void testRSyncLogRetrievalWithSpaceInTargetDirectory() throws Exception { - testRsyncLogRetrieval(NORMAL_FOLDER_NAME, NORMAL_FILE_NAME, TARGET_FOLDER_WITH_SPECIAL_CHARS); - } - - @Test - public void testRSyncLogRetrievalWithSpaceEverywhere() throws Exception { - testRsyncLogRetrieval(SOURCE_FOLDER_WITH_SPECIAL_CHARS, FILE_NAME_SPECIAL_CHARS, TARGET_FOLDER_WITH_SPECIAL_CHARS); - } - - protected void testRsyncLogRetrieval(String folderToSynchronizeName, String fileNameToSynchronize, String targetFolderPath) throws IOException, InterruptedException { - podFolderToClean = targetFolderPath; - execOnPod(new String[] {"mkdir", "-p", targetFolderPath}); - File localTempDir = tmpFolder.newFolder(folderToSynchronizeName); - // Create a dummy file locally to be sure there will be something to rsync from Local to Remote - File tmpFile = File.createTempFile(fileNameToSynchronize, ".txt", localTempDir); - final String fileName = tmpFile.getName(); - LocalPeer localPeer = new LocalPeer(localTempDir.getAbsolutePath()+File.separator); - PodPeer podPeer = new PodPeer(targetFolderPath, pod); - - // Check Local to Remote - rsyncAndCheck(fileName, localPeer, podPeer); - tmpFile.delete(); - - // Create a dummy file locally to be sure there will be something to rsync from Remote to Local - execOnPod(new String[] {"touch", targetFolderPath +"/fileToSynchronizeBackFromPodToLocal.txt"}); - - // Check Remote to Local - rsyncAndCheck("fileToSynchronizeBackFromPodToLocal", podPeer, localPeer); - assertThat(new File(localTempDir, "fileToSynchronizeBackFromPodToLocal.txt").exists()).isTrue(); - } - - protected void execOnPod(String[] commands) throws InterruptedException { - PodExecIntegrationTest.TestExecListener execListener = new PodExecIntegrationTest.TestExecListener(); - final String container = pod.getContainers().iterator().next().getName(); - IPodExec.Options options = new IPodExec.Options(); - options.container( container ); - - pod.accept(new CapabilityVisitor() { - - @Override - public IStoppable visit(IPodExec capability) { - return capability.start(execListener, options, commands); - } - - }, null); - execListener.testDone.await( 10, TimeUnit.SECONDS ); - assertTrue( execListener.openCalled.get() ); - assertTrue( execListener.closeCalled.get() ); - assertTrue( !execListener.failureCalled.get() ); - assertTrue( !execListener.execErrCalled.get() ); - } - - protected void rsyncAndCheck(final String fileName, Peer source, Peer destination) { - List logs = pod.accept(new CapabilityVisitor>() { - - @Override - public List visit(IRSyncable cap) { - try { - final BufferedReader reader = new BufferedReader(new InputStreamReader( - cap.sync(source, destination, new SkipTlsVerify()))); - List logs = IOUtils.readLines(reader); - // wait until end of 'rsync' - cap.await(); - return logs; - } catch (Exception e) { - LOG.error("Exception rsyncing to pod:",e); - } - return new ArrayList<>(); - } - - }, new ArrayList<>()); - if(LOG.isDebugEnabled()) { - LOG.debug("**** RSync Logs ****"); - logs.forEach(l->LOG.debug(l)); - } - // then verify that the logs contain a message about the dummy file - assertThat(logs).isNotEmpty(); - assertThat(logs.stream().anyMatch(line -> line.contains(fileName))).isTrue(); - } + private static final String TARGET_FOLDER_WITH_SPECIAL_CHARS = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/with sp@cé/"; + private static final String FILE_NAME_SPECIAL_CHARS = "test with spéci@l characters and spaces"; + private static final String SOURCE_FOLDER_WITH_SPECIAL_CHARS = "with sp@cé in path"; + + private static final String NORMAL_TARGET_TMP = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/withoutspace/"; + private static final String NORMAL_FILE_NAME = "normalFileName"; + private static final String NORMAL_FOLDER_NAME = "normalFolderName"; + + private static final Logger LOG = LoggerFactory.getLogger(OpenshiftBinaryRSyncRetrievalIntegrationTest.class); + + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IClient client; + + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); + + private Pod pod; + private String podFolderToClean = null; + + @Before + public void setUp() throws Exception { + // given + System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); + client = helper.createClientForBasicAuth(); + + List pods = client.list(ResourceKind.POD, "default"); + pod = (Pod) pods.stream().filter(p -> p.getName().startsWith("docker-registry")).findFirst().orElse(null); + assertNotNull("Did not find the registry pod to which to rsync", pod); + } + + @After + public void tearDown() throws Exception { + if (podFolderToClean != null) { + execOnPod(new String[] { "rm", "-r", podFolderToClean }); + } + } + + @Test + public void testRSyncLogRetrieval() throws IOException, InterruptedException { + testRsyncLogRetrieval(NORMAL_FOLDER_NAME, NORMAL_FILE_NAME, NORMAL_TARGET_TMP); + } + + @Test + public void testRSyncLogRetrievalWithSpaceInFolderToSynchronize() throws Exception { + testRsyncLogRetrieval(SOURCE_FOLDER_WITH_SPECIAL_CHARS, NORMAL_FILE_NAME, NORMAL_TARGET_TMP); + } + + @Test + public void testRSyncLogRetrievalWithSpaceInFileToSynchronize() throws Exception { + testRsyncLogRetrieval(NORMAL_FOLDER_NAME, FILE_NAME_SPECIAL_CHARS, NORMAL_TARGET_TMP); + } + + @Test + public void testRSyncLogRetrievalWithSpaceInTargetDirectory() throws Exception { + testRsyncLogRetrieval(NORMAL_FOLDER_NAME, NORMAL_FILE_NAME, TARGET_FOLDER_WITH_SPECIAL_CHARS); + } + + @Test + public void testRSyncLogRetrievalWithSpaceEverywhere() throws Exception { + testRsyncLogRetrieval(SOURCE_FOLDER_WITH_SPECIAL_CHARS, FILE_NAME_SPECIAL_CHARS, + TARGET_FOLDER_WITH_SPECIAL_CHARS); + } + + protected void testRsyncLogRetrieval(String folderToSynchronizeName, String fileNameToSynchronize, + String targetFolderPath) throws IOException, InterruptedException { + podFolderToClean = targetFolderPath; + execOnPod(new String[] { "mkdir", "-p", targetFolderPath }); + File localTempDir = tmpFolder.newFolder(folderToSynchronizeName); + // Create a dummy file locally to be sure there will be something to rsync from + // Local to Remote + File tmpFile = File.createTempFile(fileNameToSynchronize, ".txt", localTempDir); + final String fileName = tmpFile.getName(); + LocalPeer localPeer = new LocalPeer(localTempDir.getAbsolutePath() + File.separator); + PodPeer podPeer = new PodPeer(targetFolderPath, pod); + + // Check Local to Remote + rsyncAndCheck(fileName, localPeer, podPeer); + tmpFile.delete(); + + // Create a dummy file locally to be sure there will be something to rsync from + // Remote to Local + execOnPod(new String[] { "touch", targetFolderPath + "/fileToSynchronizeBackFromPodToLocal.txt" }); + + // Check Remote to Local + rsyncAndCheck("fileToSynchronizeBackFromPodToLocal", podPeer, localPeer); + assertThat(new File(localTempDir, "fileToSynchronizeBackFromPodToLocal.txt").exists()).isTrue(); + } + + protected void execOnPod(String[] commands) throws InterruptedException { + PodExecIntegrationTest.TestExecListener execListener = new PodExecIntegrationTest.TestExecListener(); + final String container = pod.getContainers().iterator().next().getName(); + IPodExec.Options options = new IPodExec.Options(); + options.container(container); + + pod.accept(new CapabilityVisitor() { + + @Override + public IStoppable visit(IPodExec capability) { + return capability.start(execListener, options, commands); + } + + }, null); + execListener.testDone.await(10, TimeUnit.SECONDS); + assertTrue(execListener.openCalled.get()); + assertTrue(execListener.closeCalled.get()); + assertTrue(!execListener.failureCalled.get()); + assertTrue(!execListener.execErrCalled.get()); + } + + protected void rsyncAndCheck(final String fileName, Peer source, Peer destination) { + List logs = pod.accept(new CapabilityVisitor>() { + + @Override + public List visit(IRSyncable cap) { + try { + final BufferedReader reader = new BufferedReader( + new InputStreamReader(cap.sync(source, destination, new SkipTlsVerify()))); + List logs = IOUtils.readLines(reader); + // wait until end of 'rsync' + cap.await(); + return logs; + } catch (Exception e) { + LOG.error("Exception rsyncing to pod:", e); + } + return new ArrayList<>(); + } + + }, new ArrayList<>()); + if (LOG.isDebugEnabled()) { + LOG.debug("**** RSync Logs ****"); + logs.forEach(l -> LOG.debug(l)); + } + // then verify that the logs contain a message about the dummy file + assertThat(logs).isNotEmpty(); + assertThat(logs.stream().anyMatch(line -> line.contains(fileName))).isTrue(); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java index 56cc1dde..9c0a67cc 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java @@ -8,8 +8,21 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; + +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.restclient.ResourceKind; @@ -20,79 +33,60 @@ import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.Options; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IResource; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.IOException; -import java.util.List; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; +public class PodLogRetrievalAsyncIntegrationTest { -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; + private static final Logger LOG = LoggerFactory.getLogger(PodLogRetrievalAsyncIntegrationTest.class); -/** - * - * @author Jeff Cantrill - * - */ -public class PodLogRetrievalAsyncIntegrationTest { - - private static final Logger LOG = LoggerFactory.getLogger(PodLogRetrievalAsyncIntegrationTest.class); - - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private CountDownLatch latch; - - - @Test - public void testAsyncLogRetrieval() throws Exception { - latch = new CountDownLatch(2); - DefaultClient client = (DefaultClient) helper.createClientForBasicAuth(); - List pods = client.list(ResourceKind.POD, "default"); - IPod pod = (IPod) pods.stream().filter(p->p.getName().startsWith("docker-registry")).findFirst().orElse(null); - assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); - - final String container = pod.getContainers().iterator().next().getName(); - - IStoppable stop = pod.accept(new CapabilityVisitor() { - - @Override - public IStoppable visit(IPodLogRetrievalAsync capability) { - return capability.start(new IPodLogListener() { - - @Override - public void onOpen() { - LOG.debug("onOpen"); - latch.countDown(); - } - - @Override - public void onMessage(String message) { - LOG.debug(message); - } - - @Override - public void onClose(int code, String reason) { - LOG.debug("onClose code:{} reason:{}", code, reason); - latch.countDown(); - } - - @Override - public void onFailure(IOException e) { - LOG.error( "Unexpected websocket failure", e ); - fail( "Unexpected websocket failure" ); - } - - }, new Options() - .follow() - .container(container)); - } - }, null); - assertNotNull("Exp. to support the capability", stop); - latch.await(10, TimeUnit.SECONDS); - stop.stop(); - latch.await(5, TimeUnit.SECONDS); - } + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private CountDownLatch latch; + + @Test + public void testAsyncLogRetrieval() throws Exception { + latch = new CountDownLatch(2); + DefaultClient client = (DefaultClient) helper.createClientForBasicAuth(); + List pods = client.list(ResourceKind.POD, "default"); + IPod pod = (IPod) pods.stream().filter(p -> p.getName().startsWith("docker-registry")).findFirst().orElse(null); + assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); + + final String container = pod.getContainers().iterator().next().getName(); + + IStoppable stop = pod.accept(new CapabilityVisitor() { + + @Override + public IStoppable visit(IPodLogRetrievalAsync capability) { + return capability.start(new IPodLogListener() { + + @Override + public void onOpen() { + LOG.debug("onOpen"); + latch.countDown(); + } + + @Override + public void onMessage(String message) { + LOG.debug(message); + } + + @Override + public void onClose(int code, String reason) { + LOG.debug("onClose code:{} reason:{}", code, reason); + latch.countDown(); + } + + @Override + public void onFailure(IOException e) { + LOG.error("Unexpected websocket failure", e); + fail("Unexpected websocket failure"); + } + + }, new Options().follow().container(container)); + } + }, null); + assertNotNull("Exp. to support the capability", stop); + latch.await(10, TimeUnit.SECONDS); + stop.stop(); + latch.await(5, TimeUnit.SECONDS); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java index 04ec11b4..86e2b465 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java @@ -8,10 +8,18 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -33,71 +41,72 @@ import okhttp3.ws.WebSocket; @RunWith(MockitoJUnitRunner.class) -public class PodLogRetrievalAsyncTest extends TypeMapperFixture{ - - private DefaultClient client; - @Mock - private IApiTypeMapper mapper; - private PodLogRetrievalAsync capability; - private IPod pod; - private PodLogListenerAdapter adapter; - - @Mock - private IPodLogListener listener; - - @Before - public void setUp() throws Exception { - super.setUp(); - client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); - pod = new MocksFactory().mock(IPod.class); - capability = new PodLogRetrievalAsync(pod, client); - - adapter = new PodLogListenerAdapter(listener); - } - - @Test - public void testIsSupported() { - assertTrue("Exp. capability to be supported because the pod endpoint exists", capability.isSupported()); - } - - @Test - public void testIsNotSupportedWhenEndpointDoesNotExist() { - when(pod.getApiVersion()).thenReturn("somenoneexitentversion"); - assertFalse("Exp. capability to not be supported because the pod endpoint does not exist exists", capability.isSupported()); - } - - @Test - public void testAdapterCallsListenerCycle() throws Exception { - adapter.onOpen(null, null); - adapter.onOpen(null, null); - verify(listener).onOpen(); - - ResponseBody body = ResponseBody.create(MediaType.parse("text"), "a body"); - adapter.onMessage(body); - verify(listener).onMessage("a body"); - - adapter.onClose(1986, "the reason"); - adapter.onClose(1986, "the reason"); - verify(listener).onClose(1986, "the reason"); - } - - @Test - public void testStopWhenConnected() throws Exception { - WebSocket socket = mock(WebSocket.class); - adapter.onOpen(socket, null); - - adapter.stop(); - verify(socket).close(eq(IHttpConstants.STATUS_NORMAL_STOP), anyString()); - } - - @Test - public void testStopSwallowsException() throws Exception { - WebSocket socket = mock(WebSocket.class); - doThrow(Exception.class).when(socket).close(anyInt(), anyString()); - adapter.onOpen(socket, null); - - adapter.stop(); - verify(socket).close(eq(IHttpConstants.STATUS_NORMAL_STOP), anyString()); - } +public class PodLogRetrievalAsyncTest extends TypeMapperFixture { + + private DefaultClient client; + @Mock + private IApiTypeMapper mapper; + private PodLogRetrievalAsync capability; + private IPod pod; + private PodLogListenerAdapter adapter; + + @Mock + private IPodLogListener listener; + + @Before + public void setUp() throws Exception { + super.setUp(); + client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); + pod = new MocksFactory().mock(IPod.class); + capability = new PodLogRetrievalAsync(pod, client); + + adapter = new PodLogListenerAdapter(listener); + } + + @Test + public void testIsSupported() { + assertTrue("Exp. capability to be supported because the pod endpoint exists", capability.isSupported()); + } + + @Test + public void testIsNotSupportedWhenEndpointDoesNotExist() { + when(pod.getApiVersion()).thenReturn("somenoneexitentversion"); + assertFalse("Exp. capability to not be supported because the pod endpoint does not exist exists", + capability.isSupported()); + } + + @Test + public void testAdapterCallsListenerCycle() throws Exception { + adapter.onOpen(null, null); + adapter.onOpen(null, null); + verify(listener).onOpen(); + + ResponseBody body = ResponseBody.create(MediaType.parse("text"), "a body"); + adapter.onMessage(body); + verify(listener).onMessage("a body"); + + adapter.onClose(1986, "the reason"); + adapter.onClose(1986, "the reason"); + verify(listener).onClose(1986, "the reason"); + } + + @Test + public void testStopWhenConnected() throws Exception { + WebSocket socket = mock(WebSocket.class); + adapter.onOpen(socket, null); + + adapter.stop(); + verify(socket).close(eq(IHttpConstants.STATUS_NORMAL_STOP), anyString()); + } + + @Test + public void testStopSwallowsException() throws Exception { + WebSocket socket = mock(WebSocket.class); + doThrow(Exception.class).when(socket).close(anyInt(), anyString()); + adapter.onOpen(socket, null); + + adapter.stop(); + verify(socket).close(eq(IHttpConstants.STATUS_NORMAL_STOP), anyString()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java index 39fb548b..40fefef2 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java @@ -6,10 +6,18 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.util.Collection; @@ -31,63 +39,65 @@ @RunWith(MockitoJUnitRunner.class) public class ProjectTemplateProcessingTest { - - private static final String NAMESPACE = "aProjectNamespace"; - private IProjectTemplateProcessing capability; - @Mock - private ITemplate template; - @Mock - private IClient client; - @Mock - private ITemplateProcessing serverCapability; - @Mock - private IProject project; - - @Before - public void setUp() throws Exception { - when(project.getNamespaceName()).thenReturn(NAMESPACE); - when(client.supports(eq(ITemplateProcessing.class))).thenReturn(true); - when(client.getCapability(eq(ITemplateProcessing.class))).thenReturn(serverCapability); - - capability = new ProjectTemplateProcessing(project, client); - } - - @Test - public void isSupportedShouldBeFalseForNullClient() { - capability = new ProjectTemplateProcessing(project, null); - assertFalse(capability.isSupported()); - } - - @Test - public void isSupportedShouldBeFalseIfTheClientDoesntSupportTemplates() { - when(client.supports(eq(ITemplateProcessing.class))).thenReturn(false); - capability = new ProjectTemplateProcessing(project, client); - assertFalse(capability.isSupported()); - } - - @Test - public void isSupportedShouldBeTrueIfTheClientSupportTemplates() { - assertTrue(capability.isSupported()); - } - - @Test - public void processTemplateShouldUseTheClientsCapability() { - when(serverCapability.process(any(ITemplate.class), anyString())).thenReturn(template); - - assertEquals(template, capability.process(template)); - verify(serverCapability).process(eq(template), eq(NAMESPACE)); - } - - @Test - public void applyTemplateShouldUseTheClientToCreateTheResources() { - @SuppressWarnings("unchecked") - Collection resources = mock(Collection.class); - when(client.create(any(IList.class), anyString())).thenReturn(resources); - when(client.getResourceFactory()).thenReturn(new ResourceFactory(client) {}); - ITemplate template = new ResourceFactory(client) {}.create(Samples.V1_TEMPLATE.getContentAsString()); - - assertEquals(resources, capability.apply(template)); - verify(client).create(any(IList.class), eq(NAMESPACE)); - } - + + private static final String NAMESPACE = "aProjectNamespace"; + private IProjectTemplateProcessing capability; + @Mock + private ITemplate template; + @Mock + private IClient client; + @Mock + private ITemplateProcessing serverCapability; + @Mock + private IProject project; + + @Before + public void setUp() throws Exception { + when(project.getNamespaceName()).thenReturn(NAMESPACE); + when(client.supports(eq(ITemplateProcessing.class))).thenReturn(true); + when(client.getCapability(eq(ITemplateProcessing.class))).thenReturn(serverCapability); + + capability = new ProjectTemplateProcessing(project, client); + } + + @Test + public void isSupportedShouldBeFalseForNullClient() { + capability = new ProjectTemplateProcessing(project, null); + assertFalse(capability.isSupported()); + } + + @Test + public void isSupportedShouldBeFalseIfTheClientDoesntSupportTemplates() { + when(client.supports(eq(ITemplateProcessing.class))).thenReturn(false); + capability = new ProjectTemplateProcessing(project, client); + assertFalse(capability.isSupported()); + } + + @Test + public void isSupportedShouldBeTrueIfTheClientSupportTemplates() { + assertTrue(capability.isSupported()); + } + + @Test + public void processTemplateShouldUseTheClientsCapability() { + when(serverCapability.process(any(ITemplate.class), anyString())).thenReturn(template); + + assertEquals(template, capability.process(template)); + verify(serverCapability).process(eq(template), eq(NAMESPACE)); + } + + @Test + public void applyTemplateShouldUseTheClientToCreateTheResources() { + @SuppressWarnings("unchecked") + Collection resources = mock(Collection.class); + when(client.create(any(IList.class), anyString())).thenReturn(resources); + when(client.getResourceFactory()).thenReturn(new ResourceFactory(client) { + }); + ITemplate template = new ResourceFactory(client) { + }.create(Samples.V1_TEMPLATE.getContentAsString()); + + assertEquals(resources, capability.apply(template)); + verify(client).create(any(IList.class), eq(NAMESPACE)); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PropertyAccessCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PropertyAccessCapabilityTest.java index 7c1b0e75..bf9768e6 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PropertyAccessCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PropertyAccessCapabilityTest.java @@ -8,10 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; import java.util.HashMap; import java.util.Map; @@ -27,54 +28,55 @@ import com.openshift.restclient.utils.Samples; public class PropertyAccessCapabilityTest { - - private ModelNode node; - private IPropertyAccessCapability cap; - @Before - public void setup() { - IClient client = mock(IClient.class); - node = ModelNode.fromJSONString(Samples.V1_BUILD_CONFIG.getContentAsString()); - node.get(new String[] {"spec", "strategy","sourceStrategy", "xyz"}).set(1986); - BuildConfig config = new BuildConfig(node, client, new HashMap<>()); - cap = new PropertyAccessCapability(config); - } - @Test(expected=UnresolvablePathException.class) - public void testAsMapWhenPathIsNotFound() { - cap.asMap("foo.strategy.sourceStrategy.from"); - } + private ModelNode node; + private IPropertyAccessCapability cap; + + @Before + public void setup() { + IClient client = mock(IClient.class); + node = ModelNode.fromJSONString(Samples.V1_BUILD_CONFIG.getContentAsString()); + node.get(new String[] { "spec", "strategy", "sourceStrategy", "xyz" }).set(1986); + BuildConfig config = new BuildConfig(node, client, new HashMap<>()); + cap = new PropertyAccessCapability(config); + } + + @Test(expected = UnresolvablePathException.class) + public void testAsMapWhenPathIsNotFound() { + cap.asMap("foo.strategy.sourceStrategy.from"); + } + + @Test + public void testAsString() { + assertEquals("1986", cap.asString("spec.strategy.sourceStrategy.xyz")); + } + + @Test(expected = UnresolvablePathException.class) + public void testAsWhenPathIsNotFound() { + cap.asString("spec.strategy.sourceStrategy.xyzzz"); + } - @Test - public void testAsString() { - assertEquals("1986", cap.asString("spec.strategy.sourceStrategy.xyz")); - } + @Test + public void testAsMap() { + Map from = new HashMap<>(); + from.put("kind", "ImageStreamTag"); + from.put("name", "ruby-20-centos7:latest"); + Map exp = new HashMap<>(); + exp.put("from", from); + exp.put("incremental", true); + exp.put("scripts", "aLocation"); + exp.put("xyz", 1986); - @Test(expected=UnresolvablePathException.class) - public void testAsWhenPathIsNotFound() { - cap.asString("spec.strategy.sourceStrategy.xyzzz"); - } - - @Test - public void testAsMap() { - Map from = new HashMap<>(); - from.put("kind","ImageStreamTag"); - from.put("name","ruby-20-centos7:latest"); - Map exp = new HashMap<>(); - exp.put("from", from); - exp.put("incremental", true); - exp.put("scripts", "aLocation"); - exp.put("xyz", 1986); - - // @TODO Why doesnt this validate? -// Map envEntry = new HashMap<>(); -// envEntry.put("name", "foo"); -// envEntry.put("value", "bar"); -// List env = new ArrayList<>(); -// env.add(envEntry); -// -// exp.put("env", env); - Map act = cap.asMap("spec.strategy.sourceStrategy.from"); - assertEquals(from, act); - } + // @TODO Why doesnt this validate? + // Map envEntry = new HashMap<>(); + // envEntry.put("name", "foo"); + // envEntry.put("value", "bar"); + // List env = new ArrayList<>(); + // env.add(envEntry); + // + // exp.put("env", env); + Map act = cap.asMap("spec.strategy.sourceStrategy.from"); + assertEquals(from, act); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/TagCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/TagCapabilityTest.java index 2848d5e8..e3d3bb48 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/TagCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/TagCapabilityTest.java @@ -6,10 +6,11 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertArrayEquals; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -17,27 +18,24 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import com.openshift.internal.restclient.capability.resources.TagCapability; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ @RunWith(MockitoJUnitRunner.class) public class TagCapabilityTest { - private TagCapability capability; - @Mock private IResource resource; - - @Before - public void setup(){ - when(resource.getAnnotation("tags")).thenReturn("instant-app,ruby,mysql"); - capability = new TagCapability(resource); - } - - @Test - public void testGetTags() { - assertArrayEquals(new String[]{"instant-app","ruby","mysql"},capability.getTags().toArray()); - } + private TagCapability capability; + @Mock + private IResource resource; + + @Before + public void setup() { + when(resource.getAnnotation("tags")).thenReturn("instant-app,ruby,mysql"); + capability = new TagCapability(resource); + } + + @Test + public void testGetTags() { + assertArrayEquals(new String[] { "instant-app", "ruby", "mysql" }, capability.getTags().toArray()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java index dc4065f9..55078a3a 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java @@ -6,9 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; import org.junit.Before; @@ -21,40 +24,41 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IResource; -/** - * @author Jeff Cantrill - */ @RunWith(MockitoJUnitRunner.class) public class TemplateTraceabilityTest { - private TemplateTraceability capability; - @Mock private IClient client; - @Mock private IResource resource; - - @Before - public void setUp(){ - capability = new TemplateTraceability(resource); - when(resource.getNamespaceName()).thenReturn("mynamespace"); - when(resource.getKind()).thenReturn(ResourceKind.TEMPLATE); - } - - @Test - public void supportedWhenAnnotationHasTemplateKey(){ - when(resource.isAnnotatedWith("template")).thenReturn(true); - when(resource.getAnnotation("template")).thenReturn("aTemplateName"); - - assertTrue("Exp. the capability to be supported because it has the template annotation", capability.isSupported()); - assertEquals("Exp. to get the template name", "aTemplateName", capability.getTemplateName()); - } - - @Test - public void unsupportedWhenAnnotationDoesNotHasTemplateKey(){ - assertFalse("Exp. the capability to not be supported because it does not have the template annotation", capability.isSupported()); - assertEquals("Exp. to get the template name", "", capability.getTemplateName()); - } - - @Test - public void testGetName(){ - assertEquals("", TemplateTraceability.class.getSimpleName(), capability.getName()); - } + private TemplateTraceability capability; + @Mock + private IClient client; + @Mock + private IResource resource; + + @Before + public void setUp() { + capability = new TemplateTraceability(resource); + when(resource.getNamespaceName()).thenReturn("mynamespace"); + when(resource.getKind()).thenReturn(ResourceKind.TEMPLATE); + } + + @Test + public void supportedWhenAnnotationHasTemplateKey() { + when(resource.isAnnotatedWith("template")).thenReturn(true); + when(resource.getAnnotation("template")).thenReturn("aTemplateName"); + + assertTrue("Exp. the capability to be supported because it has the template annotation", + capability.isSupported()); + assertEquals("Exp. to get the template name", "aTemplateName", capability.getTemplateName()); + } + + @Test + public void unsupportedWhenAnnotationDoesNotHasTemplateKey() { + assertFalse("Exp. the capability to not be supported because it does not have the template annotation", + capability.isSupported()); + assertEquals("Exp. to get the template name", "", capability.getTemplateName()); + } + + @Test + public void testGetName() { + assertEquals("", TemplateTraceability.class.getSimpleName(), capability.getName()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java index a304888f..02a18b49 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java @@ -6,10 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; @@ -25,40 +27,38 @@ import com.openshift.restclient.capability.resources.IUpdatable; import com.openshift.restclient.model.IService; -/** - * @author Jeff Cantrill - */ @RunWith(MockitoJUnitRunner.class) public class UpdateableCapabilityTest { - @Mock private IClient client; - private IService service; - private IResourceFactory factory; - - @Before - public void setup(){ - when(client.getOpenShiftAPIVersion()).thenReturn("v1"); - factory = new ResourceFactory(client); - service = factory.stub(ResourceKind.SERVICE, "foo", "default"); - service.setAnnotation("foo", "bar"); - } - - @Test - public void testUpdateCapability() { - IService target = factory.stub(ResourceKind.SERVICE, "foo", "default"); - target.setAnnotation("foo", "xyz"); - - service.accept(new CapabilityVisitor() { + @Mock + private IClient client; + private IService service; + private IResourceFactory factory; + + @Before + public void setup() { + when(client.getOpenShiftAPIVersion()).thenReturn("v1"); + factory = new ResourceFactory(client); + service = factory.stub(ResourceKind.SERVICE, "foo", "default"); + service.setAnnotation("foo", "bar"); + } + + @Test + public void testUpdateCapability() { + IService target = factory.stub(ResourceKind.SERVICE, "foo", "default"); + target.setAnnotation("foo", "xyz"); + + service.accept(new CapabilityVisitor() { - @Override - public IService visit(IUpdatable capability) { - capability.updateFrom(target); - return null; - }; - }, null); - assertNotSame("Exp. services to not be the same instance", target, service); - assertEquals("Exp. the annotation to be updated","xyz", service.getAnnotation("foo")); - assertEquals("Exp. the JSON to be the same", target.toJson(), service.toJson()); - } + @Override + public IService visit(IUpdatable capability) { + capability.updateFrom(target); + return null; + } + }, null); + assertNotSame("Exp. services to not be the same instance", target, service); + assertEquals("Exp. the annotation to be updated", "xyz", service.getAnnotation("foo")); + assertEquals("Exp. the JSON to be the same", target.toJson(), service.toJson()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java b/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java index 9ffc5cfc..ddfe7e0b 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/testutils/BinaryCapabilityTestMocks.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.capability.resources.testutils; import static org.mockito.Mockito.doReturn; @@ -23,39 +24,39 @@ public class BinaryCapabilityTestMocks { - public static final String SERVER_URL = "https://localhost:8443"; - public static final String TOKEN = "phWDXIqSspYBZARPQIzqaevHGDIxduQGbhcZuwj48EI"; - - public static final String OC_LOCATION = "/path/to/oc"; - - public static final String POD_NAME = "papa-smurf"; - public static final String POD_NAMESPACE = "the-smurfs"; - - public static IClient mockClient() throws MalformedURLException { - IClient client = mock(IClient.class); - doReturn(new URL(SERVER_URL)).when(client).getBaseURL(); - IAuthorizationContext context = mockAuthorizationContext(); - doReturn(context).when(client).getAuthorizationContext(); - return client; - } - - private static IAuthorizationContext mockAuthorizationContext() { - IAuthorizationContext context = mock(IAuthorizationContext.class); - doReturn(TOKEN).when(context).getToken(); - return context; - } - - public static IPod mockPod() { - IPod pod = mock(IPod.class); - doReturn(POD_NAME).when(pod).getName(); - doReturn(POD_NAMESPACE).when(pod).getNamespaceName(); - return pod; - } - - public static PortPair mockPortPair(int localPort, int remotePort) { - PortPair ports = mock(PortPair.class); - doReturn(localPort).when(ports).getLocalPort(); - doReturn(remotePort).when(ports).getRemotePort(); - return ports; - } + public static final String SERVER_URL = "https://localhost:8443"; + public static final String TOKEN = "phWDXIqSspYBZARPQIzqaevHGDIxduQGbhcZuwj48EI"; + + public static final String OC_LOCATION = "/path/to/oc"; + + public static final String POD_NAME = "papa-smurf"; + public static final String POD_NAMESPACE = "the-smurfs"; + + public static IClient mockClient() throws MalformedURLException { + IClient client = mock(IClient.class); + doReturn(new URL(SERVER_URL)).when(client).getBaseURL(); + IAuthorizationContext context = mockAuthorizationContext(); + doReturn(context).when(client).getAuthorizationContext(); + return client; + } + + private static IAuthorizationContext mockAuthorizationContext() { + IAuthorizationContext context = mock(IAuthorizationContext.class); + doReturn(TOKEN).when(context).getToken(); + return context; + } + + public static IPod mockPod() { + IPod pod = mock(IPod.class); + doReturn(POD_NAME).when(pod).getName(); + doReturn(POD_NAMESPACE).when(pod).getNamespaceName(); + return pod; + } + + public static PortPair mockPortPair(int localPort, int remotePort) { + PortPair ports = mock(PortPair.class); + doReturn(localPort).when(ports).getLocalPort(); + doReturn(remotePort).when(ports).getRemotePort(); + return ports; + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java index 72b64d69..341c637f 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java @@ -6,9 +6,11 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.server; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import java.net.MalformedURLException; import java.util.ArrayList; @@ -31,56 +33,55 @@ import com.openshift.restclient.model.template.ITemplate; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class ServerTemplateProcessingIntegrationTest { - private static final Logger LOG = LoggerFactory.getLogger(ServerTemplateProcessingIntegrationTest.class); - - private IClient client; - private IntegrationTestHelper helper = new IntegrationTestHelper(); + private static final Logger LOG = LoggerFactory.getLogger(ServerTemplateProcessingIntegrationTest.class); + + private IClient client; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + + private IProject project; + + @Before + public void setup() throws MalformedURLException { + client = helper.createClientForBasicAuth(); + String namespace = helper.generateNamespace(); + client.create(client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, namespace)); + project = client.get(ResourceKind.PROJECT, namespace, ""); + } + + @Test + public void testProcessAndApplyTemplate() throws Exception { + final Collection results = new ArrayList(); + ModelNode node = ModelNode.fromJSONString(Samples.V1_TEMPLATE.getContentAsString()); + final Template template = new Template(node, client, null); + template.setNamespace(null); + try { + client.accept(new CapabilityVisitor() { + + @Override + public Object visit(ITemplateProcessing capability) { - private IProject project; + LOG.debug("Processing template: {}", template.toJson()); + assertFalse("Exp. the template to have items for this test be interesting", + template.getObjects().isEmpty()); + final int items = template.getObjects().size(); + ITemplate processedTemplate = capability.process(template, project.getName()); - @Before - public void setup () throws MalformedURLException{ - client = helper.createClientForBasicAuth(); - String namespace = helper.generateNamespace(); - client.create(client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, namespace)); - project = client.get(ResourceKind.PROJECT, namespace, ""); - } - - @Test - public void testProcessAndApplyTemplate() throws Exception{ - final Collection results = new ArrayList(); - ModelNode node = ModelNode.fromJSONString(Samples.V1_TEMPLATE.getContentAsString()); - final Template template = new Template(node, client, null); - template.setNamespace(null); - try { - client.accept(new CapabilityVisitor() { - - @Override - public Object visit(ITemplateProcessing capability) { - - LOG.debug("Processing template: {}", template.toJson()); - assertFalse("Exp. the template to have items for this test be interesting", template.getObjects().isEmpty()); - final int items = template.getObjects().size(); - ITemplate processedTemplate = capability.process(template, project.getName()); - - LOG.debug("Applying template: {}", processedTemplate.toJson()); - LOG.debug("Applied template"); - assertEquals("Exp. the pre and post item count to be the same", items, template.getObjects().size()); - for (IResource resource : processedTemplate.getObjects()) { - LOG.debug("creating: {}", resource); - results.add(client.create(resource, project.getName())); - LOG.debug("created: {}", resource.toJson()); - } - return null; - } - }, new Object()); - } finally { - IntegrationTestHelper.cleanUpResource(client, project); - } - } + LOG.debug("Applying template: {}", processedTemplate.toJson()); + LOG.debug("Applied template"); + assertEquals("Exp. the pre and post item count to be the same", items, + template.getObjects().size()); + for (IResource resource : processedTemplate.getObjects()) { + LOG.debug("creating: {}", resource); + results.add(client.create(resource, project.getName())); + LOG.debug("created: {}", resource.toJson()); + } + return null; + } + }, new Object()); + } finally { + IntegrationTestHelper.cleanUpResource(client, project); + } + } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingTest.java index 0ad0524a..5fcac005 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingTest.java @@ -6,58 +6,57 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.capability.server; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; -import com.openshift.internal.restclient.capability.server.ServerTemplateProcessing; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.server.ITemplateProcessing; -/** - * @author Jeff Cantrill - */ public class ServerTemplateProcessingTest { - private IApiTypeMapper mapper; - private IClient client; - private ITemplateProcessing cap; - - @Before - public void setup() { - mapper = mock(IApiTypeMapper.class); - client = mock(IClient.class); - cap = new ServerTemplateProcessing(client); - - } - - @Test - public void testIsSupportedWhenApiEndpointExists() { - when(mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES)).thenReturn(true); - when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); - - assertTrue("Exp. endpoint to be supported when processedtemplates is supported", cap.isSupported()); - } - - @Test - public void testIsSupportedWhenApiEndpointDoesNotExists() { - when(mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES)).thenReturn(false); - when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); - - assertFalse("Exp. endpoint to not be supported when processedtemplates does not exist", cap.isSupported()); - } - - @Test - public void testIsNotSupportedWhenNotAdaptableToApiTypeMapper() { - when(client.adapt(IApiTypeMapper.class)).thenReturn(null); - - assertFalse("Exp. endpoint to not be supported when not adaptable", cap.isSupported()); - } + private IApiTypeMapper mapper; + private IClient client; + private ITemplateProcessing cap; + + @Before + public void setup() { + mapper = mock(IApiTypeMapper.class); + client = mock(IClient.class); + cap = new ServerTemplateProcessing(client); + + } + + @Test + public void testIsSupportedWhenApiEndpointExists() { + when(mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES)).thenReturn(true); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + + assertTrue("Exp. endpoint to be supported when processedtemplates is supported", cap.isSupported()); + } + + @Test + public void testIsSupportedWhenApiEndpointDoesNotExists() { + when(mapper.isSupported(ResourceKind.PROCESSED_TEMPLATES)).thenReturn(false); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + + assertFalse("Exp. endpoint to not be supported when processedtemplates does not exist", cap.isSupported()); + } + + @Test + public void testIsNotSupportedWhenNotAdaptableToApiTypeMapper() { + when(client.adapt(IApiTypeMapper.class)).thenReturn(null); + + assertFalse("Exp. endpoint to not be supported when not adaptable", cap.isSupported()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/BuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/BuildConfigTest.java index ef8bfdcb..acc6fd63 100644 --- a/src/test/java/com/openshift/internal/restclient/model/BuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/BuildConfigTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import static org.junit.Assert.assertEquals; @@ -23,23 +24,24 @@ import com.openshift.restclient.model.IBuildConfig; /** - * Tests unrelated to the underlying model structure and - * should api version independent + * Tests unrelated to the underlying model structure and should api version + * independent + * * @author Jeff Maury * */ public class BuildConfigTest { - private IBuildConfig config; + private IBuildConfig config; - @Before - public void setUp() throws Exception { - config = new BuildConfig(new ModelNode(), mock(IClient.class), new HashMap<>()); - } + @Before + public void setUp() throws Exception { + config = new BuildConfig(new ModelNode(), mock(IClient.class), new HashMap<>()); + } - @Test - public void testBuildTriggersShouldReturn() { - assertEquals(0, config.getBuildTriggers().size()); - } + @Test + public void testBuildTriggersShouldReturn() { + assertEquals(0, config.getBuildTriggers().size()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/KubernetesResourceTest.java b/src/test/java/com/openshift/internal/restclient/model/KubernetesResourceTest.java index 0bf321e8..5b63ce3e 100644 --- a/src/test/java/com/openshift/internal/restclient/model/KubernetesResourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/KubernetesResourceTest.java @@ -6,15 +6,16 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; +import static com.openshift.internal.util.JBossDmrExtentions.getPath; import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertEquals; 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 static com.openshift.internal.util.JBossDmrExtentions.*; import java.util.ArrayList; import java.util.List; @@ -31,199 +32,202 @@ import com.openshift.restclient.capability.resources.IDeploymentTraceability; import com.openshift.restclient.capability.resources.ITemplateTraceability; -/** - * @author Jeff Cantrill - */ public class KubernetesResourceTest { - private ModelNode node; - private KubernetesResource resource; - - @Before - public void setup(){ - this.node = createModelNode(); - this.resource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), node); - } - - private ModelNode createModelNode() { - node = new ModelNode(); - node.get(ResourcePropertyKeys.KIND).set(ResourceKind.LIST.toString()); - - ModelNode annotations = node.get(getPath(KubernetesResource.ANNOTATIONS)); - annotations.get("foo").set("bar"); - annotations.get("template").set("foobar"); - - node.get(KubernetesResource.METADATA_NAME).set("bartender"); - node.get(KubernetesResource.METADATA_NAMESPACE).set("foofighters"); - - return node; - } - - private KubernetesResource createKubernetesResource(String modelVersion, ModelNode node) { - return new KubernetesResource(node, null, - ResourcePropertiesRegistry.getInstance().get(modelVersion, ResourceKind.SERVICE)) {}; - } - - @Test - public void testSetAnnoationWithNullValueShouldReturnGracefully() { - resource.setAnnotation("black",null); - } - - @Test - public void testSetAnnoation() { - resource.setAnnotation("black", "white"); - assertEquals("white",resource.getAnnotation("black")); - } - - @Test - public void testGetAnnotation() { - assertEquals("bar", resource.getAnnotation("foo")); - } - - @Test - public void removeAnnotation() { - resource.removeAnnotation("foo"); - assertNull(resource.getAnnotation("foo")); - } - - @Test - public void isAnnotatedReturnsTrueForKnownAnnotation() { - assertTrue(resource.isAnnotatedWith("foo")); - } - - @Test - public void isAnnotatedReturnsFalseForUnKnownAnnotation() { - assertFalse(resource.isAnnotatedWith("bar")); - } - - @Test - public void supportsIsFalseForUnsupportedCapability() { - assertFalse("Expected to not support capability because IClient is null",resource.supports(IDeploymentTraceability.class)); - } - - @Test - public void getCapabilityReturnsNonNullWhenSupportedCapability() { - assertTrue("Exp. to support capability since resource has template annotation", resource.supports(ITemplateTraceability.class)); - assertNotNull(resource.getCapability(ITemplateTraceability.class)); - } - - @Test - public void testAcceptVisitor(){ - final List visited = new ArrayList(); - resource.accept(new CapabilityVisitor(){ - - @Override - public Object visit(ITemplateTraceability capability) { - visited.add(Boolean.TRUE); - return (Object)null; - } - - }, new Object()); - assertEquals("Exp. the visitor to be visited", 1, visited.size()); - } - - @Test - public void shouldSameHashCodeOnAddedLabels() { - // pre-condition - int hashCodeBeforeChange = resource.hashCode(); - - // operation - resource.set(ResourcePropertyKeys.LABELS, "kungfoo"); - - // verification - int hashCodeAfterChange = resource.hashCode(); - assertEquals(hashCodeBeforeChange, hashCodeAfterChange); - } - - @Test - public void shouldDifferentHashCodeOnDifferentName() { - // pre-condition - int hashCodeBeforeChange = resource.hashCode(); - - // operation - resource.set(KubernetesResource.METADATA_NAME, "brucefoolee"); - - // verification - int hashCodeAfterChange = resource.hashCode(); - assertThat(hashCodeBeforeChange).isNotEqualTo(hashCodeAfterChange); - } - - @Test - public void shouldDifferentHashCodeOnDifferentResourceKind() { - // pre-condition - int hashCodeBeforeChange = resource.hashCode(); - - // operation - node.get(ResourcePropertyKeys.KIND).set(ResourceKind.EVENT.toString()); - - // verification - int hashCodeAfterChange = resource.hashCode(); - assertThat(hashCodeBeforeChange).isNotEqualTo(hashCodeAfterChange); - } - - @Test - public void shouldDifferentHashCodeOnDifferentNamespace() { - // pre-condition - int hashCodeBeforeChange = resource.hashCode(); - - // operation - node.get(new String [] {"metadata", "namespace"}).set("barfoo"); - - // verification - int hashCodeAfterChange = resource.hashCode(); - assertThat(hashCodeBeforeChange).isNotEqualTo(hashCodeAfterChange); - } - - @Test - public void shouldEqualsOnAddedLabels() { - // pre-condition - KubernetesResource otherResource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), node); - assertEquals(resource, otherResource); - - // operation - otherResource.set(ResourcePropertyKeys.LABELS, "bruceleefoo"); - - // verification - assertEquals(resource, otherResource); - } - - @Test - public void shouldNotEqualsOnDifferentName() { - // pre-condition - KubernetesResource otherResource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), createModelNode()); - assertEquals(resource, otherResource); - - // operation - otherResource.set(KubernetesResource.METADATA_NAME, "kungfoo"); - - // verification - assertThat(resource).isNotEqualTo(otherResource); - } - - @Test - public void shouldNotEqualsOnDifferentNamespace() { - // pre-condition - KubernetesResource otherResource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), createModelNode()); - assertEquals(resource, otherResource); - - // operation - otherResource.set(KubernetesResource.METADATA_NAMESPACE, "karate"); - - // verification - assertThat(resource).isNotEqualTo(otherResource); - } - - @Test - public void shouldNotEqualsOnDifferentResourceKind() { - // pre-condition - KubernetesResource otherResource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), createModelNode()); - assertEquals(resource, otherResource); - - // operation - otherResource.set(ResourcePropertyKeys.KIND, ResourceKind.EVENT.toString()); - - // verification - assertThat(resource).isNotEqualTo(otherResource); - } + private ModelNode node; + private KubernetesResource resource; + + @Before + public void setup() { + this.node = createModelNode(); + this.resource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), node); + } + + private ModelNode createModelNode() { + node = new ModelNode(); + node.get(ResourcePropertyKeys.KIND).set(ResourceKind.LIST.toString()); + + ModelNode annotations = node.get(getPath(KubernetesResource.ANNOTATIONS)); + annotations.get("foo").set("bar"); + annotations.get("template").set("foobar"); + + node.get(KubernetesResource.METADATA_NAME).set("bartender"); + node.get(KubernetesResource.METADATA_NAMESPACE).set("foofighters"); + + return node; + } + + private KubernetesResource createKubernetesResource(String modelVersion, ModelNode node) { + return new KubernetesResource(node, null, + ResourcePropertiesRegistry.getInstance().get(modelVersion, ResourceKind.SERVICE)) { + }; + } + + @Test + public void testSetAnnoationWithNullValueShouldReturnGracefully() { + resource.setAnnotation("black", null); + } + + @Test + public void testSetAnnoation() { + resource.setAnnotation("black", "white"); + assertEquals("white", resource.getAnnotation("black")); + } + + @Test + public void testGetAnnotation() { + assertEquals("bar", resource.getAnnotation("foo")); + } + + @Test + public void removeAnnotation() { + resource.removeAnnotation("foo"); + assertNull(resource.getAnnotation("foo")); + } + + @Test + public void isAnnotatedReturnsTrueForKnownAnnotation() { + assertTrue(resource.isAnnotatedWith("foo")); + } + + @Test + public void isAnnotatedReturnsFalseForUnKnownAnnotation() { + assertFalse(resource.isAnnotatedWith("bar")); + } + + @Test + public void supportsIsFalseForUnsupportedCapability() { + assertFalse("Expected to not support capability because IClient is null", + resource.supports(IDeploymentTraceability.class)); + } + + @Test + public void getCapabilityReturnsNonNullWhenSupportedCapability() { + assertTrue("Exp. to support capability since resource has template annotation", + resource.supports(ITemplateTraceability.class)); + assertNotNull(resource.getCapability(ITemplateTraceability.class)); + } + + @Test + public void testAcceptVisitor() { + final List visited = new ArrayList(); + resource.accept(new CapabilityVisitor() { + + @Override + public Object visit(ITemplateTraceability capability) { + visited.add(Boolean.TRUE); + return (Object) null; + } + + }, new Object()); + assertEquals("Exp. the visitor to be visited", 1, visited.size()); + } + + @Test + public void shouldSameHashCodeOnAddedLabels() { + // pre-condition + int hashCodeBeforeChange = resource.hashCode(); + + // operation + resource.set(ResourcePropertyKeys.LABELS, "kungfoo"); + + // verification + int hashCodeAfterChange = resource.hashCode(); + assertEquals(hashCodeBeforeChange, hashCodeAfterChange); + } + + @Test + public void shouldDifferentHashCodeOnDifferentName() { + // pre-condition + int hashCodeBeforeChange = resource.hashCode(); + + // operation + resource.set(KubernetesResource.METADATA_NAME, "brucefoolee"); + + // verification + int hashCodeAfterChange = resource.hashCode(); + assertThat(hashCodeBeforeChange).isNotEqualTo(hashCodeAfterChange); + } + + @Test + public void shouldDifferentHashCodeOnDifferentResourceKind() { + // pre-condition + int hashCodeBeforeChange = resource.hashCode(); + + // operation + node.get(ResourcePropertyKeys.KIND).set(ResourceKind.EVENT.toString()); + + // verification + int hashCodeAfterChange = resource.hashCode(); + assertThat(hashCodeBeforeChange).isNotEqualTo(hashCodeAfterChange); + } + + @Test + public void shouldDifferentHashCodeOnDifferentNamespace() { + // pre-condition + int hashCodeBeforeChange = resource.hashCode(); + + // operation + node.get(new String[] { "metadata", "namespace" }).set("barfoo"); + + // verification + int hashCodeAfterChange = resource.hashCode(); + assertThat(hashCodeBeforeChange).isNotEqualTo(hashCodeAfterChange); + } + + @Test + public void shouldEqualsOnAddedLabels() { + // pre-condition + KubernetesResource otherResource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), node); + assertEquals(resource, otherResource); + + // operation + otherResource.set(ResourcePropertyKeys.LABELS, "bruceleefoo"); + + // verification + assertEquals(resource, otherResource); + } + + @Test + public void shouldNotEqualsOnDifferentName() { + // pre-condition + KubernetesResource otherResource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), + createModelNode()); + assertEquals(resource, otherResource); + + // operation + otherResource.set(KubernetesResource.METADATA_NAME, "kungfoo"); + + // verification + assertThat(resource).isNotEqualTo(otherResource); + } + + @Test + public void shouldNotEqualsOnDifferentNamespace() { + // pre-condition + KubernetesResource otherResource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), + createModelNode()); + assertEquals(resource, otherResource); + + // operation + otherResource.set(KubernetesResource.METADATA_NAMESPACE, "karate"); + + // verification + assertThat(resource).isNotEqualTo(otherResource); + } + + @Test + public void shouldNotEqualsOnDifferentResourceKind() { + // pre-condition + KubernetesResource otherResource = createKubernetesResource(OpenShiftAPIVersion.v1.toString(), + createModelNode()); + assertEquals(resource, otherResource); + + // operation + otherResource.set(ResourcePropertyKeys.KIND, ResourceKind.EVENT.toString()); + + // verification + assertThat(resource).isNotEqualTo(otherResource); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/NamespaceTest.java b/src/test/java/com/openshift/internal/restclient/model/NamespaceTest.java index 9713a437..4cf9fc1f 100644 --- a/src/test/java/com/openshift/internal/restclient/model/NamespaceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/NamespaceTest.java @@ -1,16 +1,17 @@ package com.openshift.internal.restclient.model; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.INamespace; import com.openshift.restclient.utils.Samples; -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; public class NamespaceTest { diff --git a/src/test/java/com/openshift/internal/restclient/model/PortFactory.java b/src/test/java/com/openshift/internal/restclient/model/PortFactory.java index c15b6ded..f59cbbbe 100644 --- a/src/test/java/com/openshift/internal/restclient/model/PortFactory.java +++ b/src/test/java/com/openshift/internal/restclient/model/PortFactory.java @@ -8,26 +8,23 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; import org.jboss.dmr.ModelNode; -/** - * - * @author Jeff Cantrill - * - */ public class PortFactory { - public static ServicePort createServicePort(String name, String proto, int port, int targetPort) { - return createServicePort(name, proto, port, String.valueOf(targetPort)); - } - public static ServicePort createServicePort(String name, String proto, int port, String targetPort) { - ModelNode node = new ModelNode(); - node.get("name").set(name); - node.get("protocol").set(proto); - node.get("port").set(port); - node.get("targetPort").set(targetPort); - return new ServicePort(node); - } + public static ServicePort createServicePort(String name, String proto, int port, int targetPort) { + return createServicePort(name, proto, port, String.valueOf(targetPort)); + } + + public static ServicePort createServicePort(String name, String proto, int port, String targetPort) { + ModelNode node = new ModelNode(); + node.get("name").set(name); + node.get("protocol").set(proto); + node.get("port").set(port); + node.get("targetPort").set(targetPort); + return new ServicePort(node); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java b/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java index 68b0fcff..17bb54b8 100644 --- a/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java @@ -6,10 +6,14 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; @@ -22,35 +26,32 @@ import com.openshift.internal.restclient.OpenShiftAPIVersion; import com.openshift.internal.restclient.ResourceFactory; -import com.openshift.internal.restclient.model.Project; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IService; -/** - * @author Jeff Cantrill - */ @RunWith(MockitoJUnitRunner.class) public class ProjectTest { - @Mock private IClient client; - private Project project; - - @Before - public void setup(){ - project = new ResourceFactory(client){}.create(OpenShiftAPIVersion.v1.toString(), ResourceKind.PROJECT); - project.setName("aprojectname"); - } - - @Test - public void getResourcesShouldUseProjectNameForNamespaceWhenGettingResources() { - ArrayList services = new ArrayList(); - when(client.list(eq(ResourceKind.SERVICE), anyString())).thenReturn(services); - List resources = project.getResources(ResourceKind.SERVICE); - - assertEquals("Exp. a list of services", services, resources); - verify(client).list(eq(ResourceKind.SERVICE), eq(project.getName())); - } - + @Mock + private IClient client; + private Project project; + + @Before + public void setup() { + project = new ResourceFactory(client) { + }.create(OpenShiftAPIVersion.v1.toString(), ResourceKind.PROJECT); + project.setName("aprojectname"); + } + + @Test + public void getResourcesShouldUseProjectNameForNamespaceWhenGettingResources() { + ArrayList services = new ArrayList(); + when(client.list(eq(ResourceKind.SERVICE), anyString())).thenReturn(services); + List resources = project.getResources(ResourceKind.SERVICE); + + assertEquals("Exp. a list of services", services, resources); + verify(client).list(eq(ResourceKind.SERVICE), eq(project.getName())); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/RouteTest.java b/src/test/java/com/openshift/internal/restclient/model/RouteTest.java index 9104fdbd..1ff82372 100644 --- a/src/test/java/com/openshift/internal/restclient/model/RouteTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/RouteTest.java @@ -7,10 +7,14 @@ * * Contributors: * Red Hat, Inc. - initial API and implementation - ******************************************************************************/package com.openshift.internal.restclient.model; + ******************************************************************************/ -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +package com.openshift.internal.restclient.model; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import org.jboss.dmr.ModelNode; import org.junit.Before; @@ -22,45 +26,44 @@ import com.openshift.restclient.model.route.ITLSConfig; /** - * Test for route functionality that should not depend on the - * underlying api model + * Test for route functionality that should not depend on the underlying api + * model * - * @author Jeff Cantrill * */ public class RouteTest { - - private Route route; - - @Before - public void setUp() throws Exception { - ModelNode root = new ModelNode(); - JBossDmrExtentions.set(root, JBossDmrExtentions.getPath(ResourcePropertyKeys.KIND), ResourceKind.ROUTE); - route = spy(new Route(root, null, null)); - doReturn("www.host.com").when(route).getHost(); - doReturn("/abc").when(route).getPath(); - } - @Test - public void getURLShouldBeSecureWhenTLSConfigExists() { - doReturn(mock(ITLSConfig.class)).when(route).getTLSConfig(); - assertEquals("https://www.host.com/abc", route.getURL()); - } + private Route route; + + @Before + public void setUp() throws Exception { + ModelNode root = new ModelNode(); + JBossDmrExtentions.set(root, JBossDmrExtentions.getPath(ResourcePropertyKeys.KIND), ResourceKind.ROUTE); + route = spy(new Route(root, null, null)); + doReturn("www.host.com").when(route).getHost(); + doReturn("/abc").when(route).getPath(); + } + + @Test + public void getURLShouldBeSecureWhenTLSConfigExists() { + doReturn(mock(ITLSConfig.class)).when(route).getTLSConfig(); + assertEquals("https://www.host.com/abc", route.getURL()); + } - @Test - public void getURLShouldBeInSecureWhenTLSConfigDoesExists() { - doReturn(null).when(route).getTLSConfig(); - assertEquals("http://www.host.com/abc", route.getURL()); - } + @Test + public void getURLShouldBeInSecureWhenTLSConfigDoesExists() { + doReturn(null).when(route).getTLSConfig(); + assertEquals("http://www.host.com/abc", route.getURL()); + } - @Test - public void getAndSetInsecureEdgeTerminationPolicy() { - ModelNode modelNode = new ModelNode(); - Route edgeTLSRoute = spy(new Route(modelNode, null, null)); - edgeTLSRoute.createTLSConfig().setTerminationType("edge"); + @Test + public void getAndSetInsecureEdgeTerminationPolicy() { + ModelNode modelNode = new ModelNode(); + Route edgeTLSRoute = spy(new Route(modelNode, null, null)); + edgeTLSRoute.createTLSConfig().setTerminationType("edge"); - edgeTLSRoute.getTLSConfig().setInsecureEdgeTerminationPolicy("Allow"); - assertEquals("Allow", edgeTLSRoute.getTLSConfig().getInsecureEdgeTerminationPolicy()); - } + edgeTLSRoute.getTLSConfig().setInsecureEdgeTerminationPolicy("Allow"); + assertEquals("Allow", edgeTLSRoute.getTLSConfig().getInsecureEdgeTerminationPolicy()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java index ca705c77..ca82ff8f 100644 --- a/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java @@ -6,10 +6,17 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model; -import static org.mockito.Mockito.*; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyMap; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; @@ -27,50 +34,47 @@ import com.openshift.restclient.model.IService; import com.openshift.restclient.model.IServicePort; -/** - * @author Jeff Cantrill - */ public class ServiceTest { - private IService service; - private IClient client; + private IService service; + private IClient client; + + @Before + public void setup() { + client = mock(IClient.class); + when(client.getOpenShiftAPIVersion()).thenReturn(OpenShiftAPIVersion.v1.name()); + IResourceFactory factory = new ResourceFactory(client) { + }; + service = factory.stub(ResourceKind.SERVICE, OpenShiftAPIVersion.v1.name()); + } + + @Test + public void testSetPorts() { + ServicePort port = new ServicePort(new ModelNode()); + port.setName("foo"); + port.setTargetPort(12345); + port.setProtocol("tcp"); + List ports = new ArrayList<>(); + ports.add(port); + service.setPorts(ports); + assertEquals(1, service.getPorts().size()); + assertEquals("foo", service.getPorts().get(0).getName()); + } + + @SuppressWarnings("unchecked") + @Test + public void testGetPods() { + // setup + when(client.list(anyString(), anyString(), anyMap())).thenReturn(new ArrayList()); + + service.addLabel("bar", "foo"); + service.setSelector("foo", "bar"); + + // exectute + service.getPods(); - @Before - public void setup() { - client = mock(IClient.class); - when(client.getOpenShiftAPIVersion()).thenReturn(OpenShiftAPIVersion.v1.name()); - IResourceFactory factory = new ResourceFactory(client){}; - service = factory.stub(ResourceKind.SERVICE, OpenShiftAPIVersion.v1.name()); - } - - @Test - public void testSetPorts() { - List ports = new ArrayList<>(); - ServicePort port = new ServicePort(new ModelNode()); - port.setName("foo"); - port.setTargetPort(12345); - port.setProtocol("tcp"); - ports.add(port); - service.setPorts(ports); - assertEquals(1,service.getPorts().size()); - assertEquals("foo", service.getPorts().get(0).getName()); - } - - @SuppressWarnings("unchecked") - @Test - public void testGetPods() { - //setup - when(client.list(anyString(), anyString(), anyMap())) - .thenReturn(new ArrayList()); - - service.addLabel("bar","foo"); - service.setSelector("foo", "bar"); - - //exectute - service.getPods(); - - //confirm called with selector and not something else - verify(client, times(1)).list(eq(ResourceKind.POD), anyString(), eq(service.getSelector())); - } + // confirm called with selector and not something else + verify(client, times(1)).list(eq(ResourceKind.POD), anyString(), eq(service.getSelector())); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/StatusTest.java b/src/test/java/com/openshift/internal/restclient/model/StatusTest.java index c874c66e..91303ff5 100644 --- a/src/test/java/com/openshift/internal/restclient/model/StatusTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/StatusTest.java @@ -6,10 +6,13 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import org.jboss.dmr.ModelNode; import org.junit.Before; @@ -21,31 +24,30 @@ /** * Tests that have logic and not specific to a particular api version - * @author Jeff Cantrill * */ public class StatusTest { - private Status status; - - @Before - public void setup() { - ModelNode root = new ModelNode(); - JBossDmrExtentions.set(root, JBossDmrExtentions.getPath(ResourcePropertyKeys.KIND), ResourceKind.STATUS); - status = spy(new Status(root,null,null)); - } - - @Test - public void isFailureShouldReturnTrueWhenFailure() { - doReturn("Failure").when(status).getStatus(); - - assertTrue(status.isFailure()); - } - - @Test - public void isFailureShouldReturnFalseWhenNotFailure() { - doReturn("Other").when(status).getStatus(); - - assertFalse(status.isFailure()); - } + private Status status; + + @Before + public void setup() { + ModelNode root = new ModelNode(); + JBossDmrExtentions.set(root, JBossDmrExtentions.getPath(ResourcePropertyKeys.KIND), ResourceKind.STATUS); + status = spy(new Status(root, null, null)); + } + + @Test + public void isFailureShouldReturnTrueWhenFailure() { + doReturn("Failure").when(status).getStatus(); + + assertTrue(status.isFailure()); + } + + @Test + public void isFailureShouldReturnFalseWhenNotFailure() { + doReturn("Other").when(status).getStatus(); + + assertFalse(status.isFailure()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java index 64583f75..6ea8e00e 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java @@ -8,10 +8,14 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.build; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.Collections; @@ -41,62 +45,53 @@ public class BuildConfigBuilderTest { - @Mock private IClient client; - @Mock private IResourceFactory factory; - private IBuildConfig bc; - private BuildConfig bcImpl; - @Before - public void setUp() throws Exception { - bcImpl = new BuildConfig(new ModelNode(), client, Collections.emptyMap()); - when(client.getResourceFactory()).thenReturn(factory); - when(factory.stub(eq(ResourceKind.BUILD_CONFIG), anyString(), anyString())).thenReturn(bcImpl); - - } + @Mock + private IClient client; + @Mock + private IResourceFactory factory; + private IBuildConfig bc; + private BuildConfig bcImpl; + + @Before + public void setUp() throws Exception { + bcImpl = new BuildConfig(new ModelNode(), client, Collections.emptyMap()); + when(client.getResourceFactory()).thenReturn(factory); + when(factory.stub(eq(ResourceKind.BUILD_CONFIG), anyString(), anyString())).thenReturn(bcImpl); + + } + + @Test + public void testBuild() { + bc = new BuildConfigBuilder(client).named("foo").inNamespace("aNamespace").buildOnConfigChange(true) + .buildOnImageChange(true).buildOnSourceChange(true).fromGitSource() + .fromGitUrl("https://foo/bar/repo.git").usingGitReference("branch").inContextDir("root/directory").end() + .usingSourceStrategy().fromImageStreamTag("builder:latest").inNamespace("other").end() + .toImageStreamTag("foo/target:latest").build(); + + List triggerTypes = Arrays.asList(BuildTriggerType.CONFIG_CHANGE, BuildTriggerType.GENERIC, + BuildTriggerType.GITHUB, BuildTriggerType.IMAGE_CHANGE); + List triggers = bc.getBuildTriggers(); + assertEquals("Exp. all the allowable triggers", triggerTypes.size(), triggers.size()); + triggers.stream() + .forEach(t -> assertTrue(String.format("%s is not in expected types %s", t.getType(), triggerTypes), + triggerTypes.contains(t.getType()))); + triggers.stream().filter( + t -> t.getType().equals(BuildTriggerType.GENERIC) || t.getType().equals(BuildTriggerType.GITHUB)) + .forEach(t -> assertTrue("Exp. the secret to not be blank", + StringUtils.isNotBlank(((IWebhookTrigger) t).getSecret()))); + IGitBuildSource source = bc.getBuildSource(); + assertEquals("https://foo/bar/repo.git", source.getURI()); + assertEquals("branch", source.getRef()); + assertEquals("root/directory", source.getContextDir()); + + ISourceBuildStrategy strategy = bc.getBuildStrategy(); + assertEquals("builder:latest", strategy.getImage().toString()); + assertEquals("other", strategy.getFromNamespace()); - @Test - public void testBuild() { - bc = new BuildConfigBuilder(client) - .named("foo") - .inNamespace("aNamespace") - .buildOnConfigChange(true) - .buildOnImageChange(true) - .buildOnSourceChange(true) - .fromGitSource() - .fromGitUrl("https://foo/bar/repo.git") - .usingGitReference("branch") - .inContextDir("root/directory") - .end() - .usingSourceStrategy() - .fromImageStreamTag("builder:latest") - .inNamespace("other") - .end() - .toImageStreamTag("foo/target:latest") - .build(); - - List triggerTypes = Arrays.asList(BuildTriggerType.CONFIG_CHANGE, - BuildTriggerType.GENERIC, - BuildTriggerType.GITHUB, - BuildTriggerType.IMAGE_CHANGE); - List triggers = bc.getBuildTriggers(); - assertEquals("Exp. all the allowable triggers", triggerTypes.size(), triggers.size()); - triggers.stream() - .forEach(t->assertTrue(String.format("%s is not in expected types %s", t.getType(), triggerTypes), triggerTypes.contains(t.getType()))); - triggers.stream() - .filter(t->t.getType().equals(BuildTriggerType.GENERIC) || t.getType().equals(BuildTriggerType.GITHUB)) - .forEach(t->assertTrue("Exp. the secret to not be blank", StringUtils.isNotBlank(((IWebhookTrigger)t).getSecret()))); - IGitBuildSource source = bc.getBuildSource(); - assertEquals("https://foo/bar/repo.git", source.getURI()); - assertEquals("branch", source.getRef()); - assertEquals("root/directory", source.getContextDir()); - - ISourceBuildStrategy strategy = bc.getBuildStrategy(); - assertEquals("builder:latest", strategy.getImage().toString()); - assertEquals("other", strategy.getFromNamespace()); - - IObjectReference out = bc.getBuildOutputReference(); - assertEquals(ResourceKind.IMAGE_STREAM_TAG, out.getKind()); - assertEquals("target:latest", out.getName()); - assertEquals("foo", out.getNamespace()); - } + IObjectReference out = bc.getBuildOutputReference(); + assertEquals(ResourceKind.IMAGE_STREAM_TAG, out.getKind()); + assertEquals("target:latest", out.getName()); + assertEquals("foo", out.getNamespace()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigTest.java index 3c476702..f47fb578 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigTest.java @@ -6,10 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; -import static org.junit.Assert.*; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.getPath; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import org.jboss.dmr.ModelNode; import org.junit.Before; @@ -24,53 +26,51 @@ import com.openshift.restclient.model.build.ICustomBuildStrategy; import com.openshift.restclient.model.build.IDockerBuildStrategy; -/** - * @author Jeff Cantrill - */ public class BuildConfigTest { - @Mock private IClient client; - private BuildConfig config; - private ModelNode node = new ModelNode(); - - @Before - public void setup(){ - config = new BuildConfig(node, client, null); - } - - @Test - public void testGetCustomBuildStrategy(){ - String[] key = new String[]{"spec", "strategy"}; - node.get(key).get("type").set("Custom"); - node.get(key).get("customStrategy").get("exposeDockerSocket").set(true); - node.get(key).get("customStrategy").get("image").set("thebaseImage"); - ModelNode env = new ModelNode(); - env.get("name").set("foo"); - env.get("value").set("bar"); - node.get(key).get("customStrategy").get("env").add(env); - - IBuildStrategy strategy = config.getBuildStrategy(); - assertEquals(BuildStrategyType.CUSTOM, strategy.getType()); - ICustomBuildStrategy custom = (ICustomBuildStrategy) strategy; - assertEquals(new DockerImageURI("thebaseImage"), custom.getImage()); - assertTrue(custom.exposeDockerSocket()); - assertEquals(1, custom.getEnvironmentVariables().size()); - assertTrue("Exp. to find the environment variable", custom.getEnvironmentVariables().containsKey("foo")); - assertEquals("bar", custom.getEnvironmentVariables().get("foo")); - } - - @Test - public void testGetDockerBuildStrategy() { - node.get(getPath(BuildConfig.BUILDCONFIG_TYPE)).set("Docker"); - node.get(getPath(BuildConfig.BUILDCONFIG_DOCKER_CONTEXTDIR)).set("aContextDir"); - node.get(getPath(BuildConfig.BUILDCONFIG_DOCKER_NOCACHE)).set(true); - node.get(getPath(BuildConfig.BUILDCONFIG_DOCKER_BASEIMAGE)).set("thebaseImage"); - - IBuildStrategy strategy = config.getBuildStrategy(); - assertEquals(BuildStrategyType.DOCKER, strategy.getType()); - IDockerBuildStrategy docker = (IDockerBuildStrategy) strategy; - assertEquals("aContextDir", docker.getContextDir()); - assertTrue(docker.isNoCache()); - assertEquals(new DockerImageURI("thebaseImage"), docker.getBaseImage()); - } + @Mock + private IClient client; + private BuildConfig config; + private ModelNode node = new ModelNode(); + + @Before + public void setup() { + config = new BuildConfig(node, client, null); + } + + @Test + public void testGetCustomBuildStrategy() { + String[] key = new String[] { "spec", "strategy" }; + node.get(key).get("type").set("Custom"); + node.get(key).get("customStrategy").get("exposeDockerSocket").set(true); + node.get(key).get("customStrategy").get("image").set("thebaseImage"); + ModelNode env = new ModelNode(); + env.get("name").set("foo"); + env.get("value").set("bar"); + node.get(key).get("customStrategy").get("env").add(env); + + IBuildStrategy strategy = config.getBuildStrategy(); + assertEquals(BuildStrategyType.CUSTOM, strategy.getType()); + ICustomBuildStrategy custom = (ICustomBuildStrategy) strategy; + assertEquals(new DockerImageURI("thebaseImage"), custom.getImage()); + assertTrue(custom.exposeDockerSocket()); + assertEquals(1, custom.getEnvironmentVariables().size()); + assertTrue("Exp. to find the environment variable", custom.getEnvironmentVariables().containsKey("foo")); + assertEquals("bar", custom.getEnvironmentVariables().get("foo")); + } + + @Test + public void testGetDockerBuildStrategy() { + node.get(getPath(BuildConfig.BUILDCONFIG_TYPE)).set("Docker"); + node.get(getPath(BuildConfig.BUILDCONFIG_DOCKER_CONTEXTDIR)).set("aContextDir"); + node.get(getPath(BuildConfig.BUILDCONFIG_DOCKER_NOCACHE)).set(true); + node.get(getPath(BuildConfig.BUILDCONFIG_DOCKER_BASEIMAGE)).set("thebaseImage"); + + IBuildStrategy strategy = config.getBuildStrategy(); + assertEquals(BuildStrategyType.DOCKER, strategy.getType()); + IDockerBuildStrategy docker = (IDockerBuildStrategy) strategy; + assertEquals("aContextDir", docker.getContextDir()); + assertTrue(docker.isNoCache()); + assertEquals(new DockerImageURI("thebaseImage"), docker.getBaseImage()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java index 118b1b62..04e8af47 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildRequestTest.java @@ -6,46 +6,49 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; -import com.openshift.restclient.IClient; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; +import com.openshift.restclient.IClient; public class BuildRequestTest { - @Mock private IClient client; - private BuildRequest config; - private ModelNode node = new ModelNode(); - - @Before - public void setup(){ - config = new BuildRequest(node, client, null); - } - - @Test - public void testBuildRequestEnvVars(){ - - config.setEnvironmentVariable( "env1", "value1" ); - assertEquals( 1, node.get( "env" ).asList().size() ); - - config.setEnvironmentVariable( "env2", "value2" ); - assertEquals( 2, node.get( "env" ).asList().size() ); - - for ( ModelNode mn : node.get( "env" ).asList() ) { - if ( mn.get("name").asString().equals( "env1" ) ) { - assertEquals(mn.get("value").asString(), "value1"); - } else if (mn.get("name").asString().equals("env2")) { - assertEquals(mn.get( "value").asString(), "value2"); - } else { - fail( "Unexpected environment variable: " + mn.toJSONString(false) ); - } - } - - } + @Mock + private IClient client; + private BuildRequest config; + private ModelNode node = new ModelNode(); + + @Before + public void setup() { + config = new BuildRequest(node, client, null); + } + + @Test + public void testBuildRequestEnvVars() { + + config.setEnvironmentVariable("env1", "value1"); + assertEquals(1, node.get("env").asList().size()); + + config.setEnvironmentVariable("env2", "value2"); + assertEquals(2, node.get("env").asList().size()); + + for (ModelNode mn : node.get("env").asList()) { + if (mn.get("name").asString().equals("env1")) { + assertEquals(mn.get("value").asString(), "value1"); + } else if (mn.get("name").asString().equals("env2")) { + assertEquals(mn.get("value").asString(), "value2"); + } else { + fail("Unexpected environment variable: " + mn.toJSONString(false)); + } + } + + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/build/WebhookTriggerTest.java b/src/test/java/com/openshift/internal/restclient/model/build/WebhookTriggerTest.java index d2f201c6..4f59d7c6 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/WebhookTriggerTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/WebhookTriggerTest.java @@ -6,36 +6,36 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.build; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; -import com.openshift.internal.restclient.model.build.WebhookTrigger; import com.openshift.restclient.model.build.BuildTriggerType; import com.openshift.restclient.model.build.IWebhookTrigger; -/** - * @author Jeff Cantrill - */ public class WebhookTriggerTest { - private IWebhookTrigger trigger; - - @Before - public void setup(){ - } - @Test - public void testGetWebhookUrlWhenResourceHasBaseURL() { - trigger = new WebhookTrigger(BuildTriggerType.GENERIC, "seCRet101","https://localhost:8443/oapi/v1/namespaces/test/buildconfigs/foo"); - assertEquals("https://localhost:8443/oapi/v1/namespaces/test/buildconfigs/foo/webhooks/seCRet101/generic", trigger.getWebhookURL()); - } - - @Test - public void testGetWebhookUrlWhenResourceDoesNotHaveBaseURL(){ - trigger = new WebhookTrigger(BuildTriggerType.GENERIC, "seCRet101"," "); - assertEquals("",trigger.getWebhookURL()); - } + private IWebhookTrigger trigger; + + @Before + public void setup() { + } + + @Test + public void testGetWebhookUrlWhenResourceHasBaseURL() { + trigger = new WebhookTrigger(BuildTriggerType.GENERIC, "seCRet101", + "https://localhost:8443/oapi/v1/namespaces/test/buildconfigs/foo"); + assertEquals("https://localhost:8443/oapi/v1/namespaces/test/buildconfigs/foo/webhooks/seCRet101/generic", + trigger.getWebhookURL()); + } + + @Test + public void testGetWebhookUrlWhenResourceDoesNotHaveBaseURL() { + trigger = new WebhookTrigger(BuildTriggerType.GENERIC, "seCRet101", " "); + assertEquals("", trigger.getWebhookURL()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/deploy/DeployRequestTest.java b/src/test/java/com/openshift/internal/restclient/model/deploy/DeployRequestTest.java index 16f9d0c9..08b75df1 100644 --- a/src/test/java/com/openshift/internal/restclient/model/deploy/DeployRequestTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/deploy/DeployRequestTest.java @@ -6,38 +6,42 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.deploy; -import com.openshift.restclient.IClient; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; + import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import java.util.HashMap; +import com.openshift.restclient.IClient; public class DeployRequestTest { - @Mock private IClient client; - private DeploymentRequest config; - private ModelNode node = new ModelNode(); - - @Before - public void setup(){ - config = new DeploymentRequest(node, new HashMap()); - } - - @Test - public void testDeploymentRequest(){ - - config.setForce( true ); - assertTrue("Exp. isForce to be true when set to true", config.isForce()); - config.setLatest(true); - assertEquals("Exp. isLatest to be true when set to true",true, config.isLatest()); - config.setName("foo"); - assertEquals("foo", config.getName()); - - } + @Mock + private IClient client; + private DeploymentRequest config; + private ModelNode node = new ModelNode(); + + @Before + public void setup() { + config = new DeploymentRequest(node, new HashMap()); + } + + @Test + public void testDeploymentRequest() { + + config.setForce(true); + assertTrue("Exp. isForce to be true when set to true", config.isForce()); + config.setLatest(true); + assertEquals("Exp. isLatest to be true when set to true", true, config.isLatest()); + config.setName("foo"); + assertEquals("foo", config.getName()); + + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/kubeconfig/KubeClientConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/kubeconfig/KubeClientConfigTest.java index 487d90cc..66b4e283 100644 --- a/src/test/java/com/openshift/internal/restclient/model/kubeconfig/KubeClientConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/kubeconfig/KubeClientConfigTest.java @@ -8,9 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.kubeconfig; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import java.io.StringReader; @@ -26,38 +28,39 @@ public class KubeClientConfigTest { - private IKubeClientConfig config; - @Before - public void setUp() throws Exception { - - String kubeConfig = Samples.V1_KUBE_CONFIG.getContentAsString(); - StringReader reader = new StringReader(kubeConfig); - - KubeClientConfigSerializer serializer = new KubeClientConfigSerializer(); - config = serializer.loadKubeClientConfig(reader); - } - - @Test - public void testDeserialization() { - assertEquals("default/10-3-9-15:8443/jcantril@redhat.com", config.getCurrentContext()); - - assertEquals(2, config.getClusters().size()); - ICluster cluster = config.getClusters().iterator().next(); - assertEquals("10-3-9-15:8443", cluster.getName()); - assertEquals("https://10.3.9.15:8443", cluster.getServer()); - assertEquals("Exp. cluster skipTLSVerify", true, cluster.isInsecureSkipTLSVerify()); - - assertEquals(4, config.getContexts().size()); - IContext context = config.getContexts().iterator().next(); - assertNotNull(context); - assertEquals("default", context.getNamespace()); - assertEquals("10-3-9-15:8443", context.getCluster()); - assertEquals("jcantril@redhat.com/10-3-9-15:8443", context.getUser()); - - assertEquals("Exp. user count", 2, config.getUsers().size()); - IUser user = config.getUsers().iterator().next(); - assertEquals("admin/localhost:8443", user.getName()); - assertEquals("Q6cbJl4yMwP9o7crPbT5XMx9HSuv9W6jgXXE6omHK0Q", user.getToken()); - } + private IKubeClientConfig config; + + @Before + public void setUp() throws Exception { + + String kubeConfig = Samples.V1_KUBE_CONFIG.getContentAsString(); + StringReader reader = new StringReader(kubeConfig); + + KubeClientConfigSerializer serializer = new KubeClientConfigSerializer(); + config = serializer.loadKubeClientConfig(reader); + } + + @Test + public void testDeserialization() { + assertEquals("default/10-3-9-15:8443/jcantril@redhat.com", config.getCurrentContext()); + + assertEquals(2, config.getClusters().size()); + ICluster cluster = config.getClusters().iterator().next(); + assertEquals("10-3-9-15:8443", cluster.getName()); + assertEquals("https://10.3.9.15:8443", cluster.getServer()); + assertEquals("Exp. cluster skipTLSVerify", true, cluster.isInsecureSkipTLSVerify()); + + assertEquals(4, config.getContexts().size()); + IContext context = config.getContexts().iterator().next(); + assertNotNull(context); + assertEquals("default", context.getNamespace()); + assertEquals("10-3-9-15:8443", context.getCluster()); + assertEquals("jcantril@redhat.com/10-3-9-15:8443", context.getUser()); + + assertEquals("Exp. user count", 2, config.getUsers().size()); + IUser user = config.getUsers().iterator().next(); + assertEquals("admin/localhost:8443", user.getName()); + assertEquals("Q6cbJl4yMwP9o7crPbT5XMx9HSuv9W6jgXXE6omHK0Q", user.getToken()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/properties/ResourcePropertiesRegistryTest.java b/src/test/java/com/openshift/internal/restclient/model/properties/ResourcePropertiesRegistryTest.java index 83950379..e91efcd1 100644 --- a/src/test/java/com/openshift/internal/restclient/model/properties/ResourcePropertiesRegistryTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/properties/ResourcePropertiesRegistryTest.java @@ -8,10 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.properties; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import java.util.Arrays; import java.util.List; @@ -22,60 +24,67 @@ import com.openshift.internal.restclient.KubernetesAPIVersion; import com.openshift.internal.restclient.OpenShiftAPIVersion; -/** - * @author Jeff Cantrill - */ public class ResourcePropertiesRegistryTest { - - private ResourcePropertiesRegistry registry; - - @Before - public void setUp() throws Exception { - registry = spy(ResourcePropertiesRegistry.getInstance()); - } - - @Test - public void theClientShouldUseTheSameVersionWhenTheyAreTheSame() { - List serverVersions = Arrays.asList(new KubernetesAPIVersion[] {KubernetesAPIVersion.v1, KubernetesAPIVersion.v1beta3}); - assertEquals(KubernetesAPIVersion.v1, registry.getMaxSupportedKubernetesVersion(serverVersions)); - } - - @Test - public void theClientShouldUseTheServerVersionWhenTheServerIsBehindTheClient() { - when(registry.getSupportedKubernetesVersions()).thenReturn(new KubernetesAPIVersion [] {KubernetesAPIVersion.v1, KubernetesAPIVersion.v1beta3}); - List serverVersions = Arrays.asList(new KubernetesAPIVersion[] {KubernetesAPIVersion.v1beta3}); - - assertEquals(KubernetesAPIVersion.v1beta3, registry.getMaxSupportedKubernetesVersion(serverVersions)); - } - - @Test - public void theClientShouldUseTheClientVersionVersionWhenTheClientIsBehindTheServer() { - List serverVersions = Arrays.asList(new KubernetesAPIVersion[] {KubernetesAPIVersion.v1, KubernetesAPIVersion.v1beta3}); - when(registry.getSupportedKubernetesVersions()).thenReturn(new KubernetesAPIVersion [] {KubernetesAPIVersion.v1beta3}); - - assertEquals(KubernetesAPIVersion.v1beta3, registry.getMaxSupportedKubernetesVersion(serverVersions)); - } - - @Test - public void theClientShouldUseTheSameOpenShiftAPIVersionWhenTheyAreTheSame() { - List serverVersions = Arrays.asList(new OpenShiftAPIVersion[] {OpenShiftAPIVersion.v1, OpenShiftAPIVersion.v1beta3}); - assertEquals(OpenShiftAPIVersion.v1, registry.getMaxSupportedOpenShiftVersion(serverVersions)); - } - - @Test - public void theClientShouldUseTheOpenShiftAPIServerVersionWhenTheServerIsBehindTheClient() { - when(registry.getSupportedOpenShiftVersions()).thenReturn(new OpenShiftAPIVersion [] {OpenShiftAPIVersion.v1, OpenShiftAPIVersion.v1beta3}); - List serverVersions = Arrays.asList(new OpenShiftAPIVersion[] {OpenShiftAPIVersion.v1beta3}); - - assertEquals(OpenShiftAPIVersion.v1beta3, registry.getMaxSupportedOpenShiftVersion(serverVersions)); - } - - @Test - public void theClientShouldUseTheOpenShiftAPIClientVersionVersionWhenTheClientIsBehindTheServer() { - List serverVersions = Arrays.asList(new OpenShiftAPIVersion[] {OpenShiftAPIVersion.v1, OpenShiftAPIVersion.v1beta3}); - when(registry.getSupportedOpenShiftVersions()).thenReturn(new OpenShiftAPIVersion [] {OpenShiftAPIVersion.v1beta3}); - - assertEquals(OpenShiftAPIVersion.v1beta3, registry.getMaxSupportedOpenShiftVersion(serverVersions)); - } + + private ResourcePropertiesRegistry registry; + + @Before + public void setUp() throws Exception { + registry = spy(ResourcePropertiesRegistry.getInstance()); + } + + @Test + public void theClientShouldUseTheSameVersionWhenTheyAreTheSame() { + List serverVersions = Arrays + .asList(new KubernetesAPIVersion[] { KubernetesAPIVersion.v1, KubernetesAPIVersion.v1beta3 }); + assertEquals(KubernetesAPIVersion.v1, registry.getMaxSupportedKubernetesVersion(serverVersions)); + } + + @Test + public void theClientShouldUseTheServerVersionWhenTheServerIsBehindTheClient() { + when(registry.getSupportedKubernetesVersions()) + .thenReturn(new KubernetesAPIVersion[] { KubernetesAPIVersion.v1, KubernetesAPIVersion.v1beta3 }); + List serverVersions = Arrays + .asList(new KubernetesAPIVersion[] { KubernetesAPIVersion.v1beta3 }); + + assertEquals(KubernetesAPIVersion.v1beta3, registry.getMaxSupportedKubernetesVersion(serverVersions)); + } + + @Test + public void theClientShouldUseTheClientVersionVersionWhenTheClientIsBehindTheServer() { + List serverVersions = Arrays + .asList(new KubernetesAPIVersion[] { KubernetesAPIVersion.v1, KubernetesAPIVersion.v1beta3 }); + when(registry.getSupportedKubernetesVersions()) + .thenReturn(new KubernetesAPIVersion[] { KubernetesAPIVersion.v1beta3 }); + + assertEquals(KubernetesAPIVersion.v1beta3, registry.getMaxSupportedKubernetesVersion(serverVersions)); + } + + @Test + public void theClientShouldUseTheSameOpenShiftAPIVersionWhenTheyAreTheSame() { + List serverVersions = Arrays + .asList(new OpenShiftAPIVersion[] { OpenShiftAPIVersion.v1, OpenShiftAPIVersion.v1beta3 }); + assertEquals(OpenShiftAPIVersion.v1, registry.getMaxSupportedOpenShiftVersion(serverVersions)); + } + + @Test + public void theClientShouldUseTheOpenShiftAPIServerVersionWhenTheServerIsBehindTheClient() { + when(registry.getSupportedOpenShiftVersions()) + .thenReturn(new OpenShiftAPIVersion[] { OpenShiftAPIVersion.v1, OpenShiftAPIVersion.v1beta3 }); + List serverVersions = Arrays + .asList(new OpenShiftAPIVersion[] { OpenShiftAPIVersion.v1beta3 }); + + assertEquals(OpenShiftAPIVersion.v1beta3, registry.getMaxSupportedOpenShiftVersion(serverVersions)); + } + + @Test + public void theClientShouldUseTheOpenShiftAPIClientVersionVersionWhenTheClientIsBehindTheServer() { + List serverVersions = Arrays + .asList(new OpenShiftAPIVersion[] { OpenShiftAPIVersion.v1, OpenShiftAPIVersion.v1beta3 }); + when(registry.getSupportedOpenShiftVersions()) + .thenReturn(new OpenShiftAPIVersion[] { OpenShiftAPIVersion.v1beta3 }); + + assertEquals(OpenShiftAPIVersion.v1beta3, registry.getMaxSupportedOpenShiftVersion(serverVersions)); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/template/ParameterTest.java b/src/test/java/com/openshift/internal/restclient/model/template/ParameterTest.java index e86ce0ff..18a0c033 100644 --- a/src/test/java/com/openshift/internal/restclient/model/template/ParameterTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/template/ParameterTest.java @@ -12,131 +12,132 @@ public class ParameterTest { - private Parameter param = new Parameter(new ModelNode()); - - @Test - public void testGetNameWhenUndefined() { - assertEquals("", param.getValue()); - } - - @Test - public void testGetDescriptionWhenUndefined() { - assertEquals("", param.getDescription()); - } - - @Test - public void testGetFromWhenUndefined() { - assertEquals("", param.getFrom()); - } - - @Test - public void testGetGeneratorNameWhenUndefined() { - assertEquals("", param.getGeneratorName()); - } - - @Test - public void testIsRequiredUndefined() { - assertFalse(param.isRequired()); - } - @Test - public void testIsRequiredFalse() { - ModelNode node = new ModelNode(); - node.get("required").set(false); - param = new Parameter(node); - assertFalse(param.isRequired()); - } - - @Test - public void testIsRequired() { - ModelNode node = new ModelNode(); - node.get("required").set(true); - param = new Parameter(node); - assertTrue(param.isRequired()); - } - - @Test - public void shouldNotEqualsIfFromIsDifferent() { - // pre-requisistes - ModelNode node = new ModelNode(); - node.get("from").set("42"); - IParameter parameter = new Parameter(node); - - ModelNode otherNode = new ModelNode(); - otherNode.get("from").set("84"); - IParameter otherParameter = new Parameter(otherNode); - - // operation - // verification - Assertions.assertThat(parameter).isNotEqualTo(otherParameter); - Assertions.assertThat(otherParameter).isNotEqualTo(parameter); - } - - @Test - public void shouldNotEqualsIfGeneratorNameIsDifferent() { - // pre-requisistes - ModelNode node = new ModelNode(); - node.get("generate").set("42"); - IParameter parameter = new Parameter(node); - - ModelNode otherNode = new ModelNode(); - otherNode.get("generate").set("84"); - IParameter otherParameter = new Parameter(otherNode); - - // operation - // verification - Assertions.assertThat(parameter).isNotEqualTo(otherParameter); - Assertions.assertThat(otherParameter).isNotEqualTo(parameter); - } - - @Test - public void shouldNotEqualsIfNameIsDifferent() { - // pre-requisistes - ModelNode node = new ModelNode(); - node.get("name").set("42"); - IParameter parameter = new Parameter(node); - - ModelNode otherNode = new ModelNode(); - otherNode.get("name").set("84"); - IParameter otherParameter = new Parameter(otherNode); - - // operation - // verification - Assertions.assertThat(parameter).isNotEqualTo(otherParameter); - Assertions.assertThat(otherParameter).isNotEqualTo(parameter); - } - - @Test - public void shouldNotEqualsIfValueIsDifferent() { - // pre-requisistes - ModelNode node = new ModelNode(); - node.get("value").set("42"); - IParameter parameter = new Parameter(node); - - ModelNode otherNode = new ModelNode(); - otherNode.get("value").set("84"); - IParameter otherParameter = new Parameter(otherNode); - - // operation - // verification - Assertions.assertThat(parameter).isNotEqualTo(otherParameter); - Assertions.assertThat(otherParameter).isNotEqualTo(parameter); - } - - @Test - public void shouldNotEqualsIfIsRequiredIsDifferent() { - // pre-requisistes - ModelNode node = new ModelNode(); - node.get("required").set(true); - IParameter parameter = new Parameter(node); - - ModelNode otherNode = new ModelNode(); - otherNode.get("required").set(false); - IParameter otherParameter = new Parameter(otherNode); - - // operation - // verification - Assertions.assertThat(parameter).isNotEqualTo(otherParameter); - Assertions.assertThat(otherParameter).isNotEqualTo(parameter); - } + private Parameter param = new Parameter(new ModelNode()); + + @Test + public void testGetNameWhenUndefined() { + assertEquals("", param.getValue()); + } + + @Test + public void testGetDescriptionWhenUndefined() { + assertEquals("", param.getDescription()); + } + + @Test + public void testGetFromWhenUndefined() { + assertEquals("", param.getFrom()); + } + + @Test + public void testGetGeneratorNameWhenUndefined() { + assertEquals("", param.getGeneratorName()); + } + + @Test + public void testIsRequiredUndefined() { + assertFalse(param.isRequired()); + } + + @Test + public void testIsRequiredFalse() { + ModelNode node = new ModelNode(); + node.get("required").set(false); + param = new Parameter(node); + assertFalse(param.isRequired()); + } + + @Test + public void testIsRequired() { + ModelNode node = new ModelNode(); + node.get("required").set(true); + param = new Parameter(node); + assertTrue(param.isRequired()); + } + + @Test + public void shouldNotEqualsIfFromIsDifferent() { + // pre-requisistes + ModelNode node = new ModelNode(); + node.get("from").set("42"); + IParameter parameter = new Parameter(node); + + ModelNode otherNode = new ModelNode(); + otherNode.get("from").set("84"); + IParameter otherParameter = new Parameter(otherNode); + + // operation + // verification + Assertions.assertThat(parameter).isNotEqualTo(otherParameter); + Assertions.assertThat(otherParameter).isNotEqualTo(parameter); + } + + @Test + public void shouldNotEqualsIfGeneratorNameIsDifferent() { + // pre-requisistes + ModelNode node = new ModelNode(); + node.get("generate").set("42"); + IParameter parameter = new Parameter(node); + + ModelNode otherNode = new ModelNode(); + otherNode.get("generate").set("84"); + IParameter otherParameter = new Parameter(otherNode); + + // operation + // verification + Assertions.assertThat(parameter).isNotEqualTo(otherParameter); + Assertions.assertThat(otherParameter).isNotEqualTo(parameter); + } + + @Test + public void shouldNotEqualsIfNameIsDifferent() { + // pre-requisistes + ModelNode node = new ModelNode(); + node.get("name").set("42"); + IParameter parameter = new Parameter(node); + + ModelNode otherNode = new ModelNode(); + otherNode.get("name").set("84"); + IParameter otherParameter = new Parameter(otherNode); + + // operation + // verification + Assertions.assertThat(parameter).isNotEqualTo(otherParameter); + Assertions.assertThat(otherParameter).isNotEqualTo(parameter); + } + + @Test + public void shouldNotEqualsIfValueIsDifferent() { + // pre-requisistes + ModelNode node = new ModelNode(); + node.get("value").set("42"); + IParameter parameter = new Parameter(node); + + ModelNode otherNode = new ModelNode(); + otherNode.get("value").set("84"); + IParameter otherParameter = new Parameter(otherNode); + + // operation + // verification + Assertions.assertThat(parameter).isNotEqualTo(otherParameter); + Assertions.assertThat(otherParameter).isNotEqualTo(parameter); + } + + @Test + public void shouldNotEqualsIfIsRequiredIsDifferent() { + // pre-requisistes + ModelNode node = new ModelNode(); + node.get("required").set(true); + IParameter parameter = new Parameter(node); + + ModelNode otherNode = new ModelNode(); + otherNode.get("required").set(false); + IParameter otherParameter = new Parameter(otherNode); + + // operation + // verification + Assertions.assertThat(parameter).isNotEqualTo(otherParameter); + Assertions.assertThat(otherParameter).isNotEqualTo(parameter); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/template/TemplateTest.java b/src/test/java/com/openshift/internal/restclient/model/template/TemplateTest.java index 0c3ccbf4..eff074a0 100644 --- a/src/test/java/com/openshift/internal/restclient/model/template/TemplateTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/template/TemplateTest.java @@ -6,9 +6,12 @@ * * Contributors: Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.template; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import java.util.ArrayList; import java.util.Arrays; @@ -26,71 +29,73 @@ import com.openshift.restclient.model.template.ITemplate; public class TemplateTest { - @Mock private IClient client; - private ITemplate template; - private ModelNode node = new ModelNode(); - @Before - public void setUp() throws Exception { - ModelNode params = node.get("parameters"); - params.add(param("foo","bar")); - params.add(param("abc","xyz")); - params.add(param("123","456")); - template = new Template(node, client, null); - } - - @Test - public void testGetParametersWhenNotDefined() { - template = new Template(new ModelNode(), client, null); - assertNotNull(template.getParameters()); - } - - @Test - public void addObjectLabel() { - final String key = "objectLabelKey"; - final String value = "objectLabelValue"; - template.addObjectLabel(key, value); - Map labels = template.getObjectLabels(); - assertEquals(value, labels.get(key)); - } + @Mock + private IClient client; + private ITemplate template; + private ModelNode node = new ModelNode(); + + @Before + public void setUp() throws Exception { + ModelNode params = node.get("parameters"); + params.add(param("foo", "bar")); + params.add(param("abc", "xyz")); + params.add(param("123", "456")); + template = new Template(node, client, null); + } + + @Test + public void testGetParametersWhenNotDefined() { + template = new Template(new ModelNode(), client, null); + assertNotNull(template.getParameters()); + } + + @Test + public void addObjectLabel() { + final String key = "objectLabelKey"; + final String value = "objectLabelValue"; + template.addObjectLabel(key, value); + Map labels = template.getObjectLabels(); + assertEquals(value, labels.get(key)); + } + + @Test + public void updateParameter() { + template.updateParameter("foo", "newbar"); + List updatedParams = new ArrayList(); + for (IParameter param : template.getParameters().values()) { + updatedParams.add(String.format("%s:%s", param.getName(), param.getValue())); + } + + String[] exp = new String[] { "foo:newbar", "abc:xyz", "123:456" }; + String[] act = updatedParams.toArray(new String[] {}); + Arrays.sort(exp); + Arrays.sort(act); + assertArrayEquals(exp, act); + } + + @Test + public void updateParameters() { + Collection parameters = new ArrayList(); + parameters.add(new Parameter(param("foo", "newbar"))); + parameters.add(new Parameter(param("123", "anewvalue"))); - @Test - public void updateParameter() { - template.updateParameter("foo", "newbar"); - List updatedParams = new ArrayList(); - for (IParameter param : template.getParameters().values()) { - updatedParams.add(String.format("%s:%s", param.getName(), param.getValue())); - } + template.updateParameterValues(parameters); - String [] exp = new String [] {"foo:newbar","abc:xyz","123:456"}; - String [] act = updatedParams.toArray(new String [] {}); - Arrays.sort(exp); - Arrays.sort(act); - assertArrayEquals(exp, act); - } + List updatedParams = new ArrayList(); + for (IParameter param : template.getParameters().values()) { + updatedParams.add(String.format("%s:%s", param.getName(), param.getValue())); + } + String[] exp = new String[] { "foo:newbar", "123:anewvalue", "abc:xyz" }; + String[] act = updatedParams.toArray(new String[] {}); + Arrays.sort(exp); + Arrays.sort(act); + assertArrayEquals(exp, act); + } - @Test - public void updateParameters() { - Collection parameters = new ArrayList(); - parameters.add(new Parameter(param("foo", "newbar"))); - parameters.add(new Parameter(param("123", "anewvalue"))); - - template.updateParameterValues(parameters); - - List updatedParams = new ArrayList(); - for (IParameter param : template.getParameters().values()) { - updatedParams.add(String.format("%s:%s", param.getName(), param.getValue())); - } - String [] exp = new String [] {"foo:newbar", "123:anewvalue","abc:xyz"}; - String [] act = updatedParams.toArray(new String [] {}); - Arrays.sort(exp); - Arrays.sort(act); - assertArrayEquals(exp, act); - } - - private ModelNode param(String name, String value) { - ModelNode node = new ModelNode(); - node.get("name").set(name); - node.get("value").set(value); - return node; - } + private ModelNode param(String name, String value) { + ModelNode node = new ModelNode(); + node.get("name").set(name); + node.get("value").set(value); + return node; + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java index 593d5efa..92056c7e 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertArrayEquals; @@ -45,142 +46,137 @@ import com.openshift.restclient.model.build.ISourceBuildStrategy; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class BuildConfigTest { - - private static final String VERSION = "v1"; - private static IBuildConfig config; - private static IClient client; - - @BeforeClass - public static void setup() throws Exception{ - client = mock(IClient.class); - when(client.getBaseURL()).thenReturn(new URL("https://localhost:8443")); - when(client.getOpenShiftAPIVersion()).thenReturn(VERSION); - ModelNode node = ModelNode.fromJSONString(Samples.V1_BUILD_CONFIG.getContentAsString()); - config = new BuildConfig(node, client, null); - } - - @Test - public void getBuildTriggers(){ - assertBuildTriggers(config.getBuildTriggers().toArray(new IBuildTrigger[]{})); - } - - @Test - public void addBuildTriggers() { - BuildConfig writeConfig = new ResourceFactory(client){}.create(VERSION, ResourceKind.BUILD_CONFIG); - - writeConfig.addBuildTrigger(new WebhookTrigger(BuildTriggerType.GITHUB, "secret101", "https://localhost:8443")); - writeConfig.addBuildTrigger(new WebhookTrigger(BuildTriggerType.GENERIC, "secret101", "https://localhost:8443")); - writeConfig.addBuildTrigger(new ImageChangeTrigger("", "", "")); - - assertBuildTriggers(reCreateBuildConfig(writeConfig).getBuildTriggers().toArray(new IBuildTrigger[]{})); - } - - @Test - public void getOutputRespositoryName(){ - assertEquals("origin-ruby-sample:latest", config.getOutputRepositoryName()); - } - - @Test - public void getSourceURI(){ - assertEquals("git://github.com/openshift/ruby-hello-world.git", config.getSourceURI()); - } - - @Test - public void getGitBuildSource(){ - IBuildSource source = config.getBuildSource(); - assertGitBuildSource(source); - } - - @Test - public void setGitBuildSource() { - BuildConfig writeConfig = new ResourceFactory(client){}.create(VERSION, ResourceKind.BUILD_CONFIG); - - Map env = new HashMap(); - env.put("foo", "bar"); - writeConfig.setBuildSource(new GitBuildSource("git://github.com/openshift/ruby-hello-world.git", "", "foobar")); - - assertGitBuildSource(reCreateBuildConfig(writeConfig).getBuildSource()); - } - - @Test - public void getSourceBuildStrategy() { - IBuildStrategy strategy = config.getBuildStrategy(); - assertSourceBuildStrategy(strategy); - } - - @Test - public void setSourceBuildStrategy() { - BuildConfig writeConfig = new ResourceFactory(client){}.create(VERSION, ResourceKind.BUILD_CONFIG); - - ModelNode node = new ModelNodeBuilder() - .set("type", BuildStrategyType.SOURCE) - .set(SourceBuildStrategy.FROM_IMAGE, "ruby-20-centos7:latest") - .set(SourceBuildStrategy.SCRIPTS, "alocation") - .set(SourceBuildStrategy.INCREMENTAL, true) - .add(SourceBuildStrategy.ENV, new ModelNodeBuilder() - .set("name", "foo") - .set("value", "bar")) - .build(); - - writeConfig.setBuildStrategy(new SourceBuildStrategy(node, new HashMap<>())); - - assertSourceBuildStrategy(reCreateBuildConfig(writeConfig).getBuildStrategy()); - } - - private void assertBuildTriggers(IBuildTrigger[] triggers) { - IBuildTrigger [] exp = new IBuildTrigger[]{ - new WebhookTrigger(BuildTriggerType.GITHUB, "secret101","https://localhost:8443"), - new WebhookTrigger(BuildTriggerType.GENERIC, "secret101","https://localhost:8443"), - new ImageChangeTrigger("", "", "") - }; - assertArrayEquals(exp, triggers); - } - - private void assertGitBuildSource(IBuildSource source) { - assertEquals(BuildSourceType.GIT, source.getType()); - assertEquals("git://github.com/openshift/ruby-hello-world.git", source.getURI()); - assertEquals("foobar", source.getContextDir()); - assertTrue(source instanceof IGitBuildSource); - - IGitBuildSource git = (IGitBuildSource)source; - assertEquals("Exp. to get the source ref","", git.getRef()); - } - - private void assertSourceBuildStrategy(IBuildStrategy strategy) { - assertEquals(BuildStrategyType.SOURCE, strategy.getType()); - assertTrue(strategy instanceof ISourceBuildStrategy); - - ISourceBuildStrategy source = (ISourceBuildStrategy)strategy; - assertEquals(new DockerImageURI("ruby-20-centos7:latest"), source.getImage()); - assertEquals("alocation", source.getScriptsLocation()); - assertEquals(true, source.incremental()); - - Map envVars = source.getEnvironmentVariables(); - assertEquals(1, envVars.size()); - assertTrue("Exp. to find the environment variable",envVars.containsKey("foo")); - assertEquals("bar",envVars.get("foo")); - - envVars.put("newKey", "newValue"); - source.setEnvironmentVariables(envVars); - envVars = source.getEnvironmentVariables(); - assertEquals(2, envVars.size()); - assertTrue("Exp. to find the environment variable",envVars.containsKey("newKey")); - assertEquals("newValue",envVars.get("newKey")); - - Collection vars = source.getEnvVars(); - assertTrue(vars.stream().filter(e->"newKey".equals(e.getName())).findFirst().isPresent()); - - vars.remove(vars.toArray()[0]); - source.setEnvVars(vars); - vars = source.getEnvVars(); - assertEquals(1, vars.size()); - } - - private BuildConfig reCreateBuildConfig(BuildConfig config) { - return new BuildConfig(config.getNode(), client, null); - } + + private static final String VERSION = "v1"; + private static IBuildConfig config; + private static IClient client; + + @BeforeClass + public static void setup() throws Exception { + client = mock(IClient.class); + when(client.getBaseURL()).thenReturn(new URL("https://localhost:8443")); + when(client.getOpenShiftAPIVersion()).thenReturn(VERSION); + ModelNode node = ModelNode.fromJSONString(Samples.V1_BUILD_CONFIG.getContentAsString()); + config = new BuildConfig(node, client, null); + } + + @Test + public void getBuildTriggers() { + assertBuildTriggers(config.getBuildTriggers().toArray(new IBuildTrigger[] {})); + } + + @Test + public void addBuildTriggers() { + BuildConfig writeConfig = new ResourceFactory(client) { + }.create(VERSION, ResourceKind.BUILD_CONFIG); + + writeConfig.addBuildTrigger(new WebhookTrigger(BuildTriggerType.GITHUB, "secret101", "https://localhost:8443")); + writeConfig + .addBuildTrigger(new WebhookTrigger(BuildTriggerType.GENERIC, "secret101", "https://localhost:8443")); + writeConfig.addBuildTrigger(new ImageChangeTrigger("", "", "")); + + assertBuildTriggers(reCreateBuildConfig(writeConfig).getBuildTriggers().toArray(new IBuildTrigger[] {})); + } + + @Test + public void getOutputRespositoryName() { + assertEquals("origin-ruby-sample:latest", config.getOutputRepositoryName()); + } + + @Test + public void getSourceURI() { + assertEquals("git://github.com/openshift/ruby-hello-world.git", config.getSourceURI()); + } + + @Test + public void getGitBuildSource() { + IBuildSource source = config.getBuildSource(); + assertGitBuildSource(source); + } + + @Test + public void setGitBuildSource() { + BuildConfig writeConfig = new ResourceFactory(client) { + }.create(VERSION, ResourceKind.BUILD_CONFIG); + + Map env = new HashMap(); + env.put("foo", "bar"); + writeConfig.setBuildSource(new GitBuildSource("git://github.com/openshift/ruby-hello-world.git", "", "foobar")); + + assertGitBuildSource(reCreateBuildConfig(writeConfig).getBuildSource()); + } + + @Test + public void getSourceBuildStrategy() { + IBuildStrategy strategy = config.getBuildStrategy(); + assertSourceBuildStrategy(strategy); + } + + @Test + public void setSourceBuildStrategy() { + BuildConfig writeConfig = new ResourceFactory(client) { + }.create(VERSION, ResourceKind.BUILD_CONFIG); + + ModelNode node = new ModelNodeBuilder().set("type", BuildStrategyType.SOURCE) + .set(SourceBuildStrategy.FROM_IMAGE, "ruby-20-centos7:latest") + .set(SourceBuildStrategy.SCRIPTS, "alocation").set(SourceBuildStrategy.INCREMENTAL, true) + .add(SourceBuildStrategy.ENV, new ModelNodeBuilder().set("name", "foo").set("value", "bar")).build(); + + writeConfig.setBuildStrategy(new SourceBuildStrategy(node, new HashMap<>())); + + assertSourceBuildStrategy(reCreateBuildConfig(writeConfig).getBuildStrategy()); + } + + private void assertBuildTriggers(IBuildTrigger[] triggers) { + IBuildTrigger[] exp = new IBuildTrigger[] { + new WebhookTrigger(BuildTriggerType.GITHUB, "secret101", "https://localhost:8443"), + new WebhookTrigger(BuildTriggerType.GENERIC, "secret101", "https://localhost:8443"), + new ImageChangeTrigger("", "", "") }; + assertArrayEquals(exp, triggers); + } + + private void assertGitBuildSource(IBuildSource source) { + assertEquals(BuildSourceType.GIT, source.getType()); + assertEquals("git://github.com/openshift/ruby-hello-world.git", source.getURI()); + assertEquals("foobar", source.getContextDir()); + assertTrue(source instanceof IGitBuildSource); + + IGitBuildSource git = (IGitBuildSource) source; + assertEquals("Exp. to get the source ref", "", git.getRef()); + } + + private void assertSourceBuildStrategy(IBuildStrategy strategy) { + assertEquals(BuildStrategyType.SOURCE, strategy.getType()); + assertTrue(strategy instanceof ISourceBuildStrategy); + + ISourceBuildStrategy source = (ISourceBuildStrategy) strategy; + assertEquals(new DockerImageURI("ruby-20-centos7:latest"), source.getImage()); + assertEquals("alocation", source.getScriptsLocation()); + assertEquals(true, source.incremental()); + + Map envVars = source.getEnvironmentVariables(); + assertEquals(1, envVars.size()); + assertTrue("Exp. to find the environment variable", envVars.containsKey("foo")); + assertEquals("bar", envVars.get("foo")); + + envVars.put("newKey", "newValue"); + source.setEnvironmentVariables(envVars); + envVars = source.getEnvironmentVariables(); + assertEquals(2, envVars.size()); + assertTrue("Exp. to find the environment variable", envVars.containsKey("newKey")); + assertEquals("newValue", envVars.get("newKey")); + + Collection vars = source.getEnvVars(); + assertTrue(vars.stream().filter(e -> "newKey".equals(e.getName())).findFirst().isPresent()); + + vars.remove(vars.toArray()[0]); + source.setEnvVars(vars); + vars = source.getEnvVars(); + assertEquals(1, vars.size()); + } + + private BuildConfig reCreateBuildConfig(BuildConfig config) { + return new BuildConfig(config.getNode(), client, null); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/BuildTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/BuildTest.java index c1f28777..212de5f9 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/BuildTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/BuildTest.java @@ -6,9 +6,11 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.mock; import org.jboss.dmr.ModelNode; @@ -23,49 +25,46 @@ import com.openshift.restclient.model.build.IBuildStatus; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class BuildTest { - - private static final String VERSION = "v1"; - private static IBuild build; - - @BeforeClass - public static void setup(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_BUILD.getContentAsString()); - build = new Build(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.BUILD)); - } - - @Test - public void getStatus(){ - assertEquals("Running", build.getStatus()); - } - @Test - public void getMessage(){ - assertEquals("Some status message", build.getMessage()); - } + private static final String VERSION = "v1"; + private static IBuild build; + + @BeforeClass + public static void setup() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_BUILD.getContentAsString()); + build = new Build(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.BUILD)); + } + + @Test + public void getStatus() { + assertEquals("Running", build.getStatus()); + } + + @Test + public void getMessage() { + assertEquals("Some status message", build.getMessage()); + } + + @Test + public void getOutputTo() { + assertEquals("origin-ruby-sample:latest", build.getOutputTo().toString()); + } + + @Test + public void getOutputKind() { + assertEquals("ImageStreamTag", build.getOutputKind()); + } - @Test - public void getOutputTo(){ - assertEquals("origin-ruby-sample:latest", build.getOutputTo().toString()); - } + @Test + public void getBuildStatus() { + IBuildStatus status = build.getBuildStatus(); + assertNotNull(status); + assertEquals("Running", status.getPhase()); + assertEquals("172.30.224.48:5000/rails-demo/rails-demo:latest", status.getOutputDockerImage().toString()); + assertEquals("2015-06-10T20:00:51Z", status.getStartTime()); + assertEquals(76895000000000L, status.getDuration()); + } - @Test - public void getOutputKind(){ - assertEquals("ImageStreamTag", build.getOutputKind()); - } - - @Test - public void getBuildStatus() { - IBuildStatus status = build.getBuildStatus(); - assertNotNull(status); - assertEquals("Running", status.getPhase()); - assertEquals("172.30.224.48:5000/rails-demo/rails-demo:latest", status.getOutputDockerImage().toString()); - assertEquals("2015-06-10T20:00:51Z", status.getStartTime()); - assertEquals(76895000000000L, status.getDuration()); - } - } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java index 9acc46a5..31f828bc 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java @@ -6,8 +6,18 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import java.util.Collections; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + import com.openshift.internal.restclient.ResourceFactory; import com.openshift.internal.restclient.model.ConfigMap; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; @@ -15,36 +25,31 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IConfigMap; import com.openshift.restclient.utils.Samples; -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; - -import java.util.Collections; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; /** * @author Ulf Lilleengen */ public class ConfigMapTest { - private static final String VERSION = "v1"; - private IConfigMap configMap; - private IClient client; - - @Before - public void setUp(){ - client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_CONFIG_MAP.getContentAsString()); - configMap = new ConfigMap(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.CONFIG_MAP)); - } - @Test - public void testIsRegisteredWithFactory() { - configMap = new ResourceFactory(client).create(Samples.V1_CONFIG_MAP.getContentAsString()); - } - @Test - public void testGetData() { - assertEquals(Collections.singletonMap("key1", "config1"), configMap.getData()); - } + private static final String VERSION = "v1"; + private IConfigMap configMap; + private IClient client; + + @Before + public void setUp() { + client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_CONFIG_MAP.getContentAsString()); + configMap = new ConfigMap(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.CONFIG_MAP)); + } + + @Test + public void testIsRegisteredWithFactory() { + configMap = new ResourceFactory(client).create(Samples.V1_CONFIG_MAP.getContentAsString()); + } + + @Test + public void testGetData() { + assertEquals(Collections.singletonMap("key1", "config1"), configMap.getData()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java index 9c25d7b8..546eaf7c 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java @@ -6,13 +6,16 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; +import static com.openshift.internal.util.JBossDmrExtentions.getPath; import static org.fest.assertions.Assertions.assertThat; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static com.openshift.internal.util.JBossDmrExtentions.*; import java.util.ArrayList; import java.util.HashMap; @@ -39,143 +42,144 @@ import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class DeploymentConfigTest { - - private static final String CONTAINER2_NAME = "deployment"; - private static final String CONTAINER1_NAME = "ruby-helloworld-database"; - private static final String VERSION = "v1"; - private DeploymentConfig config; - private IClient client; - private ModelNode node; - private Map propertyKeys; - private IContainer container1; - private IContainer container2; - - @Before - public void setup(){ - client = mock(IClient.class); - node = ModelNode.fromJSONString(Samples.V1_DEPLOYMENT_CONIFIG.getContentAsString()); - propertyKeys = ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.DEPLOYMENT_CONFIG); - config = new DeploymentConfig(node, client, propertyKeys); - container1 = config.getContainer(CONTAINER1_NAME); - container2 = config.getContainer(CONTAINER2_NAME); - } - - @Test - public void testIsDeployCapable() { - assertThat(config.supports(IDeployCapability.class)).isTrue(); - } - - @Test - public void getLabels() { - assertArrayEquals(new String[] {"template"},config.getLabels().keySet().toArray(new String[] {})); - } - - @Test - public void getConfigChangeTrigger() { - List trigger = new ArrayList<>(config.getTriggers()); - assertEquals("Exp. equal number of triggers",2,trigger.size()); - assertTrue("Expected to find a config change trigger", IDeploymentConfigChangeTrigger.class.isAssignableFrom(trigger.get(0).getClass())); - assertTrue("Expected to find a config change trigger", IDeploymentImageChangeTrigger.class.isAssignableFrom(trigger.get(1).getClass())); - - IDeploymentImageChangeTrigger ict = (IDeploymentImageChangeTrigger) trigger.get(1); - assertEquals("foo", ict.getNamespace()); - } - - @Test - public void getReplicas(){ - assertEquals(1, config.getReplicas()); - } - - @Test - public void setReplicas(){ - config.setReplicas(3); - assertEquals(3, config.getReplicas()); - } - - @Test - public void setLatestVersionNumber(){ - config.setLatestVersionNumber(3); - assertEquals(3, config.getLatestVersionNumber()); - } - - @Test - public void setReplicaSelector() { - Map exp = new HashMap(); - exp.put("foo", "bar"); - node = ModelNode.fromJSONString(Samples.V1_DEPLOYMENT_CONIFIG.getContentAsString()); - DeploymentConfig config = new DeploymentConfig(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.DEPLOYMENT_CONFIG)); - config.setReplicaSelector(exp); - assertEquals(exp, config.getReplicaSelector()); - } - - @Test - public void getReplicaSelector() { - Map exp = new HashMap(); - exp.put("name", "database"); - assertEquals(exp, config.getReplicaSelector()); - } - - @Test - public void getTriggerTypes() { - assertArrayEquals(new String[] {"ConfigChange", "ImageChange"}, config.getTriggerTypes().toArray(new String[] {})); - } - - @Test - public void testGetDeploymentStrategyTypes() { - assertEquals("Recreate", config.getDeploymentStrategyType()); - } - - @Test - public void testAddContainer() { - //remove containers hack - String[] path = getPath(DeploymentConfig.DEPLOYMENTCONFIG_CONTAINERS); - node.get(path).clear(); - - //setup - DockerImageURI uri = new DockerImageURI("aproject/an_image_name"); - IPort port = mock(IPort.class); - when(port.getProtocol()).thenReturn("TCP"); - when(port.getContainerPort()).thenReturn(8080); - Set ports = new HashSet<>(); - ports.add(port); - - config.addContainer(uri, ports, new HashMap()); - - List containers = node.get(path).asList(); - assertEquals(1, containers.size()); - - //expectations - ModelNode portNode = new ModelNode(); - portNode.get("protocol").set(port.getProtocol()); - portNode.get("containerPort").set(port.getContainerPort()); - - ModelNode exp = new ModelNode(); - exp.get("name").set(uri.getName()); - exp.get("image").set(uri.getUriWithoutHost()); - exp.get("ports").add(portNode); - - assertEquals(exp.toJSONString(false), containers.get(0).toJSONString(false)); - } - - @Test - public void shouldNotReturnLivenessProbe() { - IProbe livenessProbe = container1.getLivenessProbe(); - assertThat(livenessProbe).isNull(); - } - - @Test - public void shouldNotReturnReadinessProbe() { - IProbe readinessProbe = container1.getReadinessProbe(); - assertThat(readinessProbe).isNull(); - } - - @Test - public void shouldReturnLivenessProbe() { - // given + + private static final String CONTAINER2_NAME = "deployment"; + private static final String CONTAINER1_NAME = "ruby-helloworld-database"; + private static final String VERSION = "v1"; + private DeploymentConfig config; + private IClient client; + private ModelNode node; + private Map propertyKeys; + private IContainer container1; + private IContainer container2; + + @Before + public void setup() { + client = mock(IClient.class); + node = ModelNode.fromJSONString(Samples.V1_DEPLOYMENT_CONIFIG.getContentAsString()); + propertyKeys = ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.DEPLOYMENT_CONFIG); + config = new DeploymentConfig(node, client, propertyKeys); + container1 = config.getContainer(CONTAINER1_NAME); + container2 = config.getContainer(CONTAINER2_NAME); + } + + @Test + public void testIsDeployCapable() { + assertThat(config.supports(IDeployCapability.class)).isTrue(); + } + + @Test + public void getLabels() { + assertArrayEquals(new String[] { "template" }, config.getLabels().keySet().toArray(new String[] {})); + } + + @Test + public void getConfigChangeTrigger() { + List trigger = new ArrayList<>(config.getTriggers()); + assertEquals("Exp. equal number of triggers", 2, trigger.size()); + assertTrue("Expected to find a config change trigger", + IDeploymentConfigChangeTrigger.class.isAssignableFrom(trigger.get(0).getClass())); + assertTrue("Expected to find a config change trigger", + IDeploymentImageChangeTrigger.class.isAssignableFrom(trigger.get(1).getClass())); + + IDeploymentImageChangeTrigger ict = (IDeploymentImageChangeTrigger) trigger.get(1); + assertEquals("foo", ict.getNamespace()); + } + + @Test + public void getReplicas() { + assertEquals(1, config.getReplicas()); + } + + @Test + public void setReplicas() { + config.setReplicas(3); + assertEquals(3, config.getReplicas()); + } + + @Test + public void setLatestVersionNumber() { + config.setLatestVersionNumber(3); + assertEquals(3, config.getLatestVersionNumber()); + } + + @Test + public void setReplicaSelector() { + Map exp = new HashMap(); + exp.put("foo", "bar"); + node = ModelNode.fromJSONString(Samples.V1_DEPLOYMENT_CONIFIG.getContentAsString()); + DeploymentConfig config = new DeploymentConfig(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.DEPLOYMENT_CONFIG)); + config.setReplicaSelector(exp); + assertEquals(exp, config.getReplicaSelector()); + } + + @Test + public void getReplicaSelector() { + Map exp = new HashMap(); + exp.put("name", "database"); + assertEquals(exp, config.getReplicaSelector()); + } + + @Test + public void getTriggerTypes() { + assertArrayEquals(new String[] { "ConfigChange", "ImageChange" }, + config.getTriggerTypes().toArray(new String[] {})); + } + + @Test + public void testGetDeploymentStrategyTypes() { + assertEquals("Recreate", config.getDeploymentStrategyType()); + } + + @Test + public void testAddContainer() { + // remove containers hack + String[] path = getPath(DeploymentConfig.DEPLOYMENTCONFIG_CONTAINERS); + node.get(path).clear(); + + // setup + IPort port = mock(IPort.class); + when(port.getProtocol()).thenReturn("TCP"); + when(port.getContainerPort()).thenReturn(8080); + Set ports = new HashSet<>(); + ports.add(port); + + DockerImageURI uri = new DockerImageURI("aproject/an_image_name"); + config.addContainer(uri, ports, new HashMap()); + + List containers = node.get(path).asList(); + assertEquals(1, containers.size()); + + // expectations + ModelNode portNode = new ModelNode(); + portNode.get("protocol").set(port.getProtocol()); + portNode.get("containerPort").set(port.getContainerPort()); + + ModelNode exp = new ModelNode(); + exp.get("name").set(uri.getName()); + exp.get("image").set(uri.getUriWithoutHost()); + exp.get("ports").add(portNode); + + assertEquals(exp.toJSONString(false), containers.get(0).toJSONString(false)); + } + + @Test + public void shouldNotReturnLivenessProbe() { + IProbe livenessProbe = container1.getLivenessProbe(); + assertThat(livenessProbe).isNull(); + } + + @Test + public void shouldNotReturnReadinessProbe() { + IProbe readinessProbe = container1.getReadinessProbe(); + assertThat(readinessProbe).isNull(); + } + + @Test + public void shouldReturnLivenessProbe() { + // given // when IProbe probe = container2.getLivenessProbe(); @@ -186,11 +190,11 @@ public void shouldReturnLivenessProbe() { assertThat(probe.getPeriodSeconds()).isEqualTo(13); assertThat(probe.getSuccessThreshold()).isEqualTo(14); assertThat(probe.getFailureThreshold()).isEqualTo(15); - } + } - @Test - public void shouldAlterLivenessProbe() { - // given + @Test + public void shouldAlterLivenessProbe() { + // given // when IProbe probe = container2.getLivenessProbe(); probe.setInitialDelaySeconds(100); @@ -206,11 +210,11 @@ public void shouldAlterLivenessProbe() { assertThat(probe.getPeriodSeconds()).isEqualTo(102); assertThat(probe.getSuccessThreshold()).isEqualTo(103); assertThat(probe.getFailureThreshold()).isEqualTo(104); - } + } - @Test - public void shouldReturnReadynessProbe() { - // given + @Test + public void shouldReturnReadynessProbe() { + // given // when IProbe probe = container2.getReadinessProbe(); @@ -221,11 +225,11 @@ public void shouldReturnReadynessProbe() { assertThat(probe.getPeriodSeconds()).isEqualTo(5); assertThat(probe.getSuccessThreshold()).isEqualTo(6); assertThat(probe.getFailureThreshold()).isEqualTo(7); - } + } - @Test - public void shouldAlterReadinessProbe() { - // given + @Test + public void shouldAlterReadinessProbe() { + // given // when IProbe probe = container2.getReadinessProbe(); probe.setInitialDelaySeconds(200); @@ -241,7 +245,6 @@ public void shouldAlterReadinessProbe() { assertThat(probe.getPeriodSeconds()).isEqualTo(202); assertThat(probe.getSuccessThreshold()).isEqualTo(203); assertThat(probe.getFailureThreshold()).isEqualTo(204); - } - + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java index ea6b1695..0fdea0f7 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java @@ -8,17 +8,19 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import com.openshift.internal.restclient.model.volume.EmptyDirVolumeSource; -import com.openshift.restclient.model.volume.IEmptyDirVolumeSource; -import com.openshift.restclient.utils.Samples; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import com.openshift.internal.restclient.model.volume.EmptyDirVolumeSource; +import com.openshift.restclient.model.volume.IEmptyDirVolumeSource; +import com.openshift.restclient.utils.Samples; /** * @author Ulf Lilleengen diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java index 3ccfc025..d7e4f8d4 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java @@ -8,9 +8,10 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.fest.assertions.Assertions.*; +import static org.fest.assertions.Assertions.assertThat; import java.util.List; @@ -29,27 +30,27 @@ import com.openshift.restclient.utils.Samples; @RunWith(MockitoJUnitRunner.class) -public class EndpointsTest extends TypeMapperFixture{ +public class EndpointsTest extends TypeMapperFixture { + + private static String JSON = Samples.V1_ENDPOINTS.getContentAsString(); + + @Mock + private IEndpoints endpoint; - private static String JSON = Samples.V1_ENDPOINTS.getContentAsString(); - - @Mock - private IEndpoints endpoint; + @Before + public void setUp() throws Exception { + super.setUp(); + IResourceFactory factory = getIClient().getResourceFactory(); + endpoint = factory.create(JSON); + } - @Before - public void setUp() throws Exception { - super.setUp(); - IResourceFactory factory = getIClient().getResourceFactory(); - endpoint = factory.create(JSON); - } + @Test + public void testDeserialization() { + List subSets = endpoint.getSubSets(); + assertThat(subSets).isNotEmpty(); + IEndpointSubset subset = subSets.get(0); - @Test - public void testDeserialization() { - List subSets = endpoint.getSubSets(); - assertThat(subSets).isNotEmpty(); - IEndpointSubset subset = subSets.get(0); - - List addresses = subset.getAddresses(); + List addresses = subset.getAddresses(); assertThat(addresses).isNotEmpty(); IEndpointAddress address = addresses.get(0); assertThat(address.getName()).isEmpty(); @@ -73,6 +74,6 @@ public void testDeserialization() { assertThat(port.getName()).isEqualTo("443-tcp"); assertThat(port.getPort()).isEqualTo(443); assertThat(port.getProtocol()).isEqualTo("TCP"); - } + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java index 36dfbe15..33e69d0c 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.fest.assertions.Assertions.assertThat; @@ -28,64 +29,68 @@ */ public class EnvironmentVariableTest { - @Test - public void shouldBeEqualGivenEqualNameAndValue() { - // given - IEnvironmentVariable var1 = createEnvironmentVariable("foo", "bar"); - IEnvironmentVariable var2 = createEnvironmentVariable("foo", "bar"); - // when - // then - assertThat(var1).isEqualTo(var2); - } + @Test + public void shouldBeEqualGivenEqualNameAndValue() { + // given + IEnvironmentVariable var1 = createEnvironmentVariable("foo", "bar"); + IEnvironmentVariable var2 = createEnvironmentVariable("foo", "bar"); + // when + // then + assertThat(var1).isEqualTo(var2); + } - @Test - public void shouldBeNonEqualGivenNonEqualNameAndValue() { - // given - IEnvironmentVariable var1 = createEnvironmentVariable("foo", "bar"); - IEnvironmentVariable var2 = createEnvironmentVariable("kung", "foo"); - // when - // then - assertThat(var1).isNotEqualTo(var2); - } + @Test + public void shouldBeNonEqualGivenNonEqualNameAndValue() { + // given + IEnvironmentVariable var1 = createEnvironmentVariable("foo", "bar"); + IEnvironmentVariable var2 = createEnvironmentVariable("kung", "foo"); + // when + // then + assertThat(var1).isNotEqualTo(var2); + } - @Test - public void shouldReturnEmptyMapGivenEmptyEnvVars() { - // given - Collection envVars = Collections.emptyList(); - // when - Map envVarsMap = EnvironmentVariableUtils.toMapOfStrings(envVars); - // then - assertThat(envVarsMap).isEmpty(); - } + @Test + public void shouldReturnEmptyMapGivenEmptyEnvVars() { + // given + Collection envVars = Collections.emptyList(); + // when + Map envVarsMap = EnvironmentVariableUtils.toMapOfStrings(envVars); + // then + assertThat(envVarsMap).isEmpty(); + } - @SuppressWarnings("serial") - @Test - public void shouldReturnMapOfStringsForEnvVariables() { - // given - Collection envVars = createEnvironmentVariables("foo", "bar", "kung", "foo", "smurfHater", "gargamel"); - // when - Map envVarsMap = EnvironmentVariableUtils.toMapOfStrings(envVars); - // then - assertThat(envVarsMap).isEqualTo( - new HashMap() {{ put("foo", "bar"); put("kung", "foo"); put("smurfHater", "gargamel"); }}); - } + @SuppressWarnings("serial") + @Test + public void shouldReturnMapOfStringsForEnvVariables() { + // given + Collection envVars = createEnvironmentVariables("foo", "bar", "kung", "foo", "smurfHater", + "gargamel"); + // when + Map envVarsMap = EnvironmentVariableUtils.toMapOfStrings(envVars); + // then + assertThat(envVarsMap).isEqualTo(new HashMap() { + { + put("foo", "bar"); + put("kung", "foo"); + put("smurfHater", "gargamel"); + } + }); + } - private Collection createEnvironmentVariables(String... touples) { - assertThat(touples).isNotNull(); - assertThat(touples.length % 2).isEqualTo(0); + private Collection createEnvironmentVariables(String... touples) { + assertThat(touples).isNotNull(); + assertThat(touples.length % 2).isEqualTo(0); - ArrayList envVars = new ArrayList(); - for (int i = 0; i < touples.length;) { - envVars.add(createEnvironmentVariable(touples[i++], touples[i++])); - } - return envVars; - } + ArrayList envVars = new ArrayList(); + for (int i = 0; i < touples.length;) { + envVars.add(createEnvironmentVariable(touples[i++], touples[i++])); + } + return envVars; + } - private IEnvironmentVariable createEnvironmentVariable(String name, String value) { - ModelNodeBuilder builder = new ModelNodeBuilder(); - builder - .set(EnvironmentVariable.NAME, name) - .set(EnvironmentVariable.VALUE, value); - return new EnvironmentVariable(builder.build(), null); - } + private IEnvironmentVariable createEnvironmentVariable(String name, String value) { + ModelNodeBuilder builder = new ModelNodeBuilder(); + builder.set(EnvironmentVariable.NAME, name).set(EnvironmentVariable.VALUE, value); + return new EnvironmentVariable(builder.build(), null); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java index 948d5c85..6b11b5bd 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java @@ -8,9 +8,11 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import java.util.HashMap; @@ -31,60 +33,60 @@ @RunWith(MockitoJUnitRunner.class) public class EventTest { - private static String JSON = Samples.V1_EVENT.getContentAsString(); - - @Mock - private IClient client; - private IEvent event; - - @Before - public void setUp() throws Exception { - ModelNode node = ModelNode.fromJSONString(JSON); - event = new KubernetesEvent(node, client, new HashMap<>()); - } - - @Test - public void testGetEventSource() { - IEventSource source = event.getEventSource(); - assertNotNull(source); - assertEquals("deploymentconfig-controller", source.getComponent()); - assertEquals("", source.getHost()); - } - - @Test - public void testGetType() { - assertEquals("Normal", event.getType()); - } - - @Test - public void testGetCount() { - assertEquals(1, event.getCount()); - } - - @Test - public void testGetFirstSeen() { - assertEquals("2016-08-08T01:49:26Z", event.getFirstSeenTimestamp()); - } - - @Test - public void testGetLastSeen() { - assertEquals("2016-08-08T01:49:26Z", event.getLastSeenTimestamp()); - } - - @Test - public void testGetReason() { - assertEquals("DeploymentCreated", event.getReason()); - } - - @Test - public void testGetInvolvedObject() { - IObjectReference ref = event.getInvolvedObject(); - assertNotNull(ref); - } - - @Test - public void testGetMessage() { - assertEquals("Created new deployment \"nodejs-1\" for version 1", event.getMessage()); - } + private static String JSON = Samples.V1_EVENT.getContentAsString(); + + @Mock + private IClient client; + private IEvent event; + + @Before + public void setUp() throws Exception { + ModelNode node = ModelNode.fromJSONString(JSON); + event = new KubernetesEvent(node, client, new HashMap<>()); + } + + @Test + public void testGetEventSource() { + IEventSource source = event.getEventSource(); + assertNotNull(source); + assertEquals("deploymentconfig-controller", source.getComponent()); + assertEquals("", source.getHost()); + } + + @Test + public void testGetType() { + assertEquals("Normal", event.getType()); + } + + @Test + public void testGetCount() { + assertEquals(1, event.getCount()); + } + + @Test + public void testGetFirstSeen() { + assertEquals("2016-08-08T01:49:26Z", event.getFirstSeenTimestamp()); + } + + @Test + public void testGetLastSeen() { + assertEquals("2016-08-08T01:49:26Z", event.getLastSeenTimestamp()); + } + + @Test + public void testGetReason() { + assertEquals("DeploymentCreated", event.getReason()); + } + + @Test + public void testGetInvolvedObject() { + IObjectReference ref = event.getInvolvedObject(); + assertNotNull(ref); + } + + @Test + public void testGetMessage() { + assertEquals("Created new deployment \"nodejs-1\" for version 1", event.getMessage()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java index ae432ef6..af9d4b02 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.hamcrest.CoreMatchers.is; @@ -22,30 +23,28 @@ import com.openshift.restclient.model.volume.IHostPathVolumeSource; public class HostPathVolumeSourceTest { - - private IHostPathVolumeSource source; - - @Before - public void setUp() throws Exception { - ModelNode node = new ModelNodeBuilder() - .set("name", "somevolumesourcename") - .set("hostPath", new ModelNodeBuilder() - .set("path", "/foo").build()).build(); - source = (IHostPathVolumeSource) VolumeSource.create(node); - } - - @Test - public void testName() { - assertThat(source.getName(), is("somevolumesourcename")); - source.setName("thenewname"); - assertThat(source.getName(), is("thenewname")); - } - - @Test - public void testPath() { - assertThat(source.getPath(), is("/foo")); - source.setPath("thenewpath"); - assertThat(source.getPath(), is("thenewpath")); - } + + private IHostPathVolumeSource source; + + @Before + public void setUp() throws Exception { + ModelNode node = new ModelNodeBuilder().set("name", "somevolumesourcename") + .set("hostPath", new ModelNodeBuilder().set("path", "/foo").build()).build(); + source = (IHostPathVolumeSource) VolumeSource.create(node); + } + + @Test + public void testName() { + assertThat(source.getName(), is("somevolumesourcename")); + source.setName("thenewname"); + assertThat(source.getName(), is("thenewname")); + } + + @Test + public void testPath() { + assertThat(source.getPath(), is("/foo")); + source.setPath("thenewpath"); + assertThat(source.getPath(), is("thenewpath")); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamImportTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamImportTest.java index 71b91323..7c70eb51 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamImportTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamImportTest.java @@ -6,9 +6,13 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import java.util.Collection; @@ -26,40 +30,39 @@ import com.openshift.restclient.model.image.IImageStreamImport; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class ImageStreamImportTest { - private static final String VERSION = "v1"; - private static IClient client; - private IImageStreamImport stream; + private static final String VERSION = "v1"; + private static IClient client; + private IImageStreamImport stream; + + @Before + public void setup() { + client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_IMAGE_STREAM_IMPORT.getContentAsString()); + stream = new ImageStreamImport(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.IMAGE_STREAM_IMPORT)); + } + + @Test + public void testImport() { + assertFalse(stream.isImport()); + + stream.setImport(true); + assertTrue(stream.isImport()); + } + + @Test + public void testGetImageStatus() { + Collection status = stream.getImageStatus(); + assertEquals(1, status.size()); + assertEquals("Success", status.iterator().next().getStatus()); + } - @Before - public void setup(){ - client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_IMAGE_STREAM_IMPORT.getContentAsString()); - stream = new ImageStreamImport(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.IMAGE_STREAM_IMPORT)); - } - - @Test - public void testImport() { - assertFalse(stream.isImport()); - - stream.setImport(true); - assertTrue(stream.isImport()); - } - - @Test - public void testGetImageStatus() { - Collection status = stream.getImageStatus(); - assertEquals(1, status.size()); - assertEquals("Success", status.iterator().next().getStatus()); - } - - @Test - public void testGetImageJsonFor() { - assertTrue("Exp. to find the json blob for the given image", StringUtils.isNotBlank(stream.getImageJsonFor("latest"))); + @Test + public void testGetImageJsonFor() { + assertTrue("Exp. to find the json blob for the given image", + StringUtils.isNotBlank(stream.getImageJsonFor("latest"))); - assertNull("Exp. to not find the json blob", stream.getImageJsonFor("bar")); - } + assertNull("Exp. to not find the json blob", stream.getImageJsonFor("bar")); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamTest.java index 91ad6354..2f0d5abd 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ImageStreamTest.java @@ -6,9 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import java.util.Collection; @@ -28,57 +31,55 @@ import com.openshift.restclient.model.image.ITagReference; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class ImageStreamTest { - private static final String VERSION = "v1"; - private static IClient client; - private IImageStream stream; - private ModelNode node; + private static final String VERSION = "v1"; + private static IClient client; + private IImageStream stream; + private ModelNode node; + + @Before + public void setup() { + client = mock(IClient.class); + node = ModelNode.fromJSONString(Samples.V1_IMAGE_STREAM.getContentAsString()); + stream = new ImageStream(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.IMAGE_STREAM)); + } + + @Test + public void testGetTags() { + Collection tags = stream.getTags().stream().map(tr -> tr.getName()).collect(Collectors.toList()); + assertArrayEquals(new Object[] { "8.1", "latest" }, tags.toArray()); + } + + @Test + public void testAddTag() { + ITagReference tag = stream.addTag("1234", ResourceKind.IMAGE_STREAM_TAG, "foo/bar"); + Optional actTag = stream.getTags().stream().filter(t -> "1234".equals(t.getName())).findFirst(); + assertTrue("Exp. the tag to have been added", actTag.isPresent()); + assertEquals(tag.toJson(), actTag.get().toJson()); + } + + @Test + public void testAddTagWithNamespace() { + ITagReference tag = stream.addTag("1234", ResourceKind.IMAGE_STREAM_TAG, "foo/bar", "fromNmspc"); + Optional actTag = stream.getTags().stream().filter(t -> "1234".equals(t.getName())).findFirst(); + assertTrue("Exp. the tag to have been added", actTag.isPresent()); + assertEquals(tag.toJson(), actTag.get().toJson()); + } - @Before - public void setup(){ - client = mock(IClient.class); - node = ModelNode.fromJSONString(Samples.V1_IMAGE_STREAM.getContentAsString()); - stream = new ImageStream(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.IMAGE_STREAM)); - } - - @Test - public void testGetTags() { - Collection tags = stream.getTags().stream().map(tr->tr.getName()).collect(Collectors.toList()); - assertArrayEquals(new Object [] {"8.1", "latest"}, tags.toArray()); - } - - @Test - public void testAddTag() { - ITagReference tag = stream.addTag("1234", ResourceKind.IMAGE_STREAM_TAG, "foo/bar"); - Optional actTag = stream.getTags().stream().filter(t->"1234".equals(t.getName())).findFirst(); - assertTrue("Exp. the tag to have been added",actTag.isPresent()); - assertEquals(tag.toJson(), actTag.get().toJson()); - } - - @Test - public void testAddTagWithNamespace() { - ITagReference tag = stream.addTag("1234", ResourceKind.IMAGE_STREAM_TAG, "foo/bar", "fromNmspc"); - Optional actTag = stream.getTags().stream().filter(t->"1234".equals(t.getName())).findFirst(); - assertTrue("Exp. the tag to have been added",actTag.isPresent()); - assertEquals(tag.toJson(), actTag.get().toJson()); - } - - @Test - public void getDockerImageRepository() { - DockerImageURI uri = new DockerImageURI("172.30.224.48:5000/openshift/wildfly:latest"); - assertEquals(uri, stream.getDockerImageRepository()); - node.get("spec").clear(); - assertEquals(uri, stream.getDockerImageRepository()); - } + @Test + public void getDockerImageRepository() { + DockerImageURI uri = new DockerImageURI("172.30.224.48:5000/openshift/wildfly:latest"); + assertEquals(uri, stream.getDockerImageRepository()); + node.get("spec").clear(); + assertEquals(uri, stream.getDockerImageRepository()); + } - @Test - public void setDockerImageRepository() { - DockerImageURI newUri = new DockerImageURI("172.30.244.213:5000/tests/origin-ruby-sample"); - stream.setDockerImageRepository(newUri); - assertEquals(newUri, stream.getDockerImageRepository()); - } + @Test + public void setDockerImageRepository() { + DockerImageURI newUri = new DockerImageURI("172.30.244.213:5000/tests/origin-ruby-sample"); + stream.setDockerImageRepository(newUri); + assertEquals(newUri, stream.getDockerImageRepository()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/LifecycleTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/LifecycleTest.java index b5a7ca50..6b8eca82 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/LifecycleTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/LifecycleTest.java @@ -8,20 +8,22 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + import com.openshift.internal.restclient.model.ExecAction; import com.openshift.internal.restclient.model.Lifecycle; import com.openshift.restclient.model.IExecAction; import com.openshift.restclient.model.IHandler; import com.openshift.restclient.model.ILifecycle; import com.openshift.restclient.utils.Samples; -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; /** * @author Ulf Lilleengen diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ListTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ListTest.java index 841e0317..88446d11 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ListTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ListTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; @@ -28,42 +29,39 @@ import com.openshift.restclient.model.IResource; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class ListTest { - - private static final String VERSION = "v1"; - private static IClient client; - - @BeforeClass - public static void setup() throws Exception{ - client = mock(IClient.class); - when(client.getBaseURL()).thenReturn(new URL("https://localhost:8443")); - when(client.getOpenShiftAPIVersion()).thenReturn(VERSION); - when(client.getResourceFactory()).thenReturn(new ResourceFactory(client)); - } - private IList createList(Samples sample) { - ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); - return new List(node, client, null); - } - - @Test - public void testItemKindAndApiVersionAreDefined() { - IList resource = createList(Samples.V1_BUILD_CONFIG_LIST); - Collection items = resource.getItems(); - assertTrue("Expected to be entries in the list",items.size() >0 ); - IResource bc = items.iterator().next(); - assertEquals(ResourceKind.BUILD_CONFIG, bc.getKind()); - assertEquals("v1", bc.getApiVersion()); - } + private static final String VERSION = "v1"; + private static IClient client; + + @BeforeClass + public static void setup() throws Exception { + client = mock(IClient.class); + when(client.getBaseURL()).thenReturn(new URL("https://localhost:8443")); + when(client.getOpenShiftAPIVersion()).thenReturn(VERSION); + when(client.getResourceFactory()).thenReturn(new ResourceFactory(client)); + } + + private IList createList(Samples sample) { + ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); + return new List(node, client, null); + } + + @Test + public void testItemKindAndApiVersionAreDefined() { + IList resource = createList(Samples.V1_BUILD_CONFIG_LIST); + Collection items = resource.getItems(); + assertTrue("Expected to be entries in the list", items.size() > 0); + IResource bc = items.iterator().next(); + assertEquals(ResourceKind.BUILD_CONFIG, bc.getKind()); + assertEquals("v1", bc.getApiVersion()); + } - @Test - public void testEmptyList() { - IList resource = createList(Samples.V1_CONFIG_MAP_LIST_EMPTY); - Collection items = resource.getItems(); - assertEquals(0, items.size()); - } + @Test + public void testEmptyList() { + IList resource = createList(Samples.V1_CONFIG_MAP_LIST_EMPTY); + Collection items = resource.getItems(); + assertEquals(0, items.size()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ObjectRefTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ObjectRefTest.java index 0425c39c..77bf21ec 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ObjectRefTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ObjectRefTest.java @@ -6,9 +6,10 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.jboss.dmr.ModelNode; import org.junit.Before; @@ -19,65 +20,64 @@ import com.openshift.restclient.model.IObjectReference; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class ObjectRefTest { - private static final String CONTENT = Samples.V1_OBJECT_REF.getContentAsString(); - private IObjectReference objRef; - private ModelNode node; - - @Before - public void setup(){ - node = ModelNode.fromJSONString(CONTENT); - objRef = new ObjectReference(node); - } - - @Test - public void testGetKind(){ - assertEquals("ServiceAccount", objRef.getKind()); - } - - @Test - public void testSetKind() { - objRef.setKind(ResourceKind.BUILD); - assertEquals(ResourceKind.BUILD, new ObjectReference(node.clone()).getKind()); - } - - @Test - public void testGetNamespace(){ - assertEquals("test", objRef.getNamespace()); - } - - @Test - public void testSetNamespace() { - objRef.setNamespace("newnamespace"); - assertEquals("newnamespace", new ObjectReference(node.clone()).getNamespace()); - } - - @Test - public void testGetName(){ - assertEquals("builder", objRef.getName()); - } - - @Test - public void testSetName() { - objRef.setName("newname"); - assertEquals("newname", new ObjectReference(node.clone()).getName()); - } - - @Test - public void testGetUID(){ - assertEquals("ce20b132-7986-11e5-b1e5-080027bdffff", objRef.getUID()); - } - @Test - public void getResourceVersion(){ - assertEquals("33366", objRef.getResourceVersion()); - } - @Test - public void getApiVersion(){ - assertEquals("v1", objRef.getApiVersion()); - } + private static final String CONTENT = Samples.V1_OBJECT_REF.getContentAsString(); + private IObjectReference objRef; + private ModelNode node; + + @Before + public void setup() { + node = ModelNode.fromJSONString(CONTENT); + objRef = new ObjectReference(node); + } + + @Test + public void testGetKind() { + assertEquals("ServiceAccount", objRef.getKind()); + } + + @Test + public void testSetKind() { + objRef.setKind(ResourceKind.BUILD); + assertEquals(ResourceKind.BUILD, new ObjectReference(node.clone()).getKind()); + } + + @Test + public void testGetNamespace() { + assertEquals("test", objRef.getNamespace()); + } + + @Test + public void testSetNamespace() { + objRef.setNamespace("newnamespace"); + assertEquals("newnamespace", new ObjectReference(node.clone()).getNamespace()); + } + + @Test + public void testGetName() { + assertEquals("builder", objRef.getName()); + } + + @Test + public void testSetName() { + objRef.setName("newname"); + assertEquals("newname", new ObjectReference(node.clone()).getName()); + } + + @Test + public void testGetUID() { + assertEquals("ce20b132-7986-11e5-b1e5-080027bdffff", objRef.getUID()); + } + + @Test + public void getResourceVersion() { + assertEquals("33366", objRef.getResourceVersion()); + } + + @Test + public void getApiVersion() { + assertEquals("v1", objRef.getApiVersion()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java index 91066437..f03ec7f9 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java @@ -6,11 +6,15 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; +import java.util.Collections; + import org.junit.Before; import org.junit.Test; @@ -20,54 +24,48 @@ import com.openshift.restclient.model.volume.PVCAccessModes; import com.openshift.restclient.utils.Samples; -import java.util.Collections; - -/** - * @author Jeff Cantrill - */ public class PVCTest { - private static final String V1 = "v1"; - private IPersistentVolumeClaim claim; - - @Before - public void setup(){ - IClient client = mock(IClient.class); - claim = new ResourceFactory(client).create(Samples.V1_PVC.getContentAsString()); - assertEquals(V1, claim.getApiVersion()); - } - - @Test - public void testGetAccessModes(){ - assertArrayEquals(new String[] {PVCAccessModes.READ_WRITE_ONCE}, claim.getAccessModes().toArray()); - } + private static final String V1 = "v1"; + private IPersistentVolumeClaim claim; + + @Before + public void setup() { + IClient client = mock(IClient.class); + claim = new ResourceFactory(client).create(Samples.V1_PVC.getContentAsString()); + assertEquals(V1, claim.getApiVersion()); + } + + @Test + public void testGetAccessModes() { + assertArrayEquals(new String[] { PVCAccessModes.READ_WRITE_ONCE }, claim.getAccessModes().toArray()); + } + + @Test + public void testSetAccessModes() { + claim.setAccessModes(Collections.singleton(PVCAccessModes.READ_WRITE_MANY)); + assertArrayEquals(new String[] { PVCAccessModes.READ_WRITE_MANY }, claim.getAccessModes().toArray()); + } + + @Test + public void testGetStatus() { + assertEquals("Pending", claim.getStatus()); + } - @Test - public void testSetAccessModes() { - claim.setAccessModes(Collections.singleton(PVCAccessModes.READ_WRITE_MANY)); - assertArrayEquals(new String[] {PVCAccessModes.READ_WRITE_MANY}, claim.getAccessModes().toArray()); - } + @Test + public void testGetRequestedStorage() { + assertEquals("15m", claim.getRequestedStorage()); + } - - @Test - public void testGetStatus(){ - assertEquals("Pending", claim.getStatus()); - } - - @Test - public void testGetRequestedStorage(){ - assertEquals("15m", claim.getRequestedStorage()); - } + @Test + public void testSetRequestedStorage() { + claim.setRequestedStorage("1Gi"); + assertEquals("1Gi", claim.getRequestedStorage()); + } - @Test - public void testSetRequestedStorage() { - claim.setRequestedStorage("1Gi"); - assertEquals("1Gi", claim.getRequestedStorage()); - } - - @Test - public void testGetVolumeName() { - assertEquals("pv02", claim.getVolumeName()); - } + @Test + public void testGetVolumeName() { + assertEquals("pv02", claim.getVolumeName()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PVCVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PVCVolumeSourceTest.java index f6118923..cd6b90c8 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PVCVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PVCVolumeSourceTest.java @@ -8,18 +8,20 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import com.openshift.internal.restclient.model.volume.PersistentVolumeClaimVolumeSource; -import com.openshift.internal.restclient.model.volume.VolumeSource; -import com.openshift.restclient.model.volume.IPersistentVolumeClaimVolumeSource; -import com.openshift.restclient.utils.Samples; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import com.openshift.internal.restclient.model.volume.PersistentVolumeClaimVolumeSource; +import com.openshift.internal.restclient.model.volume.VolumeSource; +import com.openshift.restclient.model.volume.IPersistentVolumeClaimVolumeSource; +import com.openshift.restclient.utils.Samples; /** * @author Ulf Lilleengen diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PersistentVolumeTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PersistentVolumeTest.java index 5510d341..eb6d5491 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PersistentVolumeTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PersistentVolumeTest.java @@ -8,8 +8,13 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + import java.util.Arrays; import java.util.HashSet; import java.util.Set; @@ -30,117 +35,113 @@ import com.openshift.restclient.utils.MemoryUnit; import com.openshift.restclient.utils.Samples; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; - - public class PersistentVolumeTest { - private static final String VERSION = "v1"; - private static final Samples sample = Samples.V1_PERSISTENT_VOLUME; - private IPersistentVolume pv; - private IClient client; - - @Before - public void setUp() { - client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); - pv = new PersistentVolume(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PERSISTENT_VOLUME)); - } - - @Test - public void testGetCapacityString() { - pv.setCapacity(13L, MemoryUnit.Pi); - long capacity = pv.getCapacity("Ki"); - assertEquals(14293651161088L, capacity); - - capacity = pv.getCapacity("Ti"); - assertEquals(13312L, capacity); - - capacity = pv.getCapacity("Pi"); - assertEquals(13L, capacity); - } - - @Test - public void testGetCapacity() { - pv.setCapacity(13L, MemoryUnit.Pi); - long capacity = pv.getCapacity(); - assertEquals(14636698788954112L, capacity); - } - - @Test - public void testSetCapacity() { - pv.setCapacity(1L, MemoryUnit.Ki); - long capacity = pv.getCapacity(); - assertEquals(1024L, capacity); - - pv.setCapacity(31L, MemoryUnit.Ti); - capacity = pv.getCapacity(MemoryUnit.Ti); - assertEquals(31L, capacity); - } - - @Test(expected = ArithmeticException.class) - public void testSetCapacityOverflow() { - /* - * 2^4 * 2 ^60 = 2^64, LONG_MAX is only 2^64-1 - */ - pv.setCapacity(16L, MemoryUnit.Ei); - pv.getCapacity(); - } - - @Test - public void testGetCapacityUnit() { - pv.setCapacity(1L, MemoryUnit.Ki); - MemoryUnit unit = pv.getCapacityUnit(); - assertEquals(MemoryUnit.Ki, unit); - - pv.setCapacity(1L, MemoryUnit.Pi); - unit = pv.getCapacityUnit(); - assertEquals(MemoryUnit.Pi, unit); - } - - @Test - public void testAccessModes() { - pv.setAccessModes("ReadWriteOnce"); - Set modes = pv.getAccessModes(); - assertTrue(modes.contains("ReadWriteOnce")); - - pv.setAccessModes("ReadWriteOnce", "ReadOnlyMany", "ReadWriteMany"); - modes = pv.getAccessModes(); - Set expected = new HashSet<>(); - expected.addAll(Arrays.asList("ReadWriteOnce", "ReadOnlyMany", "ReadWriteMany")); - assertTrue(modes.containsAll(expected)); - } - - @Test - public void testReclaimPolicy() { - pv.setReclaimPolicy("Recycle"); - String policy = pv.getReclaimPolicy(); - assertEquals(policy, "Recycle"); - } - - @Test - public void testGetPersistentVolumeProperties() { - pv.getPersistentVolumeProperties(); - - } - - @Test - public void testNFSVolume() { - INfsVolumeProperties volume = new NfsVolumeProperties("10.10.10.10", "/tmp/dir", true); - pv.setPersistentVolumeProperties(volume); - volume = (INfsVolumeProperties) pv.getPersistentVolumeProperties(); - assertEquals("/tmp/dir", volume.getPath()); - assertEquals("10.10.10.10", volume.getServer()); - assertEquals(true, volume.isReadOnly()); - } - - @Test - public void testHostPathVolume() { - IHostPathVolumeProperties volume = new HostPathVolumeProperties("/tmp/dir"); - pv.setPersistentVolumeProperties(volume); - volume = (IHostPathVolumeProperties) pv.getPersistentVolumeProperties(); - assertEquals("/tmp/dir", volume.getPath()); - } + private static final String VERSION = "v1"; + private static final Samples sample = Samples.V1_PERSISTENT_VOLUME; + private IPersistentVolume pv; + private IClient client; + + @Before + public void setUp() { + client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); + pv = new PersistentVolume(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PERSISTENT_VOLUME)); + } + + @Test + public void testGetCapacityString() { + pv.setCapacity(13L, MemoryUnit.Pi); + long capacity = pv.getCapacity("Ki"); + assertEquals(14293651161088L, capacity); + + capacity = pv.getCapacity("Ti"); + assertEquals(13312L, capacity); + + capacity = pv.getCapacity("Pi"); + assertEquals(13L, capacity); + } + + @Test + public void testGetCapacity() { + pv.setCapacity(13L, MemoryUnit.Pi); + long capacity = pv.getCapacity(); + assertEquals(14636698788954112L, capacity); + } + + @Test + public void testSetCapacity() { + pv.setCapacity(1L, MemoryUnit.Ki); + long capacity = pv.getCapacity(); + assertEquals(1024L, capacity); + + pv.setCapacity(31L, MemoryUnit.Ti); + capacity = pv.getCapacity(MemoryUnit.Ti); + assertEquals(31L, capacity); + } + + @Test(expected = ArithmeticException.class) + public void testSetCapacityOverflow() { + /* + * 2^4 * 2 ^60 = 2^64, LONG_MAX is only 2^64-1 + */ + pv.setCapacity(16L, MemoryUnit.Ei); + pv.getCapacity(); + } + + @Test + public void testGetCapacityUnit() { + pv.setCapacity(1L, MemoryUnit.Ki); + MemoryUnit unit = pv.getCapacityUnit(); + assertEquals(MemoryUnit.Ki, unit); + + pv.setCapacity(1L, MemoryUnit.Pi); + unit = pv.getCapacityUnit(); + assertEquals(MemoryUnit.Pi, unit); + } + + @Test + public void testAccessModes() { + pv.setAccessModes("ReadWriteOnce"); + Set modes = pv.getAccessModes(); + assertTrue(modes.contains("ReadWriteOnce")); + + pv.setAccessModes("ReadWriteOnce", "ReadOnlyMany", "ReadWriteMany"); + modes = pv.getAccessModes(); + Set expected = new HashSet<>(); + expected.addAll(Arrays.asList("ReadWriteOnce", "ReadOnlyMany", "ReadWriteMany")); + assertTrue(modes.containsAll(expected)); + } + + @Test + public void testReclaimPolicy() { + pv.setReclaimPolicy("Recycle"); + String policy = pv.getReclaimPolicy(); + assertEquals(policy, "Recycle"); + } + + @Test + public void testGetPersistentVolumeProperties() { + pv.getPersistentVolumeProperties(); + + } + + @Test + public void testNFSVolume() { + INfsVolumeProperties volume = new NfsVolumeProperties("10.10.10.10", "/tmp/dir", true); + pv.setPersistentVolumeProperties(volume); + volume = (INfsVolumeProperties) pv.getPersistentVolumeProperties(); + assertEquals("/tmp/dir", volume.getPath()); + assertEquals("10.10.10.10", volume.getServer()); + assertEquals(true, volume.isReadOnly()); + } + + @Test + public void testHostPathVolume() { + IHostPathVolumeProperties volume = new HostPathVolumeProperties("/tmp/dir"); + pv.setPersistentVolumeProperties(volume); + volume = (IHostPathVolumeProperties) pv.getPersistentVolumeProperties(); + assertEquals("/tmp/dir", volume.getPath()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java index a599bc41..fc6a3c79 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.fest.assertions.Assertions.assertThat; @@ -44,156 +45,138 @@ */ public class PipelineBuildConfigTest { - private static final String VERSION = "v1"; - - private IBuildConfig pipelineBc; - private IBuildConfigBuilder builder; - - @Before - public void setup() throws Exception{ - this.pipelineBc = createBuildConfig(Samples.V1_BUILDCONFIG_PIPELINE.getContentAsString()); - this.builder = createBuilder(); - } - - private IBuildConfig createBuildConfig(String content) throws MalformedURLException { - IClient client = createClient(); - BuildConfig bc = new BuildConfig(ModelNode.fromJSONString(content), client, null); - IResourceFactory factory = createResourceFactoryFor(bc); - when(client.getResourceFactory()).thenReturn(factory); - return bc; - } - - private IBuildConfigBuilder createBuilder() throws MalformedURLException { - IClient client = createClient(); - IBuildConfig bc = new BuildConfig(new ModelNode(), client, null); - IResourceFactory factory = createResourceFactoryFor(bc); - when(client.getResourceFactory()).thenReturn(factory); - - return new BuildConfigBuilder(client) - .named("foor") - .inNamespace("bar"); - } - - private IClient createClient() throws MalformedURLException { - IClient client = mock(IClient.class); - doReturn(new URL("https://localhost:8443")).when(client).getBaseURL(); - doReturn(VERSION).when(client).getOpenShiftAPIVersion(); - return client; - } - - private IResourceFactory createResourceFactoryFor(IBuildConfig bc) { - IResourceFactory factory = mock(IResourceFactory.class); - when(factory.stub(eq(ResourceKind.BUILD_CONFIG), anyString(), anyString())).thenReturn(bc); - return factory; - } - - @Test - public void shouldHaveJenkinsPipelineBuildStrategy() { - // given - // when - IBuildStrategy strategy = pipelineBc.getBuildStrategy(); - // then - assertThat(strategy).isNotNull(); - assertThat(strategy.getType()).isEqualTo(BuildStrategyType.JENKINS_PIPELINE); - } - - @Test - public void shouldHaveJenkinsfile() { - // given - // when - IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); - // then - assertThat(strategy.getJenkinsfile()).isNotEmpty(); - } - - @Test - public void shouldHaveJenkinsfileGivenItWasSet() { - // given - IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); - // when - strategy.setJenkinsfile("fooBar"); - // then - assertThat(strategy.getJenkinsfile()).isEqualTo("fooBar"); - } - - @Test - public void shouldHaveJenkinsfilePath() { - // given - // when - IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); - // then - assertThat(strategy.getJenkinsfilePath()).isNotEmpty(); - } - - @Test - public void shouldHaveJenkinsfilePathGivenItWasSet() { - // given - IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); - // when - strategy.setJenkinsfilePath("/foo/bar"); - // then - assertThat(strategy.getJenkinsfilePath()).isEqualTo("/foo/bar"); - } - - @Test - public void shouldHaveEnvVars() { - // given - // when - IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); - // then - assertThat(strategy.getEnvVars()).containsOnly( - new EnvironmentVariable(new ModelNodeBuilder() - .set("name", "foo") - .set("value", "bar") - .build(), null), - new EnvironmentVariable(new ModelNodeBuilder() - .set("name", "kung") - .set("value", "foo") - .build(), null) - ); - } - - @Test - public void shouldHaveEnvVarsThatWereSet() { - // given - IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); - IEnvironmentVariable envVar = new EnvironmentVariable(new ModelNodeBuilder() - .set("name", "gargamel") - .set("value", "crazyLad") - .build(), null); - List envVars = Arrays.asList(envVar); - // when - strategy.setEnvVars(envVars); - // then - assertThat(strategy.getEnvVars()).containsOnly(envVar); - } - - @Test - public void shouldBuildJenkinsPipelineStrategyBuildConfig() { - // given - // when - IBuildConfig bc = builder - .usingJenkinsPipelineStrategy() - .end() - .build(); - // then - IBuildStrategy strategy = bc.getBuildStrategy(); - assertThat(strategy).isInstanceOf(IJenkinsPipelineStrategy.class); - } - - @Test - public void shouldBuildJenkinsPipelineStrategyWithJenkinsfileAndPath() { - // given - // when - IBuildConfig bc = builder - .usingJenkinsPipelineStrategy() - .usingFile("node('aNode') {}") - .usingFilePath("some/path/to/some/location") - .end() - .build(); - // then - IJenkinsPipelineStrategy strategy = bc.getBuildStrategy(); - assertThat(strategy.getJenkinsfile()).isEqualTo("node('aNode') {}"); - assertThat(strategy.getJenkinsfilePath()).isEqualTo("some/path/to/some/location"); - } + private static final String VERSION = "v1"; + + private IBuildConfig pipelineBc; + private IBuildConfigBuilder builder; + + @Before + public void setup() throws Exception { + this.pipelineBc = createBuildConfig(Samples.V1_BUILDCONFIG_PIPELINE.getContentAsString()); + this.builder = createBuilder(); + } + + private IBuildConfig createBuildConfig(String content) throws MalformedURLException { + IClient client = createClient(); + BuildConfig bc = new BuildConfig(ModelNode.fromJSONString(content), client, null); + IResourceFactory factory = createResourceFactoryFor(bc); + when(client.getResourceFactory()).thenReturn(factory); + return bc; + } + + private IBuildConfigBuilder createBuilder() throws MalformedURLException { + IClient client = createClient(); + IBuildConfig bc = new BuildConfig(new ModelNode(), client, null); + IResourceFactory factory = createResourceFactoryFor(bc); + when(client.getResourceFactory()).thenReturn(factory); + + return new BuildConfigBuilder(client).named("foor").inNamespace("bar"); + } + + private IClient createClient() throws MalformedURLException { + IClient client = mock(IClient.class); + doReturn(new URL("https://localhost:8443")).when(client).getBaseURL(); + doReturn(VERSION).when(client).getOpenShiftAPIVersion(); + return client; + } + + private IResourceFactory createResourceFactoryFor(IBuildConfig bc) { + IResourceFactory factory = mock(IResourceFactory.class); + when(factory.stub(eq(ResourceKind.BUILD_CONFIG), anyString(), anyString())).thenReturn(bc); + return factory; + } + + @Test + public void shouldHaveJenkinsPipelineBuildStrategy() { + // given + // when + IBuildStrategy strategy = pipelineBc.getBuildStrategy(); + // then + assertThat(strategy).isNotNull(); + assertThat(strategy.getType()).isEqualTo(BuildStrategyType.JENKINS_PIPELINE); + } + + @Test + public void shouldHaveJenkinsfile() { + // given + // when + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // then + assertThat(strategy.getJenkinsfile()).isNotEmpty(); + } + + @Test + public void shouldHaveJenkinsfileGivenItWasSet() { + // given + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // when + strategy.setJenkinsfile("fooBar"); + // then + assertThat(strategy.getJenkinsfile()).isEqualTo("fooBar"); + } + + @Test + public void shouldHaveJenkinsfilePath() { + // given + // when + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // then + assertThat(strategy.getJenkinsfilePath()).isNotEmpty(); + } + + @Test + public void shouldHaveJenkinsfilePathGivenItWasSet() { + // given + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // when + strategy.setJenkinsfilePath("/foo/bar"); + // then + assertThat(strategy.getJenkinsfilePath()).isEqualTo("/foo/bar"); + } + + @Test + public void shouldHaveEnvVars() { + // given + // when + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + // then + assertThat(strategy.getEnvVars()).containsOnly( + new EnvironmentVariable(new ModelNodeBuilder().set("name", "foo").set("value", "bar").build(), null), + new EnvironmentVariable(new ModelNodeBuilder().set("name", "kung").set("value", "foo").build(), null)); + } + + @Test + public void shouldHaveEnvVarsThatWereSet() { + // given + IJenkinsPipelineStrategy strategy = pipelineBc.getBuildStrategy(); + IEnvironmentVariable envVar = new EnvironmentVariable( + new ModelNodeBuilder().set("name", "gargamel").set("value", "crazyLad").build(), null); + List envVars = Arrays.asList(envVar); + // when + strategy.setEnvVars(envVars); + // then + assertThat(strategy.getEnvVars()).containsOnly(envVar); + } + + @Test + public void shouldBuildJenkinsPipelineStrategyBuildConfig() { + // given + // when + IBuildConfig bc = builder.usingJenkinsPipelineStrategy().end().build(); + // then + IBuildStrategy strategy = bc.getBuildStrategy(); + assertThat(strategy).isInstanceOf(IJenkinsPipelineStrategy.class); + } + + @Test + public void shouldBuildJenkinsPipelineStrategyWithJenkinsfileAndPath() { + // given + // when + IBuildConfig bc = builder.usingJenkinsPipelineStrategy().usingFile("node('aNode') {}") + .usingFilePath("some/path/to/some/location").end().build(); + // then + IJenkinsPipelineStrategy strategy = bc.getBuildStrategy(); + assertThat(strategy.getJenkinsfile()).isEqualTo("node('aNode') {}"); + assertThat(strategy.getJenkinsfilePath()).isEqualTo("some/path/to/some/location"); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index 46ad785f..c0d520f3 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertArrayEquals; @@ -36,154 +37,147 @@ import com.openshift.restclient.model.IPort; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class PodTest { - private static final String VERSION = "v1"; - private IPod pod; - private IContainer container1; - - @Before - public void setup() { - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_POD.getContentAsString()); - this.pod = new Pod(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.POD)); - this.container1 = pod.getContainers().stream().findFirst().orElse(null); - } - - @Test - public void testGetHost() { - assertEquals("127.0.0.1", pod.getHost()); - } - - @Test - public void testGetStatusPhase() { - assertEquals("Running", pod.getStatus()); - } - - @Test - public void testGetStatusDeletion() { - ((Pod)pod).getNode().get("metadata", "deletionTimestamp").set("2016-11-02T16:31:55Z"); - assertEquals(pod.getStatus(), "Terminating"); - } - - @Test - public void testGetStatusWaitingReason() { - ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") - .set("waiting", new ModelNode().set("reason", "ReasonNotToWork")); - assertEquals(pod.getStatus(), "ReasonNotToWork"); - } - - @Test - public void testGetStatusTerminateReason() { - ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") - .set("terminated", new ModelNode().set("reason", "ReasonToTerminate")); - assertEquals(pod.getStatus(), "ReasonToTerminate"); - } - - /** - * Check that if both reason and exit code are set, status returns the reason. - */ - @Test - public void testGetStatusTerminateReasonAndExit() { - ModelNode node = new ModelNode(); - node.get("reason").set("ReasonToTerminate"); - node.get("exitCode").set("Let's go! Time to exit!"); - ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") - .set("terminated", node); - assertEquals(pod.getStatus(), "ReasonToTerminate"); - } - - @Test - public void testGetStatusTerminatedSignal() { - ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") - .set("terminated", new ModelNode().set("signal", "Alarm! Terminate!")); - assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); - } - - /** - * Check that if both signal and exit code are set, status returns the signal. - */ - @Test - public void testGetStatusTerminatedSignalAndExit() { - ModelNode node = new ModelNode(); - node.get("signal").set("Alarm! Terminate!"); - node.get("exitCode").set("Let's go! Time to exit!"); - ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") - .set("terminated", node); - assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); - } - - @Test - public void testGetStatusTerminatedExit() { - ((Pod)pod).getNode().get("status", "containerStatuses").asList().get(0).get("state") - .set("terminated", new ModelNode().set("exitCode", "Let's go! Time to exit!")); - assertEquals(pod.getStatus(), "Exit Code: Let's go! Time to exit!"); - } - - @Test - public void testGetImages() { - String [] exp = new String []{"openshift/origin-deployer:v0.6"}; - assertArrayEquals(exp, pod.getImages().toArray()); - } - - @Test - public void getIP() { - assertEquals("1.2.3.4", pod.getIP()); - } - - @Test - public void getContainerPorts() { - Set ports = new HashSet(); - Port port = new Port(new ModelNode()); - port.setName("http"); - port.setProtocol("TCP"); - port.setContainerPort(8080); - ports.add(port); - assertEquals(ports, pod.getContainerPorts()); - } - - @Test - public void testAddContainer() { - Collection initial = pod.getContainers(); - IContainer foo = pod.addContainer("foo"); - - - foo.setLifecycle(new Lifecycle.Builder() - .preStop(new ExecAction.Builder() - .command("cmd1") - .command("cmd2") - .build()) - .build()); - - Collection containers = pod.getContainers(); - assertEquals(initial.size() + 1, containers.size()); - - Optional container = containers.stream().filter(c->"foo".equals(c.getName()) && "cmd1".equals(((IExecAction)c.getLifecycle().getPreStop().get()).getCommand().get(0))).findFirst(); - assertTrue("Exp. the container to be added", container.isPresent()); - } - - @Test - public void getContainerCommands() { - List cmd = container1.getCommand(); - List cmdArgs = container1.getCommandArgs(); - assertEquals(cmd.get(0),"/bin/sh"); - assertEquals(cmdArgs.get(0), "-c"); - assertEquals(cmdArgs.get(1), "echo 'hello'"); - } - - @Test - public void getContainerResourceRequirements() { + private static final String VERSION = "v1"; + private IPod pod; + private IContainer container1; + + @Before + public void setup() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_POD.getContentAsString()); + this.pod = new Pod(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.POD)); + this.container1 = pod.getContainers().stream().findFirst().orElse(null); + } + + @Test + public void testGetHost() { + assertEquals("127.0.0.1", pod.getHost()); + } + + @Test + public void testGetStatusPhase() { + assertEquals("Running", pod.getStatus()); + } + + @Test + public void testGetStatusDeletion() { + ((Pod) pod).getNode().get("metadata", "deletionTimestamp").set("2016-11-02T16:31:55Z"); + assertEquals(pod.getStatus(), "Terminating"); + } + + @Test + public void testGetStatusWaitingReason() { + ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("waiting", + new ModelNode().set("reason", "ReasonNotToWork")); + assertEquals(pod.getStatus(), "ReasonNotToWork"); + } + + @Test + public void testGetStatusTerminateReason() { + ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", + new ModelNode().set("reason", "ReasonToTerminate")); + assertEquals(pod.getStatus(), "ReasonToTerminate"); + } + + /** + * Check that if both reason and exit code are set, status returns the reason. + */ + @Test + public void testGetStatusTerminateReasonAndExit() { + ModelNode node = new ModelNode(); + node.get("reason").set("ReasonToTerminate"); + node.get("exitCode").set("Let's go! Time to exit!"); + ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", node); + assertEquals(pod.getStatus(), "ReasonToTerminate"); + } + + @Test + public void testGetStatusTerminatedSignal() { + ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", + new ModelNode().set("signal", "Alarm! Terminate!")); + assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); + } + + /** + * Check that if both signal and exit code are set, status returns the signal. + */ + @Test + public void testGetStatusTerminatedSignalAndExit() { + ModelNode node = new ModelNode(); + node.get("signal").set("Alarm! Terminate!"); + node.get("exitCode").set("Let's go! Time to exit!"); + ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", node); + assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); + } + + @Test + public void testGetStatusTerminatedExit() { + ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", + new ModelNode().set("exitCode", "Let's go! Time to exit!")); + assertEquals(pod.getStatus(), "Exit Code: Let's go! Time to exit!"); + } + + @Test + public void testGetImages() { + String[] exp = new String[] { "openshift/origin-deployer:v0.6" }; + assertArrayEquals(exp, pod.getImages().toArray()); + } + + @Test + public void getIP() { + assertEquals("1.2.3.4", pod.getIP()); + } + + @Test + public void getContainerPorts() { + Port port = new Port(new ModelNode()); + port.setName("http"); + port.setProtocol("TCP"); + port.setContainerPort(8080); + Set ports = new HashSet<>(); + ports.add(port); + assertEquals(ports, pod.getContainerPorts()); + } + + @Test + public void testAddContainer() { + Collection initial = pod.getContainers(); + IContainer foo = pod.addContainer("foo"); + + foo.setLifecycle(new Lifecycle.Builder() + .preStop(new ExecAction.Builder().command("cmd1").command("cmd2").build()).build()); + + Collection containers = pod.getContainers(); + assertEquals(initial.size() + 1, containers.size()); + + Optional container = containers.stream() + .filter(c -> "foo".equals(c.getName()) + && "cmd1".equals(((IExecAction) c.getLifecycle().getPreStop().get()).getCommand().get(0))) + .findFirst(); + assertTrue("Exp. the container to be added", container.isPresent()); + } + + @Test + public void getContainerCommands() { + List cmd = container1.getCommand(); + List cmdArgs = container1.getCommandArgs(); + assertEquals(cmd.get(0), "/bin/sh"); + assertEquals(cmdArgs.get(0), "-c"); + assertEquals(cmdArgs.get(1), "echo 'hello'"); + } + + @Test + public void getContainerResourceRequirements() { assertEquals("1", container1.getRequestsCPU()); assertEquals("128Mi", container1.getRequestsMemory()); assertEquals("4", container1.getLimitsCPU()); assertEquals("1Gi", container1.getLimitsMemory()); - } + } - @Test - public void resetContainerResourceRequirements() { + @Test + public void resetContainerResourceRequirements() { container1.setRequestsMemory(null); container1.setRequestsCPU(null); container1.setLimitsMemory(null); @@ -192,5 +186,5 @@ public void resetContainerResourceRequirements() { assertEquals("", container1.getRequestsMemory()); assertEquals("", container1.getLimitsCPU()); assertEquals("", container1.getLimitsMemory()); - } + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ProjectRequestTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ProjectRequestTest.java index a7b0ef22..14e1b7a2 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ProjectRequestTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ProjectRequestTest.java @@ -6,12 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; - import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; @@ -25,39 +25,39 @@ /** * Test to validate the lookup paths are correct for the version - * @author Jeff Cantrill */ -public class ProjectRequestTest{ - - private static final String VERSION = "v1"; - private IProjectRequest request; - - @Before - public void setUp(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_PROJECT_REQUEST.getContentAsString()); - request = new OpenshiftProjectRequest(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PROJECT_REQUEST)); - } - - @Test - public void setDisplayName() { - request.setDisplayName("the other display name"); - assertEquals("the other display name", request.getDisplayName()); - } - - @Test - public void testGetDisplayName() { - assertEquals("the display name", request.getDisplayName()); - } - - @Test - public void testGetDescription() { - assertEquals("The project description", request.getDescription()); - } - - @Test - public void testSetDescription() { - request.setDescription("The other project description"); - assertEquals("The other project description", request.getDescription()); - } +public class ProjectRequestTest { + + private static final String VERSION = "v1"; + private IProjectRequest request; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_PROJECT_REQUEST.getContentAsString()); + request = new OpenshiftProjectRequest(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PROJECT_REQUEST)); + } + + @Test + public void setDisplayName() { + request.setDisplayName("the other display name"); + assertEquals("the other display name", request.getDisplayName()); + } + + @Test + public void testGetDisplayName() { + assertEquals("the display name", request.getDisplayName()); + } + + @Test + public void testGetDescription() { + assertEquals("The project description", request.getDescription()); + } + + @Test + public void testSetDescription() { + request.setDescription("The other project description"); + assertEquals("The other project description", request.getDescription()); + } } \ No newline at end of file diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ProjectTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ProjectTest.java index 6e8ef73d..9ef559e6 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ProjectTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ProjectTest.java @@ -6,12 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; - import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; @@ -25,27 +25,27 @@ /** * Test to validate the lookup paths are correct for the version - * @author Jeff Cantrill */ -public class ProjectTest{ - - private static final String VERSION = "v1"; - private IProject project; - - @Before - public void setUp(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_PROJECT.getContentAsString()); - project = new Project(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PROJECT)); - } - - @Test - public void testGetDisplayName() { - assertEquals("OpenShift 3 Sample", project.getDisplayName()); - } - - @Test - public void testGetDescription() { - assertEquals("This is an example project to demonstrate OpenShift v3", project.getDescription()); - } +public class ProjectTest { + + private static final String VERSION = "v1"; + private IProject project; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_PROJECT.getContentAsString()); + project = new Project(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PROJECT)); + } + + @Test + public void testGetDisplayName() { + assertEquals("OpenShift 3 Sample", project.getDisplayName()); + } + + @Test + public void testGetDescription() { + assertEquals("This is an example project to demonstrate OpenShift v3", project.getDescription()); + } } \ No newline at end of file diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java index 1ff2a40a..d098f7ab 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java @@ -6,11 +6,12 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static com.openshift.internal.util.JBossDmrExtentions.getPath; import static org.fest.assertions.Assertions.assertThat; -import static org.fest.assertions.MapAssert.*; +import static org.fest.assertions.MapAssert.entry; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -56,304 +57,298 @@ import com.openshift.restclient.model.volume.IVolumeSource; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class ReplicationControllerTest { - private static final String VERSION = "v1"; - private static IReplicationController rc; - private static ModelNode node; - private static IClient client; - - @Before - public void setup(){ - client = mock(IClient.class); - node = ModelNode.fromJSONString(Samples.V1_REPLICATION_CONTROLLER.getContentAsString()); - rc = new ReplicationController(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.REPLICATION_CONTROLLER)); - } - - public void testGetEnvironmentVariablesWithValueFrom() { - - Collection envVars = rc.getEnvironmentVariables(); - - //fieldref - Optional envVar = envVars.stream().filter(e->"OPENSHIFT_KUBE_PING_NAMESPACE".equals(e.getName())).findFirst(); - assertTrue("Exp. to find env var", envVar.isPresent()); - IEnvVarSource from = envVar.get().getValueFrom(); - assertTrue(from instanceof IObjectFieldSelector); - IObjectFieldSelector selector = (IObjectFieldSelector)from; - assertEquals("v1",selector.getApiVersion()); - assertEquals("metadata.namespace",selector.getFieldPath()); - - //configmapkeyref - envVar = envVars.stream().filter(e->"OPENSHIFT_CONFIGMAP_KEY_REF".equals(e.getName())).findFirst(); - assertTrue("Exp. to find env var", envVar.isPresent()); - from = envVar.get().getValueFrom(); - assertTrue(from instanceof IConfigMapKeySelector); - IConfigMapKeySelector configSelector = (IConfigMapKeySelector) from; - assertEquals("xyz",configSelector.getName()); - assertEquals("abc123",configSelector.getKey()); - - //secretkeyref - envVar = envVars.stream().filter(e->"OPENSHIFT_SECRET_KEY_REF".equals(e.getName())).findFirst(); - assertTrue("Exp. to find env var", envVar.isPresent()); - from = envVar.get().getValueFrom(); - assertTrue(from instanceof ISecretKeySelector); - ISecretKeySelector secretKeySelector = (ISecretKeySelector) from; - assertEquals("bar",secretKeySelector.getName()); - assertEquals("foo",secretKeySelector.getKey()); - } - - @Test - public void testEnvironmentVariable() { - //add - rc.setEnvironmentVariable("foo", "bar"); - Collection envVars = rc.getEnvironmentVariables(); - Optional envVar = envVars.stream().filter(e->"foo".equals(e.getName())).findFirst(); - assertTrue("Exp. to find env var", envVar.isPresent()); - assertEquals("bar", envVar.get().getValue()); - - //update - int size = rc.getEnvironmentVariables().size(); - rc.setEnvironmentVariable("foo", "baz"); - assertEquals(size, rc.getEnvironmentVariables().size()); - envVars = rc.getEnvironmentVariables(); - envVar = envVars.stream().filter(e->"foo".equals(e.getName())).findFirst(); - assertEquals("baz", envVar.get().getValue()); - - rc.removeEnvironmentVariable("foo"); - assertEquals(size - 1, rc.getEnvironmentVariables().size()); - } - - @Test - public void testEnvironmentVariableFromMissingEnv() { - String[] path = getPath(ReplicationController.SPEC_TEMPLATE_CONTAINERS); - ModelNode containers = node.get(path); - containers.get(0).remove("env"); - testEnvironmentVariable(); - } - - @Test - public void testEnvironmentVariableForANamedContainer() { - rc.setEnvironmentVariable("ruby-helloworld-database", "fooz", "balls"); - Collection envVars = rc.getEnvironmentVariables("ruby-helloworld-database"); - Optional envVar = envVars.stream().filter(e->"fooz".equals(e.getName())).findFirst(); - assertTrue("Exp. to find env var", envVar.isPresent()); - assertEquals("balls", envVar.get().getValue()); - } - - @Test - public void setReplicaSelector() { - Map exp = new HashMap<>(); - exp.put("foo", "bar"); - rc.setReplicaSelector(exp); - assertEquals(exp, rc.getReplicaSelector()); - } - - @Test - public void setReplicaSelectorFromMissingSelector() { - String[] path = new String[]{"status"}; - node.get(path).clear(); - setReplicaSelector(); - } - - - @Test - public void setReplicaSelectorWithKeyValue() { - Map exp = new HashMap<>(); - exp.put("foo", "bar"); - rc.setReplicaSelector("foo","bar"); - assertEquals(exp, rc.getReplicaSelector()); - } - - @Test - public void getReplicaSelector() { - Map labels = new HashMap<>(); - labels.put("name", "database"); - labels.put("deployment", "database-1"); - labels.put("deploymentconfig", "database"); - assertEquals(labels, rc.getReplicaSelector()); - } - - @Test + private static final String VERSION = "v1"; + private static IReplicationController rc; + private static ModelNode node; + private static IClient client; + + @Before + public void setup() { + client = mock(IClient.class); + node = ModelNode.fromJSONString(Samples.V1_REPLICATION_CONTROLLER.getContentAsString()); + rc = new ReplicationController(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.REPLICATION_CONTROLLER)); + } + + public void testGetEnvironmentVariablesWithValueFrom() { + + Collection envVars = rc.getEnvironmentVariables(); + + // fieldref + Optional envVar = envVars.stream() + .filter(e -> "OPENSHIFT_KUBE_PING_NAMESPACE".equals(e.getName())).findFirst(); + assertTrue("Exp. to find env var", envVar.isPresent()); + IEnvVarSource from = envVar.get().getValueFrom(); + assertTrue(from instanceof IObjectFieldSelector); + IObjectFieldSelector selector = (IObjectFieldSelector) from; + assertEquals("v1", selector.getApiVersion()); + assertEquals("metadata.namespace", selector.getFieldPath()); + + // configmapkeyref + envVar = envVars.stream().filter(e -> "OPENSHIFT_CONFIGMAP_KEY_REF".equals(e.getName())).findFirst(); + assertTrue("Exp. to find env var", envVar.isPresent()); + from = envVar.get().getValueFrom(); + assertTrue(from instanceof IConfigMapKeySelector); + IConfigMapKeySelector configSelector = (IConfigMapKeySelector) from; + assertEquals("xyz", configSelector.getName()); + assertEquals("abc123", configSelector.getKey()); + + // secretkeyref + envVar = envVars.stream().filter(e -> "OPENSHIFT_SECRET_KEY_REF".equals(e.getName())).findFirst(); + assertTrue("Exp. to find env var", envVar.isPresent()); + from = envVar.get().getValueFrom(); + assertTrue(from instanceof ISecretKeySelector); + ISecretKeySelector secretKeySelector = (ISecretKeySelector) from; + assertEquals("bar", secretKeySelector.getName()); + assertEquals("foo", secretKeySelector.getKey()); + } + + @Test + public void testEnvironmentVariable() { + // add + rc.setEnvironmentVariable("foo", "bar"); + Collection envVars = rc.getEnvironmentVariables(); + Optional envVar = envVars.stream().filter(e -> "foo".equals(e.getName())).findFirst(); + assertTrue("Exp. to find env var", envVar.isPresent()); + assertEquals("bar", envVar.get().getValue()); + + // update + int size = rc.getEnvironmentVariables().size(); + rc.setEnvironmentVariable("foo", "baz"); + assertEquals(size, rc.getEnvironmentVariables().size()); + envVars = rc.getEnvironmentVariables(); + envVar = envVars.stream().filter(e -> "foo".equals(e.getName())).findFirst(); + assertEquals("baz", envVar.get().getValue()); + + rc.removeEnvironmentVariable("foo"); + assertEquals(size - 1, rc.getEnvironmentVariables().size()); + } + + @Test + public void testEnvironmentVariableFromMissingEnv() { + String[] path = getPath(ReplicationController.SPEC_TEMPLATE_CONTAINERS); + ModelNode containers = node.get(path); + containers.get(0).remove("env"); + testEnvironmentVariable(); + } + + @Test + public void testEnvironmentVariableForANamedContainer() { + rc.setEnvironmentVariable("ruby-helloworld-database", "fooz", "balls"); + Collection envVars = rc.getEnvironmentVariables("ruby-helloworld-database"); + Optional envVar = envVars.stream().filter(e -> "fooz".equals(e.getName())).findFirst(); + assertTrue("Exp. to find env var", envVar.isPresent()); + assertEquals("balls", envVar.get().getValue()); + } + + @Test + public void setReplicaSelector() { + Map exp = new HashMap<>(); + exp.put("foo", "bar"); + rc.setReplicaSelector(exp); + assertEquals(exp, rc.getReplicaSelector()); + } + + @Test + public void setReplicaSelectorFromMissingSelector() { + String[] path = new String[] { "status" }; + node.get(path).clear(); + setReplicaSelector(); + } + + @Test + public void setReplicaSelectorWithKeyValue() { + Map exp = new HashMap<>(); + exp.put("foo", "bar"); + rc.setReplicaSelector("foo", "bar"); + assertEquals(exp, rc.getReplicaSelector()); + } + + @Test + public void getReplicaSelector() { + Map labels = new HashMap<>(); + labels.put("name", "database"); + labels.put("deployment", "database-1"); + labels.put("deploymentconfig", "database"); + assertEquals(labels, rc.getReplicaSelector()); + } + + @Test public void getServiceAccountName() { assertEquals("dbServiceAccountName", rc.getServiceAccountName()); } - - @Test + + @Test public void setServiceAccountName() { - rc.setServiceAccountName("newDBServiceAccountName"); + rc.setServiceAccountName("newDBServiceAccountName"); assertEquals("newDBServiceAccountName", rc.getServiceAccountName()); } - - @Test - public void getDesiredReplicaCount(){ - assertEquals(1, rc.getDesiredReplicaCount()); - } - - @Test - public void setDesiredReplicaCount(){ - rc.setDesiredReplicaCount(9); - assertEquals(9, rc.getDesiredReplicaCount()); - - rc.setReplicas(6); - assertEquals(6, rc.getDesiredReplicaCount()); - } - - @Test - public void getCurrentReplicaCount(){ - assertEquals(2, rc.getCurrentReplicaCount()); - } - - @Test - public void testGetImages(){ - String [] exp = new String []{"openshift/mysql-55-centos7:latest"}; - assertArrayEquals(exp , rc.getImages().toArray()); - } - - @Test - public void testGetContainer() { - assertNull(rc.getContainer(" ")); - assertNotNull(rc.getContainer("ruby-helloworld-database")); - } - @Test - public void testGetContainers() { - Collection containers = rc.getContainers(); - assertNotNull(containers); - assertEquals(1, containers.size()); - - String[] path = getPath(ReplicationController.SPEC_TEMPLATE_CONTAINERS); - node.get(path).clear(); - assertNotNull(rc.getContainers()); - } - - @Test - public void testAddContainer() throws JSONException { - //remove containers hack - String[] path = getPath(ReplicationController.SPEC_TEMPLATE_CONTAINERS); - node.get(path).clear(); - //setup - DockerImageURI uri = new DockerImageURI("aproject/an_image_name"); - IPort port = mock(IPort.class); - when(port.getProtocol()).thenReturn("TCP"); - when(port.getContainerPort()).thenReturn(8080); - Set ports = new HashSet<>(); - ports.add(port); - - IContainer container = rc.addContainer(uri.getName(), uri, ports, new HashMap(), Arrays.asList("/tmp")); - - List containers = node.get(path).asList(); - assertEquals(1, containers.size()); - - ModelNode exp = new ModelNodeBuilder() - .set("name", uri.getName()) - .set("image",uri.toString()) - .add("ports", new ModelNodeBuilder() - .set("containerPort", port.getContainerPort()) - .set("protocol", port.getProtocol()) - ) - .add("volumeMounts", new ModelNodeBuilder() - .set("name", uri.getName() +"-"+1) - .set("mountPath", "/tmp") - .set("readOnly", false) - ) - .build(); - - JSONAssert.assertEquals(exp.toJSONString(false), container.toJSONString(), true); - - Object [] sourceNames = rc.getVolumes().stream().map(IVolumeSource::getName).toArray(); - - Object [] contVolNames = container.getVolumes().stream().map(IVolume::getName).toArray(); - assertArrayEquals(sourceNames,contVolNames); - } - - @Test - public void testAddContainerAllowsContainerToBeFurtherManipulated() throws JSONException{ - //remove containers hack - String[] path = getPath(ReplicationController.SPEC_TEMPLATE_CONTAINERS); - node.get(path).clear(); - - //setup - DockerImageURI uri = new DockerImageURI("arepo/aproject/an_image_name"); - IPort port = mock(IPort.class); - when(port.getProtocol()).thenReturn("TCP"); - when(port.getContainerPort()).thenReturn(8080); - Set ports = new HashSet<>(); - ports.add(port); - - IVolumeMount mount = mock(IVolumeMount.class); - when(mount.getName()).thenReturn(uri.getName() +"-"+1); - when(mount.getMountPath()).thenReturn("/tmp"); - when(mount.isReadOnly()).thenReturn(Boolean.FALSE); - Set mounts = new HashSet<>(); - mounts.add(mount); - - IContainer container = rc.addContainer(uri.getName()); - container.setImage(uri); - container.setPorts(ports); - container.setVolumeMounts(mounts); - - IVolumeMount fooVolumeMount = container.addVolumeMount("foobar"); - fooVolumeMount.setMountPath("/tmp2"); - - ModelNode exp = new ModelNodeBuilder() - .set("name", uri.getName()) - .set("image",uri.toString()) - .add("ports", new ModelNodeBuilder() - .set("containerPort", port.getContainerPort()) - .set("protocol", port.getProtocol()) - ) - .add("volumeMounts", new ModelNodeBuilder() - .set("name", uri.getName() +"-"+1) - .set("mountPath", "/tmp") - .set("readOnly", false) - ) - .add("volumeMounts", new ModelNodeBuilder() - .set("name", "foobar") - .set("mountPath", "/tmp2") - ) - .build(); - - JSONAssert.assertEquals(exp.toJSONString(false), container.toJSONString(), true); - } - - @Test - public void shouldReturnTemplateLabels() { - Map labels = rc.getTemplateLabels(); - assertThat(labels) - .hasSize(3) - .includes(entry("deployment", "database-1")) - .includes(entry("deploymentconfig", "database")) - .includes(entry("name", "database")); - } - - @Test - public void testSetVolumes() { - IVolumeSource source = new EmptyDirVolumeSource("myvolume"); - rc.setVolumes(Collections.singleton(source)); - Set volumes = rc.getVolumes(); - assertEquals(1, volumes.size()); - assertEquals("myvolume", volumes.iterator().next().getName()); - } - - @Test - public void testAddSecretVolumeToPodSpec() throws JSONException { - IVolumeMount volumeMount = new IVolumeMount() { - public String getName() { return "my-secret"; } - public String getMountPath() { return "/path/to/my/secret/"; } - public boolean isReadOnly() { return true; } - public void setName(String name) {} - public void setMountPath(String path) {} - public void setReadOnly(boolean readonly) {} - }; - SecretVolumeSource source = new SecretVolumeSource(volumeMount.getName()); - source.setSecretName("the-secret"); - rc.addVolume(source); - Set podSpecVolumes = rc.getVolumes(); - Optional vol = podSpecVolumes.stream() - .filter(v->v.getName().equals(volumeMount.getName())) - .findFirst(); - assertTrue("Expected to find secret volume in pod spec", vol.isPresent()); - } + + @Test + public void getDesiredReplicaCount() { + assertEquals(1, rc.getDesiredReplicaCount()); + } + + @Test + public void setDesiredReplicaCount() { + rc.setDesiredReplicaCount(9); + assertEquals(9, rc.getDesiredReplicaCount()); + + rc.setReplicas(6); + assertEquals(6, rc.getDesiredReplicaCount()); + } + + @Test + public void getCurrentReplicaCount() { + assertEquals(2, rc.getCurrentReplicaCount()); + } + + @Test + public void testGetImages() { + String[] exp = new String[] { "openshift/mysql-55-centos7:latest" }; + assertArrayEquals(exp, rc.getImages().toArray()); + } + + @Test + public void testGetContainer() { + assertNull(rc.getContainer(" ")); + assertNotNull(rc.getContainer("ruby-helloworld-database")); + } + + @Test + public void testGetContainers() { + Collection containers = rc.getContainers(); + assertNotNull(containers); + assertEquals(1, containers.size()); + + String[] path = getPath(ReplicationController.SPEC_TEMPLATE_CONTAINERS); + node.get(path).clear(); + assertNotNull(rc.getContainers()); + } + + @Test + public void testAddContainer() throws JSONException { + // remove containers hack + String[] path = getPath(ReplicationController.SPEC_TEMPLATE_CONTAINERS); + node.get(path).clear(); + // setup + IPort port = mock(IPort.class); + when(port.getProtocol()).thenReturn("TCP"); + when(port.getContainerPort()).thenReturn(8080); + Set ports = new HashSet<>(); + ports.add(port); + DockerImageURI uri = new DockerImageURI("aproject/an_image_name"); + + IContainer container = rc.addContainer(uri.getName(), uri, ports, new HashMap(), + Arrays.asList("/tmp")); + + List containers = node.get(path).asList(); + assertEquals(1, containers.size()); + + ModelNode exp = new ModelNodeBuilder().set("name", uri.getName()).set("image", uri.toString()) + .add("ports", + new ModelNodeBuilder().set("containerPort", port.getContainerPort()).set("protocol", + port.getProtocol())) + .add("volumeMounts", new ModelNodeBuilder().set("name", uri.getName() + "-" + 1) + .set("mountPath", "/tmp").set("readOnly", false)) + .build(); + + JSONAssert.assertEquals(exp.toJSONString(false), container.toJson(), true); + + Object[] sourceNames = rc.getVolumes().stream().map(IVolumeSource::getName).toArray(); + + Object[] contVolNames = container.getVolumes().stream().map(IVolume::getName).toArray(); + assertArrayEquals(sourceNames, contVolNames); + } + + @Test + public void testAddContainerAllowsContainerToBeFurtherManipulated() throws JSONException { + // remove containers hack + String[] path = getPath(ReplicationController.SPEC_TEMPLATE_CONTAINERS); + node.get(path).clear(); + + // setup + IPort port = mock(IPort.class); + when(port.getProtocol()).thenReturn("TCP"); + when(port.getContainerPort()).thenReturn(8080); + Set ports = new HashSet<>(); + ports.add(port); + DockerImageURI uri = new DockerImageURI("arepo/aproject/an_image_name"); + + IVolumeMount mount = mock(IVolumeMount.class); + when(mount.getName()).thenReturn(uri.getName() + "-" + 1); + when(mount.getMountPath()).thenReturn("/tmp"); + when(mount.isReadOnly()).thenReturn(Boolean.FALSE); + Set mounts = new HashSet<>(); + mounts.add(mount); + + IContainer container = rc.addContainer(uri.getName()); + container.setImage(uri); + container.setPorts(ports); + container.setVolumeMounts(mounts); + + IVolumeMount fooVolumeMount = container.addVolumeMount("foobar"); + fooVolumeMount.setMountPath("/tmp2"); + + ModelNode exp = new ModelNodeBuilder().set("name", uri.getName()).set("image", uri.toString()) + .add("ports", + new ModelNodeBuilder().set("containerPort", port.getContainerPort()).set("protocol", + port.getProtocol())) + .add("volumeMounts", + new ModelNodeBuilder().set("name", uri.getName() + "-" + 1).set("mountPath", "/tmp") + .set("readOnly", false)) + .add("volumeMounts", new ModelNodeBuilder().set("name", "foobar").set("mountPath", "/tmp2")).build(); + + JSONAssert.assertEquals(exp.toJSONString(false), container.toJson(), true); + } + + @Test + public void shouldReturnTemplateLabels() { + Map labels = rc.getTemplateLabels(); + assertThat(labels).hasSize(3).includes(entry("deployment", "database-1")) + .includes(entry("deploymentconfig", "database")).includes(entry("name", "database")); + } + + @Test + public void testSetVolumes() { + IVolumeSource source = new EmptyDirVolumeSource("myvolume"); + rc.setVolumes(Collections.singleton(source)); + Set volumes = rc.getVolumes(); + assertEquals(1, volumes.size()); + assertEquals("myvolume", volumes.iterator().next().getName()); + } + + @Test + public void testAddSecretVolumeToPodSpec() throws JSONException { + IVolumeMount volumeMount = new IVolumeMount() { + public String getName() { + return "my-secret"; + } + + public String getMountPath() { + return "/path/to/my/secret/"; + } + + public boolean isReadOnly() { + return true; + } + + public void setName(String name) { + } + + public void setMountPath(String path) { + } + + public void setReadOnly(boolean readonly) { + } + }; + SecretVolumeSource source = new SecretVolumeSource(volumeMount.getName()); + source.setSecretName("the-secret"); + rc.addVolume(source); + Set podSpecVolumes = rc.getVolumes(); + Optional vol = podSpecVolumes.stream().filter(v -> v.getName().equals(volumeMount.getName())).findFirst(); + assertTrue("Expected to find secret volume in pod spec", vol.isPresent()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ResourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ResourceTest.java index 6ccf4eea..8f606538 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ResourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ResourceTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; @@ -23,34 +24,32 @@ import com.openshift.restclient.model.IResource; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class ResourceTest { - - private static final String VERSION = "v1"; - private static IResource resource; - - @Before - public void setup(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_SERVICE.getContentAsString()); - resource = new KubernetesResource(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.SERVICE)) {}; - } - - @Test - public void getNamespace(){ - assertEquals("test", resource.getNamespaceName()); - } - - @Test - public void getNamespaceWhenUndefinedShouldReturnEmptyString(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_SERVICE.getContentAsString()); - node.get("metadata").remove("namespace"); - resource = new Build(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PROJECT)); - assertEquals("", resource.getNamespaceName()); - } - - + + private static final String VERSION = "v1"; + private static IResource resource; + + @Before + public void setup() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_SERVICE.getContentAsString()); + resource = new KubernetesResource(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.SERVICE)) { + }; + } + + @Test + public void getNamespace() { + assertEquals("test", resource.getNamespaceName()); + } + + @Test + public void getNamespaceWhenUndefinedShouldReturnEmptyString() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_SERVICE.getContentAsString()); + node.get("metadata").remove("namespace"); + resource = new Build(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.PROJECT)); + assertEquals("", resource.getNamespaceName()); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/RoleBindingTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/RoleBindingTest.java index 7d5e19b2..6dacbc20 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/RoleBindingTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/RoleBindingTest.java @@ -6,9 +6,11 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import java.util.Arrays; @@ -28,61 +30,59 @@ import com.openshift.restclient.model.authorization.IRoleBinding; import com.openshift.restclient.utils.Samples; -/** - * @author Jeff Cantrill - */ public class RoleBindingTest { - private static final String VERSION = "v1"; - private static IRoleBinding binding; - - @BeforeClass - public static void setup(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_ROLE_BINDING.getContentAsString()); - binding = new RoleBinding(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROLE_BINDING)); - } - - @Test - public void testUserNames(){ - Set users = new HashSet<>(Arrays.asList("alpha","beta")); - binding.setUserNames(users); - binding.addUserName("omega"); - - users.add("omega"); - assertArrayEquals(users.toArray(), binding.getUserNames().toArray()); - } - - @Test - public void testGroupNames(){ - Set groups = new HashSet<>(Arrays.asList("phi","zeta")); - binding.setGroupNames(groups); - binding.addGroupName("pi"); - - groups.add("pi"); - assertArrayEquals(groups.toArray(), binding.getGroupNames().toArray()); - } - - @Test - public void testSubjects(){ - ModelNode node = new ModelNode(); - node.get("name").set("bar"); - IObjectReference ref = new ObjectReference(node); - Set subjects = new HashSet<>(); - subjects.add(ref); - - binding.setSubjects(subjects); - - assertArrayEquals(subjects.toArray(), binding.getSubjects().toArray()); - } - - @Test - public void testRoleRefs() { - ModelNode node = new ModelNode(); - node.get("name").set("bar"); - IObjectReference ref = new ObjectReference(node); - binding.setRoleRef(ref); - assertEquals("bar", binding.getRoleRef().getName()); - } - + private static final String VERSION = "v1"; + private static IRoleBinding binding; + + @BeforeClass + public static void setup() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_ROLE_BINDING.getContentAsString()); + binding = new RoleBinding(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROLE_BINDING)); + } + + @Test + public void testUserNames() { + Set users = new HashSet<>(Arrays.asList("alpha", "beta")); + binding.setUserNames(users); + binding.addUserName("omega"); + + users.add("omega"); + assertArrayEquals(users.toArray(), binding.getUserNames().toArray()); + } + + @Test + public void testGroupNames() { + Set groups = new HashSet<>(Arrays.asList("phi", "zeta")); + binding.setGroupNames(groups); + binding.addGroupName("pi"); + + groups.add("pi"); + assertArrayEquals(groups.toArray(), binding.getGroupNames().toArray()); + } + + @Test + public void testSubjects() { + ModelNode node = new ModelNode(); + node.get("name").set("bar"); + IObjectReference ref = new ObjectReference(node); + Set subjects = new HashSet<>(); + subjects.add(ref); + + binding.setSubjects(subjects); + + assertArrayEquals(subjects.toArray(), binding.getSubjects().toArray()); + } + + @Test + public void testRoleRefs() { + ModelNode node = new ModelNode(); + node.get("name").set("bar"); + IObjectReference ref = new ObjectReference(node); + binding.setRoleRef(ref); + assertEquals("bar", binding.getRoleRef().getName()); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java index b910d96f..a130c662 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java @@ -6,11 +6,13 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ -package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +package com.openshift.internal.restclient.model.v1; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.mockito.Mockito.mock; import org.jboss.dmr.ModelNode; import org.junit.Before; @@ -28,42 +30,41 @@ /** * Test to validate the lookup paths are correct for the version - * @author Jeff Cantrill */ -public class RouteTest{ - - private static final String VERSION = "v1"; - private static final Samples sample = Samples.V1_ROUTE; - private IRoute route; - private IClient client; - - @Before - public void setUp(){ - client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); - route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); - } - - @Test - public void getTLSConfigWhenUndefined() { - ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); - route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); - ITLSConfig tlsConfig = route.getTLSConfig(); - assertNull(tlsConfig); - } +public class RouteTest { + + private static final String VERSION = "v1"; + private static final Samples sample = Samples.V1_ROUTE; + private IRoute route; + private IClient client; + + @Before + public void setUp() { + client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); + route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); + } @Test - public void createTLSConfigWhenUndefined() { - ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); - route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); - ITLSConfig tls = route.createTLSConfig(); - assertNotNull(tls); - assertEquals("", tls.getTerminationType()); - assertEquals("", tls.getCertificate()); - assertEquals("", tls.getCACertificate()); - assertEquals("", tls.getKey()); - } - + public void getTLSConfigWhenUndefined() { + ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); + route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); + ITLSConfig tlsConfig = route.getTLSConfig(); + assertNull(tlsConfig); + } + + @Test + public void createTLSConfigWhenUndefined() { + ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); + route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); + ITLSConfig tls = route.createTLSConfig(); + assertNotNull(tls); + assertEquals("", tls.getTerminationType()); + assertEquals("", tls.getCertificate()); + assertEquals("", tls.getCACertificate()); + assertEquals("", tls.getKey()); + } + @Test public void getPortWhenUndefined() { ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); @@ -101,49 +102,48 @@ public void getNamePortWhenDefined() { } @Test - public void testGetHost() { - assertEquals("www.example.com", route.getHost()); - } - - @Test - public void testGetPath() { - assertEquals("/abc", route.getPath()); - } - - @Test - public void testGetAndSetPath() { - route.setPath("/def"); - assertEquals("/def", route.getPath()); - } - - @Test - public void getServiceName() throws Exception { - assertEquals("frontend", route.getServiceName()); - } - - @Test - public void setServiceName() throws Exception { - route.setServiceName("frontend-alt"); - assertEquals("frontend-alt", route.getServiceName()); - } - - @Test - public void getTLSConfig() throws Exception { - ITLSConfig tls = route.getTLSConfig(); - assertEquals(TLSTerminationType.EDGE, tls.getTerminationType()); - assertEquals("theCert", tls.getCertificate()); - assertEquals("theCACert", tls.getCACertificate()); - assertEquals("theKey", tls.getKey()); - } - - @Test - public void createTLSConfigWhenAlreadyDefined() throws Exception { - ITLSConfig tls = route.createTLSConfig(); - assertEquals(TLSTerminationType.EDGE, tls.getTerminationType()); - assertEquals("theCert", tls.getCertificate()); - assertEquals("theCACert", tls.getCACertificate()); - assertEquals("theKey", tls.getKey()); - } + public void testGetHost() { + assertEquals("www.example.com", route.getHost()); + } + @Test + public void testGetPath() { + assertEquals("/abc", route.getPath()); + } + + @Test + public void testGetAndSetPath() { + route.setPath("/def"); + assertEquals("/def", route.getPath()); + } + + @Test + public void getServiceName() throws Exception { + assertEquals("frontend", route.getServiceName()); + } + + @Test + public void setServiceName() throws Exception { + route.setServiceName("frontend-alt"); + assertEquals("frontend-alt", route.getServiceName()); + } + + @Test + public void getTLSConfig() throws Exception { + ITLSConfig tls = route.getTLSConfig(); + assertEquals(TLSTerminationType.EDGE, tls.getTerminationType()); + assertEquals("theCert", tls.getCertificate()); + assertEquals("theCACert", tls.getCACertificate()); + assertEquals("theKey", tls.getKey()); + } + + @Test + public void createTLSConfigWhenAlreadyDefined() throws Exception { + ITLSConfig tls = route.createTLSConfig(); + assertEquals(TLSTerminationType.EDGE, tls.getTerminationType()); + assertEquals("theCert", tls.getCertificate()); + assertEquals("theCACert", tls.getCACertificate()); + assertEquals("theKey", tls.getKey()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java index bf6d3be1..6bbb1e1d 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; @@ -28,38 +29,38 @@ /** * Test to validate that Secret object works as expected + * * @author Jiri Pechanec */ -public class SecretTest{ +public class SecretTest { + + private static final String VERSION = "v1"; + private static final Samples sample = Samples.V1_SECRET; + private ISecret secret; - private static final String VERSION = "v1"; - private static final Samples sample = Samples.V1_SECRET; - private ISecret secret; - - @Before - public void setUp() { - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); - secret = new Secret(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.SECRET)); - } - - @Test - public void testSecretType() { - assertEquals("kubernetes.io/dockercfg", secret.getType()); - } + @Before + public void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); + secret = new Secret(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.SECRET)); + } - @Test - public void testGetData() { - assertTrue(StringUtils.isNotBlank(new String(secret.getData(".dockercfg")))); - } + @Test + public void testSecretType() { + assertEquals("kubernetes.io/dockercfg", secret.getType()); + } - @Test - public void testAddAndGetData() { - secret.addData("my-key1", "secret word".getBytes()); - secret.addData("my-key2", new ByteArrayInputStream("blah blah".getBytes())); - assertEquals("secret word", new String(secret.getData("my-key1"))); - assertEquals("blah blah", new String(secret.getData("my-key2"))); - } + @Test + public void testGetData() { + assertTrue(StringUtils.isNotBlank(new String(secret.getData(".dockercfg")))); + } + @Test + public void testAddAndGetData() { + secret.addData("my-key1", "secret word".getBytes()); + secret.addData("my-key2", new ByteArrayInputStream("blah blah".getBytes())); + assertEquals("secret word", new String(secret.getData("my-key1"))); + assertEquals("blah blah", new String(secret.getData("my-key2"))); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/SecretVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/SecretVolumeSourceTest.java index 11f7d824..48a5f7ca 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/SecretVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/SecretVolumeSourceTest.java @@ -8,17 +8,19 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import com.openshift.internal.restclient.model.volume.SecretVolumeSource; -import com.openshift.restclient.model.volume.ISecretVolumeSource; -import com.openshift.restclient.utils.Samples; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import com.openshift.internal.restclient.model.volume.SecretVolumeSource; +import com.openshift.restclient.model.volume.ISecretVolumeSource; +import com.openshift.restclient.utils.Samples; /** * @author Ulf Lilleengen diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceAccountTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceAccountTest.java index 9ad7efe0..5299328e 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceAccountTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceAccountTest.java @@ -6,78 +6,80 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + import com.openshift.internal.restclient.model.ServiceAccount; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.serviceaccount.IServiceAccount; import com.openshift.restclient.utils.Samples; -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; /** * @author David Simansky | dsimansk@redhat.com */ public class ServiceAccountTest { - private static final String VERSION = "v1"; - private static final Samples sample = Samples.V1_SERVICE_ACCOUNT; - private IServiceAccount serviceAccount; - - @Before - public void setUp() { - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); - serviceAccount = new ServiceAccount(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, - ResourceKind.SERVICE_ACCOUNT)); - } - - @Test - public void testGetSecrets() { - String[] expSecrets = new String []{"deployer-token-luifi", "deployer-dockercfg-jq62e"}; - assertArrayEquals(expSecrets, serviceAccount.getSecrets().toArray()); - } + private static final String VERSION = "v1"; + private static final Samples sample = Samples.V1_SERVICE_ACCOUNT; + private IServiceAccount serviceAccount; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(sample.getContentAsString()); + serviceAccount = new ServiceAccount(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.SERVICE_ACCOUNT)); + } + + @Test + public void testGetSecrets() { + String[] expSecrets = new String[] { "deployer-token-luifi", "deployer-dockercfg-jq62e" }; + assertArrayEquals(expSecrets, serviceAccount.getSecrets().toArray()); + } - @Test - public void testGetImagePullSecrets() { - String[] expSecrets = new String []{"deployer-dockercfg-jq62e"}; - assertArrayEquals(expSecrets, serviceAccount.getImagePullSecrets().toArray()); - } + @Test + public void testGetImagePullSecrets() { + String[] expSecrets = new String[] { "deployer-dockercfg-jq62e" }; + assertArrayEquals(expSecrets, serviceAccount.getImagePullSecrets().toArray()); + } - @Test - public void testAddSecret() { - serviceAccount.addSecret("my-test-secret"); - assertEquals(3, serviceAccount.getSecrets().size()); - assertTrue(serviceAccount.getSecrets().contains("my-test-secret")); - } + @Test + public void testAddSecret() { + serviceAccount.addSecret("my-test-secret"); + assertEquals(3, serviceAccount.getSecrets().size()); + assertTrue(serviceAccount.getSecrets().contains("my-test-secret")); + } - @Test - public void testAddNullSecret() { - serviceAccount.addSecret(null); - assertEquals(3, serviceAccount.getSecrets().size()); - assertTrue(serviceAccount.getSecrets().contains("")); - } + @Test + public void testAddNullSecret() { + serviceAccount.addSecret(null); + assertEquals(3, serviceAccount.getSecrets().size()); + assertTrue(serviceAccount.getSecrets().contains("")); + } - @Test - public void testAddImagePullSecret() { - serviceAccount.addImagePullSecret("my-test-secret"); - assertEquals(2, serviceAccount.getImagePullSecrets().size()); - assertTrue(serviceAccount.getImagePullSecrets().contains("my-test-secret")); - } + @Test + public void testAddImagePullSecret() { + serviceAccount.addImagePullSecret("my-test-secret"); + assertEquals(2, serviceAccount.getImagePullSecrets().size()); + assertTrue(serviceAccount.getImagePullSecrets().contains("my-test-secret")); + } - @Test - public void testAddNullImagePullSecret() { - serviceAccount.addImagePullSecret(null); - assertEquals(2, serviceAccount.getImagePullSecrets().size()); - assertTrue(serviceAccount.getImagePullSecrets().contains("")); - } + @Test + public void testAddNullImagePullSecret() { + serviceAccount.addImagePullSecret(null); + assertEquals(2, serviceAccount.getImagePullSecrets().size()); + assertTrue(serviceAccount.getImagePullSecrets().contains("")); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java index ba99169f..3867aee8 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; @@ -30,121 +31,121 @@ /** * Test to validate the lookup paths are correct for the version - * @author Jeff Cantrill */ -public class ServiceTest{ - - private static final String VERSION = "v1"; - private IService service; - - @Before - public void setUp(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_SERVICE.getContentAsString()); - service = new Service(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.SERVICE)); - } - - @Test - public void testGetPortalIP() { - assertEquals("172.30.57.114", service.getPortalIP()); - } +public class ServiceTest { + + private static final String VERSION = "v1"; + private IService service; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_SERVICE.getContentAsString()); + service = new Service(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.SERVICE)); + } + + @Test + public void testGetPortalIP() { + assertEquals("172.30.57.114", service.getPortalIP()); + } @Test public void testGetClusterIP() { assertEquals("172.30.57.114", service.getClusterIP()); } - @Test - public void testGetTargetPort() { - assertEquals("3306", service.getTargetPort()); - } - - @Test - public void testSetTargetPort() { - service.setTargetPort(5030); - assertEquals("5030", service.getTargetPort()); - } - - @Test - public void testGetPort() { - assertEquals(5434, service.getPort()); - } - - @Test - public void testSetPort() { - service.setPort(5055); - assertEquals(5055, service.getPort()); - } - - @Test - public void testGetSelector() { - Map selector = new HashMap(); - selector.put("name", "database"); - assertEquals(selector, service.getSelector()); - } - - @Test - public void testSetSelectorSimple() { - Map selector = new HashMap(); - selector.put("name", "myselector"); - service.setSelector("name","myselector"); - assertEquals(selector, service.getSelector()); - } - - @Test - public void testGetName() { - assertEquals("database", service.getName()); - } - - @Test - public void testSetName() { - ((Service) service).setName("hello-openshift"); - assertEquals("hello-openshift", service.getName()); - } - - @Test - public void testGetNamespace() { - assertEquals("test", service.getNamespaceName()); - } - - @Test - public void testSetNamespace() { - // pre-condition - // operation - ((Service) service).setNamespace("foo"); - // verification - assertEquals("foo", service.getNamespaceName()); - } - - @Test - public void testGetPorts() { - IServicePort [] ports = service.getPorts().toArray(new IServicePort[] {}); - assertEquals(2, ports.length); - assertEquals(PortFactory.createServicePort("db", "TCP", 5434, 3306), ports[0]); - assertEquals(PortFactory.createServicePort("other", "TCP", 9999, 8888), ports[1]); - } - - @Test - public void testSetPorts() { - IServicePort port = PortFactory.createServicePort("newport", "TCP", 4444, 5555); - service.setPorts(Arrays.asList(port)); - IServicePort [] ports = service.getPorts().toArray(new IServicePort[] {}); - assertEquals(1, service.getPorts().size()); - assertEquals(port, ports[0]); - } - - @Test - public void testAddPorts() { - IServicePort port = service.addPort(8299, 9299, "testport"); - service.setPorts(Arrays.asList(port)); - IServicePort [] ports = service.getPorts().toArray(new IServicePort[] {}); - assertEquals(1, service.getPorts().size()); - assertEquals(port, ports[0]); - } - - @Test - public void testSetType() { - service.setType("NodePort"); - assertEquals("NodePort", service.getType()); - } + @Test + public void testGetTargetPort() { + assertEquals("3306", service.getTargetPort()); + } + + @Test + public void testSetTargetPort() { + service.setTargetPort(5030); + assertEquals("5030", service.getTargetPort()); + } + + @Test + public void testGetPort() { + assertEquals(5434, service.getPort()); + } + + @Test + public void testSetPort() { + service.setPort(5055); + assertEquals(5055, service.getPort()); + } + + @Test + public void testGetSelector() { + Map selector = new HashMap(); + selector.put("name", "database"); + assertEquals(selector, service.getSelector()); + } + + @Test + public void testSetSelectorSimple() { + Map selector = new HashMap(); + selector.put("name", "myselector"); + service.setSelector("name", "myselector"); + assertEquals(selector, service.getSelector()); + } + + @Test + public void testGetName() { + assertEquals("database", service.getName()); + } + + @Test + public void testSetName() { + ((Service) service).setName("hello-openshift"); + assertEquals("hello-openshift", service.getName()); + } + + @Test + public void testGetNamespace() { + assertEquals("test", service.getNamespaceName()); + } + + @Test + public void testSetNamespace() { + // pre-condition + // operation + ((Service) service).setNamespace("foo"); + // verification + assertEquals("foo", service.getNamespaceName()); + } + + @Test + public void testGetPorts() { + IServicePort[] ports = service.getPorts().toArray(new IServicePort[] {}); + assertEquals(2, ports.length); + assertEquals(PortFactory.createServicePort("db", "TCP", 5434, 3306), ports[0]); + assertEquals(PortFactory.createServicePort("other", "TCP", 9999, 8888), ports[1]); + } + + @Test + public void testSetPorts() { + IServicePort port = PortFactory.createServicePort("newport", "TCP", 4444, 5555); + service.setPorts(Arrays.asList(port)); + IServicePort[] ports = service.getPorts().toArray(new IServicePort[] {}); + assertEquals(1, service.getPorts().size()); + assertEquals(port, ports[0]); + } + + @Test + public void testAddPorts() { + IServicePort port = service.addPort(8299, 9299, "testport"); + service.setPorts(Arrays.asList(port)); + IServicePort[] ports = service.getPorts().toArray(new IServicePort[] {}); + assertEquals(1, service.getPorts().size()); + assertEquals(port, ports[0]); + } + + @Test + public void testSetType() { + service.setType("NodePort"); + assertEquals("NodePort", service.getType()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/StatusTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/StatusTest.java index 22b705ae..f4c36a12 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/StatusTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/StatusTest.java @@ -6,10 +6,11 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; import org.jboss.dmr.ModelNode; import org.junit.BeforeClass; @@ -24,32 +25,31 @@ /** * Test to validate the lookup paths are correct for the version - * @author Jeff Cantrill */ -public class StatusTest{ - - private static final String VERSION = "v1"; - private static IStatus status; - - @BeforeClass - public static void setUp(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_Status.getContentAsString()); - status = new Status(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.STATUS)); - } - - @Test - public void testGetMessage() { - assertEquals("Unable to determine kind and namespace from url, /osapi/users", status.getMessage()); - } - - @Test - public void testGetCode() { - assertEquals(403, status.getCode()); - } - - @Test - public void testGetStatus() { - assertEquals("Failure", status.getStatus()); - } +public class StatusTest { + + private static final String VERSION = "v1"; + private static IStatus status; + + @BeforeClass + public static void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_Status.getContentAsString()); + status = new Status(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.STATUS)); + } + + @Test + public void testGetMessage() { + assertEquals("Unable to determine kind and namespace from url, /osapi/users", status.getMessage()); + } + + @Test + public void testGetCode() { + assertEquals(403, status.getCode()); + } + + @Test + public void testGetStatus() { + assertEquals("Failure", status.getStatus()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/TemplateTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/TemplateTest.java index 4ff73cf8..8e8dd5cb 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/TemplateTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/TemplateTest.java @@ -6,10 +6,14 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.util.Map; @@ -27,53 +31,54 @@ /** * Test to validate the lookup paths are correct for the version * - * @author Jeff Cantrill */ -public class TemplateTest{ +public class TemplateTest { + + private static final String VERSION = "v1"; + private ITemplate template; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + when(client.getResourceFactory()).thenReturn(new ResourceFactory(client) { + }); + ModelNode node = ModelNode.fromJSONString(Samples.V1_TEMPLATE.getContentAsString()); + template = new Template(node, client, null); + } + + @Test + public void testGetApiVersion() { + assertEquals(VERSION, template.getApiVersion()); + } - private static final String VERSION = "v1"; - private ITemplate template; - - @Before - public void setUp(){ - IClient client = mock(IClient.class); - when(client.getResourceFactory()).thenReturn(new ResourceFactory(client){}); - ModelNode node = ModelNode.fromJSONString(Samples.V1_TEMPLATE.getContentAsString()); - template = new Template(node, client, null); - } - @Test - public void testGetApiVersion() { - assertEquals(VERSION, template.getApiVersion()); - } + @Test + public void testGetItems() { + assertEquals("Exp. the number of items to be more than zero", 8, template.getObjects().size()); + } - @Test - public void testGetItems() { - assertEquals("Exp. the number of items to be more than zero", 8, template.getObjects().size()); - } + @Test + public void testGetParameters() { + Map parameters = template.getParameters(); + assertEquals("Exp. the number of items to be more than zero", 5, parameters.size()); + IParameter param = parameters.get("MYSQL_PASSWORD"); + assertNotNull(param); + assertEquals("", param.getValue()); + assertEquals("[a-zA-Z0-9]{8}", param.getFrom()); + assertEquals("expression", param.getGeneratorName()); + assertEquals("database password", param.getDescription()); + assertTrue("required", param.isRequired()); + } - @Test - public void testGetParameters() { - Map parameters = template.getParameters(); - assertEquals("Exp. the number of items to be more than zero",5, parameters.size()); - IParameter param = parameters.get("MYSQL_PASSWORD"); - assertNotNull(param); - assertEquals("",param.getValue()); - assertEquals("[a-zA-Z0-9]{8}",param.getFrom()); - assertEquals("expression",param.getGeneratorName()); - assertEquals("database password",param.getDescription()); - assertTrue("required", param.isRequired()); - } - - @Test - public void testGetLabels() { - assertEquals("Exp. to retrieve the labels",2, template.getLabels().size()); - assertEquals("bar", template.getLabels().get("foo")); - } + @Test + public void testGetLabels() { + assertEquals("Exp. to retrieve the labels", 2, template.getLabels().size()); + assertEquals("bar", template.getLabels().get("foo")); + } - @Test - public void testGetObjectLabels() { - assertEquals("Exp. to retrieve the object labels",1, template.getObjectLabels().size()); - assertEquals("application-template-stibuild", template.getObjectLabels().get("template")); - } + @Test + public void testGetObjectLabels() { + assertEquals("Exp. to retrieve the object labels", 1, template.getObjectLabels().size()); + assertEquals("application-template-stibuild", template.getObjectLabels().get("template")); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java index 1c590a9d..80367700 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/UnrecognizedResourceTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; @@ -21,31 +22,30 @@ /** * Test to validate the lookup paths are correct for the version - * @author Jeff Cantrill */ -public class UnrecognizedResourceTest{ - - private IResource service; - - @Before - public void setUp(){ - IClient client = mock(IClient.class); - service = new ResourceFactory(client).create(Samples.V1_UNRECOGNIZED.getContentAsString()); - } - - @Test - public void testGetName() { - assertEquals("database", service.getName()); - } - - @Test - public void testGetNamespace() { - assertEquals("test", service.getNamespaceName()); - } - - @Test - public void testGetKind() { - assertEquals("IMadeThisOneUp", service.getKind()); - } +public class UnrecognizedResourceTest { + + private IResource service; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + service = new ResourceFactory(client).create(Samples.V1_UNRECOGNIZED.getContentAsString()); + } + + @Test + public void testGetName() { + assertEquals("database", service.getName()); + } + + @Test + public void testGetNamespace() { + assertEquals("test", service.getNamespaceName()); + } + + @Test + public void testGetKind() { + assertEquals("IMadeThisOneUp", service.getKind()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java index bfe5a3ae..a128b9fd 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java @@ -6,10 +6,11 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; import org.jboss.dmr.ModelNode; import org.junit.Before; @@ -24,28 +25,28 @@ /** * Test to validate the lookup paths are correct for the version - * @author Jeff Cantrill */ -public class UserTest{ - - private static final String VERSION = "v1"; - private IUser user; - - @Before - public void setUp(){ - IClient client = mock(IClient.class); - ModelNode node = ModelNode.fromJSONString(Samples.V1_USER.getContentAsString()); - user = new OpenShiftUser(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.USER)); - } - - @Test - public void testFullName() { - assertEquals("Foo Master", user.getFullName()); - } - - @Test - public void testUid() { - assertEquals("94b42e96-0faa-11e5-9467-080027893417", user.getUID()); - } +public class UserTest { + + private static final String VERSION = "v1"; + private IUser user; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_USER.getContentAsString()); + user = new OpenShiftUser(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.USER)); + } + + @Test + public void testFullName() { + assertEquals("Foo Master", user.getFullName()); + } + + @Test + public void testUid() { + assertEquals("94b42e96-0faa-11e5-9467-080027893417", user.getUID()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java index bb3716d5..eeb683f3 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java @@ -8,10 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.okhttp; -import static org.junit.Assert.*; -import static org.mockito.Mockito.*; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; import org.apache.commons.lang.StringUtils; import org.junit.Before; @@ -29,51 +31,47 @@ @RunWith(MockitoJUnitRunner.class) public class BasicChallangeHandlerTest { - @Mock - private IAuthorizationContext context; - private BasicChallangeHandler handler; - - @Before - public void setUp() throws Exception { - this.handler = new BasicChallangeHandler(context); - - when(context.getUserName()).thenReturn("username"); - when(context.getPassword()).thenReturn("password"); - } + @Mock + private IAuthorizationContext context; + private BasicChallangeHandler handler; + + @Before + public void setUp() throws Exception { + this.handler = new BasicChallangeHandler(context); + + when(context.getUserName()).thenReturn("username"); + when(context.getPassword()).thenReturn("password"); + } + + @Test + public void testCanHandle() { + assertTrue(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "basic"))); + assertTrue(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "bAsIC"))); + assertFalse(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "foobar"))); + assertFalse(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, ""))); + assertFalse(handler.canHandle(givenHeader("key", "value"))); + } + + @Test + public void testHandleChallange() { + Builder builder = new Request.Builder().url("http://foo"); + Request request = handler.handleChallange(builder).build(); + String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); + assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); + assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); + } - @Test - public void testCanHandle() { - assertTrue(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "basic"))); - assertTrue(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "bAsIC"))); - assertFalse(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "foobar"))); - assertFalse(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, ""))); - assertFalse(handler.canHandle(givenHeader("key","value"))); - } - - @Test - public void testHandleChallange() { - Builder builder = new Request.Builder() - .url("http://foo"); - Request request = handler.handleChallange(builder).build(); - String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); - assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); - assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); - } + @Test + public void testHandleChallangeWhenUsernameIsNull() { + when(context.getUserName()).thenReturn(null); + Builder builder = new Request.Builder().url("http://foo"); + Request request = handler.handleChallange(builder).build(); + String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); + assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); + assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); + } - @Test - public void testHandleChallangeWhenUsernameIsNull() { - when(context.getUserName()).thenReturn(null); - Builder builder = new Request.Builder() - .url("http://foo"); - Request request = handler.handleChallange(builder).build(); - String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); - assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); - assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); - } - - private Headers givenHeader(String name, String value) { - return new Headers.Builder() - .add(name, value) - .build(); - } + private Headers givenHeader(String name, String value) { + return new Headers.Builder().add(name, value).build(); + } } diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java index eed1f6cf..a57f7cb1 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.okhttp; import static org.hamcrest.CoreMatchers.equalTo; @@ -38,47 +39,43 @@ * @author Andre Dietisheim */ public class WatchClientTest { - - @Test - public void testOnFailureCallBackNotifiesListener() { - DefaultClient client = null; - - IOpenShiftWatchListener listener = mock(IOpenShiftWatchListener.class); - - WatchEndpoint endpoint = new WatchEndpoint(client, listener, ResourceKind.BUILD); - endpoint.onFailure(new IOException(), null); - verify(listener).error(any(Throwable.class)); - } - - @Test - public void shouldIgnoreUnsupportedFeatureResponseOnFailure() { - DefaultClient client = mock(DefaultClient.class); - IOpenShiftWatchListener listener = mock(IOpenShiftWatchListener.class); - - WatchEndpoint endpoint = new WatchEndpoint(client, listener, ResourceKind.BUILD); - Response.Builder responseBuilder = new Response.Builder(); - responseBuilder.code(IHttpConstants.STATUS_OK) - .protocol(Protocol.HTTP_2) - .request(new Request.Builder().url("http://localhost").build()); - endpoint.onFailure(new ProtocolException(), responseBuilder.build()); - verify(listener, never()).error(any()); - } - @Test - public void changeTypeShouldEqualSameChangeType() { - assertThat(ChangeType.ADDED, - equalTo(ChangeType.ADDED)); - } - - @Test - public void changeTypeShouldNotEqualDifferentChangeType() { - assertThat(ChangeType.ADDED, - not(equalTo(ChangeType.DELETED))); - } + @Test + public void testOnFailureCallBackNotifiesListener() { + DefaultClient client = null; + + IOpenShiftWatchListener listener = mock(IOpenShiftWatchListener.class); + + WatchEndpoint endpoint = new WatchEndpoint(client, listener, ResourceKind.BUILD); + endpoint.onFailure(new IOException(), null); + verify(listener).error(any(Throwable.class)); + } + + @Test + public void shouldIgnoreUnsupportedFeatureResponseOnFailure() { + DefaultClient client = mock(DefaultClient.class); + IOpenShiftWatchListener listener = mock(IOpenShiftWatchListener.class); + + WatchEndpoint endpoint = new WatchEndpoint(client, listener, ResourceKind.BUILD); + Response.Builder responseBuilder = new Response.Builder(); + responseBuilder.code(IHttpConstants.STATUS_OK).protocol(Protocol.HTTP_2) + .request(new Request.Builder().url("http://localhost").build()); + endpoint.onFailure(new ProtocolException(), responseBuilder.build()); + verify(listener, never()).error(any()); + } + + @Test + public void changeTypeShouldEqualSameChangeType() { + assertThat(ChangeType.ADDED, equalTo(ChangeType.ADDED)); + } + + @Test + public void changeTypeShouldNotEqualDifferentChangeType() { + assertThat(ChangeType.ADDED, not(equalTo(ChangeType.DELETED))); + } - @Test - public void changeTypeShouldEqualSameChangeTypeInLowercase() { - assertThat(ChangeType.ADDED, - equalTo(new ChangeType(ChangeType.ADDED.getValue().toLowerCase()))); - } + @Test + public void changeTypeShouldEqualSameChangeTypeInLowercase() { + assertThat(ChangeType.ADDED, equalTo(new ChangeType(ChangeType.ADDED.getValue().toLowerCase()))); + } } diff --git a/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java b/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java index 1d8203c5..c5dcb705 100644 --- a/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java +++ b/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java @@ -6,10 +6,20 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.util; -import static org.junit.Assert.*; -import static com.openshift.internal.util.JBossDmrExtentions.*; +import static com.openshift.internal.util.JBossDmrExtentions.asBoolean; +import static com.openshift.internal.util.JBossDmrExtentions.asInt; +import static com.openshift.internal.util.JBossDmrExtentions.asList; +import static com.openshift.internal.util.JBossDmrExtentions.asMap; +import static com.openshift.internal.util.JBossDmrExtentions.asSet; +import static com.openshift.internal.util.JBossDmrExtentions.asString; +import static com.openshift.internal.util.JBossDmrExtentions.toJsonString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.util.HashMap; import java.util.List; @@ -20,105 +30,105 @@ import org.junit.Before; import org.junit.Test; -/** - * @author Jeff Cantrill - */ public class JBossDmrExtentionsTest { - private ModelNode node = ModelNode.fromJSONString("{\"foo\":\"bar\", \"int\":\"3\", \"bool\":\"true\", \"list\": [\"1\", \"2\", \"3\"]}"); - private Map paths = new HashMap(); - private static final String KEY_FOO = "foo"; - private static final String KEY_XYZ = "xyz"; - private static final String KEY_BOOL = "bool"; - private static final String KEY_INT = "int"; - private static final String KEY_LIST = "list"; - - @Before - public void setup() { - paths.put(KEY_FOO, new String[] {"foo"}); - paths.put(KEY_XYZ, new String[] {"xyz"}); - paths.put(KEY_BOOL, new String[] {"bool"}); - paths.put(KEY_INT, new String[] {"int"}); - paths.put(KEY_LIST, new String[] {"list"}); - } - - @Test - public void testToJson() { - ModelNode complex = new ModelNode(); - complex.get("sub1", "sub2"); - complex.get("sub1a").set("avalue"); - - ModelNode node = new ModelNode(); - node.get("foo","bar"); - node.get("xyz").add(1).add(2).add(3); - node.get("xyz").get(1).clear(); - node.get("xyz").add(complex); - node.get("def").add(new ModelNode()); - node.get("abc").set("xyx"); - assertEquals("{\"foo\" : {}, \"xyz\" : [1,3,{\"sub1\" : {}, \"sub1a\" : \"avalue\"}], \"abc\" : \"xyx\"}", toJsonString(node, true)); - } - - @Test - public void testGettersDoNotAddNodeToJsonTree() { - asMap(node, paths, "openshift.map"); - assertFalse(node.has("openshift","map")); - - asSet(node, paths, "openshift.set", ModelType.STRING); - assertFalse(node.has("openshift","set")); - - asInt(node, paths, "openshift.int"); - assertFalse(node.has("openshift","int")); - - asString(node, paths, "openshift.string"); - assertFalse(node.has("openshift","string")); - - asBoolean(node, paths, "openshift.bool"); - assertFalse(node.has("openshift","bool")); - - asList(node, paths, "openshift.list", ModelType.STRING); - assertFalse(node.has("openshift","set")); - } - - @Test - public void testAsMapWhenPropertyKeysAreNull() { - assertNotNull(asMap(new ModelNode(), null, null)); - } - - @Test - public void asIntForUndefinedShouldReturnZero() { - assertEquals(0, asInt(node, paths, KEY_XYZ)); - } - - @Test - public void asIntForAValueShouldReturnValue() { - assertEquals(3,asInt(node, paths, KEY_INT)); - } - @Test - public void asBooleanForUndefinedShouldReturnFalse() { - assertFalse(asBoolean(node, paths, KEY_XYZ)); - } - - @Test - public void asBooleanForAValueShouldReturnValue() { - assertTrue(asBoolean(node, paths, KEY_BOOL)); - } - - @Test - public void asStringForUndefinedShouldReturnEmptySpace() { - assertEquals("", asString(node, paths, KEY_XYZ)); - } - - @Test - public void asStringForAValueShouldReturnTheValue() { - assertEquals("bar", asString(node, paths, KEY_FOO)); - } - - @Test + private ModelNode node = ModelNode + .fromJSONString("{\"foo\":\"bar\", \"int\":\"3\", \"bool\":\"true\", \"list\": [\"1\", \"2\", \"3\"]}"); + private Map paths = new HashMap(); + private static final String KEY_FOO = "foo"; + private static final String KEY_XYZ = "xyz"; + private static final String KEY_BOOL = "bool"; + private static final String KEY_INT = "int"; + private static final String KEY_LIST = "list"; + + @Before + public void setup() { + paths.put(KEY_FOO, new String[] { "foo" }); + paths.put(KEY_XYZ, new String[] { "xyz" }); + paths.put(KEY_BOOL, new String[] { "bool" }); + paths.put(KEY_INT, new String[] { "int" }); + paths.put(KEY_LIST, new String[] { "list" }); + } + + @Test + public void testToJson() { + ModelNode complex = new ModelNode(); + complex.get("sub1", "sub2"); + complex.get("sub1a").set("avalue"); + + ModelNode node = new ModelNode(); + node.get("foo", "bar"); + node.get("xyz").add(1).add(2).add(3); + node.get("xyz").get(1).clear(); + node.get("xyz").add(complex); + node.get("def").add(new ModelNode()); + node.get("abc").set("xyx"); + assertEquals("{\"foo\" : {}, \"xyz\" : [1,3,{\"sub1\" : {}, \"sub1a\" : \"avalue\"}], \"abc\" : \"xyx\"}", + toJsonString(node, true)); + } + + @Test + public void testGettersDoNotAddNodeToJsonTree() { + asMap(node, paths, "openshift.map"); + assertFalse(node.has("openshift", "map")); + + asSet(node, paths, "openshift.set", ModelType.STRING); + assertFalse(node.has("openshift", "set")); + + asInt(node, paths, "openshift.int"); + assertFalse(node.has("openshift", "int")); + + asString(node, paths, "openshift.string"); + assertFalse(node.has("openshift", "string")); + + asBoolean(node, paths, "openshift.bool"); + assertFalse(node.has("openshift", "bool")); + + asList(node, paths, "openshift.list", ModelType.STRING); + assertFalse(node.has("openshift", "set")); + } + + @Test + public void testAsMapWhenPropertyKeysAreNull() { + assertNotNull(asMap(new ModelNode(), null, null)); + } + + @Test + public void asIntForUndefinedShouldReturnZero() { + assertEquals(0, asInt(node, paths, KEY_XYZ)); + } + + @Test + public void asIntForAValueShouldReturnValue() { + assertEquals(3, asInt(node, paths, KEY_INT)); + } + + @Test + public void asBooleanForUndefinedShouldReturnFalse() { + assertFalse(asBoolean(node, paths, KEY_XYZ)); + } + + @Test + public void asBooleanForAValueShouldReturnValue() { + assertTrue(asBoolean(node, paths, KEY_BOOL)); + } + + @Test + public void asStringForUndefinedShouldReturnEmptySpace() { + assertEquals("", asString(node, paths, KEY_XYZ)); + } + + @Test + public void asStringForAValueShouldReturnTheValue() { + assertEquals("bar", asString(node, paths, KEY_FOO)); + } + + @Test public void asListForStringReturnsOrderedValues() { - List l = asList(node, paths, KEY_LIST, ModelType.STRING); - assertEquals("1", l.get(0)); - assertEquals("2", l.get(1)); - assertEquals("3", l.get(2)); + List l = asList(node, paths, KEY_LIST, ModelType.STRING); + assertEquals("1", l.get(0)); + assertEquals("2", l.get(1)); + assertEquals("3", l.get(2)); } } diff --git a/src/test/java/com/openshift/internal/util/StringSplitterTest.java b/src/test/java/com/openshift/internal/util/StringSplitterTest.java index 6812ec0a..3ac5e8ad 100644 --- a/src/test/java/com/openshift/internal/util/StringSplitterTest.java +++ b/src/test/java/com/openshift/internal/util/StringSplitterTest.java @@ -6,70 +6,71 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ -package com.openshift.internal.util; -import static org.junit.Assert.assertThat; +package com.openshift.internal.util; import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; import java.util.Arrays; import java.util.List; + import org.junit.Test; public class StringSplitterTest { - @Test - public void testSimpleUniqueParameter() { - List result = StringSplitter.split("parm1"); - List expected = Arrays.asList("parm1"); - assertThat(result, is(expected)); - } - - @Test - public void testSimpleManyParameters() { - List result = StringSplitter.split("parm1 parm2 parm3"); - List expected = Arrays.asList("parm1", "parm2", "parm3"); - assertThat(result, is(expected)); - } - - @Test - public void testQuotedUniqueParameter() { - List result = StringSplitter.split("\"parm1\""); - List expected = Arrays.asList("parm1"); - assertThat(result, is(expected)); - } + @Test + public void testSimpleUniqueParameter() { + List result = StringSplitter.split("parm1"); + List expected = Arrays.asList("parm1"); + assertThat(result, is(expected)); + } + + @Test + public void testSimpleManyParameters() { + List result = StringSplitter.split("parm1 parm2 parm3"); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } + + @Test + public void testQuotedUniqueParameter() { + List result = StringSplitter.split("\"parm1\""); + List expected = Arrays.asList("parm1"); + assertThat(result, is(expected)); + } + + @Test + public void testQuotedManyParameters() { + List result = StringSplitter.split("\"parm1\" \"parm2\" \"parm3\""); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } + + @Test + public void testQuotedManyParametersWithAdjacentValue() { + List result = StringSplitter.split("\"parm1\" \"parm2\"a \"parm3\""); + List expected = Arrays.asList("parm1", "parm2a", "parm3"); + assertThat(result, is(expected)); + } + + @Test + public void testQuotedManyParametersUnfinished() { + List result = StringSplitter.split("\"parm1\" \"parm2\" \"parm3"); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } - @Test - public void testQuotedManyParameters() { - List result = StringSplitter.split("\"parm1\" \"parm2\" \"parm3\""); - List expected = Arrays.asList("parm1", "parm2", "parm3"); - assertThat(result, is(expected)); - } - - @Test - public void testQuotedManyParametersWithAdjacentValue() { - List result = StringSplitter.split("\"parm1\" \"parm2\"a \"parm3\""); - List expected = Arrays.asList("parm1", "parm2a", "parm3"); - assertThat(result, is(expected)); - } + @Test + public void testSimpleDoubleSpaceManyParameters() { + List result = StringSplitter.split("parm1 parm2 parm3"); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } - @Test - public void testQuotedManyParametersUnfinished() { - List result = StringSplitter.split("\"parm1\" \"parm2\" \"parm3"); - List expected = Arrays.asList("parm1", "parm2", "parm3"); - assertThat(result, is(expected)); - } - - @Test - public void testSimpleDoubleSpaceManyParameters() { - List result = StringSplitter.split("parm1 parm2 parm3"); - List expected = Arrays.asList("parm1", "parm2", "parm3"); - assertThat(result, is(expected)); - } - - @Test - public void testSimpleEndSpaceManyParameters() { - List result = StringSplitter.split("parm1 parm2 parm3 "); - List expected = Arrays.asList("parm1", "parm2", "parm3"); - assertThat(result, is(expected)); - } + @Test + public void testSimpleEndSpaceManyParameters() { + List result = StringSplitter.split("parm1 parm2 parm3 "); + List expected = Arrays.asList("parm1", "parm2", "parm3"); + assertThat(result, is(expected)); + } } diff --git a/src/test/java/com/openshift/internal/util/TestTimer.java b/src/test/java/com/openshift/internal/util/TestTimer.java index adc97511..beb78df1 100644 --- a/src/test/java/com/openshift/internal/util/TestTimer.java +++ b/src/test/java/com/openshift/internal/util/TestTimer.java @@ -6,44 +6,45 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.util; -import com.openshift.restclient.OpenShiftException; +import java.io.IOException; + import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.rules.TestName; -import java.io.IOException; +import com.openshift.restclient.OpenShiftException; /** * @author Corey Daley */ public class TestTimer { - protected long startTime; - protected long endTime; - - @Rule - public TestName name = new TestName(); - - @Before - public void startTimer() throws OpenShiftException, IOException { - this.startTime = 0; - this.startTime = System.currentTimeMillis(); - } - - @After - public void endTimer() { - this.endTime = 0; - this.endTime = System.currentTimeMillis(); - calcExecTime(); - - - } - - public void calcExecTime() { - if (System.getProperty("showTestTimes") != null) { - System.out.println(this.getClass() +"#"+name.getMethodName() + " : " + (this.endTime - this.startTime)); - } - } + protected long startTime; + protected long endTime; + + @Rule + public TestName name = new TestName(); + + @Before + public void startTimer() throws OpenShiftException, IOException { + this.startTime = 0; + this.startTime = System.currentTimeMillis(); + } + + @After + public void endTimer() { + this.endTime = 0; + this.endTime = System.currentTimeMillis(); + calcExecTime(); + + } + + public void calcExecTime() { + if (System.getProperty("showTestTimes") != null) { + System.out.println(this.getClass() + "#" + name.getMethodName() + " : " + (this.endTime - this.startTime)); + } + } } diff --git a/src/test/java/com/openshift/internal/util/URIUtilsTest.java b/src/test/java/com/openshift/internal/util/URIUtilsTest.java index 53cb7ae7..c97d89de 100644 --- a/src/test/java/com/openshift/internal/util/URIUtilsTest.java +++ b/src/test/java/com/openshift/internal/util/URIUtilsTest.java @@ -6,9 +6,10 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.internal.util; -import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; import java.net.URI; import java.net.URISyntaxException; @@ -18,44 +19,39 @@ import org.junit.Before; import org.junit.Test; -import com.openshift.internal.util.URIUtils; - -/** - * @author Jeff Cantrill - */ public class URIUtilsTest { - - private String location = "https://10.0.2.15:8443/oauth/token/display#access_token=MmJiMTQzMGMtZjA0Mi00ODJmLTkzMDUtYzEyMTE5ODU1OGJh&expires_in=3600&token_type=bearer"; - private Map exp = new HashMap(); - - @Before - public void setup(){ - exp.put("access_token", "MmJiMTQzMGMtZjA0Mi00ODJmLTkzMDUtYzEyMTE5ODU1OGJh"); - exp.put("expires_in", "3600"); - exp.put("token_type", "bearer"); - } - - @Test - public void testSplitFragmentFromURIString(){ - assertMaps(exp, URIUtils.splitFragment(location)); - } - - @Test - public void testSplitFragmentFromURIWithNoFragment() throws Exception{ - URI uri = new URI("http://localhost"); - Map pairs = URIUtils.splitFragment(uri); - assertMaps(new HashMap(), pairs); - } - - @Test - public void testSplitFragmentFromURI() throws URISyntaxException { - URI uri = new URI(location); - - Map pairs = URIUtils.splitFragment(uri); - assertMaps(exp, pairs); - } - - private void assertMaps(Map exp, Map act){ - assertArrayEquals(exp.entrySet().toArray(), act.entrySet().toArray()); - } + + private String location = "https://10.0.2.15:8443/oauth/token/display#access_token=MmJiMTQzMGMtZjA0Mi00ODJmLTkzMDUtYzEyMTE5ODU1OGJh&expires_in=3600&token_type=bearer"; + private Map exp = new HashMap(); + + @Before + public void setup() { + exp.put("access_token", "MmJiMTQzMGMtZjA0Mi00ODJmLTkzMDUtYzEyMTE5ODU1OGJh"); + exp.put("expires_in", "3600"); + exp.put("token_type", "bearer"); + } + + @Test + public void testSplitFragmentFromURIString() { + assertMaps(exp, URIUtils.splitFragment(location)); + } + + @Test + public void testSplitFragmentFromURIWithNoFragment() throws Exception { + URI uri = new URI("http://localhost"); + Map pairs = URIUtils.splitFragment(uri); + assertMaps(new HashMap(), pairs); + } + + @Test + public void testSplitFragmentFromURI() throws URISyntaxException { + URI uri = new URI(location); + + Map pairs = URIUtils.splitFragment(uri); + assertMaps(exp, pairs); + } + + private void assertMaps(Map exp, Map act) { + assertArrayEquals(exp.entrySet().toArray(), act.entrySet().toArray()); + } } diff --git a/src/test/java/com/openshift/restclient/OpenShiftContextTest.java b/src/test/java/com/openshift/restclient/OpenShiftContextTest.java index 9c05b69f..3d62e19f 100644 --- a/src/test/java/com/openshift/restclient/OpenShiftContextTest.java +++ b/src/test/java/com/openshift/restclient/OpenShiftContextTest.java @@ -6,6 +6,7 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient; import static junit.framework.Assert.assertEquals; @@ -22,63 +23,63 @@ */ public class OpenShiftContextTest { - @After - public void tearDown() { - OpenShiftContext.get().clear(); - } - - @Test - public void testGetValue() { - String value = "bar"; - OpenShiftContext.get().put("foo", value); - assertEquals(value, OpenShiftContext.get().get("foo")); - } - - @Test - public void testRemove() { - OpenShiftContext.get().put("foo", "bar"); - OpenShiftContext.get().remove("foo"); - assertNull(OpenShiftContext.get().get("foo")); - } - - @Test - public void testClear() { - OpenShiftContext.get().put("foo", "bar"); - OpenShiftContext.get().clear(); - assertNull(OpenShiftContext.get().get("foo")); - } - - @Test - public void testConcurrency() throws Exception { - OpenShiftContext[] contexts = new OpenShiftContext[2]; - Thread t0 = new SomeThread(0, contexts); - Thread t1 = new SomeThread(1, contexts); - - t0.start(); - t1.start(); - t0.join(); - t1.join(); - - assertNotSame(contexts[0], contexts[1]); - assertEquals(t0.getName(), contexts[0].get("foo")); - assertEquals(t1.getName(), contexts[1].get("foo")); - } - - static class SomeThread extends Thread { - - private int index; - private OpenShiftContext[] contexts; + @After + public void tearDown() { + OpenShiftContext.get().clear(); + } + + @Test + public void testGetValue() { + String value = "bar"; + OpenShiftContext.get().put("foo", value); + assertEquals(value, OpenShiftContext.get().get("foo")); + } + + @Test + public void testRemove() { + OpenShiftContext.get().put("foo", "bar"); + OpenShiftContext.get().remove("foo"); + assertNull(OpenShiftContext.get().get("foo")); + } + + @Test + public void testClear() { + OpenShiftContext.get().put("foo", "bar"); + OpenShiftContext.get().clear(); + assertNull(OpenShiftContext.get().get("foo")); + } + + @Test + public void testConcurrency() throws Exception { + OpenShiftContext[] contexts = new OpenShiftContext[2]; + Thread t0 = new SomeThread(0, contexts); + Thread t1 = new SomeThread(1, contexts); + + t0.start(); + t1.start(); + t0.join(); + t1.join(); + + assertNotSame(contexts[0], contexts[1]); + assertEquals(t0.getName(), contexts[0].get("foo")); + assertEquals(t1.getName(), contexts[1].get("foo")); + } + + static class SomeThread extends Thread { + + private int index; + private OpenShiftContext[] contexts; + + SomeThread(int index, OpenShiftContext[] contexts) { + super("Thread-" + index); + this.index = index; + this.contexts = contexts; + } - SomeThread(int index, OpenShiftContext[] contexts) { - super("Thread-"+index); - this.index = index; - this.contexts = contexts; - } - - public void run() { - assertNull(OpenShiftContext.get().get("foo")); - OpenShiftContext.get().put("foo", getName()); - contexts[index] = OpenShiftContext.get(); - }; - } + public void run() { + assertNull(OpenShiftContext.get().get("foo")); + OpenShiftContext.get().put("foo", getName()); + contexts[index] = OpenShiftContext.get(); + } + } } diff --git a/src/test/java/com/openshift/restclient/ResourceKindTest.java b/src/test/java/com/openshift/restclient/ResourceKindTest.java index 3eac5044..3fc79228 100644 --- a/src/test/java/com/openshift/restclient/ResourceKindTest.java +++ b/src/test/java/com/openshift/restclient/ResourceKindTest.java @@ -8,54 +8,54 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Test; -/** - * - * @author jeff.cantrill - * - */ public class ResourceKindTest { - @Test - public void testPluralizeWhenNull() { - assertEquals("",ResourceKind.pluralize(null)); - } - - @Test - public void testPluralizeWhenEmpty() { - assertEquals("",ResourceKind.pluralize(" ")); - } - - @Test - public void testPluralizeWhenEndsWithAnS() { - assertEquals("Status",ResourceKind.pluralize(ResourceKind.STATUS)); - } - - @Test - public void testPluralizeWhenEndsWithY() { - assertEquals("Families",ResourceKind.pluralize("Family")); - } - - @Test - public void testPluralizeWhenEndsWithAnythingElse() { - assertEquals("Services",ResourceKind.pluralize(ResourceKind.SERVICE)); - } - @Test - public void testPluralizeCamelCaseKind() { - assertEquals("ReplicationControllers",ResourceKind.pluralize(ResourceKind.REPLICATION_CONTROLLER)); - } - @Test - public void testPluralizeCamelCaseKindForceLower() { - assertEquals("replicationcontrollers",ResourceKind.pluralize(ResourceKind.REPLICATION_CONTROLLER, true, true)); - } - @Test - public void testPluralizeCamelCaseKindUncapitalize() { - assertEquals("replicationControllers",ResourceKind.pluralize(ResourceKind.REPLICATION_CONTROLLER, false, true)); - } + @Test + public void testPluralizeWhenNull() { + assertEquals("", ResourceKind.pluralize(null)); + } + + @Test + public void testPluralizeWhenEmpty() { + assertEquals("", ResourceKind.pluralize(" ")); + } + + @Test + public void testPluralizeWhenEndsWithAnS() { + assertEquals("Status", ResourceKind.pluralize(ResourceKind.STATUS)); + } + + @Test + public void testPluralizeWhenEndsWithY() { + assertEquals("Families", ResourceKind.pluralize("Family")); + } + + @Test + public void testPluralizeWhenEndsWithAnythingElse() { + assertEquals("Services", ResourceKind.pluralize(ResourceKind.SERVICE)); + } + + @Test + public void testPluralizeCamelCaseKind() { + assertEquals("ReplicationControllers", ResourceKind.pluralize(ResourceKind.REPLICATION_CONTROLLER)); + } + + @Test + public void testPluralizeCamelCaseKindForceLower() { + assertEquals("replicationcontrollers", ResourceKind.pluralize(ResourceKind.REPLICATION_CONTROLLER, true, true)); + } + + @Test + public void testPluralizeCamelCaseKindUncapitalize() { + assertEquals("replicationControllers", + ResourceKind.pluralize(ResourceKind.REPLICATION_CONTROLLER, false, true)); + } } diff --git a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java index c501982e..1f440db9 100644 --- a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java +++ b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient; import static com.openshift.internal.restclient.IntegrationTestHelper.cleanUpResource; @@ -34,88 +35,83 @@ public class WatchClientIntegrationTest { - private static final Logger LOG = LoggerFactory.getLogger(WatchClientIntegrationTest.class); - - private IntegrationTestHelper helper = new IntegrationTestHelper(); - private IClient client; - private IResource project; - public static final String [] KINDS = new String[] { - ResourceKind.BUILD_CONFIG, - ResourceKind.DEPLOYMENT_CONFIG, - ResourceKind.SERVICE, - ResourceKind.POD, - ResourceKind.REPLICATION_CONTROLLER, - ResourceKind.BUILD, - ResourceKind.IMAGE_STREAM, - ResourceKind.ROUTE - }; - - private ExecutorService service; - private boolean isError; - - @Before - public void setup() { - service = Executors.newSingleThreadScheduledExecutor(); - client = helper.createClientForBasicAuth(); - IResource projRequest = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, helper.generateNamespace()); - project = client.create(projRequest); - } - - @After - public void teardown() { - cleanUpResource(client, project); - service.shutdownNow(); - } - - @SuppressWarnings("rawtypes") - @Test(timeout=60000) - public void test() throws Exception{ - List results = new ArrayList(); - CountDownLatch latch = new CountDownLatch(KINDS.length); - IOpenShiftWatchListener listener = new IOpenShiftWatchListener() { - - @SuppressWarnings("unchecked") - @Override - public void received(IResource resource, ChangeType change) { - results.add(change); - } - - @Override - public void connected(List resources) { - latch.countDown(); - } - - @Override - public void disconnected() { - latch.countDown(); - } - - @Override - public void error(Throwable err) { - latch.countDown(); - isError = true; - LOG.error("",err); - } - }; - - IWatcher watcher = null; - try { - watcher = client.watch(project.getName(), listener, KINDS); - latch.await(); - assertFalse("Expected connection without error",isError); - IService service = client.getResourceFactory().stub(ResourceKind.SERVICE,"hello-world", project.getName()); - service.addPort(8080,8080); - service = client.create(service); - service.addLabel("foo", "bar"); - service = client.update(service); - client.delete(service); - assertArrayEquals(new ChangeType[] {ChangeType.ADDED, ChangeType.MODIFIED, ChangeType.DELETED}, results.toArray()); - assertEquals(0, latch.getCount()); - }finally { - if(watcher != null) { - watcher.stop(); - } - } - } + private static final Logger LOG = LoggerFactory.getLogger(WatchClientIntegrationTest.class); + + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IClient client; + private IResource project; + public static final String[] KINDS = new String[] { ResourceKind.BUILD_CONFIG, ResourceKind.DEPLOYMENT_CONFIG, + ResourceKind.SERVICE, ResourceKind.POD, ResourceKind.REPLICATION_CONTROLLER, ResourceKind.BUILD, + ResourceKind.IMAGE_STREAM, ResourceKind.ROUTE }; + + private ExecutorService service; + private boolean isError; + + @Before + public void setup() { + service = Executors.newSingleThreadScheduledExecutor(); + client = helper.createClientForBasicAuth(); + IResource projRequest = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, + helper.generateNamespace()); + project = client.create(projRequest); + } + + @After + public void teardown() { + cleanUpResource(client, project); + service.shutdownNow(); + } + + @SuppressWarnings("rawtypes") + @Test(timeout = 60000) + public void test() throws Exception { + List results = new ArrayList(); + CountDownLatch latch = new CountDownLatch(KINDS.length); + IOpenShiftWatchListener listener = new IOpenShiftWatchListener() { + + @SuppressWarnings("unchecked") + @Override + public void received(IResource resource, ChangeType change) { + results.add(change); + } + + @Override + public void connected(List resources) { + latch.countDown(); + } + + @Override + public void disconnected() { + latch.countDown(); + } + + @Override + public void error(Throwable err) { + latch.countDown(); + isError = true; + LOG.error("", err); + } + }; + + IWatcher watcher = null; + try { + watcher = client.watch(project.getName(), listener, KINDS); + latch.await(); + assertFalse("Expected connection without error", isError); + IService service = client.getResourceFactory().stub(ResourceKind.SERVICE, "hello-world", project.getName()); + service.addPort(8080, 8080); + service = client.create(service); + service.addLabel("foo", "bar"); + service = client.update(service); + client.delete(service); + assertArrayEquals(new ChangeType[] { ChangeType.ADDED, ChangeType.MODIFIED, ChangeType.DELETED }, + results.toArray()); + assertEquals(0, latch.getCount()); + } finally { + if (watcher != null) { + watcher.stop(); + } + } + } } diff --git a/src/test/java/com/openshift/restclient/images/DockerImageURITest.java b/src/test/java/com/openshift/restclient/images/DockerImageURITest.java index cc6b3e4b..4dad6b30 100644 --- a/src/test/java/com/openshift/restclient/images/DockerImageURITest.java +++ b/src/test/java/com/openshift/restclient/images/DockerImageURITest.java @@ -6,101 +6,108 @@ * * Contributors: Red Hat, Inc. ******************************************************************************/ + package com.openshift.restclient.images; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.openshift.restclient.images.DockerImageURI; - -/** - * @author Jeff Cantrill - */ public class DockerImageURITest { - - private static final String NAME = "foo"; - private static final String TAG = "bar"; - private static final String USERNAME = "openshift"; - private static final String REPO_HOST = "127.0.0.1"; - - private static final String NAME_TAG = String.format("%s:%s", NAME, TAG); - private static final String USER_NAME_TAG = String.format("%s/%s:%s", USERNAME, NAME, TAG); - private static final String REPO_USER_NAME_TAG = String.format("%s/%s/%s:%s", REPO_HOST, USERNAME, NAME, TAG);;; - - @Test - public void testGetUriWithoutHost(){ - assertEquals("Exp. to get the uri without tag", String.format("%s/%s:%s", USERNAME, NAME, TAG), new DockerImageURI(REPO_USER_NAME_TAG).getUriWithoutHost()); - } - @Test - public void testGetUriWithoutTag(){ - assertEquals("Exp. to get the uri without tag", String.format("%s/%s/%s", REPO_HOST, USERNAME, NAME), new DockerImageURI(REPO_USER_NAME_TAG).getUriWithoutTag()); - } - @Test - public void testGetBaseUri(){ - assertEquals("Exp. to get the uri without repo", USER_NAME_TAG, new DockerImageURI(REPO_USER_NAME_TAG).getBaseUri()); - } - @Test - public void testGetAbsoluteUri() { - assertEquals("Exp. to get the full uri", REPO_USER_NAME_TAG, new DockerImageURI(REPO_USER_NAME_TAG).getAbsoluteUri()); - } - - @Test - public void testGetAbsoluteUriWithoutRepo() { - assertEquals("Exp. to get the full uri without rep", USER_NAME_TAG, new DockerImageURI(USER_NAME_TAG).getAbsoluteUri()); - } - - @Test - public void testGetAbsoluteUriWithoutUserName() { - assertEquals("Exp. to get the full uri without user name", NAME_TAG, new DockerImageURI(NAME_TAG).getAbsoluteUri()); - } - - @Test - public void testGetAbsoluteUriWithoutTag() { - assertEquals("Exp. to get the full uri without user name", String.format("%s:%s", NAME, "latest"), new DockerImageURI(NAME).getAbsoluteUri()); - } - - @Test - public void testName() { - DockerImageURI tag = new DockerImageURI(NAME); - assertEquals(NAME, tag.getName()); - assertEquals("Expected to toString to return the correct uri", String.format("%s:%s", NAME, "latest"), tag.toString()); - } - - @Test - public void testNameWithTag() { - DockerImageURI tag = new DockerImageURI(NAME_TAG); - assertNameAndTag(tag); - assertEquals("Expected to toString to return the correct uri", NAME_TAG, tag.toString()); - } - - @Test - public void testUserWithNameAndTag() { - DockerImageURI tag = new DockerImageURI(USER_NAME_TAG); - assertNameAndTag(tag); - assertUserName(tag); - assertEquals("Expected to toString to return the correct uri", USER_NAME_TAG, tag.toString()); - } - - @Test - public void testRepoWithUserWithNameAndTag() { - DockerImageURI tag = new DockerImageURI(REPO_USER_NAME_TAG); - assertNameAndTag(tag); - assertUserName(tag); - assertRepoHost(tag); - assertEquals("Expected to toString to return the correct uri", REPO_USER_NAME_TAG, tag.toString()); - } - - private void assertRepoHost(DockerImageURI tag) { - assertEquals("Expected to parse our the repo host", REPO_HOST, tag.getRepositoryHost()); - } - - private void assertUserName(DockerImageURI tag) { - assertEquals("Expected to parse our the username", USERNAME, tag.getUserName()); - } - - private void assertNameAndTag(DockerImageURI tag){ - assertEquals("Expected to parse out the name", NAME, tag.getName()); - assertEquals("Expected to parse out the tage", TAG, tag.getTag()); - } + + private static final String NAME = "foo"; + private static final String TAG = "bar"; + private static final String USERNAME = "openshift"; + private static final String REPO_HOST = "127.0.0.1"; + + private static final String NAME_TAG = String.format("%s:%s", NAME, TAG); + private static final String USER_NAME_TAG = String.format("%s/%s:%s", USERNAME, NAME, TAG); + private static final String REPO_USER_NAME_TAG = String.format("%s/%s/%s:%s", REPO_HOST, USERNAME, NAME, TAG); + + @Test + public void testGetUriWithoutHost() { + assertEquals("Exp. to get the uri without tag", String.format("%s/%s:%s", USERNAME, NAME, TAG), + new DockerImageURI(REPO_USER_NAME_TAG).getUriWithoutHost()); + } + + @Test + public void testGetUriWithoutTag() { + assertEquals("Exp. to get the uri without tag", String.format("%s/%s/%s", REPO_HOST, USERNAME, NAME), + new DockerImageURI(REPO_USER_NAME_TAG).getUriWithoutTag()); + } + + @Test + public void testGetBaseUri() { + assertEquals("Exp. to get the uri without repo", USER_NAME_TAG, + new DockerImageURI(REPO_USER_NAME_TAG).getBaseUri()); + } + + @Test + public void testGetAbsoluteUri() { + assertEquals("Exp. to get the full uri", REPO_USER_NAME_TAG, + new DockerImageURI(REPO_USER_NAME_TAG).getAbsoluteUri()); + } + + @Test + public void testGetAbsoluteUriWithoutRepo() { + assertEquals("Exp. to get the full uri without rep", USER_NAME_TAG, + new DockerImageURI(USER_NAME_TAG).getAbsoluteUri()); + } + + @Test + public void testGetAbsoluteUriWithoutUserName() { + assertEquals("Exp. to get the full uri without user name", NAME_TAG, + new DockerImageURI(NAME_TAG).getAbsoluteUri()); + } + + @Test + public void testGetAbsoluteUriWithoutTag() { + assertEquals("Exp. to get the full uri without user name", String.format("%s:%s", NAME, "latest"), + new DockerImageURI(NAME).getAbsoluteUri()); + } + + @Test + public void testName() { + DockerImageURI tag = new DockerImageURI(NAME); + assertEquals(NAME, tag.getName()); + assertEquals("Expected to toString to return the correct uri", String.format("%s:%s", NAME, "latest"), + tag.toString()); + } + + @Test + public void testNameWithTag() { + DockerImageURI tag = new DockerImageURI(NAME_TAG); + assertNameAndTag(tag); + assertEquals("Expected to toString to return the correct uri", NAME_TAG, tag.toString()); + } + + @Test + public void testUserWithNameAndTag() { + DockerImageURI tag = new DockerImageURI(USER_NAME_TAG); + assertNameAndTag(tag); + assertUserName(tag); + assertEquals("Expected to toString to return the correct uri", USER_NAME_TAG, tag.toString()); + } + + @Test + public void testRepoWithUserWithNameAndTag() { + DockerImageURI tag = new DockerImageURI(REPO_USER_NAME_TAG); + assertNameAndTag(tag); + assertUserName(tag); + assertRepoHost(tag); + assertEquals("Expected to toString to return the correct uri", REPO_USER_NAME_TAG, tag.toString()); + } + + private void assertRepoHost(DockerImageURI tag) { + assertEquals("Expected to parse our the repo host", REPO_HOST, tag.getRepositoryHost()); + } + + private void assertUserName(DockerImageURI tag) { + assertEquals("Expected to parse our the username", USERNAME, tag.getUserName()); + } + + private void assertNameAndTag(DockerImageURI tag) { + assertEquals("Expected to parse out the name", NAME, tag.getName()); + assertEquals("Expected to parse out the tage", TAG, tag.getTag()); + } } diff --git a/src/test/java/com/openshift/restclient/model/MocksFactory.java b/src/test/java/com/openshift/restclient/model/MocksFactory.java index d4da4827..58dd7a47 100644 --- a/src/test/java/com/openshift/restclient/model/MocksFactory.java +++ b/src/test/java/com/openshift/restclient/model/MocksFactory.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.model; import static org.mockito.Mockito.when; @@ -22,96 +23,86 @@ import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.utils.Samples; -/** - * A mock factory to return fixtures of api models. - * - * @author jeff.cantrill - * - */ public class MocksFactory { - - private IClient client; - private IResourceFactory factory; - public MocksFactory() { - this(Mockito.mock(IClient.class)); - } - - public MocksFactory(IClient client) { - this.client = client; - this.factory = new ResourceFactory(client); - } - - public IClient getClient() { - return client; - } - - public T mock(Class klass, String namespace, String name) { - T mock = mock(klass); - when(mock.getNamespaceName()).thenReturn(namespace); - when(mock.getName()).thenReturn(name); - return mock; - } - - /** - * Mock the given kind based on the class - * @param klass - * @return a mocked instance with mocked name, version, and namespace - */ - public T mock(Class klass) { - final String version = OpenShiftAPIVersion.v1.toString(); - T mock = Mockito.mock(klass); - when(mock.getName()).thenReturn("a" + klass.getSimpleName()); - when(mock.getApiVersion()).thenReturn(version); - when(mock.getNamespaceName()).thenReturn("aNamespace"); - when(mock.getKind()).thenReturn(klass.getSimpleName().substring(1)); - return mock; - } - - /** - * Stub a given kind based on the JSON files defined in {@link Samples} - * @param kind - * @return a stubbed resource - */ - public T stub(Class kind) { - String name = kind.getSimpleName(); - if(name.startsWith("I")) { - name = name.substring(1); - } - return stub(name); - } - - /** - * Stub a given kind based on the JSON files defined in {@link Samples} - * @param kind - * @return a stubbed resource - */ - public T stub(String kind) { - final String version = OpenShiftAPIVersion.v1.toString(); - String stub = String.format("%s_%s", version, splitCamelCase(kind, "_")).toUpperCase(); - try { - Field field = Samples.class.getField(stub); - Samples sample = (Samples) field.get(null); - return factory.create(sample.getContentAsString()); - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - throw new RuntimeException(String.format("Sample not found for kind %s"), e); - } - } - - /** - * Split the camelcase string and delimit with the given delimiter - * @param value the camelcase string - * @param delimiter the delimiter for the resulting string - * @return - */ - private String splitCamelCase(String value, String delimiter) { - return value.replaceAll( - String.format("%s|%s|%s", - "(?<=[A-Z])(?=[A-Z][a-z])", - "(?<=[^A-Z])(?=[A-Z])", - "(?<=[A-Za-z])(?=[^A-Za-z])" - ), - delimiter - ); - } + private IClient client; + private IResourceFactory factory; + + public MocksFactory() { + this(Mockito.mock(IClient.class)); + } + + public MocksFactory(IClient client) { + this.client = client; + this.factory = new ResourceFactory(client); + } + + public IClient getClient() { + return client; + } + + public T mock(Class klass, String namespace, String name) { + T mock = mock(klass); + when(mock.getNamespaceName()).thenReturn(namespace); + when(mock.getName()).thenReturn(name); + return mock; + } + + /** + * Mock the given kind based on the class + * + * @return a mocked instance with mocked name, version, and namespace + */ + public T mock(Class klass) { + final String version = OpenShiftAPIVersion.v1.toString(); + T mock = Mockito.mock(klass); + when(mock.getName()).thenReturn("a" + klass.getSimpleName()); + when(mock.getApiVersion()).thenReturn(version); + when(mock.getNamespaceName()).thenReturn("aNamespace"); + when(mock.getKind()).thenReturn(klass.getSimpleName().substring(1)); + return mock; + } + + /** + * Stub a given kind based on the JSON files defined in {@link Samples} + * + * @return a stubbed resource + */ + public T stub(Class kind) { + String name = kind.getSimpleName(); + if (name.startsWith("I")) { + name = name.substring(1); + } + return stub(name); + } + + /** + * Stub a given kind based on the JSON files defined in {@link Samples} + * + * @return a stubbed resource + */ + public T stub(String kind) { + final String version = OpenShiftAPIVersion.v1.toString(); + String stub = String.format("%s_%s", version, splitCamelCase(kind, "_")).toUpperCase(); + try { + Field field = Samples.class.getField(stub); + Samples sample = (Samples) field.get(null); + return factory.create(sample.getContentAsString()); + } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + throw new RuntimeException(String.format("Sample not found for kind %s"), e); + } + } + + /** + * Split the camelcase string and delimit with the given delimiter + * + * @param value + * the camelcase string + * @param delimiter + * the delimiter for the resulting string + */ + private String splitCamelCase(String value, String delimiter) { + return value.replaceAll(String.format("%s|%s|%s", "(?<=[A-Z])(?=[A-Z][a-z])", "(?<=[^A-Z])(?=[A-Z])", + "(?<=[A-Za-z])(?=[^A-Za-z])"), delimiter); + } } diff --git a/src/test/java/com/openshift/restclient/server/HttpServerFake.java b/src/test/java/com/openshift/restclient/server/HttpServerFake.java index 4ecbdcc8..02cbaddd 100644 --- a/src/test/java/com/openshift/restclient/server/HttpServerFake.java +++ b/src/test/java/com/openshift/restclient/server/HttpServerFake.java @@ -16,6 +16,7 @@ * under the License. * *************************************************************************/ + package com.openshift.restclient.server; import java.io.BufferedReader; @@ -31,174 +32,173 @@ import java.text.MessageFormat; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; + import org.apache.commons.io.IOUtils; + /** * @author André Dietisheim * @author Nicolas Spano */ public class HttpServerFake { - public static final int DEFAULT_PORT = 1234; - private static final String DEFAULT_STATUSLINE = "HTTP/1.1 200 OK\n"; - - private ExecutorService executor; - private int port; - private String response; - private String statusLine; - private ServerFakeSocket serverFakeSocket; - - public HttpServerFake(int port) { - this(port, null, DEFAULT_STATUSLINE); - } - - public HttpServerFake() { - this(null); - } - - public HttpServerFake(String response) { - this(DEFAULT_PORT, response, DEFAULT_STATUSLINE); - } - - public HttpServerFake(String response, String statusLine) { - this(DEFAULT_PORT, response, statusLine); - } - - /** - * - * @param port - * the port to listen to (address is always localhost) - * @param response - * the reponse to return to the requesting socket. If - * null the request string is returned. - * @param statusLine the status line that shall be returned - * - * @see ServerFakeSocket#getResponse(Socket) - */ - public HttpServerFake(int port, String response, String statusLine) { - this.port = port; - this.response = response; - if (statusLine != null) { - this.statusLine = statusLine; - } else { - this.statusLine = DEFAULT_STATUSLINE; - } - } - - public void start() throws Exception { - executor = Executors.newFixedThreadPool(1); - this.serverFakeSocket = createServerFakeSocket(statusLine, response, port); - executor.submit(serverFakeSocket); - } - - protected ServerFakeSocket createServerFakeSocket(String statusLine, String response, int port) throws Exception { - return new ServerFakeSocket(statusLine, response, port); - } - - public URL getUrl() throws MalformedURLException { - return new URL(MessageFormat.format("http://localhost:{0}/", String.valueOf(port))); - } - - public URL getHttpsUrl() throws MalformedURLException { - return new URL(MessageFormat.format("https://localhost:{0}/", String.valueOf(port))); - } - - public void stop() { - serverFakeSocket.close(); - executor.shutdownNow(); - } - - - protected void write(byte[] bytes, OutputStream outputStream) throws IOException{ + public static final int DEFAULT_PORT = 1234; + private static final String DEFAULT_STATUSLINE = "HTTP/1.1 200 OK\n"; + + private ExecutorService executor; + private int port; + private String response; + private String statusLine; + private ServerFakeSocket serverFakeSocket; + + public HttpServerFake(int port) { + this(port, null, DEFAULT_STATUSLINE); + } + + public HttpServerFake() { + this(null); + } + + public HttpServerFake(String response) { + this(DEFAULT_PORT, response, DEFAULT_STATUSLINE); + } + + public HttpServerFake(String response, String statusLine) { + this(DEFAULT_PORT, response, statusLine); + } + + /** + * + * @param port + * the port to listen to (address is always localhost) + * @param response + * the reponse to return to the requesting socket. If + * null the request string is returned. + * @param statusLine + * the status line that shall be returned + * + * @see ServerFakeSocket#getResponse(Socket) + */ + public HttpServerFake(int port, String response, String statusLine) { + this.port = port; + this.response = response; + if (statusLine != null) { + this.statusLine = statusLine; + } else { + this.statusLine = DEFAULT_STATUSLINE; + } + } + + public void start() throws Exception { + executor = Executors.newFixedThreadPool(1); + this.serverFakeSocket = createServerFakeSocket(statusLine, response, port); + executor.submit(serverFakeSocket); + } + + protected ServerFakeSocket createServerFakeSocket(String statusLine, String response, int port) throws Exception { + return new ServerFakeSocket(statusLine, response, port); + } + + public URL getUrl() throws MalformedURLException { + return new URL(MessageFormat.format("http://localhost:{0}/", String.valueOf(port))); + } + + public URL getHttpsUrl() throws MalformedURLException { + return new URL(MessageFormat.format("https://localhost:{0}/", String.valueOf(port))); + } + + public void stop() { + serverFakeSocket.close(); + executor.shutdownNow(); + } + + protected void write(byte[] bytes, OutputStream outputStream) throws IOException { outputStream.write(bytes); } - protected int getPort() { - return port; - } - - protected class ServerFakeSocket implements Runnable { - - private String statusLine; - private String response; - private ServerSocket serverSocket; - - public ServerFakeSocket(String statusLine, String response, int port) throws Exception { - this.statusLine = statusLine; - this.response = response; - this.serverSocket = createServerSocket(port); - } - - protected ServerSocket createServerSocket(int port) throws Exception { - return new ServerSocket(port); - } - - public void run() { - Socket socket = null; - OutputStream outputStream = null; - try { - socket = serverSocket.accept(); - String response = getResponse(socket); - outputStream = socket.getOutputStream(); - writeResponseHeader(outputStream); - write(response.getBytes(), outputStream); - outputStream.flush(); - } catch (IOException e) { - // e.printStackTrace(); - } finally { - // we should not close the connection, let the client close the - // connection - IOUtils.closeQuietly(outputStream); - } - } - - protected void writeResponseHeader(OutputStream outputStream) throws IOException { - outputStream.write(statusLine.getBytes()); - outputStream.write("\n".getBytes()); - } - - /** - * Returns the response given to this server at creation time or the - * content that may be read from the socket is returned. - * - * @param inputStream - * @return - * @throws IOException - */ - private String getResponse(Socket socket) throws IOException { - if (response != null) { - return response; - } - return readRequestToString(socket.getInputStream()); - } - - private String readRequestToString(InputStream inputStream) throws IOException { - BufferedReader bufferedReader = null; - bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - StringWriter writer = new StringWriter(); - String line = null; - while ((line = bufferedReader.readLine()) != null) { - if (line.isEmpty()) { - break; - } - writer.write(line); - writer.write('\n'); - } - return writer.toString(); - } - - public void close() { - silentlyClose(serverSocket); - } - - private void silentlyClose(ServerSocket serverSocket) { - if (serverSocket != null) { - try { - serverSocket.close(); - } catch (IOException e) { - //e.printStackTrace(); - } - } - } - - } + protected int getPort() { + return port; + } + + protected class ServerFakeSocket implements Runnable { + + private String statusLine; + private String response; + private ServerSocket serverSocket; + + public ServerFakeSocket(String statusLine, String response, int port) throws Exception { + this.statusLine = statusLine; + this.response = response; + this.serverSocket = createServerSocket(port); + } + + protected ServerSocket createServerSocket(int port) throws Exception { + return new ServerSocket(port); + } + + public void run() { + Socket socket = null; + OutputStream outputStream = null; + try { + socket = serverSocket.accept(); + String response = getResponse(socket); + outputStream = socket.getOutputStream(); + writeResponseHeader(outputStream); + write(response.getBytes(), outputStream); + outputStream.flush(); + } catch (IOException e) { + // e.printStackTrace(); + } finally { + // we should not close the connection, let the client close the + // connection + IOUtils.closeQuietly(outputStream); + } + } + + protected void writeResponseHeader(OutputStream outputStream) throws IOException { + outputStream.write(statusLine.getBytes()); + outputStream.write("\n".getBytes()); + } + + /** + * Returns the response given to this server at creation time or the content + * that may be read from the socket is returned. + * + */ + private String getResponse(Socket socket) throws IOException { + if (response != null) { + return response; + } + return readRequestToString(socket.getInputStream()); + } + + private String readRequestToString(InputStream inputStream) throws IOException { + BufferedReader bufferedReader = null; + bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); + StringWriter writer = new StringWriter(); + String line = null; + while ((line = bufferedReader.readLine()) != null) { + if (line.isEmpty()) { + break; + } + writer.write(line); + writer.write('\n'); + } + return writer.toString(); + } + + public void close() { + silentlyClose(serverSocket); + } + + private void silentlyClose(ServerSocket serverSocket) { + if (serverSocket != null) { + try { + serverSocket.close(); + } catch (IOException e) { + // e.printStackTrace(); + } + } + } + + } } diff --git a/src/test/java/com/openshift/restclient/server/HttpsServerFake.java b/src/test/java/com/openshift/restclient/server/HttpsServerFake.java index 00260530..76a99d65 100644 --- a/src/test/java/com/openshift/restclient/server/HttpsServerFake.java +++ b/src/test/java/com/openshift/restclient/server/HttpsServerFake.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.server; import java.net.MalformedURLException; @@ -25,71 +26,75 @@ /** * A Https server fake that holds a single self-signed certificate in its * keystore. The certificate is in src/test/resources/server-keystore.jks and - * hold a single self-signed certificate that was created in the following way (password: 123456): - *

+ * hold a single self-signed certificate that was created in the following way
+ * (password: 123456):
+ * 
+ * 
+ * 
  * keytool -genkey -keystore server-keystore.jks -alias localhost -dname "CN=localhost,OU=JBoss Tools" -keyalg "RSA" -sigalg "SHA1withRSA" -keysize 2048 -validity 3650
- * 
+ *
+ *
* * @author André Dietisheim */ public class HttpsServerFake extends HttpServerFake { - private static final String KEYSTORE_PASSWORD = "123456"; - private static final String KEYSTORE_TYPE = "JKS"; - private static final String KEYSTORE_FILE = "/server-keystore.jks"; - - public HttpsServerFake(int port) { - super(port); - } + private static final String KEYSTORE_PASSWORD = "123456"; + private static final String KEYSTORE_TYPE = "JKS"; + private static final String KEYSTORE_FILE = "/server-keystore.jks"; - /** - * - * @param port - * the port to listen to (address is always localhost) - * @param response - * the reponse to return to the requesting socket. If - * null the request string is returned. - * @param statusLine - * the status line that shall be returned - * - * @see ServerFakeSocket#getResponse(Socket) - */ - public HttpsServerFake(int port, String response, String statusLine) { - super(port, response, statusLine); - } + public HttpsServerFake(int port) { + super(port); + } - @Override - public URL getUrl() throws MalformedURLException { - return new URL(MessageFormat.format("https://localhost:{0}/", String.valueOf(getPort()))); - } + /** + * + * @param port + * the port to listen to (address is always localhost) + * @param response + * the reponse to return to the requesting socket. If + * null the request string is returned. + * @param statusLine + * the status line that shall be returned + * + * @see ServerFakeSocket#getResponse(Socket) + */ + public HttpsServerFake(int port, String response, String statusLine) { + super(port, response, statusLine); + } - @Override - protected ServerFakeSocket createServerFakeSocket(String statusLine, String response, int port) throws Exception { - return new HttpsServerFakeSocket(statusLine, response, port); - } + @Override + public URL getUrl() throws MalformedURLException { + return new URL(MessageFormat.format("https://localhost:{0}/", String.valueOf(getPort()))); + } + @Override + protected ServerFakeSocket createServerFakeSocket(String statusLine, String response, int port) throws Exception { + return new HttpsServerFakeSocket(statusLine, response, port); + } - protected class HttpsServerFakeSocket extends ServerFakeSocket { + protected class HttpsServerFakeSocket extends ServerFakeSocket { - public HttpsServerFakeSocket(String statusLine, String response, int port) throws Exception { - super(statusLine, response, port); - } + public HttpsServerFakeSocket(String statusLine, String response, int port) throws Exception { + super(statusLine, response, port); + } - @Override - protected ServerSocket createServerSocket(int port) throws Exception { - KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); - keyStore.load(getClass().getResourceAsStream(KEYSTORE_FILE), KEYSTORE_PASSWORD.toCharArray()); + @Override + protected ServerSocket createServerSocket(int port) throws Exception { + KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE); + keyStore.load(getClass().getResourceAsStream(KEYSTORE_FILE), KEYSTORE_PASSWORD.toCharArray()); - KeyManagerFactory keyManagerFactory = - KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - keyManagerFactory.init(keyStore, KEYSTORE_PASSWORD.toCharArray()); - KeyManager keyManagers[] = keyManagerFactory.getKeyManagers(); + KeyManagerFactory keyManagerFactory = KeyManagerFactory + .getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, KEYSTORE_PASSWORD.toCharArray()); + KeyManager [] keyManagers = keyManagerFactory.getKeyManagers(); - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(keyManagers, null, null); - SSLServerSocket sslServerSocket = (SSLServerSocket) sslContext.getServerSocketFactory().createServerSocket(port); - sslServerSocket.setEnabledCipherSuites(sslContext.getServerSocketFactory().getSupportedCipherSuites()); - return sslServerSocket; - } - } + SSLContext sslContext = SSLContext.getInstance("TLS"); + sslContext.init(keyManagers, null, null); + SSLServerSocket sslServerSocket = (SSLServerSocket) sslContext.getServerSocketFactory() + .createServerSocket(port); + sslServerSocket.setEnabledCipherSuites(sslContext.getServerSocketFactory().getSupportedCipherSuites()); + return sslServerSocket; + } + } } diff --git a/src/test/java/com/openshift/restclient/server/WaitingHttpServerFake.java b/src/test/java/com/openshift/restclient/server/WaitingHttpServerFake.java index 6b417801..33ffd6d1 100644 --- a/src/test/java/com/openshift/restclient/server/WaitingHttpServerFake.java +++ b/src/test/java/com/openshift/restclient/server/WaitingHttpServerFake.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.server; import java.io.IOException; diff --git a/src/test/java/com/openshift/restclient/utils/ExceptionCauseMatcher.java b/src/test/java/com/openshift/restclient/utils/ExceptionCauseMatcher.java index 54738825..38eb77c3 100644 --- a/src/test/java/com/openshift/restclient/utils/ExceptionCauseMatcher.java +++ b/src/test/java/com/openshift/restclient/utils/ExceptionCauseMatcher.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.utils; import org.hamcrest.Description; @@ -19,19 +20,18 @@ */ public class ExceptionCauseMatcher extends TypeSafeMatcher { - private Matcher causeMatcher; + private Matcher causeMatcher; - public ExceptionCauseMatcher(Matcher matcher) { - this.causeMatcher = matcher; - } + public ExceptionCauseMatcher(Matcher matcher) { + this.causeMatcher = matcher; + } - public void describeTo(Description description) { - description.appendText("exception with cause "); - } - - @Override - public boolean matchesSafely(Throwable throwable) { - return causeMatcher.matches(throwable.getCause()); - } -} + public void describeTo(Description description) { + description.appendText("exception with cause "); + } + @Override + public boolean matchesSafely(Throwable throwable) { + return causeMatcher.matches(throwable.getCause()); + } +} diff --git a/src/test/java/com/openshift/restclient/utils/ResourceTestHelper.java b/src/test/java/com/openshift/restclient/utils/ResourceTestHelper.java index cbe229fd..99248d2d 100644 --- a/src/test/java/com/openshift/restclient/utils/ResourceTestHelper.java +++ b/src/test/java/com/openshift/restclient/utils/ResourceTestHelper.java @@ -8,9 +8,12 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.utils; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.openshift.restclient.IClient; import com.openshift.restclient.model.IDeploymentConfig; @@ -18,29 +21,28 @@ /** * Helper for BDD driven unit tests - * @author jeff.cantrill * */ public class ResourceTestHelper { - public static void givenResourceIsAnnotatedWith(IResource resource, String annotation, String value) { - when(resource.isAnnotatedWith(annotation)).thenReturn(true); - when(resource.getAnnotation(annotation)).thenReturn(value); - } - - public static void givenDeployConfigIsVersion(IDeploymentConfig config, int version) { - when(config.getLatestVersionNumber()).thenReturn(version); - } - - public static void thenResourceShouldBeUpdated(IClient client, IResource config) { - verify(client, times(1)).update(config); - } - - public static void thenResourceShouldNotBeUpdated(IClient client, IResource config) { - verify(client, times(0)).update(config); - } - - public static void thenResourceShouldBeRetrieved(IClient client, String namespace, String kind, String name) { - verify(client, times(1)).get(kind, name, namespace); - } + public static void givenResourceIsAnnotatedWith(IResource resource, String annotation, String value) { + when(resource.isAnnotatedWith(annotation)).thenReturn(true); + when(resource.getAnnotation(annotation)).thenReturn(value); + } + + public static void givenDeployConfigIsVersion(IDeploymentConfig config, int version) { + when(config.getLatestVersionNumber()).thenReturn(version); + } + + public static void thenResourceShouldBeUpdated(IClient client, IResource config) { + verify(client, times(1)).update(config); + } + + public static void thenResourceShouldNotBeUpdated(IClient client, IResource config) { + verify(client, times(0)).update(config); + } + + public static void thenResourceShouldBeRetrieved(IClient client, String namespace, String kind, String name) { + verify(client, times(1)).get(kind, name, namespace); + } } diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 13613969..5603bd79 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.restclient.utils; import java.io.InputStream; @@ -19,79 +20,78 @@ * @author Jeff Cantrill */ public enum Samples { - - OPENSHIFT_VERSION("openshift3/api_openshift_version.json"), - KUBERNETES_VERSION("openshift3/api_kubernetes_version.json"), + OPENSHIFT_VERSION("openshift3/api_openshift_version.json"), + KUBERNETES_VERSION("openshift3/api_kubernetes_version.json"), - GROUP_ENDPONT_API_V1("openshift3/api_v1_endpoint.json"), - GROUP_ENDPONT_OAPI_V1("openshift3/oapi_v1_endpoint.json"), - GROUP_ENDPONT_APIS("openshift3/apis_endpoint.json"), - GROUP_ENDPONT_APIS_EXTENSIONS("openshift3/apis_endpoint_extensions.json"), - - // api/extensions - V1BETA1_API_EXT_SCALE("openshift3/api/extensions/v1beta1_scale.json"), - - //v1 - V1_KUBE_CONFIG("openshift3/v1_kubeconfig.yaml"), + GROUP_ENDPONT_API_V1("openshift3/api_v1_endpoint.json"), + GROUP_ENDPONT_OAPI_V1("openshift3/oapi_v1_endpoint.json"), + GROUP_ENDPONT_APIS("openshift3/apis_endpoint.json"), + GROUP_ENDPONT_APIS_EXTENSIONS("openshift3/apis_endpoint_extensions.json"), + + // api/extensions + V1BETA1_API_EXT_SCALE("openshift3/api/extensions/v1beta1_scale.json"), + + //v1 + V1_KUBE_CONFIG("openshift3/v1_kubeconfig.yaml"), - V1_BUILD_CONFIG("openshift3/v1_build_config.json"), - V1_BUILD_CONFIG_LIST("openshift3/v1_build_config_list.json"), - V1_DEPLOYMENT_CONIFIG("openshift3/v1_deployment_config.json"), - V1_ENDPOINTS("openshift3/api/v1_endpoints.json"), - V1_EVENT("openshift3/v1_event.json"), - V1_IMAGE_STREAM("openshift3/v1_image_stream.json"), - V1_IMAGE_STREAM_IMPORT("openshift3/v1_image_stream_import.json"), - V1_BUILD("openshift3/v1_build.json"), - V1_OBJECT_REF("openshift3/v1_objectref.json"), - V1_NAMESPACE("openshift3/v1_namespace.json"), - V1_POD("openshift3/v1_pod.json"), - V1_PROJECT("openshift3/v1_project.json"), - V1_PROJECT_REQUEST("openshift3/v1_project_request.json"), - V1_PVC("openshift3/v1_pvc.json"), - V1_PERSISTENT_VOLUME("openshift3/v1_persistent_volume.json"), - V1_REPLICATION_CONTROLLER("openshift3/v1_replication_controller.json"), - V1_ROLE_BINDING("openshift3/v1_role_binding.json"), - V1_ROUTE("openshift3/v1_route.json"), - V1_ROUTE_WO_TLS("openshift3/v1_route_wo_tls.json"), - V1_ROUTE_PORT_NUMERIC("openshift3/v1_route_port_numeric.json"), - V1_ROUTE_PORT_NAME("openshift3/v1_route_port_name.json"), - V1_SERVICE("openshift3/v1_service.json"), - V1_SERVICE_ACCOUNT("openshift3/v1_service_account.json"), - V1_Status("openshift3/v1_status.json"), - V1_TEMPLATE("openshift3/v1_template.json"), - V1_USER("openshift3/v1_user.json"), - V1_SECRET("openshift3/v1_secret.json"), - V1_UNRECOGNIZED("openshift3/v1_unrecognized.json"), - V1_CONFIG_MAP("openshift3/v1_config_map.json"), - V1_CONFIG_MAP_LIST_EMPTY("openshift3/v1_config_map_list_empty.json"), - V1_EMPTYDIR_VOLUME_SOURCE("openshift3/v1_empty_dir_volume_source.json"), - V1_SECRET_VOLUME_SOURCE("openshift3/v1_secret_volume_source.json"), - V1_PVC_VOLUME_SOURCE("openshift3/v1_pvc_volume_source.json"), + V1_BUILD_CONFIG("openshift3/v1_build_config.json"), + V1_BUILD_CONFIG_LIST("openshift3/v1_build_config_list.json"), + V1_DEPLOYMENT_CONIFIG("openshift3/v1_deployment_config.json"), + V1_ENDPOINTS("openshift3/api/v1_endpoints.json"), + V1_EVENT("openshift3/v1_event.json"), + V1_IMAGE_STREAM("openshift3/v1_image_stream.json"), + V1_IMAGE_STREAM_IMPORT("openshift3/v1_image_stream_import.json"), + V1_BUILD("openshift3/v1_build.json"), + V1_OBJECT_REF("openshift3/v1_objectref.json"), + V1_NAMESPACE("openshift3/v1_namespace.json"), + V1_POD("openshift3/v1_pod.json"), + V1_PROJECT("openshift3/v1_project.json"), + V1_PROJECT_REQUEST("openshift3/v1_project_request.json"), + V1_PVC("openshift3/v1_pvc.json"), + V1_PERSISTENT_VOLUME("openshift3/v1_persistent_volume.json"), + V1_REPLICATION_CONTROLLER("openshift3/v1_replication_controller.json"), + V1_ROLE_BINDING("openshift3/v1_role_binding.json"), + V1_ROUTE("openshift3/v1_route.json"), + V1_ROUTE_WO_TLS("openshift3/v1_route_wo_tls.json"), + V1_ROUTE_PORT_NUMERIC("openshift3/v1_route_port_numeric.json"), + V1_ROUTE_PORT_NAME("openshift3/v1_route_port_name.json"), + V1_SERVICE("openshift3/v1_service.json"), + V1_SERVICE_ACCOUNT("openshift3/v1_service_account.json"), + V1_Status("openshift3/v1_status.json"), + V1_TEMPLATE("openshift3/v1_template.json"), + V1_USER("openshift3/v1_user.json"), + V1_SECRET("openshift3/v1_secret.json"), + V1_UNRECOGNIZED("openshift3/v1_unrecognized.json"), + V1_CONFIG_MAP("openshift3/v1_config_map.json"), + V1_CONFIG_MAP_LIST_EMPTY("openshift3/v1_config_map_list_empty.json"), + V1_EMPTYDIR_VOLUME_SOURCE("openshift3/v1_empty_dir_volume_source.json"), + V1_SECRET_VOLUME_SOURCE("openshift3/v1_secret_volume_source.json"), + V1_PVC_VOLUME_SOURCE("openshift3/v1_pvc_volume_source.json"), V1_LIFECYCLE("openshift3/v1_lifecycle.json"), - V1_DOCKER_IMAGE_MANIFEST("dockerregistry/v1_image_manifest.json"), - V1_BUILDCONFIG_PIPELINE("openshift3/v1_buildconfig_pipeline.json"); + V1_DOCKER_IMAGE_MANIFEST("dockerregistry/v1_image_manifest.json"), + V1_BUILDCONFIG_PIPELINE("openshift3/v1_buildconfig_pipeline.json"); + + private static final String SAMPLES_FOLDER = "/samples/"; - private static final String SAMPLES_FOLDER = "/samples/"; + private String filePath; - private String filePath; + Samples(String fileName) { + this.filePath = SAMPLES_FOLDER + fileName; + } - Samples(String fileName) { - this.filePath = SAMPLES_FOLDER + fileName; - } - - Samples(String root, String filename){ - this.filePath = root + filename; - } + Samples(String root, String filename) { + this.filePath = root + filename; + } - public String getContentAsString() { - String content = null; - try { - final InputStream contentStream = Samples.class.getResourceAsStream(filePath); - content = IOUtils.toString(contentStream, "UTF-8"); - } catch (Throwable e) { - e.printStackTrace(); - throw new RuntimeException("Could not read file " + filePath + ": " + e.getMessage()); - } - return content; - } + public String getContentAsString() { + String content = null; + try { + final InputStream contentStream = Samples.class.getResourceAsStream(filePath); + content = IOUtils.toString(contentStream, "UTF-8"); + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException("Could not read file " + filePath + ": " + e.getMessage()); + } + return content; + } } From 7e3f1a4f6ce1ac593da990ca485b24d2b6ab0fd5 Mon Sep 17 00:00:00 2001 From: Vlad Slepukhin Date: Wed, 18 Apr 2018 16:33:18 +0400 Subject: [PATCH 114/258] Add Proxy/ProxySelector capabilities to ClientBuilder --- .../openshift/restclient/ClientBuilder.java | 34 ++++- .../okhttp/ClientProxyConnectionTest.java | 127 ++++++++++++++++++ 2 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/okhttp/ClientProxyConnectionTest.java diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 636495f9..8c1fdd4d 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -12,6 +12,8 @@ package com.openshift.restclient; import java.io.IOException; +import java.net.Proxy; +import java.net.ProxySelector; import java.net.URL; import java.security.KeyManagementException; import java.security.KeyStore; @@ -62,6 +64,9 @@ public class ClientBuilder { private String token; private String password; private String userAgentPrefix; + + private Proxy proxy; + private ProxySelector proxySelector; private Authenticator proxyAuthenticator; private int maxRequests = 64; @@ -143,7 +148,7 @@ public ClientBuilder withConnectTimeout(int timeout, TimeUnit unit) { /** * The connect timeout parameter used for establishing the connection to a * remote server - * + * * @param connectInMillis * A value in milliseconds */ @@ -151,7 +156,7 @@ public ClientBuilder withConnectTimeout(int connectInMillis) { this.connectTimeout = connectInMillis; return this; } - + public ClientBuilder withReadTimeout(int timeout, TimeUnit unit) { this.readTimeout = timeout; this.readTimeoutUnit = unit; @@ -164,6 +169,17 @@ public ClientBuilder withWriteTimeout(int timeout, TimeUnit unit) { return this; } + public ClientBuilder proxy(Proxy proxy) { + this.proxy = proxy; + return this; + } + + public ClientBuilder proxySelector(ProxySelector proxySelector) { + this.proxySelector = proxySelector; + return this; + } + + public ClientBuilder proxyAuthenticator(Authenticator proxyAuthenticator) { this.proxyAuthenticator = proxyAuthenticator; return this; @@ -172,7 +188,7 @@ public ClientBuilder proxyAuthenticator(Authenticator proxyAuthenticator) { /** * The maximum concurrent requests for this client. - * + * * @param maxRequests * the maximum number of concurrent requests * @return the client builder @@ -184,7 +200,7 @@ public ClientBuilder withMaxRequests(int maxRequests) { /** * The maximum concurrent request for this client for a single host. - * + * * @param maxRequestsPerHost * the maximum number of concurrent requests for a single host * @return the client builder @@ -196,7 +212,7 @@ public ClientBuilder withMaxRequestsPerHost(int maxRequestsPerHost) { /** * Build a client - * + * * @throws KeyManagementException an exception */ public IClient build() { @@ -232,6 +248,14 @@ public Response intercept(Chain chain) throws IOException { builder.hostnameVerifier(sslCertificateCallback); } + if (proxy != null) { + builder.proxy(proxy); + } + + if (proxySelector != null) { + builder.proxySelector(proxySelector); + } + if (proxyAuthenticator != null) { builder.proxyAuthenticator(proxyAuthenticator); } diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/ClientProxyConnectionTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/ClientProxyConnectionTest.java new file mode 100644 index 00000000..f4171895 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/okhttp/ClientProxyConnectionTest.java @@ -0,0 +1,127 @@ +/******************************************************************************* + * Copyright (c) 2015 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package com.openshift.internal.restclient.okhttp; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.internal.restclient.DefaultClient; +import com.openshift.restclient.ClientBuilder; + +import okhttp3.OkHttpClient; + +/** + * @author Vlad Slepukhin + */ +public class ClientProxyConnectionTest { + + private static final Logger LOG = LoggerFactory.getLogger(ClientProxyConnectionTest.class); + + + private static final String OPENSHIFT_URL = "https://openshift.test.com"; + private static final String PROXY_HOST = "127.0.0.1"; + private static final int PROXY_PORT = 8080; + + private class TestProxySelector extends ProxySelector { + + @Override + public List select(URI uri) { + List result = new ArrayList<>(); + result.add(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT))); + return result; + } + + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + } + } + + @Test + public void testProxySetInOkHttp() throws NoSuchFieldException, IllegalAccessException { + Proxy expectedProxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT)); + DefaultClient client = (DefaultClient) new ClientBuilder(OPENSHIFT_URL) + .proxy(expectedProxy) + .build(); + + OkHttpClient okClient = getOkHttpClient(client); + Proxy proxyInOkClient = okClient.proxy(); + + LOG.info(proxyInOkClient.toString()); + + assertEquals(expectedProxy.type(), proxyInOkClient.type()); + assertEquals(expectedProxy.address(), proxyInOkClient.address()); + } + + @Test + public void testProxyNotSetInOkHttp() throws NoSuchFieldException, IllegalAccessException { + DefaultClient client = (DefaultClient) new ClientBuilder(OPENSHIFT_URL) + .build(); + + OkHttpClient okClient = getOkHttpClient(client); + Proxy proxyInOkClient = okClient.proxy(); + + assertNull(proxyInOkClient); + } + + @Test + public void testProxySelectorSetInOkHttp() throws NoSuchFieldException, IllegalAccessException { + ProxySelector expectedSelector = new TestProxySelector(); + DefaultClient client = (DefaultClient) new ClientBuilder(OPENSHIFT_URL) + .proxySelector(expectedSelector) + .build(); + + + OkHttpClient okClient = getOkHttpClient(client); + ProxySelector proxySelector = okClient.proxySelector(); + + assertNotSame(proxySelector, ProxySelector.getDefault()); + assertEquals(expectedSelector, proxySelector); + + Proxy expectedProxyFromList = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(PROXY_HOST, PROXY_PORT)); + Proxy actualProxyFromList = proxySelector.select(null).get(0); + assertEquals(expectedProxyFromList.type(), actualProxyFromList.type()); + assertEquals(expectedProxyFromList.address(), actualProxyFromList.address()); + } + + @Test + public void testProxySelectorNotSetInOkHttp() throws NoSuchFieldException, IllegalAccessException { + DefaultClient client = (DefaultClient) new ClientBuilder(OPENSHIFT_URL) + .build(); + + OkHttpClient okClient = getOkHttpClient(client); + ProxySelector proxySelector = okClient.proxySelector(); + + assertEquals(proxySelector, ProxySelector.getDefault()); + } + + + private OkHttpClient getOkHttpClient(DefaultClient client) throws NoSuchFieldException, IllegalAccessException { + Field clientField = client.getClass().getDeclaredField("client"); + clientField.setAccessible(true); + return (OkHttpClient) clientField.get(client); + } +} From 53ab8783f1ccfff9f42a5048dd9f24abc484ac57 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Tue, 15 May 2018 12:30:57 +0200 Subject: [PATCH 115/258] JBIDE-25673: api for getting status of project --- .../com/openshift/internal/restclient/model/Project.java | 8 ++++++++ .../java/com/openshift/restclient/model/IProject.java | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/main/java/com/openshift/internal/restclient/model/Project.java b/src/main/java/com/openshift/internal/restclient/model/Project.java index 9de52420..ee433bfb 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Project.java +++ b/src/main/java/com/openshift/internal/restclient/model/Project.java @@ -29,6 +29,9 @@ public class Project extends KubernetesResource implements IProject { private static final String ANNOTATION_DISPLAY_NAME = "openshift.io/display-name"; private static final String ANNOTATION_DESCRIPTION = "openshift.io/description"; + + private static final String PROJECT_STATUS = "status"; + private static final String PROJECT_STATUS_PHASE = "phase"; public Project(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); @@ -74,4 +77,9 @@ public List getResources(String kind) { } return getClient().list(kind, getName()); } + + @Override + public String getStatus() { + return getNode().get(PROJECT_STATUS, PROJECT_STATUS_PHASE).asString(); + } } diff --git a/src/main/java/com/openshift/restclient/model/IProject.java b/src/main/java/com/openshift/restclient/model/IProject.java index bcf036ee..db19c5b7 100644 --- a/src/main/java/com/openshift/restclient/model/IProject.java +++ b/src/main/java/com/openshift/restclient/model/IProject.java @@ -28,5 +28,7 @@ public interface IProject extends IResource { String getDescription(); void setDescription(String value); + + String getStatus(); } From a5ae8a29bda9704be72560e9d99c1943586b0b3b Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Tue, 15 May 2018 12:44:03 +0200 Subject: [PATCH 116/258] jbide-25673: project.getStatus() test --- .../openshift/internal/restclient/model/v1/ProjectTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ProjectTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ProjectTest.java index 9ef559e6..12051100 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ProjectTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ProjectTest.java @@ -48,4 +48,9 @@ public void testGetDisplayName() { public void testGetDescription() { assertEquals("This is an example project to demonstrate OpenShift v3", project.getDescription()); } + + @Test + public void testGetStatus() { + assertEquals("Active", project.getStatus()); + } } \ No newline at end of file From 644e7284a77c956f1a3131710b9f9d49708d1f64 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Thu, 17 May 2018 12:01:48 +0200 Subject: [PATCH 117/258] bumping to 6.0.1.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3408b3c8..b6791ca7 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.0.1-SNAPSHOT + 6.0.1.Final jar OpenShift Java REST Client http://openshift.redhat.com From c1e98ffccfd4009a51929dbbbdd304255a531de6 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Tue, 22 May 2018 17:33:27 +0200 Subject: [PATCH 118/258] jbide-25673: add resource status constants to restclient Signed-off-by: Dmitrii Bocharov --- .../internal/restclient/model/Pod.java | 3 ++- .../restclient/utils/ResourceStatus.java | 23 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/openshift/restclient/utils/ResourceStatus.java diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index ffd9e086..909100b8 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -29,6 +29,7 @@ import com.openshift.restclient.model.IContainer; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IPort; +import com.openshift.restclient.utils.ResourceStatus; public class Pod extends KubernetesResource implements IPod { @@ -87,7 +88,7 @@ public Collection getImages() { @Override public String getStatus() { if (has(POD_DELETION_TIMESTAMP)) { - return "Terminating"; + return ResourceStatus.TERMINATING.getValue(); } ModelNode node = get(POD_STATUS_CONTAINER_STATUSES); if (node.getType() == ModelType.LIST) { diff --git a/src/main/java/com/openshift/restclient/utils/ResourceStatus.java b/src/main/java/com/openshift/restclient/utils/ResourceStatus.java new file mode 100644 index 00000000..a5ccd023 --- /dev/null +++ b/src/main/java/com/openshift/restclient/utils/ResourceStatus.java @@ -0,0 +1,23 @@ +package com.openshift.restclient.utils; + +public enum ResourceStatus { + + ACTIVE("Active"), + TERMINATING("Terminating"); + + private String value; + + private ResourceStatus(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + + @Override + public String toString() { + return this.value; + } + +} From 3c2dc8fe658026ef005658cdb86bde6fc185480d Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 22 May 2018 22:26:03 +0200 Subject: [PATCH 119/258] bump to 6.0.2-SNAPSHOT after release of 6.0.1.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b6791ca7..7517162b 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.0.1.Final + 6.0.2-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 60f464bb28e5599118eb6fd91411600049c1d856 Mon Sep 17 00:00:00 2001 From: Dmitrii Bocharov Date: Wed, 23 May 2018 11:20:10 +0200 Subject: [PATCH 120/258] jbide-25673: change enum to interface with constants --- .../internal/restclient/model/Pod.java | 2 +- .../restclient/utils/ResourceStatus.java | 21 +++---------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index 909100b8..523367f9 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -88,7 +88,7 @@ public Collection getImages() { @Override public String getStatus() { if (has(POD_DELETION_TIMESTAMP)) { - return ResourceStatus.TERMINATING.getValue(); + return ResourceStatus.TERMINATING; } ModelNode node = get(POD_STATUS_CONTAINER_STATUSES); if (node.getType() == ModelType.LIST) { diff --git a/src/main/java/com/openshift/restclient/utils/ResourceStatus.java b/src/main/java/com/openshift/restclient/utils/ResourceStatus.java index a5ccd023..0eba70b4 100644 --- a/src/main/java/com/openshift/restclient/utils/ResourceStatus.java +++ b/src/main/java/com/openshift/restclient/utils/ResourceStatus.java @@ -1,23 +1,8 @@ package com.openshift.restclient.utils; -public enum ResourceStatus { +public interface ResourceStatus { - ACTIVE("Active"), - TERMINATING("Terminating"); - - private String value; - - private ResourceStatus(String value) { - this.value = value; - } - - public String getValue() { - return this.value; - } - - @Override - public String toString() { - return this.value; - } + public static final String ACTIVE = "Active"; + public static final String TERMINATING = "Terminating"; } From 31b100052b4672992ff683e112734f49ba64797f Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 23 May 2018 13:23:53 +0200 Subject: [PATCH 121/258] bumping to 6.1.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7517162b..c5b081c2 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.0.2-SNAPSHOT + 6.1.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From dc508faa569b9ce8c4815849171ef99fd1ddaa8b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 23 May 2018 13:25:54 +0200 Subject: [PATCH 122/258] releasing 6.1.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c5b081c2..c142b4da 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.0-SNAPSHOT + 6.1.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From 1a5c34e32ef38e84e3133344e8e92641f7e6d4af Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 23 May 2018 21:48:46 +0200 Subject: [PATCH 123/258] bumping to 6.1.1-SNAPSHOT after release of 6.1.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c142b4da..2a8c1d53 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.0.Final + 6.1.1-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 6d7bb8091a8da15fd8a0da789df177d1c5e8ffa1 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 5 Jul 2018 23:21:18 +0200 Subject: [PATCH 124/258] [JBIDE-26172] corrected request url when using api groups --- pom.xml | 2 +- .../internal/restclient/DefaultClient.java | 23 ++++++++++++++--- .../internal/restclient/URLBuilder.java | 25 ++++++++++++------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 2a8c1d53..5a6f1285 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.1-SNAPSHOT + 6.1.1.Final jar OpenShift Java REST Client http://openshift.redhat.com diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 58114a74..2257072b 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -239,11 +239,20 @@ public T execute(ITypeFactory factory, String method, String kind, String na if (ResourceKind.LIST.equals(kind)) { throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); } - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper).kind(kind).name(name).namespace(namespace) - .subresource(subresource).subContext(subContext).addParameters(params).build(); + + final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) + .apiVersion(getApiVersion(payload)) + .kind(kind) + .name(name) + .namespace(namespace) + .subresource(subresource) + .subContext(subContext) + .addParameters(params) + .build(); try { - Request request = newRequestBuilderTo(endpoint.toString()).method(method, getPayload(method, payload)) + Request request = newRequestBuilderTo(endpoint.toString()) + .method(method, getPayload(method, payload)) .build(); LOGGER.debug("About to make {} request: {}", request.method(), request); try (Response result = client.newCall(request).execute()) { @@ -256,6 +265,14 @@ public T execute(ITypeFactory factory, String method, String kind, String na } } + private String getApiVersion(JSONSerializeable payload) { + String apiVersion = null; + if (payload instanceof IResource) { + apiVersion = ((IResource) payload).getApiVersion(); + } + return apiVersion; + } + private RequestBody getPayload(String method, JSONSerializeable payload) { switch (method.toUpperCase()) { case "GET": diff --git a/src/main/java/com/openshift/internal/restclient/URLBuilder.java b/src/main/java/com/openshift/internal/restclient/URLBuilder.java index f32fa06a..942488ee 100644 --- a/src/main/java/com/openshift/internal/restclient/URLBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/URLBuilder.java @@ -150,15 +150,8 @@ private void buildWithNamespaceInPath(StringBuilder url) { } url.append("/"); IVersionedApiResource apiResource = typeMappings.getEndpointFor(apiVersion, kind); - url.append(apiResource.getPrefix()).append("/").append(apiResource.getVersion()); - if (namespace == null && apiResource.isNamespaced()) { - LOG.debug( - "The api endpoint for kind '{}' requires a namespace but none was provided. Will only work for priviledged user.", - kind); - } - if (!ResourceKind.PROJECT.equals(kind) && namespace != null) { - url.append("/namespaces/").append(namespace); - } + appendApiResource(url, apiResource); + appendNamespace(url); url.append("/").append(apiResource.getName()); if (name != null) { url.append("/").append(name); @@ -177,6 +170,20 @@ private void buildWithNamespaceInPath(StringBuilder url) { url = appendParameters(url); } + private void appendApiResource(StringBuilder url, IVersionedApiResource apiResource) { + url.append(apiResource.getPrefix()).append("/"); + if (!StringUtils.isEmpty(apiResource.getApiGroupName())) { + url.append(apiResource.getApiGroupName()).append("/"); + } + url.append(apiResource.getVersion()); + } + + private void appendNamespace(StringBuilder url) { + if (!ResourceKind.PROJECT.equals(kind) && namespace != null) { + url.append("/namespaces/").append(namespace); + } + } + private StringBuilder appendParameters(StringBuilder url) { if (!params.isEmpty()) { url.append(IHttpConstants.QUESTION_MARK); From c1eb51c3ffa78ae6c7c298a46f1e510d25c0bc46 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 6 Jul 2018 00:46:30 +0200 Subject: [PATCH 125/258] bumping 6.1.1.Final -> 6.1.2-SNAPSHOT after release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5a6f1285..7ce21a67 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.1.Final + 6.1.2-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 7b0c59c17fea6b6f50ffadf3d3e6740c8419c12d Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 31 Jul 2018 16:02:46 +0200 Subject: [PATCH 126/258] [339] dont use -p when port forwarding (deprecated in oc 3.11) Signed-off-by: Andre Dietisheim --- .../capability/resources/OpenShiftBinaryPortForwarding.java | 2 +- .../resources/OpenShiftBinaryPortForwardingTest.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java index 74207e9b..c94858bd 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwarding.java @@ -40,7 +40,7 @@ public PodName(IPod pod) { @Override public void append(StringBuilder commandLine) { - commandLine.append(" -p ").append(pod.getName()); + commandLine.append(' ').append(pod.getName()); } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java index 8c7ca84d..eaaee470 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java @@ -76,7 +76,7 @@ public void shouldBuildCommandLineWithoutSkipSSL() { ProcessBuilder builder = processBuilderArgument.getValue(); assertThat(builder.command()) .isEqualTo(Arrays.asList(OC_LOCATION, OpenShiftBinaryPortForwarding.PORT_FORWARD_COMMAND, - "--token=" + TOKEN, "--server=" + SERVER_URL.toString(), "-n", POD_NAMESPACE, "-p", POD_NAME, + "--token=" + TOKEN, "--server=" + SERVER_URL.toString(), "-n", POD_NAMESPACE, POD_NAME, LOCAL_PORT2 + ":" + REMOTE_PORT2)); } @@ -94,6 +94,6 @@ public void shouldBuildCommandLineWith2PortsSkipSSL() { assertThat(builder.command()).isEqualTo( Arrays.asList(OC_LOCATION, OpenShiftBinaryPortForwarding.PORT_FORWARD_COMMAND, "--token=" + TOKEN, "--server=" + SERVER_URL.toString(), "--insecure-skip-tls-verify=true", "-n", POD_NAMESPACE, - "-p", POD_NAME, LOCAL_PORT1 + ":" + REMOTE_PORT1, LOCAL_PORT2 + ":" + REMOTE_PORT2)); + POD_NAME, LOCAL_PORT1 + ":" + REMOTE_PORT1, LOCAL_PORT2 + ":" + REMOTE_PORT2)); } } From aab77c755e61793770b3747521b5c365ccefaaba Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 5 Sep 2018 10:16:10 +0200 Subject: [PATCH 127/258] [#345] use /healthz for server health checks /healthz/ready was deprecated in 3.10, gives 404. /healthz existed since at least OS 1.5. --- .../java/com/openshift/internal/restclient/DefaultClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 2257072b..fbd9a153 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -64,6 +64,8 @@ public class DefaultClient implements IClient, IHttpConstants { public static final String SYSTEM_PROP_K8E_API_VERSION = "osjc.k8e.apiversion"; public static final String SYSTEM_PROP_OPENSHIFT_API_VERSION = "osjc.openshift.apiversion"; + private static final String URL_HEALTH_CHECK = "healthz"; + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); private URL baseUrl; private OkHttpClient client; @@ -288,7 +290,7 @@ private RequestBody getPayload(String method, JSONSerializeable payload) { @Override public String getServerReadyStatus() { try { - Request request = new Request.Builder().url(new URL(this.baseUrl, "healthz/ready")) + Request request = new Request.Builder().url(new URL(this.baseUrl, URL_HEALTH_CHECK)) .header(PROPERTY_ACCEPT, "*/*").build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); From c27f96f87eb7b84c2a73b59efab3f22c1a9250b8 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 5 Sep 2018 14:53:59 +0200 Subject: [PATCH 128/258] bump to 6.1.2.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7ce21a67..0cd9bb84 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.2-SNAPSHOT + 6.1.2.Final jar OpenShift Java REST Client http://openshift.redhat.com From 667a44099ed7612c0d0a7838993b56d3a0e68963 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 5 Sep 2018 15:04:29 +0200 Subject: [PATCH 129/258] bump to 6.1.3-SNAPSHOT after release of 6.1.2.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0cd9bb84..05572089 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.2.Final + 6.1.3-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 910dac9db003510a202b0ba1714f87cff82354d0 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Tue, 11 Sep 2018 11:32:51 +0200 Subject: [PATCH 130/258] [OSJC-283] - Binary build support Signed-off-by: Jeff MAURY --- .../internal/restclient/DefaultClient.java | 104 ++++++++++- .../capability/CapabilityInitializer.java | 5 +- .../resources/BinaryBuildTrigger.java | 162 ++++++++++++++++++ .../capability/resources/BuildTrigger.java | 16 +- .../internal/restclient/model/Build.java | 7 +- .../restclient/model/BuildConfig.java | 22 ++- .../model/build/BinaryBuildSource.java | 48 ++++++ .../model/build/BuildConfigBuilder.java | 60 +++++-- .../com/openshift/restclient/IClient.java | 38 +++- .../resources/IBinaryBuildTriggerable.java | 131 ++++++++++++++ .../restclient/http/IHttpConstants.java | 5 +- .../model/build/BuildSourceType.java | 4 +- .../model/build/IBinaryBuildSource.java | 19 ++ .../model/build/IBuildConfigBuilder.java | 20 ++- .../restclient/model/build/IBuildSource.java | 8 +- .../model/build/IGitBuildSource.java | 8 +- ...inaryBuildCapabilitiesIntegrationTest.java | 129 ++++++++++++++ .../model/build/BuildConfigTest.java | 16 +- .../restclient/model/v1/BuildConfigTest.java | 4 +- src/test/resources/rest-spring-boot.zip | Bin 0 -> 179085 bytes 20 files changed, 757 insertions(+), 49 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/capability/resources/BinaryBuildTrigger.java create mode 100644 src/main/java/com/openshift/internal/restclient/model/build/BinaryBuildSource.java create mode 100644 src/main/java/com/openshift/restclient/capability/resources/IBinaryBuildTriggerable.java create mode 100644 src/main/java/com/openshift/restclient/model/build/IBinaryBuildSource.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/BinaryBuildCapabilitiesIntegrationTest.java create mode 100644 src/test/resources/rest-spring-boot.zip diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index fbd9a153..be96ed61 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -13,6 +13,7 @@ import static java.util.stream.Collectors.joining; import java.io.IOException; +import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -55,6 +56,9 @@ import okhttp3.Request; import okhttp3.RequestBody; import okhttp3.Response; +import okio.BufferedSink; +import okio.Okio; +import okio.Source; /** * @author Jeff Cantrill @@ -196,6 +200,16 @@ public T create(String kind, String namespace, String name return execute(HttpMethod.POST, kind, namespace, name, subresource, payload); } + public T create(String kind, String version, String namespace, String name, String subresource, + InputStream payload) { + return create(kind, version, namespace, name, subresource, payload, Collections.emptyMap()); + } + + public T create(String kind, String version, String namespace, String name, String subresource, + InputStream payload, Map parameters) { + return execute(HttpMethod.POST, kind, version, namespace, name, subresource, payload, parameters); + } + enum HttpMethod { GET, PUT, POST, DELETE } @@ -205,6 +219,11 @@ private T execute(HttpMethod method, String kind, String n return execute(method.toString(), kind, namespace, name, subresource, payload); } + private T execute(HttpMethod method, String kind, String version, String namespace, String name, + String subresource, InputStream payload, Map parameters) { + return execute(method.toString(), kind, version, namespace, name, subresource, payload, parameters); + } + @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, String subContext) { @@ -220,6 +239,22 @@ public T execute(String method, String kind, String namesp Collections.emptyMap()); } + @Override + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String version, String namespace, String name, + String subresource, InputStream payload) { + return (T) execute(this.factory, method, kind, version, namespace, name, subresource, null, payload, + Collections.emptyMap()); + } + + @Override + @SuppressWarnings("unchecked") + public T execute(String method, String kind, String version, String namespace, String name, + String subresource, InputStream payload, Map parameters) { + return (T) execute(this.factory, method, kind, version, namespace, name, subresource, null, payload, + parameters); + } + @Override @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, @@ -267,6 +302,46 @@ public T execute(ITypeFactory factory, String method, String kind, String na } } + @SuppressWarnings("unchecked") + public T execute(ITypeFactory factory, String method, String kind, String version, String namespace, String name, + String subresource, String subContext, InputStream payload, Map params) { + if (factory == null) { + throw new OpenShiftException("ITypeFactory is null while trying to call IClient#execute"); + } + + if (params == null) { + params = Collections.emptyMap(); + } + + if (ResourceKind.LIST.equals(kind)) { + throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); + } + + final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) + .apiVersion(version) + .kind(kind) + .name(name) + .namespace(namespace) + .subresource(subresource) + .subContext(subContext) + .addParameters(params) + .build(); + + try { + Request request = newRequestBuilderTo(endpoint.toString()) + .method(method, getPayload(method, payload)) + .build(); + LOGGER.debug("About to make {} request: {}", request.method(), request); + try (Response result = client.newCall(request).execute()) { + String response = result.body().string(); + LOGGER.debug("Response: {}", response); + return (T) factory.createInstanceFrom(response); + } + } catch (IOException e) { + throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); + } + } + private String getApiVersion(JSONSerializeable payload) { String apiVersion = null; if (payload instanceof IResource) { @@ -287,6 +362,29 @@ private RequestBody getPayload(String method, JSONSerializeable payload) { } } + private RequestBody getPayload(String method, InputStream payload) { + switch (method.toUpperCase()) { + case "GET": + case "DELETE": + return null; + default: + LOGGER.debug("About to send binary payload"); + RequestBody requestBody = new RequestBody() { + @Override + public void writeTo(BufferedSink sink) throws IOException { + Source source = Okio.source(payload); + sink.writeAll(source); + } + + @Override + public MediaType contentType() { + return MediaType.parse(MEDIATYPE_APPLICATION_OCTET_STREAM); + } + }; + return requestBody; + } + } + @Override public String getServerReadyStatus() { try { @@ -331,12 +429,12 @@ public void delete(T resource) { @Override public IList get(String kind, String namespace) { - return execute(HttpMethod.GET, kind, namespace, null, null, null); + return execute(HttpMethod.GET, kind, namespace, null, null, (IResource)null); } @Override public T get(String kind, String name, String namespace) { - return execute(HttpMethod.GET, kind, namespace, name, null, null); + return execute(HttpMethod.GET, kind, namespace, name, null, (IResource)null); } public synchronized void initializeCapabilities() { diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index 052168d0..16d60632 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -14,6 +14,7 @@ import com.openshift.internal.restclient.api.capabilities.PodExec; import com.openshift.internal.restclient.api.capabilities.ScaleCapability; import com.openshift.internal.restclient.apis.TypeMetaFactory; +import com.openshift.internal.restclient.capability.resources.BinaryBuildTrigger; import com.openshift.internal.restclient.capability.resources.BuildCanceller; import com.openshift.internal.restclient.capability.resources.BuildTrigger; import com.openshift.internal.restclient.capability.resources.ClientCapability; @@ -39,6 +40,7 @@ import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.api.capabilities.IScalable; import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.capability.resources.IBinaryBuildTriggerable; import com.openshift.restclient.capability.resources.IBuildCancelable; import com.openshift.restclient.capability.resources.IBuildTriggerable; import com.openshift.restclient.capability.resources.IClientCapability; @@ -102,6 +104,7 @@ public static void initializeCapabilities(Map, ICap public static void initializeCapabilities(Map, ICapability> capabilities, IBuildConfig buildConfig, IClient client) { initializeCapability(capabilities, IBuildTriggerable.class, new BuildTrigger(buildConfig, client)); + initializeCapability(capabilities, IBinaryBuildTriggerable.class, new BinaryBuildTrigger(buildConfig, client)); } /** diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/BinaryBuildTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/BinaryBuildTrigger.java new file mode 100644 index 00000000..25544dae --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/BinaryBuildTrigger.java @@ -0,0 +1,162 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package com.openshift.internal.restclient.capability.resources; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.resources.IBinaryBuildTriggerable; +import com.openshift.restclient.model.IBuild; +import com.openshift.restclient.model.IBuildConfig; +import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.build.IBinaryBuildSource; + +public class BinaryBuildTrigger implements IBinaryBuildTriggerable { + + private static final String BUILDCONFIG_BINARY_SUBRESOURCE = "instantiatebinary"; + private static final String AS_FILE_PARAMETER = "asFile"; + private static final String AUTHOR_EMAIL_PARAMETER = "revision.authorEmail"; + private static final String AUTHOR_NAME_PARAMETER = "revision.authorName"; + private static final String COMMIT_PARAMETER = "revision.commit"; + private static final String COMMITTER_EMAIL_PARAMETER = "revision.committerEmail"; + private static final String COMMITTER_NAME_PARAMETER = "revision.committerName"; + private static final String MESSAGE_PARAMETER = "revision.message"; + private IResource resource; + private IClient client; + private final String subresource; + private String asFile; + private String authorEmail; + private String authorName; + private String commit; + private String committerEmail; + private String committerName; + private String message; + + public BinaryBuildTrigger(IBuildConfig buildConfig, IClient client) { + this.resource = buildConfig; + this.client = client; + this.subresource = BUILDCONFIG_BINARY_SUBRESOURCE; + } + + @Override + public boolean isSupported() { + return resource != null && client != null && ResourceKind.BUILD_CONFIG.equals(resource.getKind()) + && ((IBuildConfig) resource).getBuildSource() instanceof IBinaryBuildSource; + } + + @Override + public String getName() { + return BinaryBuildTrigger.class.getSimpleName(); + } + + @Override + public IBuild triggerBinary(InputStream payload) { + Map parameters = new HashMap<>(); + if (StringUtils.isNotBlank(asFile)) { + parameters.put(AS_FILE_PARAMETER, asFile); + } + if (StringUtils.isNotBlank(authorEmail)) { + parameters.put(AUTHOR_EMAIL_PARAMETER, authorEmail); + } + if (StringUtils.isNotBlank(authorName)) { + parameters.put(AUTHOR_NAME_PARAMETER, authorName); + } + if (StringUtils.isNotBlank(commit)) { + parameters.put(COMMIT_PARAMETER, commit); + } + if (StringUtils.isNotBlank(committerEmail)) { + parameters.put(COMMITTER_EMAIL_PARAMETER, committerEmail); + } + if (StringUtils.isNotBlank(committerName)) { + parameters.put(COMMITTER_NAME_PARAMETER, committerName); + } + if (StringUtils.isNotBlank(message)) { + parameters.put(MESSAGE_PARAMETER, message); + } + return client.create(resource.getKind(), resource.getApiVersion(), resource.getNamespaceName(), resource.getName(), subresource, payload, parameters); + } + + @Override + public void setAsFile(String asFile) { + this.asFile = asFile; + } + + @Override + public String getAsFile() { + return asFile; + } + + @Override + public void setCommit(String commit) { + this.commit = commit; + } + + @Override + public String getCommit() { + return commit; + } + + @Override + public void setAuthorEmail(String authorEmail) { + this.authorEmail = authorEmail; + } + + @Override + public String getAuthorEmail() { + return authorEmail; + } + + @Override + public void setAuthorName(String authorName) { + this.authorName = authorName; + } + + @Override + public String getAuthorName() { + return authorName; + } + + @Override + public void setCommitterEmail(String committerEmail) { + this.committerEmail = committerEmail; + } + + @Override + public String getCommitterEmail() { + return committerEmail; + } + + @Override + public void setCommitterName(String committerName) { + this.committerName = committerName; + } + + @Override + public String getCommitterName() { + return committerName; + } + + @Override + public void setMessage(String message) { + this.message = message; + } + + @Override + public String getMessage() { + return message; + } +} diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java index 08562018..e2ad3be1 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -23,6 +23,7 @@ import com.openshift.restclient.model.IBuild; import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.build.IBinaryBuildSource; import com.openshift.restclient.model.build.IBuildRequest; public class BuildTrigger implements IBuildTriggerable { @@ -52,8 +53,17 @@ public BuildTrigger(IBuild build, IClient client) { @Override public boolean isSupported() { - return resource != null && client != null && (ResourceKind.BUILD.equals(resource.getKind()) - || ResourceKind.BUILD_CONFIG.equals(resource.getKind())); + return resource != null && client != null && (isSupportedBuild() || isSupportedBuildConfig()); + } + + private boolean isSupportedBuild() { + return ResourceKind.BUILD.equals(resource.getKind()) + && !(((IBuild) resource).getBuildSource() instanceof IBinaryBuildSource); + } + + private boolean isSupportedBuildConfig() { + return ResourceKind.BUILD_CONFIG.equals(resource.getKind()) + && !(((IBuildConfig) resource).getBuildSource() instanceof IBinaryBuildSource); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/model/Build.java b/src/main/java/com/openshift/internal/restclient/model/Build.java index a3c2754a..d804bdcf 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Build.java +++ b/src/main/java/com/openshift/internal/restclient/model/Build.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -14,6 +14,7 @@ import org.jboss.dmr.ModelNode; import com.openshift.internal.restclient.capability.CapabilityInitializer; +import com.openshift.internal.restclient.model.build.BinaryBuildSource; import com.openshift.internal.restclient.model.build.BuildStatus; import com.openshift.internal.restclient.model.build.CustomBuildStrategy; import com.openshift.internal.restclient.model.build.DockerBuildStrategy; @@ -91,7 +92,9 @@ public T getBuildSource() { switch (asString("spec.source.type")) { case BuildSourceType.GIT: return (T) new GitBuildSource(asString("spec.source.git.uri"), asString("spec.source.git.ref"), - asString("spec.source.git.contextDir")); + asString("spec.source.contextDir")); + case BuildSourceType.BINARY: + return (T) new BinaryBuildSource(asString("spec.source.binary.asFile"), asString("spec.source.contextDir")); default: } return null; diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index a0c13bed..d95c862b 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -17,6 +17,7 @@ import org.jboss.dmr.ModelNode; import com.openshift.internal.restclient.capability.CapabilityInitializer; +import com.openshift.internal.restclient.model.build.BinaryBuildSource; import com.openshift.internal.restclient.model.build.CustomBuildStrategy; import com.openshift.internal.restclient.model.build.DockerBuildStrategy; import com.openshift.internal.restclient.model.build.GitBuildSource; @@ -30,6 +31,7 @@ import com.openshift.restclient.model.build.BuildSourceType; import com.openshift.restclient.model.build.BuildStrategyType; import com.openshift.restclient.model.build.BuildTriggerType; +import com.openshift.restclient.model.build.IBinaryBuildSource; import com.openshift.restclient.model.build.IBuildSource; import com.openshift.restclient.model.build.IBuildStrategy; import com.openshift.restclient.model.build.IBuildTrigger; @@ -43,10 +45,11 @@ public class BuildConfig extends KubernetesResource implements IBuildConfig { - private static final String BUILDCONFIG_SOURCE_CONTEXTDIR = "spec.source.contextDir"; - private static final String BUILDCONFIG_SOURCE_TYPE = "spec.source.type"; + public static final String BUILDCONFIG_SOURCE_CONTEXTDIR = "spec.source.contextDir"; + public static final String BUILDCONFIG_SOURCE_TYPE = "spec.source.type"; private static final String BUILDCONFIG_SOURCE_URI = "spec.source.git.uri"; private static final String BUILDCONFIG_SOURCE_REF = "spec.source.git.ref"; + private static final String BUILDCONFIG_SOURCE_BINARY_ASFILE = "spec.source.binary.asFile"; public static final String BUILDCONFIG_TYPE = "spec.strategy.type"; private static final String BUILDCONFIG_CUSTOM_IMAGE = "spec.strategy.customStrategy.image"; @@ -167,6 +170,8 @@ public T getBuildSource() { case BuildSourceType.GIT: return (T) new GitBuildSource(asString(BUILDCONFIG_SOURCE_URI), asString(BUILDCONFIG_SOURCE_REF), asString(BUILDCONFIG_SOURCE_CONTEXTDIR)); + case BuildSourceType.BINARY: + return (T) new BinaryBuildSource(asString(BUILDCONFIG_SOURCE_BINARY_ASFILE), asString(BUILDCONFIG_SOURCE_CONTEXTDIR)); default: } return null; @@ -181,10 +186,17 @@ public void setBuildSource(IBuildSource source) { } IGitBuildSource git = (IGitBuildSource) source; set(BUILDCONFIG_SOURCE_REF, git.getRef()); + set(BUILDCONFIG_SOURCE_URI, git.getURI()); + break; + case BuildSourceType.BINARY: + if (!(source instanceof IBinaryBuildSource)) { + throw new IllegalArgumentException("IBuildSource of type Binary does not implement IBinaryBuildSource"); + } + IBinaryBuildSource binary = (IBinaryBuildSource) source; + set(BUILDCONFIG_SOURCE_BINARY_ASFILE, binary.getAsFile()); break; } - set(BUILDCONFIG_SOURCE_URI, source.getURI()); - set(BUILDCONFIG_SOURCE_TYPE, source.getType().toString()); + set(BUILDCONFIG_SOURCE_TYPE, source.getType()); set(BUILDCONFIG_SOURCE_CONTEXTDIR, source.getContextDir()); } diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BinaryBuildSource.java b/src/main/java/com/openshift/internal/restclient/model/build/BinaryBuildSource.java new file mode 100644 index 00000000..b7a92c9d --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/build/BinaryBuildSource.java @@ -0,0 +1,48 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient.model.build; + +import com.openshift.restclient.model.build.BuildSourceType; +import com.openshift.restclient.model.build.IBinaryBuildSource; + +public class BinaryBuildSource implements IBinaryBuildSource { + + private String asFile; + private String contextDir; + + public BinaryBuildSource(String asFile, String contextDir) { + this.asFile = asFile; + this.contextDir = contextDir; + } + + @Override + public String getType() { + return BuildSourceType.BINARY; + } + + @Override + public String getAsFile() { + return asFile; + } + + public void setAsFile(String asFile) { + this.asFile = asFile; + } + + @Override + public String getContextDir() { + return contextDir; + } + + public void setContextDir(String contextDir) { + this.contextDir = contextDir; + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java index 03e4c58d..2444fa0a 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2017 Red Hat, Inc. + * Copyright (c) 2016-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -36,6 +36,7 @@ public class BuildConfigBuilder implements IBuildConfigBuilder { private SourceStrategyBuilder sourceStrategyBuilder; private GitSourceBuilder gitSourceBuilder; + private BinarySourceBuilder binarySourceBuilder; private JenkinsPipelineStrategyBuilder jenkinsPipelineStrategyBuilder; private String imageStreamTagOutput; private boolean buildOnConfigChange; @@ -90,6 +91,8 @@ public IBuildConfig build() { if (gitSourceBuilder != null) { bc.setBuildSource(gitSourceBuilder.build()); + } else if (binarySourceBuilder != null) { + bc.setBuildSource(binarySourceBuilder.build()); } if (labels != null && !labels.isEmpty()) { @@ -155,6 +158,12 @@ public IGitSourceBuilder fromGitSource() { gitSourceBuilder = new GitSourceBuilder(this); return gitSourceBuilder; } + + @Override + public IBinarySourceBuilder fromBinarySource() { + binarySourceBuilder = new BinarySourceBuilder(this); + return binarySourceBuilder; + } @Override public IJenkinsPipelineStrategyBuilder usingJenkinsPipelineStrategy() { @@ -162,26 +171,40 @@ public IJenkinsPipelineStrategyBuilder usingJenkinsPipelineStrategy() { return jenkinsPipelineStrategyBuilder; } - class GitSourceBuilder implements IGitSourceBuilder { + class SourceBuilder implements ISourceBuilder { - private IBuildConfigBuilder builder; + protected IBuildConfigBuilder builder; + protected String contextDir; + + SourceBuilder(IBuildConfigBuilder builder) { + this.builder = builder; + } + + @Override + public IBuildConfigBuilder end() { + return builder; + } + + @Override + public T inContextDir(String contextDir) { + this.contextDir = contextDir; + return (T) this; + } + + } + + class GitSourceBuilder extends SourceBuilder implements IGitSourceBuilder { private String url; private String ref; - private String contextDir; GitSourceBuilder(IBuildConfigBuilder builder) { - this.builder = builder; + super(builder); } private GitBuildSource build() { return new GitBuildSource(url, ref, contextDir); } - @Override - public IBuildConfigBuilder end() { - return builder; - } - @Override public IGitSourceBuilder fromGitUrl(String url) { this.url = url; @@ -193,13 +216,24 @@ public IGitSourceBuilder usingGitReference(String ref) { this.ref = ref; return this; } + } + + class BinarySourceBuilder extends SourceBuilder implements IBinarySourceBuilder { + private String asFile; + + BinarySourceBuilder(IBuildConfigBuilder builder) { + super(builder); + } + + private BinaryBuildSource build() { + return new BinaryBuildSource(asFile, contextDir); + } @Override - public IGitSourceBuilder inContextDir(String contextDir) { - this.contextDir = contextDir; + public BinarySourceBuilder fromAsFile(String asFile) { + this.asFile = asFile; return this; } - } class SourceStrategyBuilder implements ISourceStrategyBuilder { diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index b3c2c2e5..5b765eb3 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -9,6 +9,7 @@ package com.openshift.restclient; +import java.io.InputStream; import java.net.URL; import java.util.Collection; import java.util.List; @@ -152,6 +153,33 @@ public interface IClient extends ICapable, Cloneable { */ T create(String kind, String namespace, String name, String subresource, IResource payload); + /** + * Creates the given resource in the given namespace using the subresource + * + * @param kind + * @param version + * @param namespace + * @param name + * @param subresource + * @param payload + * @return + */ + T create(String kind, String version, String namespace, String name, String subresource, InputStream payload); + + /** + * Creates the given resource in the given namespace using the subresource + * + * @param kind + * @param version + * @param namespace + * @param name + * @param subresource + * @param payload + * @param parameters + * @return + */ + T create(String kind, String version, String namespace, String name, String subresource, InputStream payload, Map parameters); + /** * Creates a list of resources in the given namespace * @@ -202,6 +230,11 @@ public interface IClient extends ICapable, Cloneable { */ T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload); + + T execute(String method, String kind, String version, String namespace, String name, String subresource, InputStream payload); + + T execute(String method, String kind, String version, String namespace, String name, + String subresource, InputStream payload, Map parameters); /** * Raw execution of a request @@ -240,6 +273,8 @@ T execute(String httpMethod, String kind, String namespace */ T execute(String httpMethod, String kind, String namespace, String name, String subresource, IResource payload, String subcontext); + + /** * @param factory @@ -323,4 +358,5 @@ default T adapt(Class klass) { String getKubernetesMasterVersion(); IClient clone(); + } diff --git a/src/main/java/com/openshift/restclient/capability/resources/IBinaryBuildTriggerable.java b/src/main/java/com/openshift/restclient/capability/resources/IBinaryBuildTriggerable.java new file mode 100644 index 00000000..c7ac6bca --- /dev/null +++ b/src/main/java/com/openshift/restclient/capability/resources/IBinaryBuildTriggerable.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package com.openshift.restclient.capability.resources; + +import java.io.InputStream; + +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.model.IBuild; + +/** + * Capability to trigger a binary build based on the build configuration + * + */ +public interface IBinaryBuildTriggerable extends ICapability { + + /** + * Trigger a binary build based on a build config + * + * @param payload the binary payload process by build + * @return The build that was triggered + */ + IBuild triggerBinary(InputStream payload); + + /** + * Set the asFile parameter + * + * @param asFile the asFile + */ + void setAsFile(String asFile); + + /** + * Get the asFile parameter + * + * @return the asFile parameter + */ + String getAsFile(); + + /** + * Set the SCM commit + * + * @param commit + * the SCM commit string + */ + void setCommit(String commit); + + /** + * Get the SCM commit + * + * @return the SCM commit string + */ + String getCommit(); + + /** + * Set the author email + * + * @param authorEmail the author email + */ + void setAuthorEmail(String authorEmail); + + /** + * Get the author email + * + * @return the author email + */ + String getAuthorEmail(); + + /** + * Set the author name + * + * @param authorName the author name + */ + void setAuthorName(String authorName); + + /** + * Get the author name + * + * @return the author name + */ + String getAuthorName(); + + /** + * Set the committer email + * + * @param committerEmail the committer email + */ + void setCommitterEmail(String committerEmail); + + /** + * Get the committer email + * + * @return the committer email + */ + String getCommitterEmail(); + + /** + * Set the committer name + * + * @param committerName the committer name + */ + void setCommitterName(String committerName); + + /** + * Get the committer name + * + * @return the committer name + */ + String getCommitterName(); + + /** + * Set the message + * + * @param message the message + */ + void setMessage(String message); + + /** + * Get the message + * + * @return the message + */ + String getMessage(); +} diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index 3b714971..755efa62 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -45,7 +45,8 @@ public interface IHttpConstants { public static final String MEDIATYPE_APPLICATION_JSON = "application/json"; public static final String MEDIATYPE_APPLICATION_XML = "application/xml"; public static final String MEDIATYPE_APPLICATION_FORMURLENCODED = "application/x-www-form-urlencoded"; - + public static final String MEDIATYPE_APPLICATION_OCTET_STREAM = "application/octet-stream"; + public static final String AUTHORIZATION_BASIC = "Basic"; public static final String AUTHORIZATION_BEARER = "Bearer"; diff --git a/src/main/java/com/openshift/restclient/model/build/BuildSourceType.java b/src/main/java/com/openshift/restclient/model/build/BuildSourceType.java index 9ef68bf3..d1020d9b 100644 --- a/src/main/java/com/openshift/restclient/model/build/BuildSourceType.java +++ b/src/main/java/com/openshift/restclient/model/build/BuildSourceType.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -12,5 +12,7 @@ public interface BuildSourceType { static final String GIT = "Git"; + + static final String BINARY = "Binary"; } diff --git a/src/main/java/com/openshift/restclient/model/build/IBinaryBuildSource.java b/src/main/java/com/openshift/restclient/model/build/IBinaryBuildSource.java new file mode 100644 index 00000000..f41d1dce --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/build/IBinaryBuildSource.java @@ -0,0 +1,19 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.restclient.model.build; + +public interface IBinaryBuildSource extends IBuildSource { + + /** + * The asFile + * + */ + String getAsFile(); +} diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java index 41a4f4ee..a2b03d21 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildConfigBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -25,6 +25,8 @@ public interface IBuildConfigBuilder extends IResourceBuilder extends Endable { IBuildConfigBuilder end(); - + + T inContextDir(String contextDir); + } + + interface IGitSourceBuilder extends ISourceBuilder { IGitSourceBuilder fromGitUrl(String url); IGitSourceBuilder usingGitReference(String ref); - - IGitSourceBuilder inContextDir(String contextDir); - + } + + interface IBinarySourceBuilder extends ISourceBuilder { + IBinarySourceBuilder fromAsFile(String asFile); } interface ISourceStrategyBuilder extends Endable { diff --git a/src/main/java/com/openshift/restclient/model/build/IBuildSource.java b/src/main/java/com/openshift/restclient/model/build/IBuildSource.java index b9551d93..de9e08de 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBuildSource.java +++ b/src/main/java/com/openshift/restclient/model/build/IBuildSource.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -18,12 +18,6 @@ public interface IBuildSource { */ String getType(); - /** - * The URI to the source repo - * - */ - String getURI(); - /** * The sub-directory relative to the repo root where the source code for the * application exists. This allows to have buildable sources in directory other diff --git a/src/main/java/com/openshift/restclient/model/build/IGitBuildSource.java b/src/main/java/com/openshift/restclient/model/build/IGitBuildSource.java index dc898710..3b9b8a3c 100644 --- a/src/main/java/com/openshift/restclient/model/build/IGitBuildSource.java +++ b/src/main/java/com/openshift/restclient/model/build/IGitBuildSource.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -16,4 +16,10 @@ public interface IGitBuildSource extends IBuildSource { * */ String getRef(); + + /** + * The URI to the source repo + * + */ + String getURI(); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/BinaryBuildCapabilitiesIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/BinaryBuildCapabilitiesIntegrationTest.java new file mode 100644 index 00000000..17dd5b56 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/BinaryBuildCapabilitiesIntegrationTest.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package com.openshift.internal.restclient.capability.resources; + +import static org.junit.Assert.assertNotNull; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.IOpenShiftWatchListener; +import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.CapabilityVisitor; +import com.openshift.restclient.capability.resources.IBinaryBuildTriggerable; +import com.openshift.restclient.capability.resources.IBuildCancelable; +import com.openshift.restclient.capability.resources.IBuildTriggerable; +import com.openshift.restclient.model.IBuild; +import com.openshift.restclient.model.IBuildConfig; +import com.openshift.restclient.model.IImageStream; +import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.build.IBuildConfigBuilder; + +public class BinaryBuildCapabilitiesIntegrationTest { + + private static final Logger LOG = LoggerFactory.getLogger(BinaryBuildCapabilitiesIntegrationTest.class); + private IBuildConfig config; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IProject project; + private IClient client; + + @Before + public void setUp() throws Exception { + client = helper.createClientForBasicAuth(); + project = helper.generateProject(client); + + // an output imagestream + IImageStream is = client.getResourceFactory().stub(ResourceKind.IMAGE_STREAM, "rest-spring-boot", + project.getName()); + LOG.debug("Creating imagestream {}", is); + is = client.create(is); + LOG.debug("Generated imagestream {}", is); + + // a buildconfig + IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); + assertNotNull("Exp. the client to be able to use a buildconfigbuilder", builder); + config = builder.named("rest-spring-boot").inNamespace(project.getName()).fromBinarySource().end() + .usingSourceStrategy() + .fromDockerImage("registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift").end() + .toImageStreamTag("rest-spring-boot:latest").build(); + LOG.debug("Creating BuildConfig {}", config); + config = client.create(config); + LOG.debug("Created BuildConfig {}", config); + assertNotNull(config); + } + + @Test + public void testBuildActions() throws InterruptedException { + + // trigger the build + LOG.debug("Triggering build from the buildconfig..."); + IBuild build = config.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBinaryBuildTriggerable capability) { + return capability.triggerBinary( + BinaryBuildCapabilitiesIntegrationTest.class.getResourceAsStream("/rest-spring-boot.zip")); + } + }, null); + assertNotNull("Exp. to be able to trigger a build from a buildconfig", build); + LOG.debug("Triggered build {}", build); + + LOG.debug("Canceling the build..."); + // cancel the build + build = build.accept(new CapabilityVisitor() { + + @Override + public IBuild visit(IBuildCancelable cap) { + return cap.cancel(); + } + }, null); + assertNotNull("Exp. to be able to cancel a build", build); + LOG.debug("Canceled build {}", build); + + // trigger a new build and wait for completion + build = config.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBinaryBuildTriggerable capability) { + return capability.triggerBinary( + BinaryBuildCapabilitiesIntegrationTest.class.getResourceAsStream("/rest-spring-boot.zip")); + } + }, null); + assertNotNull("Exp. to be able to trigger a build from a buildconfig", build); + LOG.debug("Triggered build {}", build); + CountDownLatch latch = new CountDownLatch(1); + client.watch(project.getNamespaceName(), new IOpenShiftWatchListener.OpenShiftWatchListenerAdapter() { + @Override + public void received(IResource resource, ChangeType change) { + if ("Complete".equals(((IBuild)resource).getStatus())) { + latch.countDown(); + } + } + + }, ResourceKind.BUILD); + latch.await(10, TimeUnit.MINUTES); + } + + @After + public void tearDown() { + IntegrationTestHelper.cleanUpResource(client, project); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigTest.java index f47fb578..a8023136 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -21,7 +21,10 @@ import com.openshift.internal.restclient.model.BuildConfig; import com.openshift.restclient.IClient; import com.openshift.restclient.images.DockerImageURI; +import com.openshift.restclient.model.build.BuildSourceType; import com.openshift.restclient.model.build.BuildStrategyType; +import com.openshift.restclient.model.build.IBinaryBuildSource; +import com.openshift.restclient.model.build.IBuildSource; import com.openshift.restclient.model.build.IBuildStrategy; import com.openshift.restclient.model.build.ICustomBuildStrategy; import com.openshift.restclient.model.build.IDockerBuildStrategy; @@ -72,5 +75,16 @@ public void testGetDockerBuildStrategy() { assertTrue(docker.isNoCache()); assertEquals(new DockerImageURI("thebaseImage"), docker.getBaseImage()); } + + @Test + public void testGetBinaryBuildSource() { + node.get(getPath(BuildConfig.BUILDCONFIG_SOURCE_TYPE)).set("Binary"); + node.get(getPath(BuildConfig.BUILDCONFIG_SOURCE_CONTEXTDIR)).set("aContextDir"); + + IBuildSource source = config.getBuildSource(); + assertEquals(BuildSourceType.BINARY, source.getType()); + IBinaryBuildSource binary = (IBinaryBuildSource) source; + assertEquals("aContextDir", binary.getContextDir()); + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java index 92056c7e..eb2c1402 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -138,12 +138,12 @@ private void assertBuildTriggers(IBuildTrigger[] triggers) { private void assertGitBuildSource(IBuildSource source) { assertEquals(BuildSourceType.GIT, source.getType()); - assertEquals("git://github.com/openshift/ruby-hello-world.git", source.getURI()); assertEquals("foobar", source.getContextDir()); assertTrue(source instanceof IGitBuildSource); IGitBuildSource git = (IGitBuildSource) source; assertEquals("Exp. to get the source ref", "", git.getRef()); + assertEquals("git://github.com/openshift/ruby-hello-world.git", git.getURI()); } private void assertSourceBuildStrategy(IBuildStrategy strategy) { diff --git a/src/test/resources/rest-spring-boot.zip b/src/test/resources/rest-spring-boot.zip new file mode 100644 index 0000000000000000000000000000000000000000..3831fe1296f062e82fdbba467da4d6e792b178b7 GIT binary patch literal 179085 zcmb5UW2`7aw=KGC+uX~xZQHhO+qP}nwrv}G*~Z=9yZ0sU$2sTac2Y^FQyE=7YIeq$ zv!=WhFbE0&1Ox=YhX<()!2jn$`giYW;^a)@WbbHUYer*eXXi{u2Mi!D1rG6_X+ZyH zuKa(Cfc;+~&>C4d8d;kdS^Qr?k^Ik4Ms~KQ7G|^_Hr6HTHcp$O2tPM^4JzrIwq8j3 zYc}TQWQ5HQSs-B9f1R_F@fM+IdH-K$mz8yY{RV`$EuGegl_=kTgAsRtTXC5f@7Q>Quu7m3D%PsUNWN=Wb zEmG^+ZN=3UhK~tA|7@#+v`>t(XQEm*Tao#uO6p^kjv~0tEs2(R2i^!*L%IJdUvBP{wo2Ji8_GqpcRjnKXlI{^`4AsG z&K+E*UTOa@D*}3ZKw~R&LZb*bIZjMDUr3xdWjyX42K*=oIAJFFC>qM={_XAtDN1&Z zZ5>bHYpg1VVxS9#)`ux{1|uiS|52=$2c?il?l!;J=!)S zv8&tfc}af(Vu>p`3{VRvM86?#b%vGOnHaMyTfnQ|+89H?<5vG@UHyIb2!WA%&${vT zw11ma?^FbS%^UBfd3{t4`W3lFHi6PUM9>${J z7pLGt+$@GR_g-?IyP);y85JQJ`G}kH!EbR@f+^izcjp|tNi$Xb#jiX&`(@>=P(0%P#hBlQT_Hc!L1NUX0mJ$%GPfRmO>wFx}v$GY5`M zh%}J>3*n`DqXPQINPI3yC?#Iy;)1f#QIjexov*ORLx)PjUJvsW_$Ew)Crsq4zJQl9 zHlHd+(G40htk@$)U+M|z55u5Tpk0r#UPpZ1NFWA;>h)HR|H^35e^8%0#PIomEPF8&yD`)&#_=9z3}!qQ#L0tC{eOy zZrE+m8he>M^DLg%Ox@+#%;|e7HR7PzzUKmUF7T&*mjR}aToJ=Du+5IA-DDw)f^-OB z0GqEEWbi$nX^cwqf+-or39Hg~IpFLByxgW7tM(;QMHkWc&(p^%*=?`0KI+60Pp?R0 zT~1RjP&FL=w8tRRA>^EAoqjj@%XJ~W{=}fN$eq%zIKh&uQERTar5iRSo!iB_Z=$pu zq!dIXL=8lkscyDJhuBLwu}XA@plSqcgq}^6)myM{M}fiEd?;;PwKISuG&H>jZNkrI zhmvo{ddNbryn5K|Spk#T5gUa%x!l?zo2 zsifW3j2AdL@Y6&|%LoO^Ykg70&#MCSfoUgrk)KELHtTZh4_hm5v|n?( zAQkVys!@Ix&}c^dKp!A4pNK8g@0d9msO->CbQzXl3R127);0XYVSZ_rMCLj*RhGFc z(6&gcl|KGJg$pfsPTG!wA3c`yXV03Po(rzK8l=w9Zk9kz^?QY(17ZW{b?;-lg}p45rYgVms2)*C`Nl4IoZfcNhjg^w zn{TSt*Aw|XE{~soRylY;HQj1vGe}86nM7Bv%u_NK+#L>2n_g9d%bF=T4nT3mA>0-? zLR_)41<=NfIaH`qs&RLn@>nik2H*%p^z38Znq(fPi8OYtowysBx>$O}g|>dwZYrlo zS#0q^Y%UCmv;n;E9vmpY>~wsH6I*>u0IT&%&(vPo3>@BEL;!PeJ4Z*ImEPd}CGMff zv6N9n_)fWWYVB9oz-MtNTPC;0FA5D@gtOFNEjfQXNP?L~ahvV;hGo?Ai?$pni-ZhC zJJJ(kp28t?vi8G(+AB)26b%1lVAentgPNf~e=IC$m$13U&thL*{XCKo3x!~?T1JOJMwa{6J+ zye+pln3^&oCh90DqRu^&tpgWSlNDA`2D2V7L;*fTmH>IGJ|2Qv{ZeF@OX@aP)oDGd ze)H&y_(^_13)uaK5M=DxNDm++eeQerEpSC@3iP{I4!1(AZ{PTX`qSuKZ^t|NHR6`!CrxF}85FbNt_~FD9YOc8DHE#LW*h zK$_+OAQDEvUs_~LTA*x@9wjRhlf0O4!C|rRS9eqPW1Ukx-reJN!3c;ewKj4QK(!c2 z%0LeM4uw9eUzG@`0X-k&=8C-ChrfJb(yCk~>)G(05hD-$Nc-@Bkf}_PiAzH9ttPfX zLD&EoOY4eDFN3zJSZ&JW3W$O9T-?h3m4`rW7`&fp^fLYaCEZMwW*A*)3@mUi99fix zy8(J+=M#97lg0{~uSKAOK|9ac=(>n1#>oPQ3<(U)#S*&dTE0N=b{f>=+E9??>+2}J zG)*a8SBGzdo%CRiyQ>AGO@&Wuqkz(wW)#|%fCcP>cF{}E>q4##hXkVp(KfxP$MYvI z-o#X|Z1`HA<|nd>?ms-64F*Ny{Nwrje~jw?+N+ycI9r(6+Buql4m7~})5C!D|CI3; z7Tuwt)Q3n^>mLV0{Qex;>ck2}-60>Ypk%qj%lDarteVgrFu^XyXr@3(5c@O-C(ln; zbQ3;$;ZqHt0AC^V{byBR1AWQ=NjEh9jsJf4(f-Tbw{f-oze*nd>lpeEikqW>y}gO! z{}md?f4ipt7fr^%)x=iqe?tq~x!GFV85o;5(pnn08swp$ zpyq&{GKA6+!Fomw%Nz+PoiFRXkPT$Pq$t5#thGB(x_4Pm)U<=Wc8sO3H9_N*o_m6< zh|r_!?3bLWHY{rdj{6 z9|2Z1%kVd^x#xflCBOu0H%+9k!BHIOZ*~b3=CU5rDM1r|au^~sXWRG{ixCqz5~C#G zL}iXbTQJ;aNhqh(Xyj7x)Oyx0l^h58tB~ah2YW=>Lx0)<^9CLKwgb<8jvwtg1J3N3 zp}>=T-C%|gx8cEaev0{U_UrJ1gX(tizXi%bQC0?I&f}D^Zp7m;PtFSysZMT4F{3dl zOAxghA%qUAqN~ZPheIW89SKVq4JOme;_(W_1kc`T8~EIRvA-IP%`nGuBeUd2R1zvA{ct90p&39s zwnD2RY`E@sE-LJ&%=Fi46zNCWOJ+EdR8n3~IT*zB-?@Gsb51^5=9`ytPUU2q+r@Hge3ACW8oTWk8Rs+^OwvbN*W#wD;c+yn!&|# zC^QH0a1A;+MH#ctTm$djIDFPH_W8zDFh;|`u$qTG0%G00AaJTH;LfImH~3^RKV-?E zSGiQfexICR74g-7SE1!HoP#d4ju_5}(Urc}>x@u1m6}LK6+`u^VJH$YkUh%^^ZUfy%c>-jaOt$}z=!$|q*W6mx$(F8dJe<2eUHUPhW8?5baO^3wcZCNsvwH|jCA?{j9tCQB$O4sPv{@N8d ztgsUrU@L2%dH9f~&xL$dlMZJQ^<4;d>aQ|LBa8?xaF*EskQLRft$0h%X*fJyAb<=| zq^kX1o>6JlI*e||@bWLfL{YO_bF`xv^{gAqZk;-8QN&H23LtwljkS72qFdYgz0WlH z9P_1;(5>%TrRFRgR^NAl#LgQ%!tFbg$HH605@s!;muH77<{k7IXQG7|gl*;F=#cDN zR3xK=H8qD}`pfi-y=tKj6BoJ^bGmQX-?x=A@xZAiIA;qnEcyDNmlo!<;K+bn!%az0&a4zS5=+_s*+CjqEZ==1`@3> z(A)p&ka?*rdlvb(F+ckSR5N4;f(}u%OioMYHtLlk{?VKd(2ro)=e;sS{l;(420?%9 z@Fw31Pp2|;)qD*qO;Dw>>tnobv_-5Rl=NuwJ2N0PxQZl2lmtJbWxo{^KCmuu>~3x& z?apA6N7Hwa&0*z$0PAt-^ZzkGP5c0v5MTfR9*F;w1k(Ng%8ku`o}avfg4{b&s*xYQ1fH-8kEQ%)|agH`|LX53fC+y_&4N z@_eYMR!jy26#@kLqbM^k<=;RW5e$tTTbqMAnc_z<<8Dxbmc z-eKws3@w0_f6_@`N%+Gp%6F6O?G1>%J-y3E+j8UY+zRLV79%_R#;?nzp~ZzXm5>}0 z3&YMh?-1uyC-DsXsJI`o79U50G!+Y>9GfeFj2IIo74Z}RjFWJJqPKHqphRqdYVZNX z*W73T)LP-s+vU=>-xhm)Ut~|xd!GryRi7~c9Dot@lAjdH`!ChUFYEemTHxDs)*ky3vyE!ca?tU|LD|!@_*n(Z_?ws^{3C9tXLDL z98&K&D;|`bcJ63+sc@uS{(c9)Xk8G`A-LtwCNB(1Sz|Tn_)xUeWY^s&a2or>c;k?; z*3qrg#;CNTcB6iSen#9#mkRmVB7H4R-K;URkISF|jFET3D;Wfym=t4yI1pSVf`LSy z7(zu6wNZ|E6qS9cb4IZj{LD@%_Mql|Qf$gaz`_Uq^s>okV#3(1BtsLsZHp!+Et~SI zIVSKntH)_%rg`J9^7~!zCPvumLPFLrYTDgM0iu6MEFIi6@ufKls&}&j)9k9%qHbC3 zwN`6_aKk_s1Q8*=I8KaISA~oDy2GWC7$VPJ?1E5Pw=&kD+!>cglA(Nqe|S%j9L4T; zSPk^3gZ5*az&w`naET#z;crXsnO7ihG7e{pEwe3cuSv|r;RTC0f>&`VjG(4xdIYNg z?7bLI>6hUM4p``MRxC15gmF_Rrwj*z#v4b`h~N#yN2{A8?%6;MFYDS{HQV3JZXr(r zRTr<-7CddDa-3hOoR{aPS40lrgsH*8v}6oE&07d{#5Rj2`IB&q7hp7zgD_@SC|D}& zWoqtl*aXHh<(p+h7e=xj6HD}fiHf#Fh{_X|iNtW+y_lPrkQNVJWm2Xs^kz*jvMY@( zE}p+u6vU(OVacpWRXwM4l5ZsIf(3I98U?MjrZ0b#%*)fqtb&rzXI+$2VuxH!hJODX zD&&Y>ig~rfqwg7Vph*IfYNw)wsS7sL;3TH0F{`=?eW>YQ9l6 z#=zbnQp7uj(9pUGusQJNST`E(k+YctW@gq41if4G+6e$y5PLD%44`d3429dUJTDZCsx_xDAvF z2QEoOV``wR*0rlF&l=Z7xrwsBy5D5qIInL_L^ODnZe2hy_}GxuHP$Px_bSoc_MiC* zz_}*orwzIFJ7bMNKZ~EcPnI?|Gw^-~G7%{2Z^IzlJB?d2@OSVWiB@t2M^kixcWfE$ zwI~hX^W~K(M%0@6j>l3>Qrk4}$ETg&Jcohp$+3ERc7%As={=bRNz!-sD?rjxS!2rFS=!Rp$X{&U-_FN76i1f^`WB}KX0Z14Un{6O*~KO?L_z2sFq=dR z9R<~zM=M{fH6@i>)4x(eg90KpkqT1e3-SX%(v9KiAqn16TU#ii5MQLsGeD{>iJDQ3 zR`#r1lMmUZF05X>wJqoXhu2C0!8dKRYhb)~2y?;1ZrCVU3+0-8#Tpz$%f{JScKUxX zXXaaa{Mj;(|0a)Gh}<>bPlkxkHaN}V`=_g&rV95GYm0<}YTXo(f^d5%Li&M?@_By| zs7j@F5k;7XF&QN;R6{{t@wkYXzhVgxr2ICSBmFtmB$^h=mp>dthMifWCLRsXEG+Wc z>31P%N_RmnjBXxY`#iR#$7c?W2NLn3*1SsBW@}n5a4N<9nXVp?S85k3z5^E!5^SYF z*nkXdl4Y$~34DUZpx32fGmpTl=%wsW;+DR}`KtMXr0$6Wn0CO*u;!o5k~mC=8?9Gv zvwE9&;Y`{TTL4l~{R+&|C9cF+O)170 zg_H1PHVa2P2GK%%aocE21HxE4GI<3)fDuv1qU9O1@zcWLLw?JDJA3g1ce>lvHsXEq zTS7qh3$C**5v7W5w~a=IT$R9PLkU;~&Ty5;JaNZqqBMUObu#&b?+YP=Vh8oER=p4K z;^sU4WcPmHHwwA><8Jxpi&B;Km$f7n*1F;ejnN}b3>O1X!m-&p)d@yKF{^cwrvHp| zjnKQ{mvFs&MAwIMGMHZiWDEo6A|4gYs-ELurczk#TidQy*em zxM7m21!soCaphpM1#->)=9ZogYSx)c=N?s&8ZvUCjYMix(1Nsu3^43wrzvGmu$4}; z7gx}aPGijPRBxY^xw5KTa%A3NiqQTmDdJYi?HdpW8 z(L;(ymDCag3#=_j_E?k*9|EatL#_qQE3JS?;;^TM%|x=wA?egH9}@FH^0WzA@2D4b zAWZ5N0`Gv>n{eA6X!s&LWfg&6URVBINukx;AmF<`#aE?QsyUZ;B$2Ax%dFmEWJ7wt z+RetOSdtiQSs<8i&2USrpE43SqJRv@;p_blhqVrhL&)-5CV}CgtJ89St zOiHuOuIr0@r|fkYrn{2Zbvn&;`@^Qleh?X-e<72Q-UZD%3I<;H#xlF3x9yIC956lJ zbE#5@cIa(a>OZMsb1aOnoPfwBqbcp&SgGi{1t{!wu@PCCu6@_-#`|oytnf2T?_ainOa zg@-k?d4y+E)rsUZ_=>nKM&J4}D$+fcO;kH@kmMw4ft)>xvALHL84Nh=4Si!ds4F#; zfXlp6G8v>ATP$kJz1V!j=&w(`Fm^%J&&eOsQ>4zn8ThP5Bhb=^t}|=!-#-rZe5J(j z2ccIu)f$b9D=l4?=PfD>M??3uIt49{(Npd|!nL>&>^vv@lWV9AQ(?L8$QZ0xiF;Vv zeA`5L*KLse8=+WCU36W_(+eAmaGEwQAT5|3LdWtNCpp<_jdz%RK@X*Zv@S-sDBYWI6no;CKLH*^9CTQ539_)2DU;yeAAfvw4 z6f}$v7nKjha!=`gzK!1#`RXiebd1(j8-KNYuWCg0(o-Ax?!5dkDqO&CkvXnk!rmDB z6!?xB>38D59L##pD;uZN6^=xWXuaxM%>fQCZ+gzBZGjNoK>K#^aUF!da(73#A-@Yo z$L*K$7k=<8c8Rrf_WwSD^mGN%8w&(pBw1pi{*h%^Din6BucJToJqCOCvxGM>WjLaRoZ7U+~S$*?z` z2{A+ULy4s849}ZNw}STjAUMdbeBUNlIl3$e>oCqZw4YjoQVgsWxhKLnz0&H=m@LO# zOdq^4_{1T&Aue{0L4vDt$_|FYFkQ-NGzX9(zQJAtVQm06y9ia^21?{rSceTej9&N# z?s8qAFaBp)dl`NKSBJEH^P%GT`IGMaz*m?3pjUrkOGXSo5k5c?1p6M7kPdnL2^cWh zOFJceB@#jVv=mrV>@q8I>JIOJV1yPRQw#N_ zD3d_ZPnh$oE>I!k#>EA|W<@ZVAP{SyRC*eQ4$q3c2%){$J$l3$*Q^Vwu#H9X>CsR}zR7W+@D|fAO?X1`E=$uFA z1pgId1L5K=TK+aU{@J6olmFIX6W`$I0Cq2&QMb=+(5liRlgN#IUfZL@k=5scq(J=n4u`zCkYIYr)P;r zno!rA4qIlwsAfUcGEF`gpK}}QHgj?u<_=y;H_2(t>Ci1q1{eENVN`{RnX9A!x zuDai5Txn~8+&BO|aP?`OTwJxV?Zv%gY3YEgUA=xsBajRW@rht=uoU5?@{tGdgzsa$rUe1e=@J9{!GM0f$U0oiccP1-ktgF#NE0YCCENciv3afFlmeI;H} z8u!z)l;nK8MPONd8M+bSp2Y@Sa(%yk)Ee|P@Wz4Yocs|Apg&cks9tn`Z`^prZzd+D zn&=Z%CBmFGPmGP-t|>T=s!-yt6OVuE;3lH7-ndIu87^*v={lq{CZ!Qq0_=*45`22yrFz2tEmTouj7;(1IF`0y)EJe^df(1ldEPVcoA>B+y;s?hhqpe0pc)aBhb51E z#RdSo0M(=wDJ$5ZVAX9>rj6jjokTV*ApZA5kK;#Rc2w)-%wmE08uh znu*wRJGmJ&bN0@=kGhASAF6b?vfjMOR(XD)V!pDCC$?)_M3Cj-JPM<%OI#P~q{b$l z(j;3eFTA5k;zIIiStV-AU9Da4tdy#@}IQ)=Vo zX_5YiH5J(N=Q@6vX=xPFY3p^gr@*)GkhuVU%$>Ti3J002GAV&FGfa8Aae5s%^7cSKytCL~WTsZr44y z<(v%g8rB*a!&Iibm&t&bj?s|#k%R=jmnu4U^HLEhcq7E6zlP34_g_m#uXg8=_`Oj< zNNkd#?9UCyBtwEjw65Jj8df6(Sd8%j(@Iv)u`Sm;W-Rd<&MFS(-fx~z~ zLCNPv2{Mo3`j%nSACh@fzIapb{!BzZ9^1{hw91I~vIE>Qg64wBj@PR$x4dBn+k9LAMDm%QqKw0N z7AiIw^wItEL%#C9<@3zeFh{rysm~FKO)S`gbvB=`3GZQmmT06+X`IsCB}Mw&3a&JU z==qU1gog3BSfad>YQTBgeL% zZQzh@2s|p^5$TaL)BHj++J=Wm-M#$^-&NM;Kz0#(jPLZ@uc-NPA23ntKI_r0r492u z47?dVYD8k{QNP35Oml;XgVn%Jz9jYbs+h~J&e*prjd9YMb?dy6+Tx>L$)vW`efz5D zkkdHMo%q*1j&B-QI(zY~=>mrwLCuUC4L|%)_rEm$-$Vj~rd(X)`ZWB zjlp_hNII5BhdOVbkHe1J$FRQwUF@QZGP5&=%*xMM0${BK{eF4bolcM}fj}xQ&$QOQ z-GkUTBIM_+0qeiR^o*3!NPHhgpfrKDrM(# z7SON%es+us{l?g_(#OMjjtIF%r3g|cjGNX-%$^MCXII8(s58S@S@CR?||M(H&-CbS!mXH(~n?+v@sJM6*#o##q1MQHw8VVkrw<=` zyY^|Y_QF|a!7BdL9(wH-J#@+OjyuYp7)a+kTaJhG204f`+{HNN8R3_ zly8$09m19>Q|8xWdBfjsfUHvp`v(JJP2|qv_YfGdp(irrK&1zj=(m51 z^N2g3dZC zi1QrGtk92Zb@~(35dk+1I{AE>c_q($;Z-r9M>$eIraNO>IdG*c$Kq~Ch0l23$L7LR z#O+fW%XGBPdG!q5PrttI2_&?CVhL;3GJUHs%~Vv%@aB>XgvQ1xDB*wAV~+_2=hsNd zbSqLtDHu1-9_UxbDGS@OScw^nRw?U`tBx^bu6=`nuXy(>vUh+PlR$D#CzB;p;j;Gp zyf*EOYmk@)U*Ym?pm_q#D)oATB&SW_TGD z6a-x?iwLbdV5(_@N1Oz?WrL*8#bUHHPpz|&(m{z(b3uh^23a+dU4%s_hQQkb|2T?URfos^ZRRi4-&!YVw^W>Tz=y0@09V2SbfQVbWb_Jo2~seM}#h1M}IW6RSO zyKoj(eyqq5r^GCp4lFMMopLBPLvEY5KtX*|!Z19>T{0lx18(&1Z65Z3;Cc|q_5$bI z);5P6UsWwGp1fxdCl?H41|PWWl=^Y&Ze%}h{@L}*@Zm9J%lZ7G4kuf{36cAk-nWh8U2taM+&Ga`wo z-<{d&&&GZ87t0q>UxRA!}H1%W(=#ClUDg62`y1*cHT?B=ftVOM_8eio4E0 zhNr_c`kP8sDT5yFfYXgw1xM`JOFp+bakw&C8RoidNY?P~1PYu-pIbI`+!~FDV67eZ zhv-M%K91T9ROrD+?CJWXr+6?Vwv@G7V7nSw$&gWK@NEh>cKPEv0P>_^ZaxMYxqPB| zk?X0x;>&YnfpPRGVs5y@>9YDQw{&{!-6wv+NNM)-1)ckM*>=)XW;lds)Ge;C7}ggZ zLbln0zmWS(Flvb7K`)eY z5yU9?&&J~i$znM&&KO$KJm2YfcMx;4@RJ4V7KS8lqmMD<_Piz1(I~}l@{vV!!mh-^ zIZ)e!q?v2;jGV9(K0TSzXiSkWwVYFq(LEJ}AL37tMx5yKMIa#%AR*!xZWHM*mnn^v zo$XIvGpDf0j;$_21YJ|PN#6`Da0sBfmX;=zu|S%%UY5FYOm(>gOtt!kzG-@G=xV;7 zjBoi97-%h&h&u1`*NTrQ14K^B5r89ND=oWOmy3x3TgID(HD9!_wmEZF?NJb;8FA z)9Ihso-^Npcpw!fW)4-EoSP|`S07*H)n*YA-iVsHVxmOS5y0;JA_x_Qgn8p8Blbq) zzMuN|XbHE}az-Z0m5cZz|yAh8~VHVBk zDxiuggDYp?!QMDjxsK-Iw|;tLfo-!j*rVoI?kt`CE)%Yc2t!@Ds7{|!c3xIN z{jh+w+fi3Y1M+V4gN4DDOA7-ZWuDp!|4v1^8E{ha4oGk3ys!@DAYuGgj8clY~OFPGzv%$t^8#WKAH{U|eSwMOKRnD6?JW}=RHMNLhT zX%fG=r-|z5)QZ2{H@M?$>b5&=XDN8qmWeSY!#!E-2n=1*&eb6wY?iaMoL< z8aSkQzjBIH9mCB6w0(a`8KOlSo!)C*uK$i+gWrX3T}I55qe=Fl#wxlFC?h4L zaotc+NM3QebTg* z)`*7i8tS(9$=RPc4T>hOx}-^?EqK!93MFJLpagHF{NbZ2hC!QvnnB&!RXwu%%tn}f zt>_D?r3+4s1aP6gd0MRpnjPd-lBuK=#wV;^rDx5ON=tvKQU|73WSna!4R)A~{@$rM zd6>~1DcmGtQ9IhLvUng@)tN_RBic@v&SUbRO|gxxkr|u!mS4Ef2Z?xs;K^1SMY2Z z#`~d@c3o9WqztP*hxuEaE?9qyr?G3;bu5dHimW>{Nu!*N&oJ-0=;8fqB@*=8F^E$^ z2zzJ16cqFF>zI=)%;?2GZdH>`hH`mK6oqt6JP#n8FRl z%tq=aQb{J}I)-P_3x&?1$NS@!^;cMEJD{na^>m_`iNrX;ohpTbM^U4Z)$X5xkp+C8 z@BHgB9Ulc(Pm-lbD%*ceS1&7~)v=c8_A`5)2TZFKcV3?5FH_hseQS zeycJE=!NGgh3s7qpedieDX=a8ql54wi|$*dTj#2HlGp@kLYJJJ2o<=3OS;K7fFIr_6qQPFo>VN`h5Z`QnXX4XP!HD># zSKIY=@g<7iW)>401HVv@|lFxPg?oi2n6h zXL5Os^yvS^F(bDB0u7~rc`B3i)o7)CLg|s46K!z!BJOQNipAW<^nOQXiY~Q&#qN z<2i<1YUYi~9~0Bd6Sz)-l$)ZoowL$gAMayi&L8muNs{l}bo*XptZ@x2)Bl!gHZi~7 z)BloqWs2230`sm-N{r^Qfob^rQ<8pF`O;5DbN=X7Uz5#7b#;M#6Xu=AbGoS~^nSDP z5Wk+}f9)r4$z#At_glbXY+qDBy*j1M8+<5{@l(loH2F)|Rd)-EU$SLS`miF^kvmsOz$;qFD;xxdml%2#lw(b%<22m9@7s; z>F0lIJA*G^q-W=L3Fk@uod1opTzk}}24^}&I2~fM__HbQdLWhw1RBE1Xr&PspgAzX z0g2d#(I$*2NB2&4p1rHehFf4FM0%-jSrIMhUe;hV+tr-XIG(3GY8Ey?5hlsO2hlvT z>9Np50H;|!@Bs0o2)R6NLx0ZrhkX0B-- zv&u(w_1LjOdq`1+X10`Q<_#={H#%)z@}^J2fl`_29j5c-^6O4`{}NiVZq-`!8pmRY zborM!r1ymsr&)XVfW-=NdtO1coFc(Dit_m~7q@_7`C@Jl$7RRoiVKtmWWdo&A4n-8 z>@Ia@&A)#+Q9;}4m`p~C>!kdCE!OLT7)sj-Bhk|TytR%-aNRhvn)CQw-#Bv(TS#9} zl{`)2#1B#1InK^g|I^PElyN=0;OuG{M6)Ao#Gzwk;rP> zTx@amj8e!pIEc_$9T6pTV0qQ*AVgSIb+1%MGj=inZaU@;QB%-4rIV?+`PXFn1Nct>RI*$HxeNYD8 zt0wx_Tf~!w?$s@&CbTt_8tl>ch2V^SY?*;@dH@RniLAD{%P#|pi_vffKn$BSzD}lc zXM(3u*lu-|d@b@#XiR$?pL%j@XuaN50FRZzd`@Rv?I*kL+tK{~({(NwQ|z=)vaF4x zTF()WQKXmA+gJC{h4x0!ZP%;vqG}vvam$-2)B|Z5gHD1_1a2kiP1}wgOC{oA5mnX6 zP`6_06xi@A_D`)g*yo-pFMqHILQgknN%gJ-CaIU|L7cl%qJI8O5*LT2hs+u@J2u)^3o#)okS|9AHKBW({-u(;UWU z$CM7yUPweAb6XSx$EDBMTXdbc$6;#^#($l@CvY}dd&`_!Sl;&uoYW0$$NT(NS$FtyTpEc)=${sK2+qjcy2;5VvAllOtt4a$ zI)eA0U9&2U%XB;VwcEm0wpIs{V*PAcH=v|7)a4~Vnk7s;UW46jsK{M9Esxb`>buvw z{j>ZxPQLlcf6Q;nX@^(2=JTKVw4*7b_CX6+!-Z?H0`(xb_w@0W=IH*=mr}Xn3~AU) zyNC51!q>m7-w<;kk8T-nei=pPC=!%Pi4}#pu^NW~mffj@I+I&Q$<~@Gvk|qCrs)tbTpZDU(T#4-FH-Ak1T(?upEQ`JoF?0cleQXXnV+#8^w`j2mCa0J0XQ z&eF=Jiq_JmzWhR!8zn!Z$fv}=Vg2PoWntFB695g)r)JQBBdbV{NH8phqF{W}gUMNa zUR$-O=jcD9F)3*ob41rok-w?-~Rd z$q4Qzh+WCyAb2TSs`D>N1>KodUvjf6{WsDrx1|3CGeFG0Eo9!GvaWAxl+$dXY)#8$ z@EKyTYX{!}mXc+5RD9`-$^%hA2+^xhq#wn{T`Kr_+bBBsje!{e#pTMcj=VN9pK5h* z#7##{!RinSQKt8z{pZ~F-F8d@+!v#J-wBTlWt=rQI=kF08$=KW4fR)lV3DT6yO?+b zzlr6F`DMYDoe^<^FJEKHs`PnKaWCW|zROUAjgidr>*1h4j4Lj0)Y^s&a%bJSsGO_B zcu+TDzYNLOvWcQ|6cpcwTp`^r5m@ISP#lp_o2MaK!cD8Ue!G1;soC^0B;*K^~9_&Fh1dTksgDG&U)A{003m*T&P4Mie zr8@s2S}uP}wCMiFZt}0JxcaL<>NB#hwM+^f1_(^rnjy{9SOR?rMH3ik1Y@1@xSMZ) zBW^nq{h{gbGB&rO8i zrH0S0wo)=j?5wGHnY}gUy5P2_J?Z(gmGg-rs2X7-b0Qj)r4-7AnCQV0XTym#wrTD9 z;5?9Y^N#HE*|T?IeBtWgh_;S-hRZL5D=H$ODry=+WiTL%<}SMdS#B=gE7}W|dJ)E& zqp;%o=FusQp_XmO=xh?5W@s-ERaFGStOV+}NN%h<;efNkp&`%BoVm0N!Dbe1Kk-KR z_FDdjcG%EDq8|->epns~F04s4>FQJ`iuI_SSRAFDL7^fPM^QC^bQrs?plg|A+S3lR zgUA*N90!feVmx88pYF6Lo_T3B2s=!$gqIZuW@mOzUL<1vFtHU}q5Cjy zs;sz+MFbKBne?4kivc!%agkIVl2O%++A?o5^ctM_aVe;?-tHSCQo3TCUg5u6=!ENN zp-OPMJPb>&Z;=F*13Kz|_n%6kUk??+5Ns)L`b`oibkDv62^8=7dh`Y&wMJ0aFQ;3_ zzjPFVc)Pi_RUxB*^u%U#34=Xj{@baER3Kd(!9+~Gw39=;B~eXLnZ6m z>juwbCG{AsUs;3sQ$S6DkW+_Jqbux!+9(olOejaLSGchAFsf@0l@(#SRF91#pT$$tJ>QTCa0$}I==#t8YCg}YR7xlW(y2p%!E2L+N8}D z;H{^Gk(SY4;&?{)W1;A4jgW(vohBPF+5M;p>=iHCZ6l(?Bi(vX_O)UkA9l)-@X$c> z)1n_ zmG|R2QErouu<>!_FI@b6s!<_TM=ZetKbE)IQGZi%1M`lM84|DBA1Iep9v3O$`)CiD z4+3PCU{U(-J%pO>NC?GL8Vm@0LOol2AekifKW$cndP5|<4uc@1gGAbLcgPf*NYoBewkSHwb+f7)@vxg<4DMU>d}+* zY4DD_dyz)K{Mi0woWNm_-)tEhBuO0gE{+3s0>6h~Kv_hwt#a%8@$+%g8UZ$I(SG#6 ziYrvv=$jN>U|0dI>BrEkYm)7(Dyf;4-uyXC@oxj^AG@hEe&qYag5XsO^V{JgsTKIF zw#U|`zaHZVKhY{$YRg|hza#@6%%iloRzY0!J~aY8f@o;(JQDxls7hn|!x*~W|Iv5T z^;H_moC_eia$Gmc>>Ou-gADSB5;7^vjsSB^#Xug2K%2xZah*@{LPS~UdiI2o(-z|? z9JkmdwwT9~mgM5_8)M@Zl&m9dUUi<19stM(nGsNC&LRkCdtmP9p$2v#+O}=?5l#!~ zLcT^rGJjp~ZWeaYbiEmy1{>VVKHmup(w=ODk*q?Y?l?hxS1gTa{J7)^Sr>5fe)Zp?Sf zVr1@PEjck(DKX|@17B+1&f6I2Yzi05n8dVkwQm4TY8st=Te~j5U|ZU{=2dz1R+7T5 zn-kOgzOFOY)}Sm?8dUciRe{z^QZNvjjQOX8LsXcjlx-VGN6MP550(OJu{v*9<;MD; zo{UFmrI~ix!-B9C#0+8#+RLdqUlb+@19g3Ys& zeQi^v-`U#3Z%KkKmuCOzN)kF(PpWqJaPR+GBOz)jo_~^)q^bM%#$Cqa zaifptW<+Ce5>n;`keynWI*DZM5}?nJaGr!IpuDOR)r%=m{WK~60VnWmbep9YV>++> z;SwKbP}C{LU7K@l^7|_JN`9M_{G)@QesY{{@>|J?cX(nX!pKNO?T3{T&yCJUEc1uY zySD-`O)}AKF%55(`u=uF$U-Y40YXaM9ZX>T@@x+Z;`PmyThzutZEb<-@LFV&7#rai z>mdPVes4F!UGK&wh;t}Q_h5V~v_%T^wC%}K56%St$0BJdwEz9nH~#kxS*b&Apuh0z zKNr-)d}wn8Ac26k5dIFBIsOiq|NEg1Nr0Wn|AA;VEge)1EWbD~i2kBVsl->GtZtQ2UGYHx72MBPhA3rF;eKan#P9@-RTowxC z4b2yt4lFqMNH?L4DagSy3fwj%<#1}sr^E`TWiqe>SZBY_G(-&*guOD`K_q?@c-qVH z_$13FFk7HT+;0jM0r8eGlLovxBEjRtLR~O&ve*Mj z?P;csKtEW#pWaeT+;pXh&5+t?W~JWo2nCBr=%lx9o2ejODW|94mf47`w~p`SIU8q} zrH-71Y;m;$(|A{fYwr56ix;4>2w;v?Y`4h&vE10Um>$mJC^T|^f?4)_0g{;KZljiO zg9JL39|h7!gOIF5kx;`|OOv6$v=8nkYgWi)|LpPr#`D=0OpC)%3!1D@M~mu2%xmY7 z<3f+m2#^$vTDPP$K*_fv63xxWSEBaQ8exY+&FXYwrr=Y9K7=6?!?~pqXA=c)(O`0k zHi}M5V>9z;p{=VGc5jm`4LA?CZ0if%8e3!zSk^R3(Y@g))SigJLBT}BX?2kWWB`}K z$JtKfdXIzlB(QCyb)_b&>#9S07v+gMx89b7a#rkUqs`u?oUv`=&u6I3g~nnJYOO;r zPyMJ^3az9tAj#jAAG)EvaUlbs93(ZN=(B8h48VML{!o^@&r+PpeF^KJOTYo_=RlN_ z5N6^3&~?aItYZadP_2JttTvEPAMpkMnZm|WI1v>JJ~b7yMYwKZ9DrY(Lnm8|pByBb zS5H+hiMbfR&8zb%ze=^GG0ZU85MIGj$z%rxg3g(wKmsg;m{F+4ORnGyNs~5J6RP?wi=pK3{c}WjhcFMUV84$LF~t9Y_!wG5EOWbrmU4H z-=jLgS!j*%_pxrb;tgqsy=v}5U-(Wke{WwpjHtFasK5kkvp?SYiN7LMuIIVBITr3A zY{xe(P@8XQ1@2wghnGQE*kbJo4=KgP+Yq`$y*0zJhCjCZg7V-;=r0f9qp;W#JWyy2 zC10KIT~TfhURt)DIq*6IL!yug;olckxXG=nH$)5a*(}qBR;D+^_3fMglQC=*&+cg% z{LIPY6L}5Pm8^TS7Q6}1EH|&6HqVu|oExU5zoJjBcyfXN%emS*of&WcH^SUI&{QGe zeXtZUQ-oQK1okrXuy@w47L`3Rg>2m*AEXY4NNdLDdnn>S0{Qy+v|;QG(nr3mp;8|g zf<3&R(m})`MipsduS_Zwdb&OQtH&4QYvml*5D5=L!UJEcVNf4Q1Ck=Y;J8=L7@e13 z4r_~E#N1uymooGNu8+W1uW$^Xh}yKc+9+FM-}is+e)a}2q(1=z0$PUt ze?HaxuSAlFy`7n*xvLZ4{}ABhq-_;kHMEglOktF{kYKQi@a8$I)xl7D;U?`!cqtlN z5fmxVu@fdt&4H!5%+<}`s^8>06=G( zPC5R?B^qwb*i@e)WvHxS>bZBbRktQa_r4;Qoz(c7B^=Ck*8Q^lc#->iNWdkl?0Zdv ztDPI2pDg!CsEA1z->n_mbA;UHqBhTTI0rk{_CYLx6MLI?Khpc+$(vCAYtKms0Otx~ zpe>`gGd!uvm@mN5CvS&hOJ+yJ2W_A_ztg72P4`o^&(=rw(ROojk~P%(?9qBc-<{k6 zGI!7+RooGMy{Rg8N)9}CkD%Kobv>5g1?$Kp=9#iDk0!0ZX~qdAAuV>FUu3TLNIp*1UC^Z`XSehOb8# zP&qaC_vCCw!=)R`J%sD_EDlX@o2cPEX!ig7A_HHCP|C#YMOvdQU$j6p+ zH#1zcaB(vg-bzO+2^h9#%Hl6XFpqL(%`f?)n5;-3R%sxWNr_dSTQit+K-|vE+xYw< zpv)2)hy$~n%A0NSdiwRXfHaViI%%Zk0QkjVn)T&O!5jxIIvV+lJ(O!T0{9)`)8d|& z4_mTBN@1?RlLht9s^F9-ixl5UXTkBi$)~uVctiX;VpA^^r^1 zMP33$iYW@0JNOcQdLAEEnl48`Q_#f_7#3IT5?VDT;b|3Y)6j&T_Rh7s(+|t^Q=bvC z*t;6++m;kc=_f)gB2qXYk^#iCS5QX-rNanDt|a|T`hp7JO$t=KdBA~+sYHX&D$N)n z6&%Ef2K1Zgw{_apggHSDtH7Ef8CXl z{U2%M4qyR58YmDD)!+X34F7{4U(CbQ*!6!OgH6_e_C{Ss=L2;jivpl>7^bKKpc}f% zipWe$w}3c@)#;3lpo)zxZ4iI4pIHPmH%YA(*(Ri1>C92sT4;AHHyO^hLF-9nUU~b= z_2xXAk;M!G?cP6IZh1Q|J5P7te=L3LdxQRV```>0gE1;$PoKHd_L5eRwKjjyH5#6~ z^W2oibI$QKe{`AUs3rn|QO{bMvWTck$&`hQ$z7Un2~64gTKMDO|2+HaE5A=gA`DWV zJS;51cYxFwh6GgYHOUsceUuL-*BI@^tIGn{?5ZqTt*&O+ z%3Y(P)`;VO(e_rsk*z(trpr`jEHg7RGcz+YGc((1W@ct)W@ctCGgH|vvpu!{-4or> zC(fSv`^?0Ob(5KqH_{`$lD?${njGNH($O4Pqd$H3d04(QHfOKb{q6{M&OwxGh}uD< zWyQPB;m!VZ=yVj zEiot^*6nX8+UO{3Q)Ye=={lS=)EGHDZqnpH;V!o^C4-&_g#_YOVHTT2t(hSnT~SFY z9cd75_!|?|PsU1BfKe4IviD$x%af`xGzOT*R21G2dHz=hoIzyZn^p2r&EU3+ssYpi z?^dlLmZ7vqZ9LQE2Ndfrr*f)Ob)moz3iHb{L6m9}bRrHE>ZqpJAbyzPmn_(uH_a;A zFVwlHgcT4`Sv+dl*o&1g_8+hYCC!&*rWl4dxKJ%^w^Ztrj%{lsR;L7xe&WNO^@;5l zX5+JgQP1uOof4;(2!q2}HqsY9W{aM>OYDGds12RWdCIhTNX=;5P0cmb>9nn5X)eku z*N}R=8_0crnO-jSic>*05dEY@OpJCaSEem8@bgm8aK}Vt^v*dd|7)eWOCymaLxznY z_Nu&t8gZNvf+n_x82HLH|7b%O;bF@v#7Y7bt9e4z*fRCd$ATRS6e9MC&&do;(ld)~ z8@os#IE$Ea_a9jvmG>z*tJK}CrbQS-jK>9Wi&sPQd!IanGsu*n`S&DbQ=9e4enjU6VEW_Rbs&T6E-@sDjr=zoEdKSOC<_bQibAu`xNG{o`>>Y~_ zy)9DWK1C`^i{JTbipx=D)mVe^b5!bfCbO2TXI5rZi9vC4)b1ermy1(sOo*RJdpiuY z`$~hJl|A@7UnzNs;%tZ;D8M;s$mUO!y>a#Ozy!z}c+9wR>!8LbX^5hHC5BUj!;d4v zm38H?kVP{pTIinwBhWcl)ur0-Q0rzl&RtyrDN1N-Ec-vz2)hTy;19I z$?7@XP<@vlj=eQn(TR&@>Y+SjATpslC>3}g!V*^DA4a)LwiGv$nZG0;I>}OVS1^lJ zDz14FmU@>Kk>KwRys;c93B0Q3@|(M;g%{9KOu9p_N9OHzkn;N2M@pMMU$HUnkXbZ+ z(EJP|O(4-Ar`7L>(F4DO2Ftv*)*Y_BwQ3R1NLzEHq+&Yy2>pjcP_TfiyipgB)h?dQ8S$=x(TIB>n!44uYD;%A5!%VxY z!l^Nlgbg>-XHk)vlnqQI`(r2iSx=TobI#wZ4cf64g5Y{E=L6|F)${jco8I1f?V)e7 z*)AZgP23&_aTVg_kVKHzWBI32@vPS!oTYF(R?#&f?gE?G44EU_MjiF-t}AO2%#5ntN1pPs#MWv5+U$#ZIPU zja5!9Qyff3=|@>C9A+XOuD_93FX6_fX1UT^!>6=>NxV;AO+>p;@P-@RC#F64QtsX0 zflm)D=_cD_)343?;p7{j9h{NlaUTlN$mU0(#{|yt2JYFT)NbpB%tI4-cmqpGMA1kz zBeWqcsS~IIHVx0K`$ep1kdzJH+af|GwZXbePogIE)A&cY%z$n}JyN+eRDXN{V9 z{1RC(!PQH*s#K*Fq!FkFhl#h1)kjv$Ik#~jvcgyBiKv}lCA_Qe9e+yG2FX0L!bi#& zm13)N{DvkzFAup(zL(6=-r+7??)E{x9m6m@x@JaJY_-gA)BzWH(KNc(S~PeMDr|12 z-B-*&`o2wMb9MjRPXhSq{q)a8Qp+1pom;!n3MA3Zr%y&bVyEi3G)ANzqRh>b6%%wO)bKRVp-| z30Rb)+yfVQTsa9Q4RD&W9~N%=?nZ8Th1DeVvAfzeRtp-0o-uJ*PYCpi1p1(Md+-Z- zpngNS#E^u~OrL_=^vKUt0*K59#p5#i@VgM@`du;xSj(lifKZwKh)n!X(p_kw4lDBz zE`^21Kq2A_sURG-xjBZ_ncd&*?B8dGEACvBzfZF){8VficHFOzFt#3XS}@pRP;qG6 zaUoarOLc0B_xK2+Lj0&qwobUl-ohX4^zSaa>PRb0Z}9W(-J70e-b-J*8jZq>%S`}zW=8`6EOU16_k;)ke!W z6HF1gkb2O##FO4Af}abue4VBhNunv>bEVz&cA9yaff>Bv8&_|zD zh0&dG+Dy7Pm3M%f#uVc8y69MdnV%dhUG_V*vxCnZKU%;7;4pSU2yy3h+uMaI5{q%h zcUw}}DDL{P2rn~GsnP&WT}oF(do9o|Obj@xKVX91Oy~Dyw@W+~eUTV#>U~C8s|g|H z;@%NTFi^dUcMe=-)+kHpivsrq(3#RmJS)B;HJs1X_P0MS`K8EyA=&drg}M(RR85c% z{`Skdgt{igZBi&Io+2}dI-nTrv?_AB{>{T4yeZNVgUILOe4_K={E}*W4ziu2D;Hz% zc-%Z^A;pF|I9ESJZycV8Q+aGZiQh@&kgI9(>SVD4CG)jd!mqaEzH**;CK zHA@|*x4_IU7ZRhze&K!r0^iEg-F)k%Y6?ompf^D5|CoG*OQ`UreEzlXhc1#%S0tGK^Dex zDL?6|ma*jU3}IJ*ndANzEnbvG{;0d6PG!|!9qIePJCIOQ$DbQYd!f_ zsSYe|$Hqb)(krxPFTJ1*li_mcP4VPYwCay@BN-ys<|Jl9l4x;V!>6pYd`dHk{;W#D z``<0fLm9GT^Hg1=Dc=-{c_7;+xK9jey&y;}2@e5dTD)#Q$5;{>94Aw6 zIUHs)?{}-UwLsdVv4k7wrZ7~w2{Ib%ib^6LV#`XMDb^Vk$%;^#mY&4vu=MjYSXb+904tAF%`qvk%L)tH~ekPfoPF02qzD1T4VsHwnF{f;& zxE(4BtlXEIj4nKIhyV5zHd7H>fjS2l(o1B~s&A?o&NDpC)a)@v45&Z#6XFARmT0jS z#Fz{}HHBa^gbLUz0Nl6riFG3lct6nYAkUA|JGST$KO7)sCnyASqxtN+2wpDDQOSyj z(uX~XX!C+(MU()j&<*2SjJ-A{QX?v^=gMP6wfOsP0|2tu83IGZL-G3Ta;_J$=B%&a zYYA`CtLZSSGoE8+3gtGd`IVg*+pfks`D5qYQJV>cD2n$D5=i|fG_{j4SRSpIt7P3- z-AqarhzG{+;`cq)cJZzdMi7i)k|f#aDY9YKsb?b$xM$#Py3hITJR&aZ8-%2?9sV)t zyf7IVyo2{&kT*#?meZpITf?D*C9;w~;Kg%V@ff(-z1}^gml=8@eT=9rgnCjwdk5dTWwVtmiT@f7O)MQ56uBd^&BXuvB1i7%ZIg*+ zxn&zWikYg4cM%^t$}qpQXa6QMROL%lN@6(9is3|#n>d6AlFcD9wkJ7mfW>jFL80Nt zW6lU7nd}oN#$F3X)gq5shDMt8IE#{nL0sNj-&Y`W0ULTVp-*vHDSas4CsKf(`CJG> z^VPL6d@vur3TPSMcL-p=z&4+@4Yyx8#)R&bmP^DIJ?qPWFE{7v*L{-*>RPC!?r!Z7 zuKRID@Z-b>kLIY;iTN5th^5~LgtYnaAm{~zGl($CRVoN=g~TB*USY1+qYxI*@A756 z*Bh8F3Q-GTMDXt+^~O)QzG-= z0JF0nxT;3_WvJ>VmtU1oAATn-yJ|QegM5DlNy`&_(Hc-7pc$C|BRTS4LZX19nTw5y zt+R-`k%|3(c5}1i1mp(je~f;KtT`9pLy00qZ-GWdiUkoc2qPyB2O(UWFc+F$q}YP= zrjQ}Q`vUPL)#HFhBfv?*;x%trB<NMlp{lQE}MokM}hoXdV$<< z!PUq1X#hXZ@Y25DwkQ=`nz(hAHWCRJ3fUv@6**gRvvi;lPbvP^zxo<7%8J%~fut;l zL$AY^u>F>Enn0ijEhaq})*3~@UqF5#8+So}=+HmLTU6dbF!fc4vVA6X*qd>WL16Ty z^#v{fqmI2qcjX|JD{uvKc9$|J9L8)T8dF$KejYgq5{g#FXt=6o8A<(vKAE=jz%yn< z50#D?2o^zPm8z8RQNofGA`BQz=GUgm;-KgM_f{@w-rYoT3>#` z--=;KF^Ct<*N2vLn>}SYZQkF#{DuQ^VQ=Xtl#eyx*BE#=D?*%MAwFJI}wciU}g5QLyJ`nG+5RJPUg znpVV(YJ@cbTJvk8J*A&mFn;C@GO3drfjV29*xs^XPP5EKXs zg3BwV^tL;pPuD?y0Xu`qleMJ=SktlD?S%yIcA(r@MV9`4&LeGEf&Ws@LvYwVb4vH{$sGte>@n*{BIac?!RKD zqNRqc_Tv){jSL{sr`)bysV*!;IMk`iUzwMT)Q1WxkPkO*fi7*jFg_&pCbbdTqoL<* z-U&r}p{e8ZE8ptT?7^<-W5#$ayV+80Wh&iiW@q=Wi{s_sM$Zq#9(>o_91*=aTY6v& zt6V013?sHU*?k}VrOO$qyed7d$%$i7l1xTw=0s<)g}DjR*$yK%T6m?7G5jT(CfyN? zd2^E%!kMIdyTHm68F~Q+`Ba^rDP<28hk{{ z_N}stv{5vlKM~~7>VV;BJv}8j$;fjYLKt%oEHHRqv|=a{)gs-^ctZa7WQfr`0JS8U z($-!^W~idC$6=9iyArs2o^r@SjdMg)H3pUrawzkPxwy1ylk}K`E`pGDzi!f;p6nmzwbNeMtv=an1l47KYtr=k8!324j!TS>2NX^Tk?wo4i1Ft zK4<}^Y=WhcFJ}lMGDMo?^+pW8oO4@+(BkK-I+?72^57V)u77q;nN`x?In8weC0wYoK*XC7KVk(xqfq^t=kI8(});`C?&50}swW+OS)elu7uhf8DhOb(<2q*^@rkAZZ3HEq@-8)& zDnCmLl|977&o92)Fj4PAB4N6;9IO3WA9KWcBcPKPBU0i_Nw>?X$ zKAl5UTzuoi)sOa3x%;srz6kmR^swfeUswrhdb-9Rp|4?KvLz!|xo9a=L9Pdd9V2@k zjRM3o@Z?5Em5z&!0ihq+x|ji#xI7>I@lD?A^<(0wx#aeqvu6MszTGO7K0SyCdYHO% zrPqvK)M&BPl2%Fe-jmgeuiRYVr@V(lN|-4xRV8asvbRS}w<&YGHQHrCVnVC53%@5O zCT9iX5JQ6XQSS=xPD&RD$0ECxfImE4`>(D<_|6lb(2x2_JPm>vf(_AI+!K;m5caV< zu=!1P-NrMd^&&?)WD z@qKPz?~lj?nhgCIATaJpHFr-8KYf}HI2R-1M_@@e z0wrqBwJEM-?xcQ_+9oG{4N39tRfAkn7UOkCL)NNVG8_j}1~k3pgW4Kp*d2MtuUOI{ zL}n2zst@yxA)=GW7C;fnk32VFj7T#@ISsMz{xCvy;uU2HfAK_0%}jWP$$gtyHLnJ? zsDEZX#@dfvv=|6FrASYfsxjzS0`wVjB=Y&tzks_@1RW7Gbv&VZYDaUa>m0XzqRv0V z;rhnvcX{c5KRa?KF8rM|-|>XV;Ik>VTTr{hdXj$GS5xE}90>M?r+?GA_QLD>O77(o zsDo=zKHK;cIV~T`^d*Pr$)lE|4}9QUqY_Dfuoa&Be8(#pEN0I;ppV7p+PY4AEAkvb5zs?jBa!-yJT!l- zxVBt2%uT#rF3bf&Qx2TQKVlGEsz_GNI^JbIE_lB!^T6Tk3W0ThcFtOhSV6r))-$0v z5rj~_(&GzFxwLs!bUL+EHu~MAC<{C2`QCn0_?4Bp1Bu7i>?m;2OItf}6leEKV6VjZ ziFOh@7OQlPG&6d4{uM)S_!(j6>%QED)=5+qr&TmC!YJgUl;|ycOBv?xElb~<;-=J<>PUn10m_1OwH@#~;OQIltzS@*0R5 zWNwiLK$av zvWwS%+nH0hu4iW6T}@qGpMK8H?gAa#(?JH+{cJ;#S`x94(qyS8N^ZW0@YLy0Ew|K) zl&vOJZr7)3C;XGY$#S}%irz}D*JCV+5y`m2ARsbSMT7$7@#s$k$R63X?Iftx{CktQ}aTGEqi^;aGrl^K!`pQquM);r93a#FL1E zGTTWb%J_qFG2UjK>;&ui!~68*WQP#_8qQ5yiJqoM3T#`Z?0H<|h1#TqYeN-g%mllx z^hL#m5rd(5DW{m*rpY-=EpHlpKDq9x;`H2Gwy0|oVV?SAw z3w_es-`yUr?&kPIzCJdRR_25*=*z>trNDkaM>ocQ&ly4TJF({l?3}1tVbs&fq^x|i zX`+uJ9qdDxWIg~E6&$f@nTs*=HF&V$eS-Db7?jfc0_nLAFbc3lPJ;~Sa9h@kv7ep| z7UhFCVr60Z0$FtmRaTmnPmdIBX|rSJl|qC*>7EoX*;#O9JLE&kfXU@{YWxqJZ<9a7|(KGtzs<`6%?)IahM!BcVI^|z(wwXNkUa#8QXEHI_dZKW^aGj4$?}H18xo!FrXnPQ8LyA?S z^+z^ngW4nezRtQuv^Ii`jSm_5=Ou52nAL0BVuIitBR7D;{FWI-)XleCxd>E?|CBGa z#?w_o1<*NC_7H3PEH?W`q75u=LRalm4NUcCW~P?#lp4`>TE`ozA9QgkF;cAZ_(l+s zuJRn??Jtsfr#SLtzo2MxGWCFcnDLI<1HNL#F)&UGB#6mFb&p}|q8{Ui6!Kn%f+9Qs zZu5BVADJI+3@DrEaWSitk#Uifq>+@ND58PYGS?H(Sp`HP1S&{4_sqQUu zL~}QGH_bFJ`-{b#P;y5@`p>YjhC#b`NaJ>sey;0>IL*FndUS% z1_c>`_PJ-P5m}!? z&)^&X8iHK@c-`IplU9NLaX+o{zaLbD44h0PY@JMOoh+O!Tuqdm9W89l{`}0|!12Gl z)j;Ww3KsbBY1-;sY+c;qAE7F*;2DIXCzX*#N-Bd%OmX%mAHrzNwK-*bVRy&(FpMVc zP0#z5+m*Gx&7X&EG%$GCKE<*7=W68h_4xqThv$N$4hiCi=ixmLV%m#-RwlnGJU*zO z+v!WyCMV)R=@yq_DXL>w<%Vhsf)U!wl50P4VtL@j z&W#i}#GkA~@*<0W=&p1Rx$IG9v}9OIw#+41gp(D9V@=U!ZyT+%j=+-^9Tmj8Gt#5~ z(b@0+=2KH#uVhBbnMg2b@MQbKjFBZ^tq^@B`4pjnw4U{(%*ByZcdmc5L7bq4X5~I6 zFUb%aI3o|HnMRAQYS%9}huf*n<`J3dv7|;HW1RPUivM_lwsv>HT=wvc0_0*#Kkl-G z{!ZLN#d85By!Jra@Lt{GBCCgxiTi!-e4*{hzz9y>~Ug zPsA1q^4oBV0k&`4Fe0aUGj(r%Tj;Ex{cv_+nKEVppA9h7_Yvco#FIqh;66sF98_>H9jJvKjk zrRf@_DaELyT*%YE*rteRvOs;_Kg?v^N844Hk!dlFLui;dwR*m*U^&;`cfbBPa&~A0 ze}uT2YH?1LpgQ4l;aYRNQNmx?J>p7DRhBR{98{4X@c6G@^v|LK?!oty3767cU&l$;HmP5yS#EA=zCA1bI{-93eK9IKW1lKow`m(m#`RLi+6^Yyb@*C9G^o80%uABDESfNQrK3`HbU0P z>}B4v@IS7mfuX(G16X=7$HelwBaxJX%s_94$V&SW_=68No9dN`N*D%MVJyp|t|63L zZWh6t-A7my?_38RENl%*=gll_M@Si18cWz-Kaxy;4}%D5qR(8hWo57w%kN(dda+@a z?6p7;SV?Vj(}|^=cPaX?;C)|qfdsH>N%#;?=s6Ss)+Lq6JB_T)Ync6x5IKJ*KZk@rpv1o;-svW!>`01l)NMWlcj1 zy~gGKP6|M+P33?=i>AI%+PP{qlf+zL85>9i%KEMe+1{=7MCLr3LSOTvjaz*_t$?IL z&w6Q@Dtp;-VF72kNqc$Oc2#9sxfv)=q91(Xh{DM2;d&AIaLiP@Q2!u`BKLbZ>U%)K z4eKQCocIf@NLfd_4=aAXS{-Gei}{gxyQ;nh!$7BcG!2rL0}iD0nQ89kP5mU`$;`^gr3OV7h_?Klfmq`>Owh?guFi2kXwtKaRc8`- zE~m1QI_(qDScg10i=Aw2%CpttAOOwY^1{%N1Ul^y7A>3kH*OT*gr}mhfqan6$*PIO zzwL=dDUh_3D6GiwqTud-nT7Y>HW{*OrR#yULReGG*Ik7i#4Yr22R=zh>C-X0dert2 z^$O5XqU4t;{xCO)Yg~0xcM30puodbB?!aT7Jy4FPuZso2kDtRSHLdQe;rNwErzV0# z3#QcHmp)MZQ#_$AuH-)3(NN4jm_wb|K#B)_HjWz15_FSY*akARQgDm`PEpx}zDQqQ ze_I=fNVineV*vrA(wTb7lZo(b)+LqimgSL+9_7oa<7NPPM{j5`W1b8a|+QdeE8jYN{%; zsU1EN+&#vwFzzg-U9zSkLVJn(>qB8mEQqOyR@m_q){tvpcD=V3J9F#^chGxR;+WE{&1IHUkVFF3m{W zA!H!F;~7EiptN~jk7fv?IzZ7(Ue--%zrw1SZxAal)M57l3%^(hRFm^jchT`s{kbXs+=Awh8cVc7CMG1kQC-<4*7(!Zg*%Oa z5pvl2R|e(bA@-R_8AFj-c3SixOe^$3lKK&brJ)KTBXyL@8g!v62Y3e2UbF=3Fht>@ zdv#LXyr&h!Kbkx&d7oq{GF3s&Y9&4gAoqp&tyX34tdC};Ys;$snxJ-gLoLo#ChWvT zx$6<9o_Zxpf0%gXQFt{}cCRAm*IH*=(LHeu?q~`8MdMml=8h`6j7_sIu#L$nX&z3Y z2UQ9a$i55tKDosgxN5kOIig*GOxKZy{E^hG)?9$>CFwTkXILgMPN#&Iz-}^eF==GY zV40~0a+`*HvnF?VH;?pnbs>`oox%MuR~b^F{4k_k)Uo}|?hIEMI#9w2=xFhEln6FhN5e+R7Z)EvzigtESt=k0rfKJ_mmAUz> zqwh|*ZJll3N$qR-M;U~%$Zq}n#LRbecjJcn%HGQQ#%B4R>0|u@*qbY4_s=A-ufu!j zW6&@tBU1}%O&pljMXIS|Ozu*4{Z62T%T=%*8rT^owkdj6l@$5AVvF~GfSrmR9><=Q zd_jf`nXwb|jxIj%5cU)?ol$v{^^832W4+_|Ji4oN%YQKZYz8Bvk4YT5B!F6lgbHhr zlsD`~d#(uZE~sNOe1wf&&OeWEkjBkDszrovoqF?|c>4gtTVOjT>7$QV60Hq2@P_$} z9HHlhyqoqy&kc+%H}FP{c>heL z{4b$7`n8ynLaRj!RYo2GwFcd=&+<(Ku^*i(PTz8Wvq^d)V|(4yH6ZP|pw<@!k61z6 z`xfLmKg!HCRWpxHMq)9WBhktCe%Hz3>;2;qs}CF3G)~`rue@UztE+{EI`sz1;)-I& z9KvK7dsFkbcIsqx1I;kFT9169o%L?3iBC7;T8_5j z)liQqYB&=k?G0)NvcXhZn|B73Yb`z@%d&K~S`3m4d6RsqU>cO_v59;MbbdcOw;bE5 zv@!z<>VgNnf|_D7+WZYdbT|1NWgS&k73DEgVB>7YUxaK>hLrFLY$B)+jrT>8vKJPF=F| zZM%Wy3+jYv%(loswyO*=I9>8meAJ{qN1h<~C|aOD4JgsUgrv!lZ7}X8rV_Byi^mxt zPw^#el`{nfdAMB7pAvv~GN2C^;KYjFVi4vBa7CLuaK!GRbK(gt4ljHY?P2lQfR}Ez zUyzZ-M021xl!qS4T6OM4&87O}zXnp1WcuEA_W^24HzXq*Bcn}pT|=-aFtWY2^{#E( zwr$(C^{#E(wr$(CZDZczFaBaCRY@hOEP9nx=b*V9OMv}?my)=OU=AZecuXYh;)kK% z>y`WJAnB)vf=KZwkS9keQ25TiIE@@l{Ssq-L>QBB?Lf$30^^P8XZB>3(fy6gpOB*j z(MYh`>V0h+;B^eb=-ufb{a>lsTTZFqTtfe7{00PO z1{99}5?W`fIR6L+nmK^7kYJ!XhsE?t%1;pgY6uEIB<7&78iaG?Jx?WTS{iLGp?;{G z<6J$PAy@>EC*<<&26<7qGzuR-U2YF>t}4YW%BXg3UM_1{(#TKX_(BZmLnx56Wp^iH zcSO?lJO_NyDG=QEQ^L+?KPwHXS`Ji*3A!^7A+-(#Gca^rSXKe z=iAo!lbjc)j)Qqq$T5PY{r%L(+wC!*T9KT8A417KH&jEL*ac-!v=}*a(Te0dS5i@~ zngikrxzMWLO}plrr*)N+dL_3CIVZcEqhrwt!)d5RUM8x`J{CP@l$E=ql?n|We}%Sq(Iy9@Vf|o zs=6*A?q21HqJfxVxwH zKp-zaa9#s)jCMS0FlBh^^$heF@&qR{m3p|K30X0?=^?;F>W|72P+KHHhBV8j&th06 zRsMsL1v=WY-6CBWe^<^15^sYYddsvjbd1SQ^Dy(kshpzG8yFU%5mM$$zwQbP!$9vS zLw=y@zFU74TXDN3L)NKdVuF65)VIVDd9CiWUOi<9Yg~xCs5|QdxLRG|L;i#w}A!m+UT3nEm%RInTl zkr)-LEHMR;+JfTOmXMk)Zf~Qr`wzQ^?cNR*P4!Rz9-_Ju;Hx(sEDgYfvoU6LV#!W- zyxgCAe0&EPiDexG0n3wK$U&7CwWnAKxmVBHT_abPvYapOdr&WzhqIp6Pj+8akF>!z zDz93RXe|R>G?%NvN8r^KyE`fcv!bqRZp)aWn;kFMRjsc|&`a_K@=b(cv`dFr7_~zL z##GhR4;wJWPiqdxoj_BoO0b~zL~NEOmNjb@Msf9RI{LjaVDAzQWy*V>2xbYH%i48T zr{B_J=X%wz@+EO%L@*_1x{GZrGJqwXBLxU| zi&_~Th}WOUdP15lV7?Fy?E%bP;3&f%jw2OmGIV9&$)dlMM=90sX^E39wPiSJcpYIWibadW{lU@S(3RC-K?6vzr+U{T zIJFX?7I-OS>{R$yC8GdG0`k5OdVEN!jQ{x01)0QcHFfiIkHzz#tA%DkQ)XBKG5xrD znhYE}3Myt3xYtsFM4{WqZ(I+GiCt&!FWfGAF?wmp@}~qqhcWXyWUG@Xj%|a7IK6)< zU^rjhrKO^=o8?&H*~sikdCpw_^ec>DiEw}_5ZfvEnw1M&W~!A_c!w7^kq$F=u)cXr zb~I4meCsENWkbG?Uo^q*-t5COb+(3yCslD1U}>2QK;bcVj9Qo@V?$WDZPswh#I8Yk zJKWr6$os}6=k(YCipz}px9b=4CZj6Hx_PY5+8vX#FwT}11{)Xa0jk-U_zac2@Jy5K z7{hr)fEW6Nbp@?Gp#*pJ-%yIzA-eL>VVAz$FEK<1DL zM5A=iD9LeHEmptfmz+Jjaarwvaw@|k!msWC64B?aG*>I0~u|F*z{5xJ6f$} z2tx)XSJ#=Xe`U`5_uqO&VWCz6G;b+`svXI>)i3M#hnQ)v&r@Y%mBwB6T%8Iq|e z`R1=r#8yY`fgy@toEq2=V111Dl{g_Li4z&5667 zwW`e|&S&;Hbs`yq+BQ?T#kbsq#5*zofX{J3>q_|OY~uEG6U zJ$?s4lYVsNON-VOO;q5(p0VMY`8S1+Kb5TCxqvAs$el1tUTZ^ap~_Qc&M*5q7tG9W zjSa>F?R$E3jrNhXSmwg+;^wlgYxx+MyM5+os9OK9%ZQ7T3;yty1sNOhv#F>|Xd12{ zQ%$Krb00@Ik=U;yHMIOJeXDT=;fFBWP|cquS_rjFO~Dd*q4}>%9N`A?E<)_a`weE_Qz{4)2Yw~zLm3!!8@`_ z_~!?h8>xO}JHIB4nPkbHO^sm#zAXt&-4ZPwt28ZA*V+n?u|VdO)PL3vU#D=nAXt#T zzfj_B8IEO2CQrd<0v|k*)jzmofOU>MPs+`L4@dmUi_`-!goQ)(u6oOW$(@9=m5g17 zd5Qs8Nh22T3%Q~iq7jfvepNbQ<~0C?+dRFWkV-|aApVy=KM@`ISyvhr;$U;+(kM>p z0_W(48*=fu8_9b7ux~XV%bIZ@E}MT&B0FTfCr7=TB`v^mN z`|$NdibxUmuHWo)f-mgo4=D=CwRHe5P(YpvAXAoLx^Y_gsI&u~Vw!d9BitNo8I)z0 z!5fHB4NT4IJZs+Wwc3v_h#aq@r^KE8T;e>~7ds592^Zm4wYNrt;Gs@2nWfHNeAeJ3 z-zD|_k6ByG)*4~6q>~D#QgZ$^mJch&AbbG>6Zny8Q80-f;y*d?Ku&GKCYIW5Ixu_h zD6?5p=~wUUV;)*QUB?fkYl;4E@7ek9G_{b%No(N%Gb$*=7Gz1g1WSvo9?|E&GZznKLWPk`Y)8ISQ62RqfeMcxXa)1d+`lTp28 zNni7-1Rc6S1m17iD5S=^V*%(|HPnUmi?LmdykA;l?4P1RFVo5;F)e%~_74^NW?-vG;L2@sA|^p|l%_{M+x|ARzr+Vg5R)g6>4B#d$F{lbsV((;ghW@gem0r!^p1Y2H{TPI66zHMzwBs+=HOwfuZba<9&+%L{oDGp9h*%n@1fz`s>0 z_GGOXULc2?SBwKeje{KvjWY~&|0K!B+jKxc;(S=MN2cL7l~zv59rh{3dq3z5vY0xM3Xg81O5Ce#VNtELB72a+g58v;dM{7PjbQiA| z{#UH`^!N4q$4}-qe6c0+i!ad3q=j8438{~P?Cas1I1J`eLjF$V4pP`UBAMlaaUD7| z!NXA08qqF9P=C05JHS34TXg>*Z8dR;X(PL)>&-EpQCF9CXD{IFD*B%vE5pn~xhPm2 z@tSWLMav;e;V4?C>ub9WWu8!d7O&I^|ADwmDcB|wp#}^R={zjS=HH`GZ7pv|PeDxX zn)3Ibh_FhX7oh5)02-(R-EjHa(kZqUGAWihF1L(OvKc*yQ&De#uay1gI(&iyqG8w1 zC8jWMm>snRCu#|8=e0kPWlHVtVmm1o6|m*L-?VFZn`r>j65r?ZZLi2Rfz8898z^GN zQpDPPNppR95#cumF+4gD>B(`y;=SR$@alolBxbW$6{=TR>hrU!ohDZ#`>>T=-1*B1 zyEuIE zpIOEF=8w?*&AJJ{Bm>KfvZDj#&pPsHPWd@5X8;EXNpZj;(l^|!=%J8ks}-4y&Bt0U zK;jMiH@Uo7yN`gkiUWYH7mVxk~ZTL;$ zq@-XU7Dnj{NSmw_g#@Ck((X|VsYV=@l|T+sr9AKol5N>VJ~VBW+A(=k96CKWsIfMN zA%Ip7LYE>wkW6N!_-u0+jfa*ofPT#(c&2R#W#FZ_?31P(7E*IM6X9+)#WOqJHTP*J zi1}TZcqMCYBtT2ElG_R|2Fa2lLxTlv{bLY?7IyXnh!W`Kz$#imz|8MdGlO78G~O(% zcNFGfVZ^g{O}fTPWJPG+B#MLxIJHnh6ypuWWr0P5>J`ek=w*@_DG3-mPC_&8vPqQc z3uVPj@QPyTM%>KjOW@d1F%0YB9Pe|cwS3L_cy=kcU0Hm_C`_D)@YH8NjE8SreEyc& z3g9}z6OCq2PNPZzG*vmW;l4hIl!RY;oqbg<6k0q;vcI{~q)dGKiJga&Q7I`V^@uxQ zlD>*sM#~3U zWM%e4<7&m@tML#P*{O=}`Z9c>FSU*Ch+PJ>(r)L0sb_@P1nTMGCfPOty?%|A?wq?x zqxzrSu?|(-4^JXn=U%rP=+HtC#r$B_yt+z9>kz0dx#Ej!)__+^wt68F4taC&zL7Ii zf9nB0-Ec48GE;uTMlVz$|Cx9M(?*}1f9|9Jn3A8sI60wR8pfI^#9U05q6E`2zln`p5| zUE3@+gdAs1P@1d#iSkEF#Ql8%4BI{Ox#Xh8iXk+_J+s?+Fp@iAjLqe;&}_Zwmwd+JLlK88Uaa}TzgOl+8R5u+GArIUJM zYPAzcSKrZ8qA6XucuUp?U#9!hr;h)<2soS2lYYq_rCAq?6Obiba_|5#Eo81DLsHSd zqd`*Y7CHZfSAAhl2V4-}xiV&xaU6R=0y|2+9Qv&F^C#Afsk7uo#rRiCT(T(0EOQEA2JHQJ}H%LCM@ zQO)k>J=V*;)(Y_6w01omRKnmoL#bybckw-km0;p)d@s>*qRn4usLwDH_T_E1ulAYq z4QU!QexT-5wsr=HCs>U@vC?;koCZXja8?uv#lu#NFxeQvCvLFHPrNTR7cnx9c;U+_ zdvqlEm^Kj+NOGET3#Yk(47$hyd*nkVnU_FC?P?q}Yh#y88OT|$_eMCJN8c(!O56cP zML7erQqLh#{^-T+mD8|DYRaka%iw`yJP15ElfXk)HD9+W4}!{p)(W4bkFg!a9p75yrz+f13F`_tf1QT(>i?ooFU04EINL$phju_M6#)a6rq9r8HgAW74)Y?86N?hkz830k= zGU{h=Z|%Uf1$zt@DUI=YG~Y(c)ON{UL0Hp3Oahy_8h9VQU}1&iP7T}3>Bkf09e0GG zGK>Mt;4D@ZBFmnn%39?aqf(`?A zw3AMb5X-^%iMaXV-Z_bH&Yig`eCq)H zD{r`LWZc#*weKa2a9Zs2cBtBa!J=q5-XdWlAKJ&of5i@SjgiFf}p zz!08e=aa|PU^^3RCSY@490?|v?M&4PC_iHPXP#Y1^TF8l_5yrzOeTECYk!4FJWhk^ z_F%wAwqtTP9TQ~^>P2O{%2}0j*S|TT4jl1~4tau1kQ^;4`I;OVJo{=Y`&fWNHzPr& z#(sl0$-zT>42VN?dzmrUZ4o-ZIktIcZBeAYQnLB!Xx(Z6xeg*z!}^Ti#`ljFG>oZw z;i&BjUd-fQLvvOo7_WqWEXDN*rz;I73Z~wTeF!!kMwQtJxIDvd+pl1?S~t_4%I-Y6 zuc^8OL|Mh3BE7U3GZ_>(>*uEq+A3Rb0TI9T%!klGD6;;QIvfk2Ks~~QQt!mh6uFYs zcJ~{j>X5Y=8@O=%%jerYOe6wR8wS`-hr)P`*TojR@T5&hk#wCV&dDn4U`80qv9zZE`ZAx>bH7hYy?z6#G`P7r_9TrCceH=Ak%3y zlrCZ>%Z6qQM|d0(uYKrp+0Kn~{!PCYl_;UVoq(~9U<2DAtE_mwBdxiuKWn#ZU+3R7 zKWb2#F`F^Gt4@M%X*YK09}v8YF-`c!30Y(e$3d15W!gYETFNS)rtC2tnfG`jn@@7vpX|0W zen&u~ZaP}l({v>)X{JOf&Oo1&;_Zx4Be~YCD)inSxYhaoQKf41E?c$yX`~PkN}ufP zBFHWgJ_d%NXZ&^U$_OG!ZAKmb`<72SxwE}yOcf|gvamE1p%(wv3{$DlVV`!kR3`Ct zu_;+hSGn8yF~LUp3D|@$u7UYs^|>KMm_DRa6>dRn7qzA%vY2GpFwiin5WB%;(BSDmwu9Mj1tNX3HXee<~h&gDKdSwJEd+4&4c3_34okhy_FQJ zSpEn999z;>lZ30t8z?V>mYeSA6q&#crV%|K(t4@4GBb9%0+e`g6%vi zWfC>GL1i-DX>&UbZTftEYSwyrSIXsc>g=SkBp&pdev)=|eD6bw7E1#2%`SZrwK?J|Zr2Cfsj(YFt|?8bm>c)~n>|6e*I|!c zn6$QQUq~4VbCGZw`%xan`u=4a?BD;zl?KQ@c{HJ4V{}4COV`MQs9L#NmNry^)wyjE zJ|f!lE3yf5`bB^>LoWx$}Nj9E*0kQ7>$>0B9YZh0B{D4 zNYawkfLrgE8BXcV-&1t89p}gGg|nrmoilgo*R18$8(uizsMg@IQ)N^~Z6gYzE!G$g zpn9ru>kM8px+Fq|ytetV9x+SL9@&QjqmEG9ez)DmGovwkPEpFf#aCqy=qyP<9ll4c z?Kpy-RHRI1xG9`-w148^JBx=q8q#K6CP!6RbyWU&=sSa}LgZe?2*VknEo$LZ1ee3Q ziVoYPJc0@>Qx-i{9+NS90^LLls)d3{dcCwuaKWA~~R2M-Y~szwL} z8P*w;-<(x^C+pno)%xpo--R2S%%29=XmrzA$ILEic!*Y!6`{zDtj4YEfvQB8jQo`o231fm6>t0jtJMtqCuP51z zsL?}2Dg_Dmh(LX?JY5T^*w~tH#1kDGPTztJql)0G?NRBs_1hPP2E4{2_=!cY`1N4^|<8zD_}ZhT^j{_raG2`#Y6lB41E`9~aD zCGIVnj`4&a67nPehTmRJ{if{;<3^re>u(tD4p7&CgV&(pY9&yah=^9}VZ`YfeKcW- zueLkEzasUREM_b8)Sr{DJOGfMQZQkabf=+o6gZe&2+eG5spcY>$9kA0htJ!&J;Y(t zPHJx(G>(#2&Jh!02b-hvP`Tyi61mGqXJ%i1SsCrSH&qph7}kps3amy(~Np+E%+<&YZK@FxE z^qD+NCcp3T7ZCR>0pyMl!s*@o5+VhkkhfH|pV)sOfGXr^Q^us4dc1T`mP2yvhnT0A z#ct;8vc|s!N9KC|>X3x!{$+3d7}ypEDiYOhB`d2KK^N8alqkch9rD4~*u(L(w9%mXtF%98!`iC@7-YlM%z2@&bP~NnES*Kt2r~Lus7fN6y)E>4}b|hVuHB z`HLADcp^AYG6+bw(k)-bZi?!qAwCFY{wWTne;N4Li_Wq%vAD-bDpEO0+e@dGxwt2c zj?cGQX}X@~U>ETufVWA*VPLSeoc!0N{9Lw${X9Bj@d!V#^DNj)pP!4P!&{AXmxuZO zrcu!}sU6&(&Uk}ov598n39ialC5n#u*hL8qv&}1Hk?L{wS|P-}JB)11GyB^bUOW9P zi;k!OGSpa;BC8FZ^9B3;(pD}oHBcM}v6r;OUhm*deoZBzJO{Tb3SK~19~a-~3gVBc z#U;tT`Ab16I4)OKZAuM&{6YO1z&oa1#)gV#0^e~_hT3SSK{1EBL0BipP~bhS z4y+L8-WG<96k}|N+$AM;HQ3~M0fc`}YMyF*ox-(VbwxSZR*^dIrV>}$LqK;?Qiq`& z)jG>Pcx>V6(n=-hWmLsQc!KPA;_)mTSF(wyX;zkYW+B^>HHyPQp(Vq<>M#fdtJx^=>kS5N~+XoKFXw?A|;wSCW@ z69qIT3SAw+^9#$0R@20}iQE=Jxs(CWTlJx}YXTt#HDyXSG;Lpflqm;Mi~he9l_v*H zb~5VUAtYdbX>t>i_H+_eFWwx7hK-eVShAM~SpcYmj$LoAOoUgsZO!v5Pl(Up1P&Zz zpLOP;8BxA#y+v_Xo*7|YKEL31(?PD5j7J-0*^yXwPt=2HYQqeR&OU@C&b_)8t3Af8 zmSt&Z%4SU+ncHK{Kl$<;= zB5Phu@UshR!pj*##Bf~|M^wE(z`$(PLAtv+DyOPvzf+ zu>0AgC&bh9>9mXdxpl3>f&?K>v+UPQ`fw^3HlCOq|I4u1@HI%ac1kod$IoxZ%!C@% zCLrcQ?c-AgXe;Ey&(C1$UQc@wBte}dW{%;gtIaQyeRa^|0+rqPGXo9Spm2OORFDq_ z_^vg;+-YS!X=gVzUS!s$zxK4g)kc>}tJV5OLi^l^%X-DHTQh_&#J@H7STZH-o)O(^ zx`ly6)+0wf8U-%turKRM1sht+EdrrVM0~jcz zRMm^tqR%bSmK4z-- zxiqN>v&oIj%-w2;D!ho{6$!chax0sQE#s_h)8!?apx9Da$YFZFuwFz)3cp_bidk*1 zz6YgoPPvX6ovvDc;RABDM<=RpTm!e)&4J*JuX}k)zo;2W7#RXGITMdRo)sOYQenDT zfH&Y>;p3CmO0xkE+N~^!tpVX&-iw(4{*2t2n)Rs*@O_!3_G7b8G2H=?@_7OrXS%TN zvFkL%1RQsN^9IG9UdILd-LWm+S*Cju2RG28aE7*DAb>eS%hEs*tb|<^2op9-^b+aV zFA|cQEn7%4a3?q`6qB`J96fN(Wh%H_ECm525Kd@R*=9)SCr0lDLjz6|;lQgPmC!UP z!-XPAotnTH=oRoS+c)KIX#bhvm2PAtftAA*XlOIe2J!$ckp||;J*(rMcflE>HXPey zSyX?w&3iR})0VH2lc7+^0m~|T{mU*;kd&B=3b0k;)N9&f+o-6vRx!A zY$FoB-)KuMgI=PLo;a#*V+asJ{NYP&iR?iWK{{SJ3Gaj0uHBzxy{TO&#hLthgdw_R zfo831#?pO(dMWB7T#`6&W63m)-SRT#s)lW|f8s#6xvy5nP2KqHIbz9m?G$4kV# z!Id`beay~i6h$u@Nm`Nq^yTBbr#oX0)T-VPqs8^fT500kj5!p(qTe@|vDE^_r(Mox z2RJo~GvaSLro~~TX{)G*% zN94@>A%uBuJWa8eRM5*1))^#Cfhwn#XOH2A~j zxs8>c=xBq(7t}lcZsNvCC(Yur)#R|No@332{?*~jLtV#yy&h2X5$CM(o?TnW2QaUz zJ1X6y3k_dD678tTV+e3KFxpDpVZO$i@K9)(cl0uWQ1I5R;+x!zflYV~2e)=oeKS9~ z2wu2-FRYM1;|osj$pa<7i&=QT+VVTDc*&QTIUFa=Qiq_pP^m|{t>JtR5iXQNNuXE8 zM>xr*rerR7a_)Vov0F#DY|u_1RJ)LYDJs>6{b+wAU8XD~FVl1e1ciZ(_Ke;l=oifj zO#5E%-}BVDSM!&v5-a2E&+CdgJuK%V?4k*jg=4Wus!zgWV_%eb#JD1X?``ZSI6^3- zd`BzX^97181)e_ytryd2@??P)ZQg-Ypaz|_osZ8LVomEz!Wv&>G@!KuOWci%34rxr zqu)A4fa_F!*T5G&@EX?oGX$H5DZr1J7@%@ z>OF+w0w+Ry7Wj9aL6Xzc2`3mEL08H|XVii4vJq|p(%Hsq5tw(#GRh&$WBaHT?&Iwq zU?+que~-Kmb?6miZUp0KQSovK@yCv}Wfkde`Luv;6%7e;k?S_oSXKvI%*RB_Jq;2Z zYDB$VGb-T{arF6fD9O2w-G|^X4lfJXL~d#Yp|fpRDaN#Fndf~Q+0Uk zR(wA|x?SY1iWq~{Qu<)7Q3Lyha66AP-E;ESz1J5q?~OFYi>O?4S>QQev$qpil&TYI zfD2w=oo^LsZI&6LTVn6cfqK*!M% z(KbD8nnvjZo+@tvQJ4kEPalIys#$271^UxIYHC8I?BFt|#BOTrR>^k@Qs;4*Qm2zb zU-w%o@~lJ<1*v-Lc@Y21&wX&KhPE4{`cnQ#*i1)#8g(c{?&m}{%xMX|QVV|WqcYVG z*G8rtoe$mMD2$^aXXv%toMbw&&OkFsw_>!;Bcq)cr=RUS##rB3^3%$~NVSVfygSj! z;nWGeCzxmOZ%V_)_w@!U@(|H5L9kST)`FVvP#l2~xM6k;Ocb{ZF!o3MCM@eemrOoB zl5j&V+*LgxB^NqRV2M^uDB_0BKZ`*oX>TE&p;3whQ(H8!A=QD#}2x`}{ z6KieyE;9Q)>Kdo}Az9T8o~m1NI4&G_6)>lwHBw5t@wt${mZD)<`dppW`Js=`FUoO%%$;o7_I1$`c4&+KFdaAqdOxyOkKaSV4wtn8s zp5(cB94rNDg96cfJPNtGgC3G2d(qq--vt{pg;it&sa@CA^kxo8+xzN;6Z=G>S_kB& z)^jn9)OoC+vkT{~Zu2DVnto;DN#>M;vHb0|IzLSEB+jYF+v5aKq9uCk>AkPpv^}>y zM+jwZ1TLU#1n-z5IFnKgjs7T>o}~F!B#73^v=onPJLr^{aM-aXkgTzbLvECpA%wFH z5D5o|TwA_bRbLD8q`jQ$I#~$6y}FJDKqV-O1rhdY7HP~J%Jk-rxBztD?ox(lm_q=< zuzHs2euB>Y1Dwlq`@`&@yHAFe4hjs2_;tJ!zWVF@#=fDE{$piY2kOx9KrATUzblU~ zd>iDVvjU^_t#ABhdssGgBs0dfeI1BHqptBz@7LB+?;mhbQDtVO?_rv*_$OEG0;#B83&>$&C3e*o|3b zMRdC&&z@Hr_IexaToJFK>aE`dT>RFR3A0Y|GL0p~m`KyyQQ(rSSfCCpZ#*eBK~_*t zMdrX~hBw}a@;u&hTX$cTkZlY?rYsP7xt0%e(IAJwJ>n-i^jhD;Xhh&)VSnD*V{7GV zq0jxJQo1yBe1u-YPnb=+Ig*x!tIxd4#%{7FxbyG%LiC@UD6YB8q&!$j*(TP@JOM`^ z@APTChH^2I?&HIUSX8w33HlYg#e>`o2?`AKulse>DjMRu{5}od^<91!a%`J2?~f%M zAlHAYj}bxSf*B5vpBBwF95BFKe{qm35o2^rLN)a%VkirTWo|M?_YMrIt6b9`;F=p+ zM3m*jy|+8{hKz*}xZ!-N+XqU9?ppThu&=ZqG$4j6q{r@|&iZ?;jS^CgYc+4lG)%TM z7=cgJROej_Us{G|9z#6d4qhY&g|Uq5*B%{6i$9#=j8u{_@QhYN3BQ5}oLsVu09z@& zX>z6K<3&3QlU-3KMg+f~ZIr=^Njrjx_agD$u$`4!b@eiHZ!We>%7=~ls{PeKfSQ3! zadSq<$T6cGyjRF<5oH7`@%b%+YJvD0tRHg|HJ2dMUOuVufc#y z;3>i3Fmh@@05QZQ!lyU?lOzHRweO2bN<~aYL0eKafKT;9MNb$91bK%1&#*J77it6y ziuLPLUy2LNOvp+|Y*KGR9%wx2OY&sa>EoA1=}Q_#`;CZlR*w#ZD~_Cet(V%;&TR4@ zmF)0J?K%WN&^Ykh1mc$x2#(wk2*!Nwml6Sk90BkPZwl?#Q*8XZ&_2%!>Zeu1((tB6 z?(H;j65xgIc!13VXeUpQT2AOr+Td=0fG zy)j9ktSnd?>mNE5)^?=9&fLS<7kDma{AGp(y|Rh5^vqwq1i8o+CLjqU#V?A z?RN_rAvk;!!=2wIv@55P#RiMM!8O%8zKZxa?7JpqNMM9M>8IW5;g`yC7`&tNeCp3x zUKT#9lf?y?TK|mn@7baskNw2cx>B^$1b%w;;a&C5eU6uM2DUpdW984JN_na!6u(wfys6QKyyDwbB_cLH;$-!ri@p8l2aq zL@6kURqGF~>F*q;+z+a900+eCpWin>9=m=eD+r4`w5GK$RkhO7y;6*~zSOPVcef9D z?o(bFD=^=|aNAy%&0mf;3*Itxgtq>FSfc#zHj8h9CplbD*VB)VMd@t198RgHBL=SF(FM!Gd?v7O*2tHP5zJQ+p@4qCrLB5Iw?afHN7ZBEiOGH zzC1}Mxe5-Ae*QNNK_LtxsStV}{SxC+qX6POFxWYf@$spG5&B<<;Qvzjqf5De0XhBa z|2t&#{}!^egpi1=lE}8Emeb}4s_$#PgGwUC8yyDe#AC`lcD zD_GqaEq=uJGf!%FK#{TAhpJ2oi^SD>txGv)sV?{95nqza zhV#MY`=#KQjB8;N`2F+c>MnP?IUCG(rdsXG=ePC(tCLY{E#}Tdw`TzKZSAeEX5{dN zWLLL_4$W;UTV=Dmn-dvtRV}oGn~#^9)AK%!ug;v3+T`>1_CqNA8!Y6TC2fszH5ZS+ zqwUXt71JYG24riZ4ADOTjiFBh+(e7aSS@_P8MPLvx!%yZ0zvh8McF7^?~g7Dua*Uy zdN;IZ5}K=)=h!BJ62FZJQH{h?IFeB)IPrCI z9Ek*^ra#7>2Hi*>u&zKgwjC@OPL%}|K{XT}rea6m;$EwfT7SbrQ}uZl@o(PRrNOA9 z`(V4f8TI*mYzrI0Kf|s0{eCefIulVbhXX;q2gOFU7JyfcJ0!|{t{*o7Fd|7v+0oN3 zl%H^FeGw|Ic9k>kt<~t`87kGVZ`t|#{?Ddb;`Mfu7tBJ)B5m`zpshpK4l#-5n*NOL z29k)Lx0mNzItwn~6N5o;fx|tpI?fM(E#qWpB!MGQ7yTf`zf@!kOgxE`eyoSm+I^Z| zso6Rwx}m>wr0^Y>3Mr@_-tK@Gh)v6IsDRyC*Vv%k!x&_M?Z?DRD|K3s6cFdjxMG@i zD%DlN$4^!=Xum;PO(hHV%n}-?*j1ek7~?2$K?O{I&7CV9-0ljQp6f>M9GeK(i-9gf zw}=FEVff^OzG|Oco1VDZiWM-tx2%6a^X)4-uHe3K+KjBp`7Et8-|Dx<;hNweffVLB zycI+I3+ym|>(LbJJjAsbc=A#moTbGxb&Uiu6ld_9pyL6|{A5|k zD=BG)?av;K{Fq-BA<3`yr54icA&6*-{ci>s41wy-zv?wL0OPpDx5s3VANU4~f#y+w z>ymhrjE92#ZS}$2*$1$+pm0}=RXJePwZ;SmwCE0i;PP-yHV0?w5b|&avi=+-M)s)H zJrWTs8NH;AL#a(%fY%-TMKVWV;I_!e|I`1ZK5s>#L!r`nfRIajzkMa$}9iiNc z*a~j1+dX$o4FF`f^2Y>7w^;s5s%D7t*TOpo0u+sv)f)(LXWE0+!$AEw>907!rPSIK za}r9Ow4DohXV%9TN-VJKa^e%+Q2l$?Gkr$)t$0^0rfRd|=$CSL6AFd-A5PKADoeOH z@NF{2EwBR6!=l9M4j9>00O6Jt64Y?Q%J}&*GRb_Gr1HeoUBaYKOuv=GQ4Rzp)=fIh zIWq0CVg+~<)_cfd`{Q)+IO8?eCMaJ&$#+7j2tbA1z7-jN8#Y@2E^c>_9f5g~j6_df zRCA(%dt^<-F6rZ&b<22URAG}1+(VzjzBHD!1B-_TlV#nhgLG3}wAD|D$vSbCIR6y@ z^gn08(bnWKFKDYS!n`9hT6+3uN1|%u^5&)e#l{4mod@fRDD_mkz&}!)fP@!df7tjb z1T<9}2vHru*~(Uq5#U(dl+^_#E8_og-uYB{O{wCojz#Gh(bI(mOl_L5?6(}9m5(h( zQ|=ZP$6|xr%bCkZ^@Gkegt!M3v}-5lqu>%+lV6Ypb7ii`6mq#zwO-ZF1v6E4iCE_u}@q_$l zh7Q910B{5;0S#U*1EfIigU_uhdqry(GHpvebp1s>98K->yh6hwbBdd`ch}GY&1FXD z1Xm)A%T;#T{oN1A-wZ^JGvXP!hg=|Gza53G0;Lkndx;L>kKOg3(YD0#ISd!sX+37< zGh~QAPQ;l_avDH$ox@}LC*J_s{sq3(?qghrPt%`sgb5%F2#mohkeYwgV7dj=0XN`! z&kH*S4K9mib&2MNkMOqy@O}3KREWY^V?YGwR(Pq3(k?G@w>YV7YtJ`MAVb89L zT02&u!Yc3I`LcFpuOoyUuf}p{{Cnjht0}Xtp~as&H&2dZsh9Ki=LTs*f005D5%9-9 zURYIbGUiVZutVr&V*sdaL*D$sQqS=-1p7D&H7&-(yGtn3ZDPeDe1INPo{ zF^iGo6d?xnYaU4nltFs9Bp#hy$z0T@BuJF#IE~IDK*hnO4@KlQSUsK=p#`c3rvFbh z^g^9n6*^Q;dL&n}T*yh23l%)%dW-^uy*#)rQ-7hEI&M3N1(7u?(3k=?L1DlzTRoxN zrYY^d9KJ@pCIO>3RJAI_i=z$ZS$JCy_?0K}#Z_?EQDO{&h1SxaE54mn~zjhdojSi>tyqztjAfVT8aJ0XKBAEuIc*ub?*c1#)Dq zR~n3eQ;w95;h7y;9SeFPWnNt#kIHzqo`f|9IXd7jIjHL!8p4 zkM-7L6$5@+S8fksQ$--l-N8M?$WSdkz+y*c1-?+DSSrOGme#;F*}~EQXg9xsT(Jz% zFxVmJ`XP1p6=_v}Aw^m5x;Su6?{lwmCkbvclI^LtcIpiuXxV=5!@S)wbP z2JL3(-k8_f?Tm&D>pJn}v*t=gP37ep+}!gKM~m%glEm<>GbJ7p0g0Ox5~wj%SZ3qG z#SAf|M(Jzi*e*cGq25x{F};v`x-9klY=7`L%L-z$N^lJd6^%ZnkQ$*A*mv2n8^^5E zlB4T$uysgEV!3eP9n&ss9?l>A7Bf6DL@Z4K2MN9g_Q1n0yFpX*Nu^2k{04dZNT7@A(3o&_Fa&1;DBN6$f+u!LAU*rH*;%62FD^riRw zLU6vLpM(m{fkg`y6|pW??22C7#n$C<-9e@}J5r$dE*?BHTLPcBBT7F1*cv(+tm7)2)Q`*(>?OJxM2 zjvMg4>L@+~xeVv`J49yiMITOvJJC7RfX4A@RSi4xAoEeLOuEqDj2?f-vfrZ_ie}7&ARrPqbYj<~Q)%u_NNL^)JA0il5lL>$%$<{Ik9cqwr$(CZQHhO+nICM zyw2R;(7k$f?fq31;w{ZU3UH7A-kHmnmk+&%%mg@`alj;&H1=mWK)Xtd16TI`;l-T< zzXwO(Gt})$<5gCqow{;-Hu1-8Ot3*t(LbnrXgf7s&z3JIL|Z#RTf<01WyDm-TGgq5FX*f9XxpgV^^^jXZi zZ7phvDoC?nzpl1NLevXt3f`Nz4%x-$w}!j*%a%UD$!rF0&|>k^qlRpgn!Zg7VK*Q- zQLKp?C9klY(LB6wI26~4>$~LyW(31VRsmOi*63V8L|gaZy1=Q_T8%yKG`gPN1waAA z!27~=L$aZ2BW8?sCgiLcQQIabX%}oHj@DkZ{696nSpLlYGSPPG=Jm?R_7xqvPCTyt^d{I0F(YzjhUu| zmycX*zdzX<7vY=(q=~b_8vo*r9EoBT(PsCnRaI3}o$Uq_?WMD^-H$)!+s%VE*8m9f zxT~c*s=e8_Et=rnA?e@!MyDnJvP4-l7tC7*YZwv4<_#(riRXORs4Q^+f&wAt3j6`H zr9c%rxk}YFMSL@3+^^jJ1A?4iar@CA<3USXBlQ~k*2AAtDDZYm3+jBiRKl5ujsVGj zUx?SkH8$bm!WP+n0Oxladrz2@;h_Rx2ZY87M_2Y{&PN7IE;H+}#h>)Y@VF(?%mhEe zzD;Ah>}djOI}S`5hc?UKfw@ftCP%+IZO7{)RaZ_Lf*betu={wR+Y)EC=uc?VF`R7` z2gZW&0Uh|;r}CGeM_`UQCGDO6+syItD>>m45d?@<&(|CG zoZI$0Yf>JAh*A+dq4T%N-$h0a%=KXYl)n(Kv)v9Kcx|5+-rq<{B_z57bGZk2KiNzu ziP1|kyLJPTfnWZm7;nE~y}`hGvA=dB!06NtFO|oPEUy|L_+1$vOR^Q0haN66_byK8a&-EuFCaXKe zM2NoOO094#V=acqp0uSog(;n*gA)vbSzL{vFA|LS(!^`#o8@!xCDp3?0}vr8*(d=w zcZl@MRT&+>9DhP;wM2Y^n(ov>{$C27Lb?v>ap%@Tm6qX%yWsfcN(jex4h1=?`jp&7l} zhdvq!2y?Xi3A&vObVDMRhFOwoqOx}Ps=49Of*X`2AM~9aUbK(a5rB7oVh2pzHdZwT zH@`^Z*&ZBya%yx{ zz-Z!f#n@uexc={6FY(rJlbL=K7Fp1x2W#a;2;`vx`Z82YLHXtZR!-%HmDT`3>NcP` zNq9%aMWnjCcC<;|uAh6BS-KWI#9gcWosA|LDBO>>L;4z~A8FzInYnU_$8wXnyw+_E zAnX`mz*uC_Nb9|gvIQGJwVQWl*wU1d4Qbd?z10u#R(Yog1ky=bi@QM9ydj_?Ub$^0 zRa#|8w^|<@A^`V9*h|c)pE7nkH!D^4Nh3FCR*Lf9NcyN{b)5%*KG{mBmaG=U7p#^B zb*1!O+affB)uNdJdlwp=N0TDtL`y-5>U(!Cayj4!_=jw%oFZpq7#b-0p312Li^wSU zdrAuP$;_f0OFvQLcPp^Vpvp=@b3eiq00ueH&{b^XieeRJT&ul8(Th<~tsuZ#pt~UH zB!KPcqH{ZY#eXd@d{vY~+64ejmXjZk8kPpZagK>7-1$qlGP=D$M%al{ED1a|VATvi=2W2K;Fmj`M*WSG38#(K zvGzrJG(?{oP-}i90L5&}jK8)7{pZaZBqM4mk&{N{hM<1SZiOMX(Jo6=2$dl1E+~=2 zloiYrXvyYq@ICBr1&wihhjy_&m1xE=%xR_2du&_0YTBC2KBxeXr~!SItRHq}@+em1dZ8b>+eH*1Fz-kiz`v@N0~8OErj4AgOB=CI- zl8cEdP;K`U|HjlA(WV~L6!w)M&^TO}e)b^ogdU@qrARRRaU8yx3bgU$S2|W_PIXca z3`oBkNHY-d4G<+(LNh|5;X>+KfnwEX7C4Cyusywz4xq*&fRz=nwsShcMYIby)wg-; z>~jg%%HeqRt<98h{Tw6WD-lP4!x}$VeT>L^We05~@shiY4AS#p45X+xJ4%AoTb7EZ zf(lwWUSy=NB<_A{aBREPS@=bk=;QZ6d7RO(>iLT70p2k#7ntWoh!<^&cJnwXMGVBD zP)_TxoZMcY$A^2(XEAlakKQR$P2F-XQP0r_n{3^J@Ktw7ViaE2+cu`qY!6RxQq>1= z7%1d%E_&s4v|&}J$HTkMZFL)r@c{<i-Lvbb`;tDmraKJ?@=3q0} z`R?kmV&!HFXdG-~EDDi)wwCSHveBO0ro30XSMe(9#0}~_o{~(!TuP%IR@cwPxdvHIiZbKMix3k~szbefH#E zUw=9n5!14F&(wh~9&N?vE%JDRg*fjp)Ub46wfV#|hVNh#>^5L_h=bh&(E3%0Jn@Tc zhe9r4Xh55aiIQYHENWCaJt7q9hzGE|qZ@5(IVSZi!2!W*-ZyxH(O+Ui)z=8s%w8?k zuz7uc(|R?=T3dkxU}RL3AGqOTLNTV~PhM7ioHsSi8v87DL(O(}40LTq8BusavOuza zkLwLfW9;f!SBcsY7?N!_*NIN5weg^g#|9614O2cQB7rgE@OapD4wn@z9V07G%Ej+p zFb(Py6*g9<#>hoM7ReW{D_Jxq2xk2|hf-5Yfk6eRlau&&np=(ZYt}UDiPmJE8O!NB zVt{9eU4$-J@z3xvoYIr(gbqgg766V#1TT2(qFi^vfahU-a=psraVF#pfgdPDykTXq zE+C`}NB0l{%%K~|;KGO#MjfmVv`0h(R>}lqI}SIXZMGQ4$cY&M1&yariHKapkbcAK1lNqXP``j(P^oQ1`G>xz7hjA?(FY6WE`qPyW?||(L%-UYfHs6* z`!v28)7U-{F{Om-s0ZA+`zRO+#)IOHjUw`N^WF6=;eyQo>U`(dsJKWSXBhmUy;c+O zI5RLG3p<2DhDr?%#Mc%u#ZDAlufDD6R3LW;w{XC|9s(h9TqCvW+26f1WcwU|> z?tgz~e=z}dk){TE#LL1RJgAp*+|r+}h|kLVp(-fA%vsH-`Q>v^j@tCufm}N;^``W% zTqH=Z9zlffcXfT>U5L$FnC9(H+elUd={2a9ipq}gupOM_I|q%SOqarzA8ZO!Xv*}R zQp0>r#iM`YV7Y4JIz;&jR&yikWup|68@+Z`P!b8Nf_&I(aZ^CnR4|I#O6;I}!Yn}c zsGu;Oo!4JE`;I1=-T9dj!F(sc%p=o~bVL*T;uZEt$q3I@$TPr4>+wB(0QKWgz_?4l zkW6jXxkXmXY&IBe$6T|TS>7pp%9-7P-EPY6JT8;)A!i*$^oc`E~G;rg2R*~#4?gnUmUa1jy$idb97J3j6hldX;AAP}#6l1b|y^2(44xW-M0PU1m*BjsUHs(Yw$P-B?@<(&eYAuxG3I?lk4j(gk# zCZ`y04hz)C6%sTRjLgvV9v~KRUi5OD+Cw96Y2W+ zhFAqcFoojupntQbCHQG?pme^HM)9tIIba}?9shKF`q^}Z+1O^*C-R$Dq=%+4x{F=I zabd3Yl*7mK)`m+kN(xCk zanQaUmrl!SpA@)z66H}YHCRE^w}<%cB0A$J1f?9#XeAC}m#`T;gcPovLkDDRHEOZ2 zgjpNt@hc5SS6J)XuAwmx2y2IFMiE+JBpbu7OQyl~KLde;If4i<#f7#`Tg~D2{yuqv z`30JOYp8G*cIN__od#hxA%4T3N=#byb3}Ntiax~tBNCS-etNGX5^=bU)b+g&+D^ye zz-^+it^l{iVWRZ(sK$eRD&JnFljcB%J2`_b=7gjz=2%FCmCAlSkLH7SY78jUFwD9n zpQ7t>Gjmy?ZS4+xSteG3wTSynBMHB4j=6{}vh;D!t!#T)QqMxO*!`vBBxgtsV@+Ma8^;b*^)WVopCWOw-n z%Hz$v4;Z74hcAsl_~vT7OXURQ*qcAJwm)wa{A%ItCDa+ws1X#);cfzc(>6og)pT@m zSAJ#|0E{!}M~^Ypee2w>nba6i57kXB&bn>VDt^JMpR`Bh%$qxTNl_fZ+TG$?CBr>~ zI_{CstkScZ@e%|>)eA?JaV2P#LLS3#MFh#XY4eA|d(t6* zjP$hU;o~IvEf1*sd9F9jz28%6omC+V#D#cZiwzzF<1W_M_{0hddAr%l7cp9x1O^R4 zozoC+H`ekTe5U)g$w96jat}QqRCR{i3=o9Qi%U(tA7~%di!qjbb{GwowkO>&E|0w~ z0?E#CuqkHIL7D(5wtW#OgDZ$TBUI8cO{}pHUUr|Ssr%Y$(XQ+6aDiiAI-_|1HK*{T{Q97*u5CY^%@~3#&ysQMMv%tY6~Cm zqJ?)?=ZWBhUY)eA@lbhw=FtHu4bqhEUWCo)FMPHr5u@OkBXG9)gSo&#zy+ZjFkY`d zQ6Mb8x-b+{O%tBZ)aHsodmN=hgC~FJdKIr}1aK5iLv0KoDhsJ-Tm zHAI&)jEOxDR=qA#XQkQ1ih|z$n2eSl3B0^Fcm6_51-aEZfH2E3s_I-Isz6G@yb;hTB``)IiHg8@s-v+6)W~_% zm9v@_nV4875FR2|&{;~+84hZ@dYz5_-VMdA215;``S+VRf=ct8lb9_O8`fH4czR5D zEl$=2jgMyKeHcz5hWC1GiOlD=CrrTZ^ddQ1ne3M)N@EiXY7Gzx_Ujp&=Ip1QmJ%m(&dk2AFMYzq+2qEurSl|Nq? z{)>0<@0?s2f44Pg&nUXpff>3w5T(4%RQ=DLkBz(sZdjmcI|aOp}v2i$i{&9%4DE86j=X;5n_!mudp3 zT{*fU|CL4#EU;q;Ga%MD9`5n;U_>_1yNnWV`i3FS$1N&_ z0u;dE!hy$B>&=)(x>j5)v7;S>>ovxq!Kt?8{S98~u+D;$(gR{b>?BP!mEQtkI zKT!qK`gI3*K1Z5Sxxbds2AZrW=QMgW^C^zO_zEq>* zWSa?{SU5@P5G{6^EXXEh{u*P42?2y1*D;6WxqkyD>vZr(%$u=U{Dn9tTYe3C0Sa8i3MHOg`hnlDOXDg zwEIoqyVEbU9fi$5PHCCl%ydcYU%@UB^$>s}lC!Wk?)`WoL>XX;2q4rC`-r!1u6EQb z9O;Aot=?7Gz8zi1Y2G>f&9wqsH{avR()$A_)ExS;B7?aF^IX-e(uDD00C(sBQt8~-sko4$p*~8b zB^Ug#Opp%EW&|((SWue;F;|3A!>ZfRuGp}vriqL?>oOGj2)~*+abBPWgC!Je(_?jb ztUxt!CmM0x%)v(uu@Y$k)A<+_er>))K?$_I4X6LKvyW?I#&~Xjxm(aPe`t zej7_u(w8Buj{WYoZKNf+P@;wa{?ceanRAx0g5BWj0ms2*c_Afh6RaAk$d!ouOu*>x zMNl|eAAzS93I}SeOLN=?*pos2pUiVVEkdtLS2)R?J#wVvya)TA6Q~xeQ>O6mlkR}s z8wqO?nul%bD#1rqr7nD)C|opW1@t97K=|TA8legvjrb*}E%yFxCcRP_XGdXuDK$#e z<0m6P%EuicgKKtz_L7te*FIXkdwNT3YW?PY-Ah0Y@0uK7Q@YiH?;uYA%hZKK;Cv4O z#y6V33eJLbnd3V6sjn|R+-tu;)B{N7(A3AcyeZB^KazXY+^^Qh z2I?#aCDfHwG{gk7{@`2IoS$VrN#yRKHm>d!l|yU)vZJ$X_`8R#Bdn={pc32zNKb8} z`U5|`VSrxXdc53vL;Gcip4ry*R>B%BTW-PbiK&Pi>ejaLF0zx3Gtv1LPs_};m8-6y zVHDO>27pM7?+GM<9V?OtK=`YzN=qO{>El$c9L69zHJ3$brU`;L#5}LL+2LRPfoUIQ ztMfWl_H+=5aXIX&Q!J8cpFvRqR#)K%EeISq#A%XMIPkGNgtdNCkqO--%1<7UQNfS^ z{woQG$RMNb9>@Y*!K&TH@4N?LWF`|3QMrx+*yxlYsoq!?W<$*vwz(5O8=9guYw$^N z!|K2JMS1ZeO}Vm0qZ}P!3GN<*T;_62FQfM>|DKDyj49drJ`)I0~oNg zZepJF(Pr42J?yXmGOwmo1CFi&*d`d03kl#BYUXX&0NNx#q?j{odlzZ7TC0^DTR7nn z0Bwljd)4a-pEVHBYu}o)kp1Qbz7C_FZa#Rew1Aq44VU?&wWhu^mowLP+vhenzF-3* zKbRK&oYc#_oCYLk@%gk9iOVo9%$Qs0r@|eiKgREQm;lZG2E(=7yLMMwd}!yKsUBYM ziRRi1t*BnV$r2Pi=snb1OU~*v7SSc4*~hO3-9pF&^i!}R-Qb@2?vaY=(YEWCb-DNG z2!I|ofK{%`@{S~ypX=Fp7Q2-B2drh(&XVVEqIbpMAFguworbO>6__NxCh%o1g8ifC z$!%Vi2!Wi=7~}3K%xp{@X!$ZefSR8=v@Hm(pI{@9rxPgv3+9YX5vML*7|yW!6HWMP z4GD;_7OXRO6T>T7lE!uybwU8EM__q6k!-9_TEL3?a6^%XFcDcCTaa~ZC5N`gC4A5@ z0+Cm=GGKV~hk^EbaC{7FtZpq9*5$zB^P&VghZ=*{NDbL9tJg%kwX$h_Lox+fW?mJg zM~+U;K-hzpPD~0{&Wxl+=Ou0JPCqkiB9Jho2qdBPv`B*#B#UbtdngG|um;&d_2C{Z zJ*kr)Bgw7#@qu1%R6Y@)?iQGC=^dZ=yj@K~QTcyF=Y*CgPYHq&Qj_e^Q1RqKn^jw} z;(4|CJ?*f|7!l`Y{9;0LR@f^zmbDxZn#VNw-&M3+*Fe!lcKCyuVw#kCmBE^UnJD(vG;%~lgV67sv&DEC9A@#fTw9l^5Z8r@p zR_ygrk>1V?y?r1#pZlqTWvDnH5aINnql|${FDTuCri{&+1~le<(u97SvT*p=>C-1+ zEY|Enb;1^yKj4YJ?i)bmw=V8!Qj{D0aBnuQ#DxfWTGN?+%k@2^<;9dF1Ur5%guEh> zPIxbTFG+$eb~4_&Y1wT+BemE^ZvfK{27L?1LY(X}I=r5rZeIt>kK+L3GSYUiaL23~ z=ci-1;~q7+q5k?6MIvt*(c!3Q-11DpxBi!6$puHJL+otneZVrbiwBZ$^fFK-xR=HA z_{+hG4~4&8uQIUsD-TF)9Xe=4&$H6-8Iwsl7~qErmsvNcUPrMLmE6vm<>^!ye$xnX z`#raAN@=L&0*=jbWu|gA+%Cs(5o;xb~CP zS8*_-f$+`%nesvf@$P3B8zCN@5neBG8MyH}8>}S$;4szrG19d+gF-5Ex~!W&59nwh z$y6vMxSyZ-21!%P};tWXqTbKqD;}(d(Dsw6F$nWg93HA1TKQ<0T=i3 zNuY86Hl*^%HkPVbyR<^5(rch1)Y7N>az*BbA5*WKBDD48JR97@T#$#vxj!dY-;>bQnSlI9Xg&ABo-C zjhYG4O_ObfeS@n_0opS7^AGOc3$&xi=?Auz%OJzJg&L?6 z{tfIKmQX7;rS3E;Lwq(~tLT)OYr>2b9jE-o&P)!yaIg)^`OR0`N#fHCP?|^}3Lyh2t0n&^Kel$R#v9h`#Z%((dSw&*f~CaD147s zCBZf=VKKc88UlwA6?lB*71Br5&2F~@J2T?;(ZZUGFcrPiy#&1Hc|uWBi+HSbC;v4D zb@j(~jl#q1mmQ*Hu7%L6{=g-gNf>^c??jU|LK+?4%iwJ`1THgvu_fIj3sWFx$i{Ug zkMfGO>9BsiFsF{D|`Z>_*qx5Kha6R|s`P=go z{1p%9O7``Z1Rf49A@rL;N&+@u#9F%#tz_~q#*9+T z*l!H@`IVJiJl?Ox6$EmS5wen9ZdH0UxX2Gc@X1uikA?T|+%c`0&^nH40V6uN_WTuq zw>+gp)VU8dG)FjE0IOgYr-NVJ&taS&1Fe@6i-h<53po0o)?H-oFGm`*qrJQ@lkg*1 zWX>kf@iWgVVs$OpoM)Ik>f_YGPv0g#q-KI8YhShi>f-~}h zzXQdO&;mHZEhep~KuDe`^w8yvT{9ynzx@%Cb89bo!O8KtXhj4>^~IE}bBBEtiee{) z1~R1+kevOaFm7>$;yD^O68+{MzR zw5X0qq^9DjS?>Nkhmy_iba}kItedpiMi{H^2o(M)=ZQMCUly zPCO$U{FxkcYTK$xShA%ARqf|kyU^h0(A8*)0yfc=GrGcxuM{m*Re2^xv+q` zb%nE|Al&agD}hF8d^E~WEKqm4b&_`f48?}VP4LIqBG~1m=$RLGxE9*bxx2}DyJ>l| z^9dgA+00A)!_L_wS~@t~G0DJ=_t9Z_=-%3}sdT+kh{x^aR>ykrSy4v&P^4SW%}pGl z>DU|k>)SfpYvHu9;_mpJ#8rUrvJ$Tw0GD+^xrXMDLrIs_Rzf z{df=zCvze{Y49bSr#G}lHp0Xk9m^nZ-habX?P}?n7R%Ek(>bwh(FQg4q!@#JNvFkP zzXowLrOkt$nwqhszm=?cm64aQhKj8oYsMqDnGpszawngURc6gmtU&T!Z1IBEUj1zy zQ@(y^s5FRhl;5^hq-)n#ic>!2&&@W)iPPbzSYt+OwP-^I7Yot;P=4oDb_ui1v2DIV zq3KzZGME_f$x&V>0iTztaN4L9A^s8n{TlxDG}@Sn<2a)cAZarQ1F2hr51JQVHN6m> zlAYaFdupK$c&O^!+lTnFJwn17LunB0d-uup;~>KT%1Irvo_z-{wo)#idWXn5oz*UT zy7krBB5D{)2)OklJ#jpCC}J-huPrWg0T0QVv|G%`9N3F$Ot$8{+&DPg2%ZfWPOUt8 zXW(Ivwrj`4>&j#oOw86Z{`KPuMEGqI$Ka}E#_lN0SFo3Pd0*S|0^(1UY`t3FuVQ)) zAqEIIJzds} zG7PeURoJw$=c5{)e~fbX6| zx(D4<=XCLoDM!F=zm`3k)g4D9-txg4G|&6wc=vv;yV6kT;saa3w0mc>)03!(ztvw6 zL8YAs2hZjIj`L$_A+Qp9_`gIW^aO%KI5_}7R^Wdl8d3i*qVb1U?) z3_{fpCFPH&awqs{w__jiOn~${h>PWVBe=O0)mVZnvA$RN*Q=+8NNvkFY32~5v3W^n z>27If_ji^3DQL7=N3-;^?Hgdb<7~VDv3A7Yh|&ZN$NfD^gqXu%xrCVkVmslhV8H7Z zFjLPU)pBwe;<&%UjR^cQ7()}Ck_OaoAq3&!2@a%z>8gwbUJFoJtapn>`L@`w9ZVs7F z0}e1#Ose?&Ogt!#RQ-eq`2=?5Aztl3xX8~1-aKspfKdsy>TbhmZe&TQfwTlMv?g(0 zP6xa|)jF2U&m0IG5gC$6S%ARaV&;KPH2^I$4sx8-ez76VP5x0+tkK6p5yN`5H9;oJ zP>Y4JBFn75#oGd%a3L%soqehDAT;0UZcr87nh9xv_@Z0>lDgDuHXGa<7kYa6d1rbJ z@JHlKUhC|^4U8uQj+g)!NLHAYEO|411*+8orggGx*_CYFuBuLp7q6Pzl`@|E-MraP z9i`coGPRMdOcu_*zz1~MH|MRjDf01mXs84?)?5o6^kc)C&H z18V5Z7?J_YiRVOCC>inv7jo8Mt|mH(xBt+^6!Gnx+DYe!5n`ssSgrW7Ks@UTJau=b z;SWoI%yTQ*FGh#TpKVRL@g+dTENk6}LT1t0-3Jj5_iTKf@9pIgkM5<;9M|~*$&d7; znT2$X4e63QT}&ty;AHc#Ry`x_aa1^p0BtS~m=`XJ94{c5+A?_y^LHJdZL zvRfKgtmc;0hXCS4mgSjJV}G+vk)HzVayNp#R~*D~ZT}N%2iW!?@bO0>WBOfdqs`=v zJDLqy=1|uEH#C$Fk2wU7akG#o+O(%c@$H}1s#6-5!yF@0&m2|*C7W5OQ;iqQSTSR| z7?ZFk);utOa>g|ZyGvO>xB5f0pTyHet-SARqKgThlZOI1*zu1u)Gcc>?;i?luPMyI z^b`YoewA2hh8VG4x0KX>cK9B%u8}F2^X1R;?Dq}=k>i?k<>6L8V_|KL0XrHfXLvIH zbzZE%Rl`x+L^+F8PerwJqL0FX@|brh5eG71IQ9UxlIjPGgN3#!3%)Nr85`~I$+U@? zVzkR7>d~mb5=FzEkNGb6VcNdgptE_k;3}L_WW*paD+~EH2=yU#=@p54^BIPRxx{j@ z93Jto4EmZ8NWEVm@3-*m(2_Xd3XqVyD?c&ou@mh|xM*z`8EAYBihbLKA2-J-PO5vYiSsPEjCn+Q|qZ!z5e0d=qF4m($s!*()7cFtou?O<8ys=>Z z2AyOa?Ly_kXHt24&itgFF>wc7h7@ewagqHpb}ye=$N#G{4uy?OZJNxQV1V>U;|Gk; zU$)`4KCcAJ+o%G{@-@$Nr9tXut14jQ9Jh1x^P~F#?B5l5SuL)Dpu)s@O0w^8b&YpZ zAJFbQeoKOcm{0k)wA6`#55hYiz{yR|(rScf6>^9^XMVzQHDa&~%3=g3`vEgl1b zu`)(m&Q2QaH6-o&7H-ryF%>;WW0#JL$?Zl7<3>41lU4ec?-vN7iJmcxrC~eFx(0yH}-9T!w!*hH`+><7!awYVRjL`2S`uvNz%$P2oMB* zIiWg-ok17e5Ov0^MljUVo9CG#Pmbuk#td`VL4*=!e$zl$*d9_$R^@8_uiwdjjampl z`5qyBH;+>c@QxvHvI{Y^76ew?U+oZBcW~@Z&!_w|E49whIZ8AKRaTGgBTre&sV3SI z4((FY;&kK&FnX;O_To-y(%E9IcMh7%Dy&+Kr>gJ+%TldP%$+Tmg8X1z$krevli z`FJYtQnPE(sLMo0t9qetyS>auI#^HaFUpp4csVW~)AJqnn7NWbN?gIcMi9q`Qfqjb z8E2i|c?B;-Ple#AcOqrvT5)0raiJwKdmn4C=mM->d&HH;<#Z?>;z8G*Pg|S>&tpY5 z1j6L|fj6jZgc&+PP1*t_DCv{!%u{YF5dmqvAxzE%l^s%RJ1S5u=wk({~-)zRTE6?F9>q{uQ0rq6^3lACbrn0AqAnbUeqz zQeJFp;m!r`k&7=>Eg`5@AO;*DfR8fo(p1>gUdG z*T9#XJ9MZ(SRtz&Sfd_jBJOcrev{C$UONz8#iucHi z_N_(?FF$~3NEv+^pns7dRd`g9Lqdz@r)!19vs0Ul_Nt_0Dqh(qRf(r6>L?Fo3chX! z+DNtNXKJxASM8qdvbO~@mLKkI8-kg~vyA@o45s3#KLW5nr$=);bh{56FD2>}JU&Fb zk8jC#N~+AAXssG=2$}_426p1yr2~E!JZ6=e`?POVToiI<2Q{{zo-%z;AE2FAeNj*_ zeOjfS9rNLt0j}`7vavwLD9az|fLb1R2|n&BWN$9X`X1{2Y~$Q&UUuvLkQ`Gr_sA!+ z52dTtRFln2_|~*tz3#Ng)~ID_De#nk8L&qE?$%fE2OCeQq@!x=J~mZ1Mei0xnp_8} z%k0Kp6fZm;uAH_9uzrguH{wb5M&-}Zps&iVjk14!hNfGaoUZ7IWQD6$9xg&uV|Q3F zAqd%Y3CItEnmFU7efNyQDPd*)RF|87G>gH1biAKq)!Q!)f_>6bmz#*@}0}%lCPyl zDD$yQ-PMxgpo|opNjzq&AB^q@pON--F~d%nvjUD4mU%pkCLO|8a=xXB+b>+^IO_!7 z|Eg*Jg8#?rWKA74v;qwPkWTd9gaPLNCk$u}t&OJDbY&04kbHG~BQ!3%{;|$59ihrH zy!uF{kigw$WvN&H^!f&>OXbyu=aNhMZ2BgUG{q=n3xd6NmKtdxd-Q;>CcRIw3 z>co%DLxD<n9S#@P{|q2G+5R<5zP$c z`rY;t&^Pg@={`3({R}#DMlJ5PxnG*|wQFdMfAqBos4nH(8zC3|_b7z5AEAOix9zz^TAb`dDb?FQjY9g1Wqd&ogu1F4>HOQ4AdnV3wnXga7xpz9bV32@MOqD z$}eL$nk0)QTNab@*3B=U`dUi=0Hj15(s=H#b4dN$|85=IjT=3I7%LIGGnEfeQU&bu zbp87!pFLXs?&NAm+W?#Wr6i07Ps@g>@zmWHuOi2d04tQYv1l{bWPlg+Ycd8IE3eZq|qadG&LGQ2XWyhnlpdEiY`SqN@xtIZWCJSt2G8zsa=N- z^rZeK%MqxbQJN^vyQ;u!>vTHznL4$6L_$)3aGEDHW1xt#SRw3wVe{_%hE4a0Wpfur zqo#6{7o$sQR1ligYLU><%kbP(X&*rvGx!RrlNdhy_Hc1oVK#bjrq2o1ZZeKr?sM7cak0ANt`jy1JOB%2 ztJ2^Ig&LG^k79WnP`Ju0y5u|CQUF?lon8ttBy2bzQ>63Q-{ZAgTCL~ncDOn*&myHf>(-cveA^84#M6Q7jnl5(8 zjp{Q!X;eGGql%sul4Z}{0oS3310T3U@Z^$Lj)!YGSBh!?F8A4ryZKo0B+7rTPZe`S zlCd->FNl8Mn#ZN+)yX58&0SV{u~p9*7HcmYxDa3)2s!R4_k};MK%-Z4TLwEGVPL1- zp`$G%EEd%5>PlYJqXSLKvXoq+R@pfEWq3-iPP|n^Q&$atb=y@s{OM)s+I4L042PMS zrj+Bs#yDXgyQ`~0OFBoWz9J9B5&6BHvZ`#0z4y=KFxFo=l&=|m`jI!P*m7)tm%-$0 zBM;6w3_wt$@bT?m4Hx>h(AaNZX1Dj|t9%V&kRS2(@q-5FyN3V8x+xz+wljO1`zsY- zcQIH;YMN9U*?8?m^)KHhaVe=a2vW)x?&5p1>~NOZLrDR zzN=n8dpgpK?NS>sHz?hx!HF8K8DG}^EWo!#D09|u8I2dhM%2sJ32n=riMEQwwi<9c z5XXk5)(w|MdZ5%`IyAk=lPxp5<=bxhX=?3U(tLgRBBoAYuQMxgD|y*90h|oM3ln1Z zFZc9^`h`0IT3vT-sSx`xj6|OHJlb< zM1)-d=0gbihNS75t{SEBl5m{-)znL6C@ELHEi!(kYhqZf9R}GW>+wqLt-hVjrYw|) zgh@X|WggM!MsDC)C62hmeCXI8%mSg=ZK#X9 zHFTq*pD?i+c1@*Q^Wod{sG4L@5w9pdhV78d(rrha$hMOXFI21ku?Tq^$Y%YUJWm0W zox4-=ToU%}QG*}`St(9-aSO?7BmflKDMoUY}>YN+qP}rW81cE+qP|=zJK+q zQCC%04SMzD+kQcr??$^9Z8)wL zB^wRe#d&+=>d5Eq!2f`dX>$vPctt$q?KJZh6g+~gA<-h%6c6#@aUSQMK&=vQlOtJZ zMTs#w=Fvu2N5w2YMUchKylTF0;Mhrui?S6qK6YL zWH%1>La9#ck*PNJ+Qa=wy2eM#@Mi>k#t;=yfklMXw`-1_)pl#vG)M>>5~SUps~~@M zeE9I@FUYsN}nWFQbg|*+&>|ISTXuI1(OefSIxOl!+QFUNne%02V^K{GT}i$iw!Rs0Y3Io z^hl2-6cqb^?C(KGmPe;CzAKfWc#<0c_BY+EQn(N8usqeRt(q6=~M zXK0c!s`jRGR^)*>{3#2YqetR}Z6w4kb`okOWs+nl%Cve!29u&la6gDk>mv+p+iKv4 z-`2Kt316bd&jITfgeWd|zQPr1Wi)YVG{w#4#_M=REwr_0UL>7yty!hO8 zjwEW_X2_+{M%0gpKbK*+$AOoYahX~pu}BG5gq)LiQaH`hF`d|(`Q>JJnFu7W7o@mW ztkVK9CP;USOifaf@PBl`7XdM8WNvEiAA0mRp==9* zoZB{BUGc8Q2<7lH3vbN-b3ELBC`?(&q#|d`&IpnZ$3R!X@(u=?n~5)p1zmPh zLB1NKE;83)$t)Tr%m8QL3^Y#uItbg5F)eRudxn;=BG7tZz#y;TB|z@Oe#v$V0ge?X zDN0!qiCb}gS^yO%j6y}L$}8L{pd<5P*`$%#Yl-u6b(zxQT~;sIB57yH897~YUh62> zPar2|-vSAVSy#A4*LuBXt4GlNW=oKlFxj$w=v?j|KWoGJ7H~6ws8Afkle41o`nE12 zW+R7}nxBC8dR$V_Mn^|8!vkU?lCT)xS^dtbSv$C#QP?5?1Ub}%^uW|Y<}`S0^9Lf8 z$buGGQ`nyDqD{J~`<-sDPuej2ivqx;=&Cv>n_hqCJkU{WMbU=}PTvFv!AU2eld6Yk z$Bcx1rez0^alZ!@g6ZxaoAlgF zEu0jg%a7FPXjvePY^A0kwkVY|QW zHYDxhI@SmtIC-#An#V5uVvp2NZ@VD3L8Wak5st5ryCA!yK<4)Kh@neQdoU+033Oh; z7kL0qxUgsPr5|m1Q`ao<^Ip+-)%nqRkVc&bg$ijCoyv+No1fk1 z$;Lb2!HUD_Vc>Nq(cDw-@wbt;U)QPqKf3;VOSRb^<)C88ADLL$MT3+@@2;<8j~W1l z*qYi|i)tEjolz07!qoUOV7liY$;d*dcS6%e&d){7YJf2R6}X>viA-ftxbUUJaWSPt zrM9lJ$(v%z<-B6SqsJ-+Xpm0`xUEz&))ji^PlGJ6vCaU}7U1RTY_sdbiWhEt0@;(y z089|;@R9R)W%U9PBb6zCH|)I_?3EW|;8~;iT!NpmponF!Ek75unFTeqxQ8;ux92#q zg0B1ujFv!ieQ7W$S$N|*WF>XKTFNQ7x(+ft749IDx}xj)Y56Lof>#y-nrWl?C);Rv zQ?scssH$t2*)}n1OOpsDA7#zw0^Bj`q_SmshSX~VE{IF{Wx<1A&Ljhz;rDP7U<Wnjw)bpU}SDWCH;SYI~61Sf27y{NUvP~kzW5Jz5Yjf{g3qeAL;c!((8Yu*Z)Yb z|B+t*Bfb7ddi{^|`XA}_|1arP_clgsh zpKcp%3w(CJP&8h*wq89LKu6ylVE__mqy(S~)?S@qM%I9q(bpe<`CgyBeoP70*6|+3 zi#wZ*nQJM`8JICA#bUC)H7u3c@NO=QFrq8#mB?Qr)Z4gOCuP}0q>r*rs(Z(E;TNP1 zJf*YLo*CF+0ba`F(xi!BMOkiL0{QOl?&|J>03r28XFTRYW8>jqoc$A6-$)Jj7Bv@Z zfX%?wOfD9&7zfwP=yRoc{xNY83`;z@V5J6gt8k7*06tFSExduTbmcNUJoa6}hZ*P{ z9U?E|RuL)VeE6DnAOKP8aYKbG7Bh1;qo$#@$76Ga-;3J)hG5M;7w9vaEY(FSG(1n| z-b{XH?tncb)7GO!A=%rYAa+@}_GRZ_)HYTkKgqV4LYC?1xP>hiGKtdn zf*taHQ)fe<#wUQe8O|_C=3gdJ^qHX2t;~4h#ib%7Jfau~VDf|+@m{=jvkn0SvS*k{ zan!MGdiLHc*Ox|Bxo+12u^{w;r5vma;7xseC~x85)OBYXX5tb=O>19#t9!dz)Uv_g_W&Gw<8Z+@@kH6HLgn>{P7F^}D~ z{i8h^SfO%yU~>C2LQ0>EnCD)8^0i$&8{>~NqD#gf7P75XAcwk0h5dK>j*lrUbmv38 zl|44gyk86-jI@g%$Hyj{JGQQ$dj7j%9j@Q|;0Dfa>t0-K6+3FPpIj&UzpsP4LBQRN z_f$1DJJ;I2+}0s~PHi<;XmNjeMMDO}{TQXWcAc{N;JLSl(FZY658y)_dy;lf&W3j% zh)jR+UB7(a=gng$s@O3>yZgm{8w-Y zX#ujvRZdSlQ{|!kHv#X3(4X54&hcJD;Sq}Ugw0gwXI|w)C_ah`d z3h`IxJpz32ku&vZ&@O@io5M6*kyQRNw5A-qX-{Ew0hY2C4Z+}@y8h?-YEh{jiy+7A zQL^BfY+@51Fh>x|>3>+O}DXS2_L)wR9LVWm!YK95l8 z>VUpYH?{2hPuouiPlN50&tj*~?IE~t=or?Qz)?Op(w*Dn(S+Hx(NFZ0M(!p6ofplv zX^*>RU{m-nng_L-($6PZaJpym*YfzyiS|2h@Qz%besuR$zDqf`y?=kh7~GoIXOM)G*1=y z{xbj>O9;bW@>(Y2orrv=4Rb@Q49v;1Q1rlIkkohWQAMUGU9%T{Khj(AjnEL~nE#2} z>_Exx-&Lp<$1|XStLcuc55PYny^ri-Z9&5(l!ZuT_j7uMDYt{xnmT`#8r7xnV7NK^ z%-P?&)ZvRTuO+|g)PX_f7)e%-HVsK&Jci{!2b5o<4W7K}aSr(9zM?0S4x{#I46npy zCo8ez_JkcjJfhBAL<;*Hs>+b>k=WMc3G5M~?#DfmX0d0B)R*nkF``b+itTom>e*-S zQZojrxLR<4m(Ch9Cinr&u%%n)8nJvqVWdW(1=eKpUkj_IN|iOiq8AWNMe;PJ*sAn~ z@L)0qkWrrRRot=in(u}kT!KKA%J$&1A(t=}Suw!oxdxmlUa~(?Z0%BCK0ENj$(lS3 z_LRAoP}&Q7;CL5QXP$6cd6r~;U>O4CrdGYsx-G{f0T!DF02|v`CCshMwdbs%+-j&8 zg~ErV1jP6?r-oSB3+#W%>7lG{Uo*A$q&>%xaJ$VVs z+4Ozn#DM9vMmRH!Mz6qQk?gxc-20m%b~rZsrth5JK}E5COg@}Jr)UT4o=_qJ&I;gJ z8p5wZGe7)+25&T$g71GCG8&TK>LCFoin9Ow9?Veg?^ZN(Xw840t_2 zGbVUy?zM4K$9AUq#8EI%&n=&Akkmy)0+{e;8=j=1KR`MC0f4rLF@B@Dq<$f*G;zta zq^Rsu&ZLs*Hf8~KDT$H3)~~5Xa*KKiLOGcv@0+N+o6QS`)8|FJm&yd^AOqu>E04pH zHJL7@2PuKGrR^Etc&sD{ri#FQUH ztf7*1YHy@66IKY8<7av7Qdn~Afz@XdZ|c0uLIh0YpZT-Rv>Mn~JPU!uUvUuC(Okp7 zrEg^FP6Rh$)J>lUDlggs&;N6*psh>(QxUgir0+#BFE?FJP$%K61X11SJ~N`k#t^0i zoO_RHQoGZ|u1VpC2~gmdDIJ*YLK+apYJaWKXVrVhj6k3K$nTzzr_%jb@kiu6lnEdo zF`JCMA;lLeEgdEl4j=8(NuX?LA#FHINX5NysQP z8%8Q!6jVAKAN~{QQC)LsUcDe-ljXoA*kjNbz->oDyMm?wu1+@XIuy|1DhJiGlw%6Y zXoH+@r8+)gQR(55Zu5B1=>8G*ol1jzk~mOZkhCcbSD!Z*-DGsv5g-$L$a-%QpsX_s zF!z{u=q+!vSG>HW{|If;w4iEovcnL7<7zPrD+cF&U5%XPCXoG14y_ryA3;|NynP7( z0tKqxQ5}PTz`6$`9@2eqPk_WeWf-5$P?%T|F=WpwMm zHr?W&qQ*S(xwAW7!xSCov`i1M*jcNR>6*W{t(&Tw%TDjl%kG7mo@a{dy}o`=#mTGd zZN;ZutB=4(q%P7O>R|j{c3->yZg1R*3RRcP(v9}^`)b)DHQ%{Pfx?s2G8olkk4QZ^ z0&cc<4#g?XJr1)T&$ejXwa8W{i*{$K{UsV=6i?gKzIq?{7pxel+kBJ&o@k9N?EO8= z)1G;q=mZ*iFW$K`g!fHKYwNH7Z)ezM&1A=>A%k{nAcQwy9+a9N9A0x$wH%oxDQxL7 z*iep1bxUpB-mdUk*#5i?=)@oJ*2L&6f28dbEh(UI3&@Aua6o^(Z~X!E zLo_O3&9Yxb<|;0BD^E=;0L?3VrR9WjRpEBQM*C_ckx1^2=0g;J@~BbUnkPHUWDaww z<*1Guw|S;v#n4wzpl_+_jJSx|Re#Sb5v zkL-9jcWh4F&qyQdeQY^y%N8RgZ)lvisc#v*%|UotX)R}SGd*up_`Hy}2AV)Q-W`nF zlviZ)aP=hy8S4?BHA3F>JzMzU!m}BSz*nGcbFK*7!?1&ME1sq!^qq(dT{&|Db)8bx_T8Z4>1gE%5#VHt#gBP+f9KAujV zAjg}&??M(P#UR-znaWT{U9FLWUV2*Q1{2tf;D%f_mrKy!Dr1Nw`RcrhkdJN``Vjm9 zwq8XH37xcLJf>}7N1?;zgp?|vHfk}d++_crgX|xnfzV}c5#w)q^v)H{o?Igr=1Eio zxv?~8^H5p0t5tl6JXr7`?xuoV(ls6&;ka1oEz@4Vqb3{EeIR;sf`d5RZ05rd1To5% zh=w!m46!fNs6#}0&4fK_&$tAPBaSie-$~e!y|A2x7;34mlueqs#D2B*LStXdJd2tJ z3LWV!(+o&Vxz!KnHfUuWn1k=*NMjojqSk+!ML*3M{?E|ht*Kn3#sdYQ_!e%yy1BJG z8#gOYGItsB*99MUCraR0$V{-*E=zN*h_qyBtA*f8!7Ni@zf9p;^4gntDCB)~2Pb#J zXD@@~F_V@NmJgK`epSF>fQ&i7WN*l8Nf^-LsTa;jX;YE?>SFbF_@si6xhs(D*SnJY zE6g$IU4(PC1Y>rjDJ^I1IhN)$pPz#^T&;OD;{+fXN~+1#r^mYP4;J-&o|UqH?cc^WFDPts5F=IXy z=)W)qjaY5EKv5{i65!^vyeM^#X?bKHuoAt;Pf|A#9j&PE#wY`B$__l6{;sb*SXcvg z<%7^cNANh5j_?Gz!Kl%dlONt!#xrrPnZ2ie)N1m2fQ%W!ySo=` zaYJxfk6-SOAuTFf+=M%&dNQ_LQiu%BOW9-MUbKl_6sS6fcZrk?NH+^FYAIdmFiFka zsz*|^GU3etzM zG7Q;n@4PU1=S5~qxSSm>$||g2cXUcBLG`>Z)TV)fsUKa9sxN2|onaOGYJie<*0ak+ zJye1=S+RbjF~%`&1AzquQ-fNgjnP{9c!_nqfGR|f0`QnxtajHdk2SGeR~zyK+wdJm zyoeDAxsT0$m9A`5{W2&AL6Dv*nD~{dc`(r&=mh1L4HKs zNZP8vgu(A*StmF}h+o=yEvb@Y%LaAs*QskK%II|KGd zZZapp!mN^4QBs5&QBg)GlP>enJG{uN*Z&r7l8QE>gqU(Xx?gexR4LfB)0DUIaw}rR zNK{C(WJxNUR5qQr z7!_@BcM+BFvczWI#zu<=*%$?96C^L=_b1Xp6Dh;?MsV}^fDKygMd_ z5l=8MYJ5-nRop$)D7SCwHwD^}Tv%hMPx&wMy2NDzO7Xsg$gp-ehiD-Z#3>N=4^yfe zOA6?~&>`n2ZfW&vO4QxrV>M3SHqy|cH%d)!_s7T{ZfB$eyO0IdVjH~eiV(YntQEy8 zj-ER8P~UfeJgGLS7sJ~J71cCWH9>_^&`5K~$WlB~xWcH8zxEOjs0Fn z1hu*s%3dwimiyJ(mT=|=cmkETP8N9r_c8T{?0`+eqWnFBQ+8;Qja!PiweHdO$b^c) z-j@jacZ|gy>&~%moN4KRnd|4s43EWEB-%YLuFI-zTJ~{pUi`H{Q0i7eDzWtMEE<2L zleh-xR+dn{)EfgC_h|G+;4Y@~k`pyDz0L0O5B?Xf2|ix@sMJ;$Q9_p_0Cjd0daWT| z$1oUcbXwQlUJ*JNAWXK=qZP8iUs<|?Ok@JxREB>USbuAqqT>P=mBom(i~8S-vj8i6 zeZx3fJfy@}oGyw`B1FBG!ZzIa@J~QJkyN$>V%8%%UP_~FBDv8oM7gI!IMkCE-BVMJ zC8CGESDj((^JuZnboC{iI~q54f1%fi%RPCf?S>K%qZ40qlChz)NW9(f6w($5=8*$p9HnCEjKQQ00(1K$O;Q4V5QZ0Y* zb_bGK0KjBjqsP#M%kfQFr4<~YKQV-3ADx4#pDEZ^FgC!1PSVewg!&L!L_6YV=dyNv z8HQPiMon0C&ql}Nwuol%W_qbz@%I(<5ZV5Y(d7N>=Y8L~niFaewtKWjJayxVGytX# zIm55ZktxMrfKl)-F|4zf=@1Ko1Z~Bl--!&7oDhpv&SCyg4}x(C$2eshfFXE^dkH=; zmE(sw8@K=vvnO-_Fpo;@%YqX)eM{m+ih=|1+8*LL^hoduYE|3YR-Z5G^OHMDI+FFo zErYh*_>48-K#m^zs|S}m+SuGKjElsUANxcxhba?G1PAt;Dj?`g$>YBla5z9$l8l1t z*;6jE!JmlN?3V)ffeZT1`m4d2^l{l*^g~$I7wdP}Rsa>D^Vj^6VCr|qrP?Ltdzy%d z?i+87fDae%wl&6cRHTW!`SA-LN_%H#l;43tN(6IhIH@fvRlq6!O|@@YuVd7EbOe}D zTn?SMG*g_$xiH3V8v^{_UeG?pHPY+ zkd+zq`tv&Z0j&89jUMUK89$25+1V8u>J&m5@zJQ79V8@Qs|VN++-VYkCwiZIOt27NTQZ`^pv{R9`G=pdOVS}7zm?PCTg>89xJ7=x7=P;ROxt$z02%uLtOw%HrIFIq8GbR4 zeSMNd%u&8Ad~AXkwj^d7?yv z5r;3+KjgCDox@r(YK^}Zaz}U#VBXYx4qYribraUa*7E12WYpGn z>rKWrr$B>cjO%m9LRi+CesSYxNxv54| zGhNhno!r@lGyEn(Sprc`>XFQ)Q;{?gttt}oDrn5_X&0Qy?kH6`vpzEmnFs~Xf9O|p zx^fE1c38VTOaMLpwukT2bbFcftiboUn7}PgadDmk&Sv<>EVE6~+9Z5T&UBCUE0*XE z%@%xMq2G6DY>*^30{p@T3!hMoxK}`XbH?V9WxNyJ0MS|sKp`pD)@)M$J?fmAs-}5bx9Z&OUX;VF$h4O9B{G{xU)1Rw>$C6m%^27$JjI%lD&hG`#xRyqefBcp*x^561YC zlcw1NlVc5#*9QYLjB{QoV57M@YK7)Y;R&73{83{M+R;B686)Q~kSN$1-lZootIar< zrZ`bQd^(^82i$LsS)D&mW87P17|FKdbv0Abh`Nm!zH305GW01ET+m`v^Z=g;QB!;1 zgzTZAkpaZ#>6>1WJ=0p$=vvQ2Do$Zs_Xp*)555po+Q&8eDUZl?FFk^b?v6`e5}qK= zJyp{or>ht%4Yf7E)H$}k>P@Tt`}JudAsON^=d6E@ax`?h6xs%w{!5Y^^TVmo^p!Vb z!*e+MM+BfV-xdSVbo+)%^S!Rktt|@sI93l*m@CJYTM_=ZF8SYmNW(lcF$$~pEul&DVG#9e7 zv9YtI5;k!)v9`0f`PXkxWngPeC2Zm3>}X-=;%xEn<$v#yXP{r!wsG2IPx$dwdBu~j z>7Zd^DshV=&!m~*|}S>85jWvr)Q z#rpnmF3kTY%K7pdwT|D8JO9|{PN`aRcbc@GJ2s2+RjW~OXO$!xw@9z)J9=?-8}~*j zjuV=x6~6v{(7o}A`qhYDsa~1TQn{Cj-URr-;I*Zpc&JRs=%5~hazW%!k-oh|jC+&i z9@m^;Qc03NNUEBt^4wR*7;8c4LWbn7Yf9c3sq~qJ_(o=-db#Rd9qHP7;4!V*m|m4o zD+$-ITO04l2kSLQOi8^%%rdo5zbr?j8ji&lgJ@PaYg7-#+RQ|^?!KVojqx15zdJ(s z-I`ysMgZ?Z63?TK{Y_2YTEV3A3H)9u9{>~}0mqua=c;BzronTb+BMs}3%`=m&YDZ32IRYD`V1$57o`Xdmqsa4 zA2)UgJVx|R+u}0JmVUR4D+!4XcwFbBfV-g#MI0wNzCY;FKJ4aZIMh-34NzHphFQ0* zbx+-JKrZPwpZ47vk#{4&UR=?K^8?W@7 zCMh+J|IkX|#{%>C3WTqIF;Vz$Vod-%Q7vmsDA}4!8Eo|_O?c$7$T05xxAv#_=qRNE zZqf^HIo3-j&`&tdWvOh{-AK*a3OIt7ieXlYH|X<4TK<)@t-{AB9-wVdVydG8weZ0CNN2?Q%mZ zj*L>+la2A_wY^n-G-4?Uk!7uH4a1f&gflG#y*fZ|oL?1PZB|VfMtZY!cNn9lfZ~Hr z@>a$C0cVI6(W2x4$FUjJbW-iG^ev7ldiriI^-R^3C<(v~;*w3`sh#F`%ob}+FgIF8 zW*`&4G4ggKMQ9zt%-;Fp_qG!pwB;+DOQeMi^Q}%9{Z)Qn{UrnlnPc@Vd2TNHSDWR4 zByx9een{6zK-xvAk5rUtf{w>5zJIgq90N3CEk;aq=xq){7CmXpESjJ&(7GFyw#iH1auJJb$ z-`uW)jz6+1;{f7s*iz`>3_73$Y-z5ZGs7nYB)ikX4&rRDnq&nN!VX4pEJZYJ@p4Px zLJaO{V1KOQ?A=Ti)DNECjkw(dk>rIAPbKc)Z3=KLgXNiNxIYLOd}N>`od~k*uW>!- zo8+Slvfo%YMCtU$uwouo1OV^!g#In^cNaxh7>yp}+tZ1zntv7eV>*c9u=gji?@$CM zwDZgtNFB~23T9wPaZ2dgk_rm!VY}C;O&KX*u6@*nJ1PlH{lg`?{dR!y54+LYIp;*Ql zLto&c2%9SWijo28I;1$-)ph)>eo|g#bG%y2zJjJi8bvy5U5Hi={tB*BFQ(Af%tzH%6FQK%bT0xhZ>|unlCu@iCTd z!3umxURqYq0cmFs#v?oju^Sq~z%&lOiSb7p{0SJ4-jR@P=*e$hZ)SI6l?PX&gufVd zZ9lgFXzI6I_WR?6wp$bWaoIPC7l$#iuwRw|qDwM9SM#7)G4cgy>yGesMPmmvUH6f> zy*QP+$YL;wF!^dS1fVDLg8=Ps_Xe{S;lh}$R~H6QvOwSjqpYvfE6_;>@h;0?(xfj0+! zpa8m%{vEgD^5lbdGJ=5j&Bp0a_4Yd+A0q~-fDg0k=Iv86sHL^ge06xq+b)G=frJ&& zrRkC<8&RN$W|_K_g%e|B&}QFoWxId5e61Cw*J6}OMWw{!8<4Bq)^A2or9%-{VLm~Y za{WNUdh)SqoM(oL@Q+v zS>Vi)F-O`D&N>hLb6xMHKSF`z*NA<&6LCUo(4f`pL(3`^@tjg+_Hcn6TTj zNC2a)+zmcV->k`&T9U*BHIv_T>&4!;FuV4Wr7*(79$W*|&%)O%Fh!i-0g)yUFI-kL zFfs>q-5o+)|EN_XmViC0o8mxZ6OoNzI}WZ${hRHjFDOa2jGze;7T{w;wH(u@%@iwe zvYtd`fX|j-|CfoqgJC2tJeP62Y<>Hsybm_O*&@yqqs)KTXc%Lpvm5^=U;LQFa|N^V zifF)<`xkg}oI)!#&n~fJFn-h6N0Sl#1EU*7U_U?gY1nN5mDs^IgeN5+$@=ta<~L|VY5OWJTo|PKZ4`Xa7PO|8 z`sZ>t>odgCv4&{EVNPt;$T^mF*V<}?#9^1XAZ6a!XaF9N7?kP`KR96X+kwCwS7ZdF zOMD#}LpQ*st#gkkyHIE+$(D7|UusbykmKdV413TB1wS>9L4cBeI72I2_A8ep$Cb@P zTdWa*rHL#5d(%SRo@`{D=Sqecy11PRKQ0ekND?88=vm%EKi>(YqEUwmOP3rQK;{D~ z$N}NVdf8G}v0y;XfQtw|Pp;!OH0a-^Jy5wh)+5)Hu`&+KrVGQSBSPIuXfud(bD6b# zMI_~>N7`6`r0ZydZghfexKJJ9!Y<%-w9tRHhyK-*+wq?3K)|;RQfMlUsP}OLPYQ>e8CdB4X46sF2k+iokcR=MbZ{kw!rET;rhV8xSG(!+z?%%0 zwBJvRy5DjTXb2es<`c!gLZsAE1T_fFY7anWvL|sh3|4S($feZ!>-LFFI_Q4zEc7E1 z~03u z-1_@yo#@oN{u1~Hi!SL@p%)e%pY&R_X~woA_m`OOlo{JF>VQ&yn)gG4ztpMxK0W&9 z--FCDwwZxE*)k=Uo6axmh?ym?=a$i}E1@a&8Poyg_fS8QS76kjet2$C!~(dsiJis` zKwtteiFEw>UltiK>pC5VZhb>(JkjWt&J8)S=qXc!p7->l*R*Tayk4m@H)wsRUw*<- zq79n}-^MGeQmiBsZgtkPZh7TL&m?lReX`L@mKGa&`*V z-B^Op#HLCVUsTzDlLRW@?=lG%41(6Ph7Lh8YZmU8cA$iv)aSIE6eo;%7gK>xqomg6 z9DQ;zbW^GJHWmBPO~*l&*mS*(CXMgCI0;N>62crLnaLi9f!;G_MK|m<(aa%P(14)n z{$lWK@x3cYt4> zX37hYb^SzCsI*1d>jqK)YHGQ5`_0ml^H%U)Wn%(rBH8m8&u8ap>|O2@^9;GX50xS> zV?a}zPvEAW))XSND?g-p&O7lA#J{zXgtwl<tdpe)3-(6H-Rp@ z#(n-~OPuI}_bRMp-?gh5e|7`D;-7`Qt`?H6c=_SlE@a2QA$j@edM|EQidU#y(BB!85U6Z}$i>BzJ08;vd_$9^7VAiq^shw202zTA7m%3K)88Fa48IZ+pd{*2h2$bZ!=XI#g%n!t$+;-GFGcsys+k@%UvL7lysc9jkH;HU0jtE|ba4fClP>w>7?N$hj1Yj?%C~Ew} zw_OmXwWwCn99JfB7C;4nd>VZhAlp|0LK-k!Q-d-HY#zw|gIk7=jQ`lN3~&`=9!sBe zKwoc>M1SEp_1-xW!uE~O6MLk7bFQG{WD@s;_W~+F@$vrn1JL1Z0Lb-i){*DEz`+5i z?_FsSD$+6o|6mv%h)N1!KRX|oolge=OoSW?2Oe==hypO)E3%S97GUPv#inlO`px$X z)7VNCJUq4l(6!^(-)K+;^u^`KFw!3tfKlH|AKRC(BKP!hv-TWC{f$%aYb6P)@_i7v zD`KO~PyH~^?a;YH7vZWGPwsZ5F+z9X3O+gRgP^~&d&@{?eglG`L3li1#FYB^=zaR^ zZ4x8zvy?cUgT$!V-{o%&a^8=6$p$rcNE)ap8k(2r6_t2z(Q3b-KFq~;D5n#=f_m#X z#su73nChYXh5GxXrvU1(XNTZsx7O5cH;pzmk5$XE+`}l;(>j1tQyJv?g!31w$^$5C zqoyTgtW%l$iM(~6=lKIGiG$EIeXDW!=ehIGGBw~!UC}o!5W1`DOGbKt!%XuR4u^7; z*sbputlG<~;K3l&v`Bcas5K9ej<;xQ#yom8F~*-fT1`(pEs@!B1S*|98ksH+sCGTo z1NyGHM2a*L&{$!Xh>RQKi}Fo)zWVVqTaaX^qnB4TYx>ckz{*^|AHabLw1Vy%J|oe) zGcCdF$z^nFgsOFFuwKU~mgb*lcmU!WzMjvwpNm0%J-8a$XA@#SrfiiApSM>Zi`JXH zFf3)}sEv(dRBAVuX)q~=stj3ho79@rJy#o`>zCyOC_ab&6= zQ0D{VYFkw)T$SS%O+HNDa88S4t&Bq`x9!WzbH$3=f|k~P;tx6#GuN!)=ek!|i-~QX z&3l`P)80|?(apZV0k?c}9|)}WCA26HG!DbeRZ@)ps-`Ml7xCf=epO_asefQMUE%OB zYM`|@oMGi)rF{}z?O3DS(Hnno#bk_w9%p2_qnGyE{zMed-hpPLTn89G*R1sp+ORyR zd~{MXk_Y2zjn$#}7nal082SXnnCpE(2_JDnZ1!YwujbABo&$0~z%S;btmfP$o1FcH~x z0&5_zlV}d=0ExorHfVMGiUnOHT*Q0+gVj3$7;MV2GdAg~7MHG2R*#3jMAD-Av<{!+ z&cg9l97N|(d|0gkQB3l(Z!JZ1klbAXV)GN8$nAKYcKmT9z|GkE)@?j@FJUw!sg%*W}y_9 zS->|YiFcPX{*vUU6fGJ)?G0ac)BE3WpA9;5;5u{w0D*rOD*orV&;Lgi1BPjzZ^zBG zgxz2F$i|8Z&5B}jsho5#Gwwqa8U@x{$%2$5)0)O+73jZt;S3P;0OYVr9=Tm&In>{m zH;;e_N!JqFl8WtIXpmWPyx;eiyxY^czvqVDzOU!5<|)sVUg+P{zYHg*CP=gQ@E@m? z^W53ScS;g;Wjns+5bl~bb&x_;ZfuS`YaU%C=B=?-vAB~1CjFlC?9pP#g zE#D?xvJZagBOWgL6U3j#Dk^r3MVh1%-xEulE)SEHobQDr*tM~7E+u>n)6XYPe|{%x z9kNRKvb%k^y@Y;0V}D+Ozi(@6^(K$NeIJ7CD_-0Fv=NuI;oOM_~LJJ)NQ^$GF447*J3l>k^Mn#3wnQbHfY$04m}zDo%66zIqzUq z;VATw?epJNn|zY6V5d5PT&(k)kh^e9^h*)@=v{2%%N?71+56=gKRrL-v*&$~$X?NS zxB*7?wobkrd%aGrzZ6ha4i-s(iFOm+ZuWH3A!9mQ;(>EP08dWSLt= zos{K2J&pWu-aGQomiBcx0lS;t5utMr%MpM=6q{^4s!Z!hGJQ^JM=Uj=VA``6fwEmh z<%1+@TI@qYa*I04NPu^dTK>@luTE@|CC|E*`oUxoLrT3yDE5%EfB>*mMX#~}0WXSU zlzyb<%$oyfKCCFMx!b2YkA1vj#yn%$;+v(zn5cv2D< zk&O}i#?6odB!(9P8_mH zri_|#M%(YfI|Rn(kvG}=XSR<`z?p`}h*9IkU4V-7I(}SNTJ6K6vXUofVzSE?a7P~G zOcPu*A}o-r<)sARiTOf5WqLdXr$@{Kxc1KY;Z*&cu?q zMhoqD3JnV!ZN@9C#%!+0#q8g$)xV@QJ!6UV`cgQ^U4Uy$ON}*-DSAM8+>PRDB8)Uk z&9dzSS3ObfOj=~++z;riKYB*O)3t-x`}*9U9E*=>UIvx<2*g11wRLhApB!yrU&+kL zm<`^8GTk-AO`;+_wV?r?>UUUmk^)bdd6h@wwxGp@@t+HPSVUuNf&D}#323H>Grn{u z{nr{K>g*z>3HwFImZvI^$cqJeRDSYeY6fOKGW7{Gv`NjTW9vsnWZV)W=HyCjU>0JT zgoIqu$q_AcgOfByRDLoYVi3vHldc2;D+2g@xCFjEH2i-q`Ay5gV*|0=OT`mS2U(PN zs1O8Cvp{f?#DqP{0IgeOJ8$!RQ|RBp-3JVf!LBPbYofO&W9)7b z1U#R4%8`cBpn^qX6}GZlI*fOHj4TSkps?FW^eaT#lDfOy%O%b)U0(?Upxa!sT2KVg zD2}mk+9EBw&(&FkTyxYj(@{}>PU(U120sq1O-E>Dqpe~^-7SVe(tROJL0C?LmNlYy zq2FW`xl(L6Wp8rw^hhhO5#Jx$@-+%)fU9l_`f#w02H;W&-GQtagQXo~=}<|gJsd4( z*Xoi6$4Y7zBvzd<3XIlLR^vNSNDgPqGuB;#zSk}G3_$R)>FtfSHb3;+{mn27wu+Epr>h)vhIBCiJ1WnAaR(t~sijm1WJ- zqp#VkFm^FSI7j}f=H+x|b+CF^Go2*)R$=9)DJ#t_L!YR&4nfSQWpSX})Lx9B9(yoL zpz|EaK1nu*K9NK%?xj`WAjvHx4}&&ckV)FlrT&x{`^cGfu9|LYS*0-5V&znT?c7Q& z)kkGua*1fQME_9#S^L%U_1iY9|cM>L(qyj1y89%hD|AmBbV!V4h}~aeVu}{B<^sQeakGcID^H zjK=j04?H27v}zua1R{$w3TZ_KAbDIGWg+hQ2!&V-6yC|W8wT-?A|ivJf+OHHkTVCa zhsrEs*~1o$t6Dvk2S~>de-8ABo?LnqG5i^8$!#v)Myb6Fo%2=?5tE9wlK%J?ZMWS@ zx{RjoOj9GWC&DhF88o4TvB_E8KK`G{sL1@`@CebkpW074mK)x-c>rukd;3zci1R6M zstU=RlY8B(DS8?pL6_FlY;Il#FW)C?`Sfm{{!}x$8T?u0hOs1Yrev9p4^<9p_QBOo zu^us`^|Lt;=}JowZH@RBKu(Mv<^{5?$hCx-160s!R*Im_r>V_`#;atngu>w6A-0zI zbF<(+Sj_4wmUDVy5x;12Eue94I?f23fk_C#k_II-NAg__4r8qMVD zSgiI35lDNfKyL&Fh+T=!K5`L%Yo2*A;*rEf<)0yBg?P=3vCi5YD6nN@oSFM{6mRC@ zA%%;l_ejMaFeq43kREY^eLZBjTkhm$x}Q4SqvmFCishRsnkyvjl{tw!!;(CrJ;9$y z#|B3Y`~z%gCGBNNY8F?c-vVmU7yRMnNb;8Phu;!^eSyfaTNDE7soF0p>!;~xZ`VGs!i zF_8kdi_p0uEthtP-~O`c_RKUE8}&Otn;CGKvxC;qv2Tc+)s0U--#d(r(+fon_+EcI z7Q7mUhBe>GoNr{hoyzz1sy5;V+*>fZ%@Sfs$pw~YJ@Pxb)nx-UAz9_Nsa`~v5QrB~ zHK%ig1>J&<{%Q^hCZ4B|jjI?0lhT*s{V_;ML;WUnBT#1srqIN8tQ3g=gwqkn9WKO> zs1-y-{L3-|7cpT|Gi?G^kM^$7hPYuU`yzr=E&IrelRCPowoVdSdJQ31F%u#bro#4* z{Ft|7@biq+P7|IXSql+M$bsZ1zTzJ{?Vz;G%cQXlP(G#K_!U)`__>r062I5w)bp z`6H=Q;}CEOTBrV|QVYlL4y`O~x_&~#qytjI9b1_zI8xP6QG8T0@geJO4?GW^47m7L zFcz#Ja+Lc01igm2$UA>M$*f)QHYsY!ioCELioJ}*Mp)sVohYdLarTuHdwYax5}O(` zw6?rub6^PqR7%ojrPH}P28IrFKHre;6e(gR_A`$Ncb+%S)B5dY@as+!)HP~S*LXot zU`p`f<@jioHiTVu`ndMYXb7qlwfhkZ;SRP&43pmDyl39Cr$m+2Gkbl`bON0#9KS;ss2|3n8=9}JGld1ckj+c-BJW~$ATg9r=t%n~}_x&Vso#X_A zpRAzpaZAGRk@}A}5}^rN$&*u1L0D<&eAUPQan;d6 zl^IkuINfT^p;OAh~rgH0|^>+x3WJpsMMDqLG&rJgvZ54^d=$z^@EI zm5HonPIH=-f~*Par#7%0!Wgj>>5QGB3fb6nb7=i=PE79M;I~+G^p1N7{fMh}xSd8_ zCzYt0&|)t~kw0iH*~}w$S%S z`Wl`Mh4%w&V>oJup8a4O<`aYPR6>{08qy6qeXf`7qOw-gkh!mc(>IY*qws{)^2M?Bsulv+-G+eQR=IyEB#g9QIcQFUQ{WlNyaf4{GHM%cWac`N zOcIF#t-5gck<$tjt2RhfD=N*+if#4bC8RBu&U1za=_90x z^!}VC#)WE7G2VW77ZHGqWCd4R&?GS>&Y*N0G4%EbMbfn+f!fUko{y%YIt^2KoC}1G zbRsoWLp_Av0v}4~<}BYxjdJD(tx0PYo9#R=8YR~$^<6M4v(4~};s?X5*=Xvb1asLP z1nri}&*`$$9bX7T&HFwz~8U!+ZP1g z^dSg`drsS4S8lABo=)U6`5aP)lGGng453{+K%k=Y7+ZJgL66Nk$r%A>F?cetgDV+r z>-J)XCx-{lL@s8Wc|pTc(pk?YzX4F!xF07A$Q&uF&959h`BqiK#s~3mmm&jx zCgGtmK8dMnbA3kFQ2wMvaID0XL;fkg+hm@^>mi)H9ELR!BH^NA8$|ZZ7#XHC^+1|D<8f@1<#wGx$u0wZ0Q-4 zA;EE~@rqfJgUH7*w|wU9$|0z24~XZ&k+-4>;rS34&NDMft?bN&i^zO8_T=L2&v}8n ze)}TnTE- z+@qxXlZU%@5FS1Vw0|Ew_{@|2hysM##6$wk{cY~*TG-p52+*mYLhe)}33Cv}-44`g>gV$g~s z9v6L#3lV7$bM`k3{qBiv)=Tk>IbMacVP^7MLmU6y8G`ptP5aLH36CJ@>Q_+(Z4Lei z9}{SJ0?`Ox{bc!6!^%1>loQXW7QL0%hU&;owFx!RV6QH6aZXO*Xq^X2?B3!CA@5(& zM4J#?=A4gBH@Y`C`7_&f^@rKv^Lx6S8``z!UiKcWSl1(Ubfju$q6|jl@$d=2hsCz; zcFIvKf$A36-Xfu`fXE{EAmm8xit~9kRS-_}fRn_-I5%CMC=;J4eoTo~3>C8~hgZ5P zI%}kKKR>KdRQpFJA;pKk{um%zZYXz}I$YPbW)dXL@YtwhSX%hg))rxaoB~UV=h$!W z!COWB53mgq&ZBO*8~mJLV9;?o1){j}_1%e1ONgGD%L32C3Z32V$Qm`LU1NPT+`zY@ z?yGd&haN717P=c9n}&q;T(K#}>Uw^|46+t?kx(L z*gL$q205nMx8PJzgUOst5PQySG(2iSOTA;0n&N$Qf6?l;aOi(xcA4Etkcc_fY*d@s9-6g;XcxdFJFZcx9yAvjL)84QK1ifjP7xE#F>w>WaZsau5H_F7I)?(Gyr*d#LaP z8c=ibnLO}XHZ43EkEoJO@Q*nQE!;bB)8<{Kdazsd#OHaNBWIL`s6@7o3IF%F5GhoF z0q4f|M!KYpGe{9r-2XD`S77-COzb!;RxA=p-zln+!O`GT4+A#7TuGTnNSU%SS>-|K zvE3L5WnzQK$t#NU-rb-5_+u8Z7=a()XN@o(Nm}spcKAwqeRQaSf*F<%AJH~S7J1zP zQZUTN0-XBh_4E2$oH5r&;p6m@aoFF(|9!*A&&|t+qPxr%p-^dwR)ou#i~#!K`>ZBq zxdQNzX35LX8n$X`<2h{6x{{?OACAn!Y{(7dwg@=?J-&KgzptDIbt3SC40~^v%h&7@ za+n5oZYi)^PYmy_M+#g(DXt@xn*Ea|mgsG>K zcbuMCIWz2Y5hGU_bm+$?tsVzH-GToa{K0)Laa_;l_VONNEkLymT81Nk<*>x-SnvxQ`(%1bg)i*)@em!X)l{&(p#T3I9<8~?q-G<^%I`Qr%dPQyoh^8%29^~RqUW877q84Xxx9X{?3(g+Q zuk~)!Sc+cox_@AuwgFm>s(?L+v3rKeqIzKC@`9uMv_?HJe?UlgQ_u%du4JV+#$DIw zq4BP@<EeSwI4{v&i9n4nxOU>+_*-rA z-w8O9jC2_}SG04&a(i5q;Y7vVTsw(hjE=szHB?a?`0e1V^lTH@D_80puA<^|t`uFe zsSIBmRrx-ueS)g9-!}@c-uNYWT6GGni_aViMS38TQqp4gpH=z~qC`alkn3xHZi2cC z0%3w~b%M&(jy#FANG$4>r&ZnG&3JPrAp@+fOqqO$RfDIboC%Im98EJF85mc4nee>D z>|tdobL>p++T&!$=^9lnpQB{Fj|Bk5R?^`qDoTsT;)m#;LQw$*8JD5oG*GI^=0Ci<6{V1>4*Tr?c*MSuMkfcuipOfU#t^^+rkbSF)lO zX7S9V>nwk7P%KHGc~xd9I4JcRls{@cIa-I?@p#sFNtwb_mE!uK_sX$oKg{uSMcHk= zdwC8AijI3GeO&&s&Q~Xyw_X{u+cUk@&og4&5d@j?sT*CPN z9q`Uf32jxWKs0;CeFs54p(#{E1FaA8+lm1(b? zM*c!GBI_-TK{8bo?UWnlzy;qk9G^WWmmVq^>mpu>m3VOVi_Q=p&5?+xhmqNQu!{Pb8#OQ5(TvlC`|)_b{tsSY9H8jWr#;g4#0a;kjA`xEsc1DRGQy|CrQF zY*@k|t3CxUs-KENBZ~jTY>-m;q>ViOB&FgPs=yr5X~8V%t;R&Z6%)?w^Tt|)FW+0( zE1{wEN7RD_?YGIOmFDM>;?+r2B0FO*t!>9DUNh=>W`{l}^3Epdo(%>vfG8nDuWRKC za>@Z^%y1lV8wXOz^J?GChxVoarEF2Lx`2ltk}9!{1PYGSPB>~8>3JKCL{(Vi_CyCz zCa}LDt#?jDNukmKOLBR~i=yk-lYQtEV8`t9m)Jz%dCaAU{SigVN+Na9*c-($k4TU= zL?@8S2TN_KeC@*zle|wPensel`r=k_PIt@`2F@PoJG^N2Roj!D8p$&Ditgr8mHL+( zCfYf4jCk2rdh~Swfgq#yZD?9%aq1QBnu>wvY@KWhIT%IU0wVPji7a!re#-;7WGhY9 z?hyL~^`ro!?xMDzU^T~I*F~^Ikz;<2@>3)i{P_)0@KR!q(|2m>Z89Ca?4pa|m~Okw zq$hxb#L}Urstw=TWII6A6y0e|Q$xJ^*RaMe;zsZWOv&aE19=Ox_DG9-O{Lk@1X+IZ2*}YL*Oi5bmx%-7u$M;es45xa zgU-lqO8c-4U-{xE8@+#HPo7z!)G_aL(TKPO zh48hTTu1Vwa*tnInIZ#bw`1c@U0m0(8@4hAA6Gm1pVhQlJ(`xKAUdlDz-e1$1+%7g zY?8+*&0Jz*x@b{z)Vn(0RZ#|H(59s%5y2A6m9sNFr~mPOc2v@yhZBOa?|Wob9lih_ zQ9pq}Jfp;=uQ;-J^;(rI!98{Oja1jju|zB1&H!V*G=w(a3+iBbqG`gAyvnmW5zQ*S zHd;ff(Xwp%rjVHc41^2O-pmV<@7!?#^+-u;-b|$19aghPbjrkKfX6FRjGqizP$ETM zE{U8TYCM%(HG&BYHt!MIy={W}@*J!L`NTvI0O24%yN(UN2pe;wlqmb^iam^k9g zF3O|2Im1%X!t~UepruP^*xUcQji*^iJy*sRN&dh2oy2mR zwt1W`eT#UKdnOvb2b7J=MQ3~(0`}3nwPV`{QX7mi3o-J{`>C!bP0S4KN#3TNed zoT7<)?wk^Gqa^9E+=x*x=^&z{#)?%bwyQMOf1p030a_W_syjWvh-CWWtmPUBlg$Q{ zO3H1iA|bEX5O&{naMxSH-&8~ge+k9ixdp^*LR&ZO>#jxDWsD|Aq>F_n>AybQ;wb}Z z)DPiEY7B>~0q>c+Qn#9ys_?4aYNS(XU-w@SsbX7Y`^RdScV(7IgKOP7ambw}O)Oji zT)6yQwF^34n%qot@^!^mKAEi)_|$poPpzp zMuwc`8o9U@Zrp^>{`6r^lQeUq*ufO6+V2Es_K@0j*Lol`BF~M{A{fYi&D<(+Dy^&B z*CJ9sNGx44SN|iJ(?vhkx!b^bax(s-8B*r>Y~MNrJ;v?czjgGT9mai<^kdGqt}o zh1y7_7DC?=oVXt!ZX#0wzBDvqiferhr7O6XXV~tlvpeG{D>+?((q}dX{yaUclzv0< z3G*qh7&AlGTK~>?o&>5+5v22@HxRP{2hHp$&H@E3ad z#>X?F`F_oe4$i;OC_(({Q7}R|UV`M?bg^8Sh$qJs)(6id0SH(@2XlsmQygg{rlf#_ zat9T!ZI}0vOUJPgk7moN4dRl3si$7MHDmDEY@ilUH0uNyrl@w7)Y0lY1p4#-`QhT`PZBi(mz1u+&zsY&c+2A8+#i|oFOa0Tja3K3Hrh~+4nVnK8gttaj z2mRwscC10pGul@JR4g6{rTv)*-f08Pk_MuVbahAwD%VzOPN2MT&v`gqI2fmH0ob8h z7XQ$Bj%zcJSq8-d%M#jddm*Nmu++dM-_ef6%t`&F9l#T)DD##!CZRctNVP1M`^1>5B;HydMXN{Icf)SC*hSV97~;BH+gJW zmpeLMT=R>G;70U@UOyiHPW{E}$cwlmR(A0-F2?3|R=wH$3QMj%ePs5Rwel=m#Db~8 zCMo^9|7bU=5KB)!h|{RN*M2vf4w8PL0Q8=qXFItk8NnDwKX9Vt7qkjbK*LKRK49iK6khZB!V*RW8Ln-VsRbS zp%5ekA(=ySn|-(F+tYscQ5z#29DgV;GaN^|E>lY+Wf>j!($zOM8K^mEe@3s;*~4Xp zT`dehc^BI~lCm8gq6GR)$NyqXo(io(V5co)m7r#bOwBUuHI*=a)KY*mUn|r4D#7La&M(Ec? z#10_~i=(RceT`2{fHD1CDZlHOO$Kl=-bu4yjuRy!IksP{ST~Xx62+wx5o#in^VA>y zdXXo>{{l|UEBs&~ZKmQtti>WS+ZFO6g3Zls4yGHnd1+8F(LS!f3g52ceI)fc%|dp! zWV?z3`qyqVeF4t66!hVtzi&+yS~q8~BqB2#t<)4D?1ex_GppS4tV{w~rCvNv0PW*CmSZ9jBZp)pBj zyaRD)JdzZeZtu9rX&+rmTu;yL_#eWki+GlzzU0Cj2)Hfx9W`itw&iC3QQb(VMM;%7 z$nAC1SatN^;DtL~q4-Ol;Zs}tBJi~MuM3~+-`^z!)dX7A3`GQbSc`Zg(+^G1j<~~G zSgZckX7K(b7u)^^eR=h(3SQkXM5>2Rw437MQTK%j&}O z92>i<55Fmn84vDy{LM^NAtNE=quJV2XSkhfj@~9DkYv;kC-PMqWAEu= zhZSW*eb81riA8_&%4o~5k~hv5`w80U(6{92P8X*agypz|DYjP4Pn_42`fqVyp{SvC zm1-C5{+&V40bsUyjag0?RFXP@VqMnWDlu!K6Y))u zG%*5I8nU&Djx~a4e7E)-~l8o1&M7fyiS;9Yek7=Q2RSp8xkh&Srd^9E+ zh*qi=m&r+h<=&(v>#2hAbGD`Sl@b**=7pG7p!A#hAT}&Io^?AFUeE1%ttgO3ugMPq zqvScweu*=)V*tERXS_WS9_Xnc>|=~vHWkqq3^@nouI972TG_5s1oSB+vpIHmIM9j-T_sJLFs^-Zq%>F*1uvBwghK z*Z8N<#fWb@)DSR)=Ne|Oj^+WAhXujn<4 zdZ$!OLgfU~xrxWkaMly!NH7w2AB+C|`$41iYDM&B<8j$?2q275{bnODQJy~(!iT2_ zO;MDnD`|CuUH2H-7MXmFofzKKLgpDN6F$iti0>fGW&2yD>mM&u&Feu^A{l>N){aBJ zU9)U%g|R-_GZFUV!p!S3_p2){5l+?&cUNHEz|NX^NnC$Dlt;ZNHuW7V6RAk{S6s1$ z@m2TO(O$(;n0`6j794QE9mszPIJDAn&{^s*sTwI%e~!05xiIM!u#q5@XJu+Ft1XQS zGnW7YY{1EDteEmGK<3bq^}}Jf0uc0^l>qo*SEbOvUClXaY%2>!u##C4_rCN*5RO23 z&nCg+t1^AW4z^4amiJ)<&KCP^iz&EM9rk@2lJgk@@V_`ZJ=9o6XPZfXYqs~Tl%m}Q zH<#!*w($9t9L6iERBoKPnk8npR>n4o@09O-Slyj{+}6(A7UTtSjcn<3g;aiR2X!FF@QmJX>qX2;Om~ZUq7RphrT9 zsSdZif1CP|N~dO?@o4Sj1x>2NL&R2`KQoJZ-2zOASl7H^M7PoIzNcHeN!3kOfhAlk zHceVQn3RV&A1YssrSmiy`PZcA_P^Mbx^fF_P*0w{>xeq(u&%ioUNzfL%w*)kTA^=% zu6C?2SkGAdS(1v}KZnF~ny>kC+b2-OQJ6-mQU2^5M5awk-~9QfFkl~cZ4b}%xy1m^ zwVfcAs}>B0Qs<%=k4mWc$dDGCcjk9{{V36PMh;`6g=SI%bDCd*C6SDw_+2$N+*_<> zgzdk0YJQddx=>W`GW)sz4utovXz$5`9gqoE7w53%v7b#_j0x*qQHTuV!O?>)Q3p@R ztQP|8U0X-gem3LbAyLx%`_GzaF`=b#*MT5{qi;1XYX|=B>ul_c9owk@r81)Dn-$yd z&C`NEzMeiDRlbuCTY>l-P~2-}D=|HmZ;LpMsiPsz&{_wVGv8BzJg*$u9XoI0ahUIF zk!n#=7)2I$`>7nSi#a*HunjNQ*e*imQ4-tN`p4`Ot8tUkRtVc4kVoOSD`myHzRdJ+ zL49$7wZ6@eyap2o>M;Ke1@AQ9d=JBu2lspJ&w6eQa?|!0gasd3szKs&a<)?vN1OwB zi}Umr@+(TqdZN#etMyHVvQlWJcj1;o5}BXR1bI7N7-(Z%YG>@on{>%`xXEU8fjFGA z4;B~8-Sy|1wWcv76F84d90>8k%SlA`iL>d;i9(J!WK>+J`mf%O3tj>}ga;_x=&zr^ z$WjWCwi2?;;@#=#D=G?2314!!<)%n5dsmXkpubk4L<%g0%uIfr%%T~Za-zBT5*6HJ zuY3q-5=FU0ZMmegcR5jG!Hfhq%uPIN$D13g+ia4)ZJcQ0p*a4PWN$)oLh=!-A%zM^ z`PVe{229Nn`>yo_^-C$2F7@%|V%?es>8SQYNf=4CQN_w#5-d{{cay;N+}`#O?U?;275?Pv3LVBz?Znxy`r&K87MS}t~uoc;( z<08*k>&YVIG21~iKNLJpn*hOhQTxZc74T2C2O9Ye&Lziz-4~XKb#fT1mjh0PBR8L2 z0^46TGPy#tBS>dTj5nhaO_U(x6QIeXG09o)xnok7k2KF8 zveN0>cGxqY6Ik>oQ`~OpGx&`85@95JW0G}HB4(xGTrxuRgn?0L=D8{23OXq_{EhIM zNKup}IMc>7;|&+O{1!@52r`+B)SR*cu?q3r5lKK}c2y~PaZ-&majK>Me;xLQmbSbm zxS!#K-gHZm8ab6*kDYwsOmbnP~tF1{Ye&285kp71wzW`;Vy zIANWO@D@%6+iRYKnB?B$`{jq$QE?-wgf|`HhnsrNW1PWAsdR32vQ>$!Ab^7egK%2* zvu5Cw5Sv(}@)HbzWh96Ce=Rn+6o0WDKWMgmCl%E8Gt4^s+L*Il zgL5&SG#3lAHZuB+)J{xzKWqBIO=C;LZA%Z|@w91#dUH{%X_jJr0wOCLcDEK6m31nf zX;5xU;^UF!f4dT+_2J(GA+V@;&mu*zh5V{$e%h6inEy#K-55-RWB}&5wzh+YnUa2- zF)h4Zg3Oe(Q${mlnvfP7a;wqhu|nr)3dpKMY+58$hnwZzTg+A-i!E&NWak}-H&zcs zKIE<-82iijX9NoOW2~!ygxME>8moV@7XnE`EJ=H88khpuE5?j$(b7&|A{g)c0<6zi zmXLhKIC)U+sy6l5n}T%B{uY<)P0S5s>*?pKi$=858b368sTYNiQ82!Mpx%jZEq z!psEeTnjbq-@Rsi?VmN-@=(YAMSq~bmaP}yvbiwSX#X%!brQJ%pzOPIr|}pX@a!MP zy^QY%Z@jKs{M*1e-)WlX(SHRIFrk?rG3?4Ez9xk*6RNITFL8O8&^3as&MBmZdUAkwI{90cM zo~8`*9`0KplcRJgp*-?RUy$W+0>LqezhF~&2Vu@#pz5&8mD?6bhvpxg@+65;Vp{L) zc1Jh&9JguU@>j2S5Gawx+R=Y?p?(TVz&b~qE!`><*hXufVxi3biQt!vV-LnBsJa}# zlNR)w8aL53O}AV-hX1dS$`qc(47;11NQbGs&E^%$Vl9bfq488dyFUBl6ZMG3bS3`dq811}UU-EI*XSJP)7Rf3&7aOn2}VE2p{muFv~*^r*n$1EOw{GY)2w>`e-2i?icZI6P)ukTVv>r z$-4S@>`9*IB{cDdLWGuzL_u1prd4jrCQLzHcS3tTl=~C)uUHGoU#Y*Q9n+djGA%_w zRWy0w-sY>QS@%XhB-dAi98WGc6C=;;T3>JtI)3Q{v?HyT+)m;;+Q5hWzC`_lpJBZq z!M9Qx4wP80E`O7L?O3J>h(sF{2?K@zymu`(5ZlX+qCyfmkJW>&-Z498&fkIfxEj$@ zEm`qTR|nGjS>KIt!i)FPzi|H&rX%WYG5l+?r&h2b7>5vdB+yJrUhlTs6Aa>y-U8uX zg^{WgTyrQD(=5M`jz)6S<$XU-b}N##s2wBW-rBN;U~o5m6QfX8IJ6g`dQN2XI1!lv zKDE-_@=ht4<`K!S0u;R!k}|4r6o((C?siVb5*Z(O-@rS3VQMt-;T;H)Yn((8+i`7k z&J=tA2YH87HwwjJFUb9o&G~@tKY+Xs73JtpPTPNHGwA;342gC{q#zXVgfpd9-|2-u ze+rk!NZ(!?$sQG&201UTDpq+-eOhan&b@|4DS9Xc7&w+ir<IheFo&VfkS`qu&Aq z3M`oc-FwZNILR{sTmu652M>FBpNpA$1xFXTU<`|pK`NjolnbYK*JGdD6YJdtCe5UJ z^7ION_08&qqn8wCp%i%0X;3* zW5(Ir-%QtHZKxN6(?WnFa?t03<|tM0<(IPjgbOupMBsH zHQy2s5vytfbn^H*7QT2DxpVGf-qyb}pDXj3OW%FdXD6Tu*V*(Gvq`UrMRPd)wHRi* z#i~=>=S0Ly-)e-sx!C%tbPK?T)0kKC?2^)Ge*XS9n6X8UHIVMK@02w7F`#-kAD8Mf zh$6six51FL_*M))N{JDI)#YhIeqfl2ajm#5nnj&=s5e6%2l_V*mul{JHwE{DI^a=j z5$^?cdexwp7-&*QMW?CsrYMp!^{Gi!*ictLQI4n7ju7&5+? z-vs~5LpF{=YE!L_|ep{|~WGLSBtV(aqS_%H;p@`rMgmJVb1b zTwENDTrFwDJWb3T|Ci^t>}TV$DVe-?Y83h-0?%Qu9bNJ_;`*k|>@qmrGKVGkFHzac z2RpmBP!nYlJcunCVfHJ_iNe-ykMA-lA*BpoyOU46y$*3uRZUHeuf@uyKmj7azEAgc z*{@MjUdQ3MK;ZVaeXi-4JK^>Qwv}gFWjsPc0*`H`#Hv^=bq=9PcQj0C!55#xN!4;m zt(R2kDO{VIwPVBX$ob!eMZ^DZItOsBzlMObpj%O?({qHep--2rm|h8Lifl}%Fl z{-K9tkL&x2{j-y+7jgKxa1A@Rg3I^r7oncWo0fOCR&BhQk_fEw+aZGv+23-il_>UC zZA?40nhYRT5O+qlG5C}VWR zYuh1x*M6SdlV?|~vqi^xY!s4}ZxwDfdQ`PwvLq?qtNu<~{6J^KYuU_P zVUJdrjs<)`{aNFkLPJi0Gj6J>1M3I}uK%sqNwG$|iJ-kUIycW5uEyyU14A3qYMMB6 zk1vE#9H&;f##y4HywjMw1((|SHL{ihz8f_IpRRo~CM7xLm)#CdFu$8AV|@(K$2p*y z@?Mz3m6f;!HXnD~(=n7>j!X9y5U0rm1#OY_Ddc;A=E}Wuh6RwHVuJBwXXxeww71^k z`c&VKmi54Q+9_806}goBbp|Jh*BF8~po!T6;*t_y?|#I7doCDPTt^NyRNA!EN=6H(yNlb_(I9kh9FC zTENt-5UhvzopjiC4M0|2&Kti?JPZA%Qs{~~-CXV|{hNqA1ZJ=H8u9|~zKL~)nAycM zFG$Y=?JZ!|2*O;d)_^hqR+^A}jI}L8fQp9f?{2dPM_G!qfO*i{l?~f8&U%EitQ$Sv zjO*v*%X zGChjFD3!z_y+USIP2{bwhs(8H^AM`g&q@{C5smfJQYZ@Bo&y(f)cxbzC3!11qvMw` zeBfv>E_G>>C!;WbMQWjX|IS+6;avQC+XMcpPrl%UsDx&>E%(qaTpNMDex-&05%R2I zFAYo>TlyQh#Ph~WZOOZqRRa2<0S!dB3gnFKUC|o3VqNSM){Ma41if;>pTE=17IkxL z2+j?BO%e4B=f7o@R;hJCg}{?B- z@X&b%fthaBKhK zg}8NafVevz-Kz;;yNRhS^H0L#xxhb=WQ_ddUO5pMj0y&47$9bG1E1S&>b}U&cM&Yb zks!239DPL}jKTT+;gf}q;}4qN&g*A0;OXg0hy^3+HFaW`-Yzs9?jb*jMUr|61qECA zLX^Lc49*N}4;Gw%jw#E=8nb_xxAHH(_+0S7eSTFqIRpE@GxHbzQ3Z&XF8JcXEC{Sb zC>FF_79F|Mh52YgxMBUU#H73pE$O_{z=2^djI8UxKT~)Lnp_*q8cNPoAG`wzMtmg6 zV>aIBHyk2UXcY4NbZAZHK|+A;4Xidju0`N@u&%+SeT#-x?t_g;A%zbc=L zDU&vZ(u<2~V^|^~1z8yLu+}|SriJV&etyBZ1;{;2Al6!miZ&7TS^TRFKu;;OFqbZ|J~d4%>j!eBKIePWsuD_eq05w^7dDGkjO6 z{H6sB<-X@Q7PkHbPf{ScF0}`v_puIa~6$n?N*wImh&gDh+xAz z3poTNr-8im0X9G~sSa@44yU4Z@u}6oa~DQBKEB!>ov-ZL9_ZSM7sLr+?$LTIDc+T+ z#H`?HiNTr9$QiL_!D!y!S(czo2u>QgwCcPyF@8IxTbdZ@=P8C*G15Ro z%XTHze`2YiP>Fff;(_u&E2lxOZFr>0P`!KkMB~Knozd`@&G|G%Clj{k-Q!<-36;bV zj=~&_3nRwusI*9NinQMHGXF~QxD{k&)Zt-|z4nk!vY$4z2Hf-N-e;EFLofchiGJq|yqSgAjh2{45O*-^(XjQtkj6TML)d^&1e!ppR4@!UR*)>EmV$T}R5m5$=Z zIbn;%#l~8P(d>U*|A4odv5!X1$ZA;$CKSI1M+&P@km*2|rBPMTHsyD7s*d!Tn(15* zDZZ)f>};+9vIi1WgCSy}{8KTw3&tSY<*~Svu&YxdBTVhu*-U?4Lfx#N{?04Inn$u- z(STCPSm2=c4o7=(?rRxy2NIYB$VghJ=wrbuy5}50L%@ukXl0loFeA2pb4|f}TAjoq z1q$g~S62mh&8T;5V9(#T6izDtV1v`x`h=$Q@J|$=AVTV}N)PIn2ci>(vL|XBmC?=9 z%3;gF9;C-RX#GbmQ?i`qk(&w%>dEcgsN%n9-8Ck;@Rl?kNgi~=d>h>0%X~;ZQHhO+qP}nwr$(C zZQHi1PT!u#d6<}w$cT*0wf0_a-%axNK{4RM_}E^M^IS=|7$h@PjM}k-tPsmGqlzhZ zp|bkZcsmq*he(5K%KL=0pu-3>@}-zFCmCF8$PblUfDZ--;6RYksllD5uSWtbyOZaVu9hKE`K0?>}1WE*0f2J1UZ3~ zCrZBoaFne%2Gty$8MAS19t+^HQq~1O6w;=uK>!t>HB07jH^~tKIukVD&N)DySLQgl zQDxLlj5slxIt=iv2BabS=mp*wbQafQx&is+v2St!OtcVjMX|W0!Q_hBBy|eLK#T?k z&_Zcnxmz>%=T*JzPo7#9WB3v~XSfvmqn04+e@Wp5m;x^f!WIsqn`z`@^F% zgF{!>3{1J~s4Fli52Y9=l^+-pK{JrgVP*g*%WzvNP~xXU7HA96 ztN90%6u=`4C{uIsCrDWE*Pj4*2=}vZ@}~+;!fj}%Z6LNJL3KAxHV2xGxGcrQ0%33| zv%w-}Vzdki*+fT=g(Hg11cFijw{vOU(@hb}>11dgPF%|wM@gBC;P30eb*v5$Ox?=$!XKIZ zPe;?>~JC7S;0G9n>M%rsD^rW+rY$7aD;7RxT^VqrSy0|f_g z;CU@z7;pQc)X6=h;Hy#nP!s_DNVG~QDyt}wL!O0^%hcl56qUk%Lo&wZzSS%<<-=uDTjlk3}pAVrT4g=V$}Oj%n#8DJ>=k zS_n%{R9dcMfT6J5paB;bFqMy15gJ8l!1mFMlki|l_+b&teB0vGJAr4hKj5&Swj>$n zKYo2PRe1wc7;RPj6+o`G;g&nX%_ctH2gcA?V>%BCKBeRJ7hH0@KZ>Fo12rG1$SF}x zCX{CHn9l1NtOw*grh;!@^hV+ahT;;u(%GmV!=)&om`5+sF0v7lqYUVB++ge_aNC0H zh)E788EMkq~3Iz76d%s_Geg${;GO3fuYZh$#k8g)5+Kqfi6Dw8<jkkKCVVA8i7I)5H_uB&dAGeM5ml3usVnX6j*0Zd(Y{BO$*&B{ z&3H{_bKs!;ktp8?QG-p}D6GNz{gI^1C+2(=#I7(-(BX3bzM%Rg8^ zB!W!J?|uY3cP-)kvct+z6TS3*^Mxt35+}87(8zEHozAxkyq_IC4RPQYRhK0`ee0FW zsRsb;(F#5WqG~>8r|=EMRdFI}qQW-Kbe#qQGHsD5@b4;Y90yj6mmKyK(cmvB7KPLs z1BD}NWT7PMC37;qSNy$1Dk|nOYv|DNLzGLfS@_hfX3Eu#hfp(jl}jQz4Ot{s7991` z-9Ax!FXABBSAW5eo1*p(oA{OgHK%p5W4+ed^?d+kHy_gfD*n@n4ac`T*zUuMS$(zm zm_ESa>*?hRf4AcsG;b3!@hJ6DuiC{P4z_*mW58+-}vJb9) zj=LIeXOR1+UoZaqh%ts6w{r0GWwa1Z53X*G-hLij9Y4r`9y~oL3s0@g{ebvR@g_*Of_ab)n z<>taWq8huh`e5bn@M;K>FyKFc;84UT12Y^CcHB>?@id!I_V3&F-UuLigemL#4??W> zMmP8HhR}t(7J)}6>x-%9wu+JF@hE4Zxe;!}NB|y!9syq}PXs_HUn0z-|>+Dp5jOqI-VB{k)cYV$Uf7AZIa5&@d{1}*rWQ?D2j9{1}OQ?GS6Kh z6S+Gz140eAXgCx%v_4K1W);uC6B$+*kvsmmBLniuc=r`nD%Wr!{*eeSA}b?BmI}tc zAtT%mDy@S{Zqpv?;&n{=&DzR^5c7M6IMmi3@Wi2cX^+u5Ote*_6LC!u4FkDMPPt)E zyfb&if4{8!%&_?rb_knRhgAJ3g zjATE^J`C?xfM#)9z}-49=axn}>abL_Ti%)ORrflIWD6<}0*S`q6*X%=zGbeQV+9`}^kOf@N4D{=E_iwlF&h|r8pK#N?n zfeITt={xh8IqV-c42$_e6oRQU(rpVq(@@Rkn-1@u!ghrJ?pno{;+#oEmBl6XMyrls zEd`AfXt-~Y1m#0iB83b4X^wP}XKcUe=8ee%Uq&+{^vfdH!8BqY!XGsJBP&t*^G_C} zpXws@BSB8G2%5fCiFlzOp@gCF5=7FOV=6K-(FZ7Y%29lnm8y8?phzHHu4pJrWtG8! zd6Rs49&dwgh&EnRkb;EMRd!WCaPb3x?};K{1Y01_+miaTzCqx)@=~#x76I7QXXcYz ziuE3yIw)gV2%2~kAay??HDCaqaBB&&K=V+K$CHp^yVXrw4kP?UqJJx}C`>6E=)rs6 zfK~!}u_l)=LccZ)T;07m`vpQQWU!OIu8aR5z5pl)h8NKnuK8Xir2%hG%*tD@R|FO$ z`1D}--VT3z;jS5YS9}C830u#e4Pdr*K9ui|fLaUXDj*A=$g32}H4(2gP$yIQ;U(iY z7dCf-kGHK?RK(R(1O3O^&GR*)Z-TQv`{W@yFN(b&Q9i;hBIg27(bS?JGtA zGfG~9f?%sIMZ;TZ6r%q8sIitk@0;Em;j7YA_?Kmmf*Q&p3zXy}(l&zcB z(^n7Di0){u=oM$-2Gn>yF%*Hb9ZSIqlDT7i6LY^;fN$S?@%#IPelcT#*75}L@!>Oi zaOzAi>MVS;D-^@TZacue-$37o{Uaqf@81QW$5S8C09S&m`}g7`2K#zD1fRYcu=Kug z|DNI<1rpW(F8*D^-k@HrNMM<_yrcKdSM>S=E!dC!^noL%{1IO4F)SPS@Dca~?Qw}H z7$!tVADUyLwYkeoW38fHLYf8Z1zceA3g`=~HUA29Xb(!H_tLBW6o@{d)PA1Vb=}5w z3-CM0)m20a;Lo#Rz#7kk+F>2TR+zLj27yDz31Eze>bY#;NW^PwQEImkYdX>UtC{b@ z?<%4r&%wv9+#&2vh}Y})1LXmjH5=-aMr}HnX!n5zjjLT&?$SON+_)^?wEVq4QYUPW z^WXk+@py4!-`eKgGM?OL@l(K4qkJwB^$h3#RG`o-X(}PkxVX@`jeA|9tCFT7tAiRv zg6xhxN6Y}AALn=V=i=kp<5xjIH(_IF(DzJj->R>7z6 zqRSs^_0>?S>t8la@F@qNP<3+b<2u_y4OPK6b&fhobh}CGIs_9YW+1FK6arL_)l^l+ zRorD)Ebz}v4TKyDTja}@B!j|HkG*eEiY3ib>}&HJxafomyH$(TVYi^QX<3#MuteE@ zYG;a{r8$ELyuKT%R4>ZtdO7t zVXVSHP4_*O~v z#I1&LBP7kQo-PKKnhU^NJHyX78PX5-73!j11y%xdP^wnz1a*clDe#FE$A{UCL|Idcrjb0$!)%4}AWnEG+M% z&!&WqVLn&~eeDWlHNQa246KW93n*3TR-*AmWsl{tnzjU_4wGI2>XEP+0*jPx@on7{ zmInZbU>hdfe&+wL!aZ-qt?>h|H^1N!21quJ#}5$x4s#>fD0EHTd8FtJv(c4biNGX* z#0uk_#45^Nd?gHqjqHpl&deQTqPmFy7>62eib(G0->C!UnufjDisiE{67ZVYKjsz zTNecY?m)6OC`K+Ax_@!AD5tBzGO%WeBMR0jYvy5S-6nBZaAGk(2}{N_D`YHu0lndI z2QwPp(PvU!H&E z^>*Cpk`GKfVE3M_rF*+H>|IUzQ%7;lmRHN7`wh!Qq;DJe{LfF9uzVG~hh0w51K>cG z|%@Nsc*@o#Z@IDeq#vU7;a z_)VdSG{fPv3kganZ;Z5SFD@7!?!Zp;57Qc5B{2j66z9U?15Z)OW2A8Od*cvZn;#MTn{m! zfUE?7I#~mIvk$+(pdhzoRp_le6>y1G$-BM~kOZbka}+PZxG;@X%3QxpsTLGB5%Du> z|J1|3ldVa4Kd4^EA0<;fj#Dt-?-3$bxy>$AUlO#v5MgFB;Pj3H z_aL-&qwMWM%rVvfs#wRC-jkhCI-v67({aJODFS4*0~kPk35(m@bRf`~F*}Xi(??2u z>bhmjpjl0okIzL9tR?6z-#? z;1TRXKS)TCk_|Z&+}V1#@EvS|WNr>$(dDMAHncxZP9J<83?0N6LE8iF!wliuOQtzY zWt@OaymcC#OUWy2RW5+GE0(;^i_dl687RLDi&`l*mg=}2OAF(eq*2-`|tfKnbf1?bg%C$j|_TFvHNRAUg(m>6KBQ5{G&d%Tu?1;L)w+IMwd2AtJrpw=DuW?_JnBz4gkRI z>j2Nu`P!9CrK$2Gt$O3YP&L;=JPR26s<>PJ43)2Uh8#9>Qb!pR%ifliD$8EKAx5V9 z1#mm;l6NX>ug8X7@fkQ}%1hI7HdN{GDlY}~B8d92 zUrQXA^k#TwuDJ6Ez7k>8btbMl&HA!nMani^VfEA6Nhj&!{8aksmK|SY+uw1aN!(Sk zR!M?3w@)x?qdK2(GuR}tqO#Ml&~;EkrVmM852w;PXp!?!`W zg{#5&j859=ILnOmfqV}2!8as-h%NU`oqdM~ zy7W%Y!q>G1>f%Ch4#+N=r{{c^;e_v`TNX$<1ahZn-B#(eBVr+KPj5t+QaVBAO@?>G zt2Hz;C~Rcam0<=ORb2xrilR8V^R*mmY0~%RDt6b8xoC4zQPfdf$6s3&us&3R7`EMB zF{)<+esy;{NyNkIS5Oeu9N`xR!u3>2^wPw^GTXLAkdewbnE_JW0%4iDCft@ciHLO} zTj&!GDOJyTZXsr+RN=6Y21WL^LbIGrNgXzCm7_!St!lOCRm-Gb&AZ4y;DkX*eubF?6sYQ3O)mFJDk+H3X({RZAY= zCkDI`%{EQ#LxDB3pZL!1e%BCKRmFdC687A3Mn?deog+Q6CP_P~!eBhEdaf+>^owrF zJf%S<9n#b)Gzc$V#DYED;u5_un&hmz@`e#PB~heE#O(a+gzUM%T|LJLDcIF>0*1Al z<)9N8l-o@{)_GT_24I+}qq^-aPcSlDsh}6~F;H>*;lKUb`Z#l}`AVJtp&h}X+jXk9 zPq^n3!_PoOInb9OZ~f^i3a3&2?zcDB^hVLdv-~xI^i&9mR3`B>g*8!Koys-^XFBU- ztti1-!Kw--Q%-wiUwNeiU7i{5O1iEdjnt5oS_k(YF?xbS$$A*HYYob%Th43+k^L7~ zEwpQsZPkXXb!FCFn}yo6mvVnvY7wu!ln&fB>+~j)T(CO;8Qf}G1fVT

Vx1cZ~miNIIRwe=B8E{e$g!wxZ4WIXgoQHUT^>ezaP$xlMCx)^OO#{6JIC?3Oiu% zoIx^@OyfqDuz?_Xso|Wv<0Qz!9FOp~n;Lz?FBv@})p(wgt}Z9x?DQN>eP-gpb&{y`7sv=Elf7!~UH(HulpV z71SaeQ+;HVeRs1nWdkx1XJf-H5SHO$HS9AC4{0XIOUFUPXn!e14)~Ma5GzRV$>2kZ z1o8&il7@3VY{mQ=>$Cu{_-soWCjbK^wm~pPt(CksUF?`eWXZ>R;aQ6M2HBXiBFY$j zJSy=v24W<+%!~<0*fb?8m|9?hxg{YTTMI%yhEZYNbo+hfPGzO6%I)ZD1Z=XlZ&X!S ziJP=%OHPH4QF-m^3|`AC+1Pseg@GaLI>Uz&NWE4BrYcidwF{EYJ?1v7z)Zf8ZMsoX zYzdYrQ{J8+NT6>oLHKego6VVIPIoT#v0-tr*tgXc3k^hnCC2>%?6Pfs<3>GowoL_X zW7)?lO>{Pgg|W-h_6(qx2e(a0ZXLugoYB-$PW~^3VaTpGb=w^&SIZ+>lQwH) za#L)($U-aN7IhdAe#W6?5*2e?7z<70SfMho49N*hVoTx6+1i%`^>+K~4yzW{O?gta zRm*7&BR~RY7qy6j>CS1x5w&N|qJC7Z64zdtCL-{Sy5g|WtT5E<5;;nVwp9Tmnu|4Y zvH#G`3oa~5%D;09GxgXsNXdUnPUqee*~Cg?qRO+{5Fi`IX3(jW+-hUq zS?>%f6ap!-CiF@encw5O%M00X!+(RaR_e`8B_-k9QpM<(ITcc-@z9`;~uK!tt<~rFrSMtbF;tHjkDeWQQD}=cQZo?yDq(%6QtxG z`6$vYV$Y2lU7b+J#nX+PLKBJ`_g1qP7+H{!T~qR4S5}ET95*gDDjjA7qbvH6wEWen=)sNZE@nHgr zD$9~KNX_wZbEuue)H`1*5=_;qF12*T^knYXGDm(ol#p{!ZHPpwXJKLR10(vua{6Y) zb@G{Qb7tJd%5pBrI=icD)ZmEVjkltM`V^>}%%9Xojj}|npOGJeIpOCO{?7{AjYkR; zn%r57pS)1^>v)->4?mK#QjXsD>!5%X6~ne=RmwrF9lK{U9nU7^8MBlqSz`4J zuOdQKeUkhwA+!!l9d-Zp|2WFbIXd z)yT|lZP~D9zoO!>La9_}uc3>hY0HGfY2$>!o^n=!fRn+!`~g|*YS6Ju79j9MW*c3*a zG1UboqZF#ivl-@jBeis!J0;JCwlRaubZrZzF=ztwa_GxVk`3!!_QjI>Btjw7qkx_Y zR{IgCv;6fYSH{rE%s%6OJUzTks3!ON(48QSp);brec7Dd9=n z8z1!PEiA=~zz zS88Q9jTA?lEI7M=L&+4Dj9|J7G3F4!o~{u7CQ+M|Ax0*B#$Af$ZA8^JM=fY|wWvd< z`&|YuX`jX0i`7LI6<@HCPu%rztsE9lCkz)A3SX>KRj3p z^|*Fop1-CnA0L-uzF2xW@8T)Zeg@sVn{3i;uzsI-Y?plKKrSA+NZsUbv zoDVy*3SH8V!-mvKHY``)(QrE4|G`n&)EOq$<%@Myt*E18Ir2BuSMJWm*%a>7t?(;d z5l-t1Wq8i_!M;z14pa-<+*399dh3)2{+U4G<={B^Eh2+jZjJ9!w>z!n#Yr zvU6OdwMjNRtdwr9d)}9oL;M$`>5Gq#|JsO+jXS)zxp@l_S7N_WI@azW0j}QiA4RLf z+!#1`v6CxYWW7#YBb5O_*`_zl7%2eB+(i2`;W5t&dW@&p6JF)C(_bOqfWLxM)gwBE4#k> z$SvO0?e}NWtX0*&y)xJZUz5i|V{xUVd&b0=+Dx?Y^GaST zzh04S)Sy(pok5`K15Upj2#+ZB%oIIY7EdSw%b~c@DF-wKkO$VzQLx z05oz>^&p|a*$smn{1UhXpt2c`2eJ*AF`fLN2z^Q3=7q~iSq53Zz9(-d5)7s@hd(=| zRjSdICYvePQMo`7;zxH6_MgKbbZRq|VIA1o+4T#xTLh>-kBA}^%c=FO~o-=j1lcTY{t&QV$6QF57O z(mbl9h4=hH#*e{Ut?r|~t6|Z1u}LhHGQ&e)W=9nw;j{XPBCnKLeziN3u2Y&ar0$db zgKMS}191YBGshub@Q;x$`ntdtjkSe8pb)m)t-x(<4L;`uM(}nAE}}=(3t-=#K~Qez z7mbL^JST35VHeLZ%vcv}$X5i&9_=MuK~p8oJ5l0LWXu!=lL~)^492DL`Hz`OOkExO z8M8GuR?W9F4AWdvS7QP7yq(pvY~fEdegV12rGAl^kC(gHuU4P8BC-a~_f9Dq-^(yOjD$OA%t=;hy>+CUj>hkVj6IDA}OBZL3PhAH;r8rk34XC>V- zM>lZO|Bv!$9i5R-#ugo!??E?ki$8py=i@cWrX+wy;+s}Z; zFo(<;Fjd)sR#i9v%GNQU8RsA!O4F>qnGiGVC)6R9qAjI{PZ`jG;&fqM1liLJ$F{F>P+e) zeGelEcns1w>Q3Rhgp9y}N>dm?@p7jLpg8q@130%X78z9&N(F)3lLVTlUl=@{R>r8Xn9j-f4kTcbFgV|bQs6?pet~?d8T&}%|H1NZdZOlbPgnMU6W+|KH z0WYG`g40Ex{)trE6!^R=qgqc`r(#usrkH?@X2}r8&L&lmx>0X(S5|T$dy@jRyOIeA zb1`!68^$9wq8WCB}!+cVwPMJ?@DZ;VE0k09MZRl zwRNiD66*_|*^_KD9beQBzFe-HFK9qrL6W1?A*s9klLad$h9bBF&Z3#jvL^85EbqRL zf#W&NksL~O^VKsSYP1S8RV@Z#`W+N%_`FFOy6Qh|!}Ie8J{7o;KQ|&UkigzEI70=% z5x<>qy^6;rR2zWK4%d3eqpcv>m7o`LA9iZ<3~`-^uEK^>vac$&gQoVt(U?~M&7J!D z5|m~tY%}~7ar{ak6&j}dH>9fgS*DAM!}&X2&7XQtFH)PrXH)~ESK!hl)u>ReWj_71(iF9TEMfIA*70ZO zT~)AgB0of1`7^wp0m0umTu=S(%fD1hWC0u=ef~{!CE)At?mHTMg8L9naNuP*Otl%7 zl<#}DB}U10hRmvz+mz_z);^`V!!Tmg`NI3k0FMG>q(Y}XNGqf#uDaP}i$Er+XIdxE z=M4_1WaU7vjH%htjP4ZtVB< zHvj$Y;<_ZHBbFlD-hZDj*tPM5u`KhzAa{b7JHF4N<^FO*^4*62ZLa#P98d|7FF36@ z%FM7I)#D2_=Kngc%@9;RVR{%y5*_6WiF$yo0+N1XoM^i8K-HT!Qf^P|3a@mb``t&8 zW)BCaR;`NuJWZzg)(U-dbRdO(-$+vL`^BagaF!&$-wJPZ#qmeYUQd z?|M(S+|7nva=%3nw{37pVDsagG64T3iSa=Y^bat@To5u_Hw9T%z=%9LSOpz91ZCdr zO~vDuVjol;&xfrAY+zJt_)a%1FiY|P54X?j^{YIc|L^DM<8_|ikI(D(_uqWDdu)+ue4yjuAQronK;V(8bEJJx3@QWQzg$(WwIBE#on=RE>!%0ri#eq zRs?F?(S(o@Hu3*@p#Yf71lbv1vp5<0kEi;Im-H_0?8|#?Q2yj@`)JrY1H87pHDPA-{qq|AO0_w*eQuj_ zutVe*C3x#A)FURp{b_~hs^gMAOP0((JEH4?UvE^DDMNOTrnwI3-ox%9)5 zIiX!By@-<{LE55t`)RLxB{r?&VqWFN^+8z6L~4>5StGSAlp0IYM6^7{SI@MVmRaQ} zfz9Y&nOam{=3>^=-Jv}BLLk%4e5Fr|2YnA3|D{#}uGvRHoE0_CySge(3oUI|^cXP1 zBuf*6|LMuZiK|j8fUEAo#PJqh<@cOWVf9-iy-CqnUmXORT7VeU&V3wWGorW_E4Qt) zM!4S43V}+u=T0)~EzaVjchS2L%ONQ&6ZjKBxHAR>6UQQU>MiJ$a$Xg}yCjxQ57Zu; z?`uCIhilT858J`SkWWz!b|&$hM)Q>>BnO_0=ZC~zVyRRXv{8~*G_{2T6$&fcYAl`nQ)xX?<9dJseQyj#O%`m@AdoU6BGDKiGR`WQ0ckLj7~A8mX-6&$?%cJF9td zt$M4I>p~J&#dZLM1#G&@0sZ!q#fY0u!t@AYI6Vd-4J%e2Pc&Of7h|k-=OpTewUvr$ zuBl$hB(}!IFHHN5RrX|8A|mam08Q*12cF?}!N)`n%*-oFMeEiza@oiiY5rcGp6!Rb z>0^PPS*Dsh$)uX6gV8ABSgho`@_}%Xw84o>r6^3LF{IOa#qd&_oESdklb{7d_xUVC zuwC1hGR^il9&S6-NonccU)}O}w^7mM@P@Z^27+{zYlPPY%5Bmn2c%J6GX;Nzt-*NU zEk&1NPM&)>-^DfE!|A^fOylCiLu>*sd!7s{>0NX9NQuX{h5~$*#eO7S$H>6q;yZK7 z`2oh)QEydJw+C}`6o%h`9xF4p$QpG)X$rGpcm;R7&PZP3C}OHzUNyg-x=Q|^npp6) z`%ih6E~)2Y&6#cp&Ik30dX7l0Y=X~|57gV+scFi0Wwfyho0{09LOzQHvTtV3EaRV0 zDSr`rBk69;20OTuttZdWf?PVAT511F5F!!YSX|gQ0c9hmi{mI}3q2y8D-4N2rVm=b zmp)aY@bQ%40QSZ%Vtajqg}Ap3MAFxgnVQAaOzuI7%_h_#>KLi8zRg(8>_`<7xTd*| zC<1u{jbyer*~I3C;6cl!?Sbu2sbztbu`<`swL&X>xOBK{o|HRx*NyIR2sCJA7))%4 z#QK#J6l5q%SuLe1mfWQTSp8OJkO&;T5uebo8LHf-k##cvzbltWU^V?Nn}a!rRx}Fe zmqM@=N;wgn#9lL7$m~c98X}}@x>LDxotr8FQ-s;{dR^Hns~!YG*T&=$k0-8i zm%*L8f57>!_`w1~1|bRo&QcA9eU)6RVN!sX1Gz;K7dAs~P_}nT^7Mhyye3IOI9)=Q zHL09K9$o1h6)m-@1RL&{|K+f8`VwVCdIv%6n>fy-{w6UQ#GlwQm!DQ&GvJvd7Q!L_^+o)?nShfe4rOT3}tYaktYUm3KcGZ|x6MtHptE@+v z&bPG}>XkF5t8ccA6@rznG}5j(074QpTI2%%fuMdwpGYXtuO0Itkm^fxynWBooEN%4 z%_)IlKoMZ?taVfA8IH&gJL!`y7BDHEwDMUhboSm&89_S5!DN#eZ{r(E;NM20Qvo9m zm-&sL`vMVvVb+vz@hF_Y93nIQx%|f@9+EZlNvMIdbEX$x2V9ERPHY-Y6{C?E)&uf{ zafT^Ve6`URSOwRLaUw!i;g)HZGeo<;Alwnc5Cyq4xv)xm(f)=}YAz=*H~Mm&5R1@t zQ|*O;v9MXa!pTlOvrGzQq@0ezoVy?N0yqf+sD6tz**ISdtQ09CKDq*>nRYPqral`O z4V6csQnoErQfpZ?Upa``s3Rd{h`UehA(rEIsC9q`#8gbY z&XvR`L`q&cjd54OIdOzVMF8ldOcQS*HeSfXaTwnFOBQI3ML9gj^8toM^R6 z+J&RoH*qwB?Onf@|H~ktWpNx1s}e!qJqfswy614ioy$Al=9lR}wTwyuo%yqxj;=@0 zJ$X{k+^E6NCzdVBqYrncThbD=1U8;Ce_qn>P$AGIQeG7|F;TH`5*&=RX=?Gc*2)AG z2cut&IK;9l1cRP4idp`&>Xewx!DbXmseow>xjq?*-o-g$d&rYnjM z=xmpoi=63LnncLBtdwDche(HRVJX3U=}{$rmARmsuq# zEaepXXLutdro@&avfJkFsV5MAzXTOnP}^~j_EV5cSKDIhaxv|sa^iHdWvftSTDDHF z!mgz4EtJA50Ew5mWP)Aet+(jQY+Nddx#W7#Ay9NBlx-|sv;5pT%ayrZ36z-Ks0TdK z*ZiY6tkqY)b^0~h`jp3s`3{R+0>>o)Z?2%we3yvL*^;r!S3nD8E)sF;#B+t!1y3ju zGbI8!^Y-^&==lMuO3R)K9qCj)$Q1Ae>NweX$qn-QHW$z8R-AHfnZx~Ix#PNXoQ7T_fNJ=DjIZo1jH(7p%fZlPb zbyoRuOC6J+hS>0IzNAi(+e#1+j{!=>edgQ{RNW`Xody*mM5fV5s`jg+aeN8KSaqE)c5PzH^GtW zMKl|(jp9)2o>!?E^&?z}(Mj&dX`aaB$`2fS{Iz*)e|;R%mMrZWb$7RLv0}@ugI{L7 zU0KnP^5R(Ykh~cD{4~ah@#@j1PdYu{8%et3aSv{CDrK_AUh1|-H%wW=k1OGxuKj>G z6yOmIN*lEJiTBKzMx42}(*Q!=KNoWc}8QgH^=s!hOdrxP;) znA{ziLo5k&L-KIw&Z(2G1=)TQ=X94)T$K1YeARW-L;mg2cWJmPWv_`a#FlKKDkw9oIDgnJ{-cth!?S0=Zy zAABG0Q=W!x$YE2q8{G%;=(_c65fb?4Qzf1me$gLo_u^MfA7}Jnpo_uk?tZigB#td7 zs-*w881A3nc8EXTeVP{6~c0&(Gr@VxP}4=U?hP`m}2kX+nr{S-bKh!(YxX zkU#Y2a}Y&l{mzCTA;s=JAIuBz!WV?bjs=iuc5=DOXbqd;@d50Sy|9{^qWI|#-YPEEB@NE^*2?33NTw)q)!mTcXhXX&`AgVk$YHy z$o!(zh{u)P@{EwTmo-VG?}|S3$>*cNYZSfb_)LKJMYFyfnWJBaDTh+?)4o&G1`1+- z8)?y6pQ<1>kBc83KNzzQp3uV%Bci!_ZmPLuT0aqUYSv{J{hm(FqoX2As{IJwDacfK z=v>}8Qx~CNuoh6+Q>{onh3Uh%yON<*asJbqB3d4gH|w=#eXLkW%~b^cKr^$NEdu$X zw5u@nq1}{r#{>5Ty$;S#*@hhv>ad^3!6GWWgw_<48}l)-y3CH&hV`?B#kPUhXLdIP zv3M9ZO5&e6&e^q-I^(k29PP3lH;64-zahou)cdjjf|#AUJO)h7`4ijuQaE=0onr?W zT4QVTL+DJ!4aV>>jSBcb#PDw2!bs&G@1%CusRcdKzNJR;KGio`bQkOmm%TSRF9OA{ zg>d9p>%s7fGjsZtkG`+eg1fmu`(nWNChWSVZXQ|!4!*POZ&E%C)fvDZVnsAjeKUq_gCY5 z@tqol2Ls$|!g&uQ&|2$SWx8yBrF#5Eo#lk-vw##BR+!1eU)@jf%O8RvJr4<1S4&1b z1jBWSe`;A?aa!I*KUc}vQelxS+bNaXtQE*rQ581f_Wv1a)3VoXtFNFXxwuIfdpG6j zEKzibh#g3;{?$TqgOU8m)B|8}L~%hv*ku0_G_Op>rrFnX)ZsEbk98dV^UR&Hk9E)! z2%{7q^0b3<8i9y*#j7{dNSo*tb&oGeb3MfA!*Ub+Hyg~e%q-TQQkS7acV9rlzua?@ zO+!JE=tSXmPXdcp97yL&@Dd`om6n3;feFgSiHNd01W{t|UuP4Y+g|FvK0p)P`&gSw z#Xrg1>&)u0IR>-e^ziGnr`|$l+InDm`t)w)gG5YWOu%Is z+qP}nc5-6d_K9uVwr%Ugwr%r{lYYAA>%4u<{D=BbwfC;Iiqz&ks0y6N7ICXvgyy5k z-|c>X)W<5 zqYvb*yReTkvw#~>i)SgA_WwU=LD;5ZvdL4nZ22_k?sGK z82raWv-*#O=4xq1`~Sj4%hlC!*&0vvyE9lQ#gtWRG3V=^Fdwa~EFzmUCy|Ab-gwXv zYN95A0A|2R2>bQxce#)V#+$6@3v{h7j8P?P6%|GRb z0mkxodp{p;x_>_&a(%N9V)1)Byfgx%wzq1lIX#y;O6_R6fw(zn)7>*a%Vy8)j_C4o zO|Ia5GkG0sTbpKZ95CL8Qg=7ZS}i&2Mt(eY8CJF4bJFKH94z0PtZmiNR;qRMvs9)J z1mjz$IG%Opwl&ppKSt}{ zJ#!*1h9a|NZR*{*SOZVn9UjKR&Y$TCisg@-8o>FdAi?W}irZ_$hjdXWogF?(HiWd>b}$m4>}J1= z20QvLGZfr*-$H`P^C@Wmwhi&N?yRo3`D7EQ1h%ct%H7?M|(>;ep30c*IS}%d(68b{Yr=pqc#$y(lM|!&8T9 zSum39i*ciPqp3c&A zt&IOHzDoIDDw7J%cIP8CVFBCRxw>NpkUNO*W zFD*^(H(Ojx(|ENyMN80y_vTqtrZ60s-9)IsDw8ly1!F(?SQS(sH$`ODnaZxoo05~{ zuxK-WaO=RzR8(NVM13ikQ@0&jJOyunBBG%U8vW}Bs zJ2?)ZQU*9wne~ypn5l0c!oKRXZD4pv<#ToAIAGdjgQo>+*hs2d+^Zx%MQ)g_rw)ts zD8h2y=T!d)^E%V11#us%^DrqO~i z-W4(b>r-@B$RgG2ukhr^2|RzA9Osx^;)3!>Tfzo~X^d*#K_!VXOu7hF`04n##F`wj zrDJ+2w`&PP)yYi;1H}$DaDs=bhp^2%U=usZ|GmKLKm9>Fl%ImRTSE(R?;+2x!?Yoa zc(^1QVS3>1HuC9nYKf-p840q3@P~tuEt;!nzpsP{)J4aR@PwZngh4yxyU`RT^UOpC zy(X3{!UB~bYI5L8SzT$;gTlrWmFk*T&<3jOBw9#DOKOb?E9Uet+~UA96w|Z6xH9J4 zmsfrjBV)HAf)TU74z*P5u|*Pjd&a?Se|8f!!tj#pOXVMzO=a}_CHEZDR)~2+Uk(Hz zjbTMC8yk=gAD=S&Nn+F?nN)XiCu@=pVQqL@zsQ#ON$ySJ3 z!hpm|i|FE$Obm$8loL#U1i<-r$tzwfDm=>$OSvNbqZ*(jqKO5 z6EB}8N2!ORRyr&Q6^`fizgwu-76u4}Iy&(H>f7C?rWZ$+PuAwacWkd;M?d!5DB`P% z_b1a}e7wQfDZm!_cn^M_N^G7xvDC_h2_+1I$QRE>Hwtc+ zAheHlzy^{50S+`nN?`J9rhm@*Q>r z((FhrF$n;vP>l1r$ z9{Jsk9To6*!&!?LkeS(T0Yzq^bVuy-9bFJA^DaYmm6G_3FfpE_WEq|&&Z~;Q8{Kaf zvC1J}@hQpm?^0Ne#W|N&rTql>YDE-s{U{AI)S(9_hsH;wRoZ|V+Ob|{XqR?3!E_2Z z(ARp`(W3=2%6w?{>^{<7maFC%4*WJcBAYkB4PeZ5h8)GnFoP+~%R!^Hg90dP<-0)% zQsO&qaz??})q^RTaQ7!Gh98hm_dHTj5^WHS?kGV&9GyrN(xV#vOSo&Gbm$cHJAo8~F* zc;=ckMz8pris)`jx^q$qrgG-xholF=_Jt^)nJwa8T znBBvu2}+sYk6$YR*+id4Sk<8_J)(u(6LuCwSWiKrkD?HWDp4d_Ak}PTs9PyjDVPaY zeC}wYn1JyJ{5g0ja-JJlmy9(yV4%pa0v!tfAvC(qYcQ3g?G5ZGdKA*Wxx*vWH+X^R zGKyq`QG3?;RA(c7yZ828Outmrxci|_GxWnG0od}0oNCocDn5&7 zIz35v!{l8kM{^D|bP10ng7?Stg=+4lm#JnX? zqoW--+JK7EW*kWw6>Sh@-v}08Nj}fC!t@Wh`5ExUVGTMO49eqj5X;0x+R5R|8pG#}WP+hso@p;pk#i6pMx(Wd|q|?c|h&iEk zqyI5tKd2bP`Pp=zs<`aSH+qu(o+|qzjoZb}JJ^T2f~7v>Yq}DpezIFuQcAJ#ZGT_< z@@ss9BEMMziY(~I`$dq5D*G?ziiQY3-l9$m{3kAmspL?7CPcLN7~7XAwpi|vk|Ttw zfJ%1KBLvs{VEF+Ev8Svh_y=yOa6WpRs2=@`SzIu#CIry3PSlB5$$mKlBzDCNWVO6C z%pPzMiuK2s5peZAhGy-isT;z#gJ@y}Etc{$G82G+4o^(T-J^+a6P5Hf(03wAHw|u%Zcgos+(^U)nh}0dbJMhp6T#4MRtprO?#v$G*k)vBANN8|w1=yPQNZA+P z5eZ}W3FZ?|QRKPL(aYIzoATi`eqx{P_k`>>5Duffg_bcA{E#{+CH0^Z!W<(Z%c_nWe;+nBZaY=XubGh1k0|t3sZ)WMAV(SXQu2< z>LQ)5{+DB}LuscR@K(s1_{fPig~__;%45;E^8S1-RQVUwU_a6l^cHr%8=Vto!}b0? zUuCCbcYIM;+EGRGSnQDIMPvqt?@dmVdnLx@Yy=(3XT61ti)=pv!H`%oue1XY86;ovQ(e;v>1O#Tt0sQgv0_-6pWLgRIEOUT}mK z#sNEs;vTF%OYAdm7dUl54;ech6k+?^)kyo$H8zhl#zr*;`LyBq{T{w4 z5qT0z0-8<2w-dD9z734Fm(ox~QPN}AUYqLZ$+I-6@BJyXa^WaNYI*_M)+p16rx}xG z?)J~~?Xf`RKQfweyW*Nss(DMgVxpvEJa77WQqxS!u)zM1f=)p+-)hyG4D7F=Z9E@LBfmvt zc$d9(#cC73S?MnTrrS(@rE%;lxWfYrzvW|;Xp)aJ1gNhpc)4D0Po=JZvV4xv@_i65 zerF@IUHgpY0#x6rMG;o9__Cn+&AuhVBt{}WQ%6eH2+xDunrW>onr{@I#fRBKyUOtb zg|E`8+fMD(8~|b}4Rs|yqocYizSTTHt2PbBGw^k?OYLO%>c|NpBN)H^MBHu|74W4a zxKG>wl&0U#mZQ`Wx4NrS>j&dxXj>nohoO&)({rbrAH40C}dl7!owD=IjAnF^456QLkmZrg3o%V?xBt8+y2 zMXLFDo$HNpp)5P&DKv(PXX($;agPtZ%)a?QR9^hG=Nd4h{P6cey*_WM9k zNTPY@>hAh`CGy#(_H)8%x;~2fOXL1TVj{c3%!=!I3P5-W)Mmn6P6=h!u!Bx4BGy;d z;dDl?Y2~meM+$}_>)^ABN)G=}xz%jzt%A)W8yX6%;2Ac@@)N{aDh9ZZBd$HU>gNv> zl_8YS*Lfk6p?GESX<}Wz)^l=*UzYwmtc^G$B0mW4AO}flbHe;Ezq;K)0WHTvY^oYj ze|R7~QM^2%Sw_WmOz&Gfdo4NhdfPlYJk?zpwo9idSt}*1lM1s@2xPKQyjg2_WVNDT zGF^2p^W(hH+wF9kA$gUZgH5$#=f09PeOV$7y9;4xot$>#Dd#T3Kbn{K z5)HT7dOrI4Ke?4b!{;&-GCjY!R)isZ>t030Dww*zyD5$Yy+bzkSUW5GK9ZpvwzK3Q zxA;$idm3l7=4-~)4L$9+#(9=iB4o6B;O|hFAJ#7q)OUhP2m3*ib(TVJ&eqAQpb*HZ z`s=4E-vO?&8 zt-%vlg$&MOQlzj2B9~AuA=pu(NcA0?Zbbh1=DB&T;5i|1bYLWqB8CkA2GoihUd|zE4vZl2ejnl^Y`hweD?euF+Bt~lE-n9_;Tc% z6bfT&F8j5%U;}AWM6leVnp6|dAupuad^stTo+B8NZz@`b@mLR0=q8h1n+5ZRcZ|4?~%iO zz;H@a&cag?BM39Kt&L8ssOXYekw76f-9DT@#u!F5>(1=%%0`2)WL|St&#AuS_fC+E zD3>d{V4KfNyep%w<*9MxI8Wk=TQ?Farp={1SrW)YKs7ED#EPi8WMY}$qJiqjULbX2 zl3YI6zt-aw&1m2q4eG_%U_fY41wIYepkn7&m}#8CW@&#uG8>39!eMVj2!nwfrsRX7 zyyeW5eA(>1(z+)o!;n9MV9w0A3WqFSdJfs`7Sm2Nf&*#9&Ft#jJNVjlFTZ}_H#n`} zh>MxVMSyG^IX}8?)?Y8c8ud9tfuKXA>A$utJa{;xpXQxCg=PJ8NTK|NGQ~ z4-kaW@b$v9G%dAO`InMg2Q*uXZ(>2A>| zzB*WPHMJm=1UNn38?k(ujx8}!dYd><7AN|4w5}0`CnFXE^K)V^pk8RRv1ii-loPz2 zEeKi^e`fmP$qU3dOMByLCM3MImq5+i`v&fQiUv4wWyVUXfbs~$JA8!m;3^0M zGQU~!e0@B!#1AhVhd=89cSoPuf%vhWg$sg&l*QDu4h?`eR4RglsfX{EohA5q2m_^5)=}T?^)gIT1Tz+W6q?8Z;LGz@*1o4G8n7{+llS<$Ml+ zMno!>0GPY-cICwiiuQP*Y{}&d#HQ>mVY8m!&hEz73Ew$Bt|&+*&mGwu24}_)gqt+v zmz7bXYM&hFjGEPdnWy0d(Yq0YL9p<2csKw9E5vnF=Gvy7gS75W|^ zzM=apK>yM%pAY)s_@(~2sjng+Vx4tA5b8aTr>HA>ksK%CRY5|EOQzS2$P?82 zdh^(`<*oQD#du3lR${wu%F!an{L_cCu#~*O|Mu^ct*6f~YoO&E+6#19F5l4h$QvW7 z@TrMCo|1DgFJlhi&ei9gg?EnS?gs>GCB528l~7>16b*b8fWK#4eHBl`zty~14WDdo%I~z8Ig=|`yt7paJf$Mi6uW*Ji2h6517a@K z1&(u^JZ}C^%1agJ;4n1I2R>d)^&z3dyet&6CVR3NC5Hhb-P4iV))w&Cd)R4DmPzSr zNv%Iz-?={o#RLb=v@RIkaR4{azx%grEniA1p;K4WW8n(ng8X7 zMJI)I4^a_^qt*0`Cp|d{f@{j+lG2EAfBjb9qyDP^Ft9Q_(6}CuMdCAbeXhQqdbe>t ztDwAleGoBKoCHbk{xoH=*uW!%;dkfk%-#d=2Vh%#D3Dg&c7<+BAZBm7$+PO8^a#rO zIzhEC#-m$8)`JE-z!#Yrm@U*b&cdz7>!aB6^=paqZrnBA<)rnaf+~ z_}3=1zHdb97rv}&Z{}0$zT&LG)9PvuI{Vj&6r1!C$`F<~rbt1Pb4=t{=J^YrebJ)@ zY4!XBqoJK=UgU}8heUm^VPh`>=aX5-$Az7Duzzv{dIvK+ZQ8w|rRvMga1Xe4#dENK zKEyEEhq++y;o!*;^_rDUigtkV%Y<&+GQ5&DEa9i*@q{Hpnqh8qPX%eq$?Y`1!TAfNwnLseWuW~LNwdpDIq=oV=im8Z;U<~F0lQpsSoXfG zP?zJ}>HVuo#!)}vkreWBj@}+Is}J6+K%UjC!kRHV@%O!l#dIrA3fSSxFbCK-&>74! zN662i7;s&}A2Zq>p;_TkqOP8!;Hxzx?a>=Jxr!3yVaUGIZ4mcZqLFv zJ()ChGc>-Zm1{2eGCL^(a~@VN?2=`j{VyFDO`T&viX3ag-@QS^^Y|LgL!KkYg0<{p zuLi#=G5JS-%x9W}~~NXeEw_MPA~aU13otz1ytSRJd^nX;*&!^wB;@}`3shL2=Yq?b^b^-b7`T)!rN)Np{nsVkgI29YY@;WY zoSypMRaaLPZW0mqgJW1GCUuX2|F{GB~TdfE^E-t6ez8}k| zK1R21W*uiMe}B&aq7|HZN}Fq@ERFV$H1@wGUhku-$yC7i z_sskzG)1M5LGqfI2nnm|jIr==)S~}LdCIJ8!&_e_YUs0MnKROztNj{48`{oSJ41rH`*bprF_z@@4E zvxs^oYSvE6_95GP_$cyeT979*tL@ufk$3irr81(^&;L&Ec9LxAI}^8`k3#Bc^F&t5 zRz4_gJ|Caa+(0u18d|mAOI)uJLwLLqL$GJL9t?My1TzPQ-iK`+oiVqS;EOuT;sCj>$_s$JZJ%j|id5GulVK*`XN$ zqyQ0tyGgFTqSOr^k9Qk0g;3~2OQJYO=cY_J2yr;{sS6hw{odwGA;!p2R4v9VpzDGi z%%?pfnrb%G>dl?001R7c6PfW(WA2Zq)o0A6i6}ZGcW@md9wc*k6R9>UaFPH79s}IA z0@4p7qNYu>xt@S1yqV705EPO_S%!Z3UfbwW=dlre&BXPOP7k#edy970ihqw5-aj88 z7EMr=FmXf;uw;4t2gv`T)@vB+!RJ|49UEE?e&2ZJacF zNXT8-)X7>tN+E0cZY+AdkS_sCnPY~8$}}b*0Z~Fljix!Ccy}uk4nd68OMFq-j!Yuu z!$oo@rzK@(+-(ekJa*Qg9JR{QIAI6(jW0#AZzRQ!M)W{t8fDiuDCB6#7{*`sA6CRg zgzn)ybnL0MOx9KYBNQwz(aNw;c%JX1vnEdIkU0O(a?*D4l*21JUq+WUBLdOrmr(Ns zO9zrR4hY7gUhYZM3+x3ERby}V7G19ekX-*1kOHHGJcOyl&HxfZk^GM5y&qDx@CAtR zi|Db&o|E5@K+*?->=>YO2wh74 zxk-^`Xd)=29RZS%Py_yP;+6>LG(aX7lA-iOtB|4GrUnFLBGgI zSVFDf7*>7bS>$an)V9J~Kt(N75p>*Y6?U-k2n}_Tn8PMY$%TT$@=x%NOWl=F780t7 zURYVbuN36$l;|YIz-9N5KA<6}8^j834}`M=^|% z691J!O!^ktAdiQtcg)SytZ7h5O<`DYQB*B?@U2`a(*|3~|Fo2sPpShYn0PD$JzzCt z@&g{qU|J9+J4Ih2F=P2cTcwR2OnnY!4ktBihjCqcmmhJqE6@Fipqt?j(3N1w~hF@_W}F$34J%kwHdPL`5=HlMW?03(ule=m5#xI_>eZpv;o&s zHThD=JQGJjLUKjOBdk&t2iZ{g7EOBYNP1fh4tiEFS8_Sv?dMqfwMpPaJjfk#lP3v{ z5W+Fb%wF=51)!&pxb>Y_gbJe|GF&1f*?nKVfrFx!)DKj={L|+~sb%BWzdRddr(rf2^~ zK=Y~p6m80sAWd}{)*J03iEjX_ofw%=Fs+?T;6?Bjz6Ak6$X8vE@vP<2x@X#)O(S(| zdNyu@y1S~{t|zyMCiN6|!)Y-jZ4D0to`rairMgucuuzKjC*WLpjPy0UAAh!h^Girs zQzK@4ik4&_Ily1O<+C{b*Y9%^?=otOV|vt^cYVIm9B*w$m%~~ahM25BW_6l?(E|R( z3Pcyvws{os?mk5JsZs#^7qsWwtEbIq3Yn9*aZv+UZLX$v!dZ(40p}uNj!HoQHMQMBxTTHZV1_};erL#J zbf8u(*=A8H_{>b1a)hPbWLpb8XM>SWR_^E68LTAdGuZ@$Vo(2w65nwsZ$x4|{0`ZK3-*#=j}t;I z1ft~}iT`q+sAFMT&_5eIzSW$O*L(nu@NBz!>OIE>ae4!5W5c{W?k*eA^KzO4No-O% zQGcs%g_(2ObqXE)4y)C{H8o9(oi7&Se`G_&_7~JbKI*0xyz{4~@+~2`iUvw9sF3P5 zCFI*MNW;|~XWeu*{tTUpVMAI?g4Sz1+f<#!wFekfUMdk~qDes$Q<8?1%XDHJgC;;K zB>zzxAHgXO*D6uLat|lHJxSL1KgvJ)B_rP4!nHy$vq(pS(J>O4=%UL=l@mE1T{@P7{l6cGi% zjX`lW-0QrjGMU;)32}Xu+^SpiMDh!DqC&;YzE*>rt-=d@)~k)*%v8yZpz6)X`(&!ya2 zHUmu!Yg#BXX_&k#*4MPhas1O5-4{ReMHtz{qE|4FUQ3ga6m6a|8=9WFd_AJdV@AtP z%h_R#x9aEoU?rSRVY{-Wkyw*nTdlp9R`Eatyh}U191}Uq-IPAcKA^iBJY)ROUD1=` z>t7a?->6an=rEQBIS?Y2ENBcmRyljYz@qOSehXWlv zGI_yEF1F`BfeDH>*zzZ$>Evu8Vk(l<_|e6#QrnoH+=DtW&uIxoJqgfaGzTr@7HTjU zpsex%U^yy05REFbGWTTG<^e8%UF$fXul}k3@||`&?!5$ zQg5A`NdIa3ooH!V8p_} zdKyq_X>SrK!`EXiI*J$Gshm8e3Gd*H*AO4kJ@*KcKfZ=hykJ-R?ESu}A!Tb$iuGZ! zcvhhJ%^=fNx2gda7%ei#?rRZgkK?chp|zVnJv?of;-L z04;-S-P3E$P-;{zj--hkqa}@pg%p?(%bVN?`~inP7WA%-{sPlTPp)cb!>K623>ReD zK_qj)E-S59W936+4^pg77upwMWkSXQl%<}{w^YA+^zQf23u5+-3|t6EBU|N^0CQ1K z6I$Lb7Qc!k=$jYJ78t=!Hb4tH>Z+XDrP{}0!Ci0!6w4ds14F`bs`1T-2Ui#%rZ`h- z;ZJw1F;{R4sV{R4HFO#~V#2(z#b`ma$Ue1n30UwwtS(a9`K0Nm9}=x7$?40SPQU7o z{F!DpA48`I=}+?TczpZ|=QN*3Nu?LDM3^umDmv!{&+u;Ln=|>j&+?KOIV~LYupK_e z2$To=#oeeVzG_?gCTCu-4+5-A^6&#D+1_TR|8Y-QqyXX{`7{1S`0~%++6iBa*}bL6 zP!EwnLr(#K<9vUfbOO9+_8Q9&#V0aEzt*WVsHafz2W&3WbR5l(mrb&6uf>jTAp^5g za24A6FxOQ>SU;#y_BN0Fn>f;gD2yra@1MN}I*ZVVGla}KD87L<8DU?>?8jv9#iF#f zgV0tDV*+sdV{e0z`ML#No$-|Dpo=@Cp8MS|rWA;@MLDe8^mbq?EuJzEKTu)XC34a# zhf^0yvn(^TkmT~!t|T#JJOQ_4O__`?V!c*7hLv%OlP?J2lvUg}1^6^xhY9lGE>~lx zql6stRt+|!_9fsae?M;PTUtM3(c2ofok`C507G-avYyWU?RHn&_qY)b@`=P`Zv0bK z0DJP&sB?=8-MW@#It&kLa3M_KR}odIbUZF=8x_&%E&BUg>3%53?Aj02QSQc6!`q)z^Ko581W_oS3s-XyMIH{DAoIeoY>hnjm*|9he*;}qDLc#( zT;d%4&B}?!Jc}mR@Z&U!d@ypR?_-+(O7O@iTlyznm_-z{eCv9wJxNI_;`2zUw>YCa z$20QI&MWPE^XZqp2H=|yk{iV_limP0&NRd2n5h4(Npi9B=lLO=8W&{9m~5JeeQfro zy&5~0TJWmfk99*UOr zxw4|zLCj)jIZEESeG=6L?*7Y|%iwr$Xj2gEEJM?uBg!Q|UOKU6)@aBkC4$8tuVbrA z#-2L7HRA%CkGKPulb#Zw>e`NZWW=nfwigmPqq`2`D)^VBA3MFMB~_4C(yH+$is-7& zA*~eP9Ls9wa!Hj2=D4c%mB4417!203qmj7Wm9Iq_jDiB8A3LDt5j~H4zz*JKTQxt| z2Y_B;bt-RGCxC=VHV(6774dsJQ*PCvZ;kA{`hF!V6?X#3L>TPn1#dB@hX&5PKLt)o zw)+!kznv^4OrLft>BISeQOd_SSeWvfTZ$m!l{f#q>nEY=7KC~4Q;L;<7yU>n$jBcL z-5lPA1yHb6;wJ4l6UJ=8^aQ_K*fqP)7glTH%k_Msrnx&tfTYS2)Ou3Lp8BYiL>8o;(({MNB7W1g zG*rD<~5SG=g7jAwJW= zHg(K~G=*$~TFau4BA#zGzroa;F&YE`Ah&FFT75^?(?Q+X_zh%bAr=?a_xn(=2prou;CV*_O!twarz+jpJXHK$>-!doTYL-P37Xp* zM(>~OiMi0yI(g)qX7!ZC2BZfeV)TA-9x|&1n$||7_Ti%TjN2<49c@)Jl`MOlN><3y z3W?|BYd@PZx#G9X=zLB3brDWrt5Tk?Z+$gOr81t%78J5Isbbm?-_)`^ zBSOqDkY7#j(^FRdM1EUkh-A`>cH(+a`djd~BfsQuC(V(F<=J4@Eze#64xj3RMzu>5 zqh%r(dyr)|vB>=#e>zQFJA08MS;N-OdKLtnJo?el%`^-pc96M_UNDbEQ(6kn<($6( z&9&T1T3i+F@6btKT(fsNkZck6`rh18g$^8@d(lErn!?c*^&ijkG1GnK5LXZ@&*UJ( zmT@n&Ni~})?XJJF27~5X_~G2SIA;qe0XWU|W|T}*6L6ub4+hh6<85Bqh;rO%)k=#y z;CYltN9bEf3TjmdmM&vWM-fiss=CnzB~)7@s0Jucd(9xscOI7|Gv`j9s=I$eshk$= z#(6Mi+G3p>S0qn8oCjGapKosS6lew?w%`PpLQb)Nw#Kx<-%60ow;?;>;$DDQEwi9Q~ zg@PKN|4m$+%x+m?hXWWGM9!COKFap2UX9~1O&MrQ7`PJ_pA#9-gOt@=dJq=AwMpbI zGAatDK0V!e(FTs zsY!$;8O{-xpZQQ6@2#FhxOUxR+l@xFi>JOcv&waRQUcEQHm93R5rdl(oc-33_Sgk$ z$ieSp(N?S9e^Of(hRED zDB(-?)F?&g@O@}1ng20+E8EG70oe_)Qf$6DCcqnD5U2@a8VIizYVpG+RP4Imo0p_A8Yx&`hunSC|LI*pOZ<~k2o8AU+!bdSc@f4z+f8J z4mszsO1b7n4B)-BY2lATzSA#R^tgGRAo|qSfGnMG3}k-zP=Ca4kmpgnN>GJ&P`1RK zI`Hd)mwW0x_R}QhiG0@2f9iDC%5w$BOp+mz7Zoa-`x*a;Y^w)UzsU0Skgg#A=FADY zm`GD09A^`tdc$LV1dLq~hNab~IU-Sf4>PW)_BWXY#(cO7D~76m&?;n0wqM#XY=qm4 zzs2?hEczc2E1$TRGe=ffyKEL9+@3)FhP9atE!OhM1yDj}p-_~DyFA|3Ro&TIM*l&r zTn#YG>1aBDMH5|Gq45nAx1Lx%SjY^mpNizDDvzg$^RnZv`v9uz@#8O{k~Ct<>hDPE zzvtADUbOzyY1U=UNREd8!x-BmW4P!OdO!9qOv|tT5a|W{hS&0hkH`%5Q3PD+a8wl? z7+I2J^KV)<4K`x2b53IJRR-OFfplnCp22?@#{6rDR2%WfXL5vbVF??fz4x+>*Z@R# zJYM)6>*~4v29`03+C=DtQ9v3VyTX3Uw4_a8^SHD&8*f^Bt3W3iKg+q}8Kpy-q8_84 z(6>x2C0G0QE@&w#9@D4b`yd>Au`c#knyKK&)dbJF-ISYYRUlr0NM^NkQzqT)%r@TAuq4 z%C81ZiIKJTmS8|cXlEvAeg5YY@B3`jY+O!i6jYJ%xF|!xOX*#Ap&7aV9$ilgGniAc zX|<%=-IhgVb()+i^A&}^j5|Q`_dpJ-<1cICnWQwEUR4f`Fex~WZdK|J!{1sYr!7UQ#}x4m~)+t3{$;{Pt}Lt{{?oz6oVynCwx z`G9TXbKNa053>+XzHnw;a#87P0(5RTX!t`K9kktJz8@r(pjE6BwX9teSBJ8zHU#gb zNtMe_oS~=u(Gs&aIq>kyIsf`+3@oDvc<#0Z_+WWM*@4Q$vY)m3_&;jDp9Z{DdMAH}E} ze(i}@C#Fs<$zTa50qd|KHSj?^VYWP1L+nH%S9fmpCN50ca(uiK(n z`mPP->#){(5Co`QiT2~S@PG_e9|DfmDInB_u7z^_4Nb4WDl=@Y(&uJSu*PiOADri; ztN&yyT59pF7o<0HMmFTNxr8(OIFYswu5(MZzs;AzC&_gg-VUE~*B7ysz8RvY8v2yR zOQFj5y68%F!&pME;Lvdf8%}g|&h#A4BABBinJt%7tXaZn_^%&Yd{g5D7;C=8yI~S$=KFnf|0lllqEdCf?#4i4vg4Q! z0kdzNZ~tN}L2%s0{0V-KjC?)~@5YwmlfxmiZgwnqyZXx~B=77k-_DojV}6~u`}`a7 z1!5d-@XdeOh@H(5Nn`T2Hx-vAhK~XKbKx4?Wy!CE1lQr++0_pz`L}OB_SSEr-hx>I za-*!?g1w(^&MP}h8Ny9aAl*5}y8_l|8$3?i3QGE#qe^2Q$BjnMnY>)4-+hzwa5AG{s? zNAAF=bG$~q&-Yv8|GZJJGiu?~hRf^vvGrr=h{*;Qu2y99tlnQ-97A^-pseSoqq}j8 zk@`ODxQhO{x-5icN1qF(*6)KU7ii7fJ5irsP7%YTfw;dg$R0iabm-WA?&4eWNrM8o zCGMox2jo7M-&}s#3jbY%ARzb;Gg7`Ge(*;UA>%N5VK z`pAA6yW!~R3n)mpGJzN%u{TR9w@uXI!GHy%db0Gwe1HjLUo9M;I$fI4IVPz0kzyFj zq_qNs%>S+-mOvgw15X9y>Sk{ooj~&Q%i$1iL-IuZHNoNN`fwY{qP$9An5LLS{XjNn znjBLZjdPzeAoScS|5Tob>><@zM-FdDD)%+)5EA@?8}^Z1KOe<}ZGB2bZGEiE-F~+6 zrvCcp<%_H>+kI(rl38EHk*l%I=WN0?KIh_GKaJ52cqUG4x#fn68_V&JH^@7_>0`cP zbdyE+Ll7k~1oaS7VE>k+{~wmP75i8j(s_kO@wjwxu(D`TgJ8G&{%$J_*VHc&n4nyy zC2U)y-LbU#$+e+}S1O@EMm=IIfOKe0M=;~77OkKI^N-EJ_We|*&j*8-_sV^-us6Mt zO3XpGX_q3$y((XLpDQgqtlK${(<$A43hS-(>bjeTW5MWO!jhKO1xn@CuCVN3AqtvV z|9^##uTHNrrv@tx+%$SDFF7O5X3+nOv2$n^ENGMPwQbwBZQJN;+qP}nwr$(CjlSme z7ZWjySxii=PSg*m^CB~!D3Zlmn!BHePu#wHot-}F!@Bdx_Yk#xN&s<;m~W!1%fID> zA~)mPTlRO=#Fl}xeQVIC2MagILP$Mrn|-7dJ(`)x)m#d%qTR1*1w8Tywd=5YZT)Ia z^}*+}U3R)UI6&VA4sye+s<7DX?H>pDT2J)~w`r1g=tT7Jtolg2+wRzzug{|ZWkv6< z9_}u}cAKw?z%~ac=JmAZ=^gjSdG^mI?Mc)qUrOYMgHoITRftpX523ksymN20ic=eH zlhD}|YZlbO-WkQCPQJf6^nv-T zJu@fGb}QK-aNF%sb8UYHC4A@EnUI%9+%PNZbkaxI6?`p>-gK^`PVj7e2h}vn-uY-q z?$+Bt>M@q<+)`dtrS)XPUWx-TngLC+fr4zf-MH`n?^hBe5F?B71f_ zfb=y0K12Lj`J(?%C?uZ-ky75*n=&db`Ol+M@oal}0Y@JPPo#|yIRj6hD`*Mc&-EFgdm0$h` z3ij`;j8`v)(0Ff;Fr=h;Qaq4NsZY)jV=DmZs3R@5klCr3U-A zEzypww45(row`=uZDlb&OmV;OtuH_T@yIondhK> zZYmV9B1K=7NvA$_3OqbKv|I!MgK^p>U>gWd%=vy2jg5RgVK$x_)pl$Jb_Ok@xYO{G zTsbE|A1J8xw{#7kC3F@J*q~a6cw*3VZ6SvlKxc1B-ODV%SLK+w?|Ek2M)^OY<{OWo zh0j`m_UWGz-j~^@G)pIRO)})-AAC2tr%-TB<<#XA+sj%_Euwj!fP7>vy0%M$ySq4l z*t>zFE4%=)>+P214A>1_=ku!kOgdfjxL!i$%B{GMSm?jvXIJo=Y>#P?{<12R3z`!k_=!*qrUU$6g%$}SLiLD>H9VI$Eyv;FE zp@5wxnRLCwodrO6FAaf5!9z_%2~qat>?NL)-aP`J{t&o!cYRr}fRn1>zy`|QHM#GL zT^t>Z%*>uQHGCdyKknZ8UHf8#aCfcX2QQoj>F(ak)b#H+& zy+#2Cz$&Q{(G_3EGJ+k5X!1PfC)@1T3j{Y%eb}a7Iqo=@flg@0axgkU6`F2~Dii$> zI+~IKEvxg(>a+Z19c~A3GB0iDZe@l1-msMXXt)*iVhnrRL4&Zt|2nfr734}nqCxos z>ML{7w@v<1qRif(jD~lx;h*5|8i60z^@Y#WAZ(=IzZ2xDcd+35N=I1t-yn!*2-VhoAki6EXh|FtQZ&L`g%7{RaP9!(#*YxvSV= znwDC5T&^UuoCKvvem=fAdeRCt1;EuS_XX1@=mcbaN}-jmi-WqaCY zVh#{lO^0$$SKmja8mdr&z%vZjSmu{LY2rte62PCTce)B7SUEXQsm52Z=L0k_Jk~Cd z8h%c{p?uGzFfV`QO!#uGcr8{zBTbPTtOY0h9E_*=gTP*D$0aiY5T$Mh=7v@!h_gqH z_}OKKjOZFdH)&j^W;e`HwAb7lk#s}?0XHuWdn0CgSwrTCJ1-#MT)9bq@L*_y)iQcJIKY;UfxYfdvH)*u< zN*S1e<%b&o53e2`P}+)_QfUgkSW9?AcprVOEpH$)dS@^d_khBBc9 z!rzApOX5FlxzUEYL!v_(tm5=O-=*6LJVSb(aP&9p2WaIBW~?zlfY~+-J3@OE5lk4V zsrZBXZ7I8PP7Hbskif0y5KaUN+y>}s)Q8|fX!o#@op0qhFbZmK{k%(t0~l1{eE5Pn zd?r1<2>ir6afWFf^arb}FTQIi0Ux2GbTIB4;-CrKmzn!mHmBBkUNgNGQ*Pmi|LB$1 z98Z;KszB+v$S>*CDH2kO;#{CLC69-jRPezPGEa_bv;t$TSqQ+IiK2*n<)&1zl>Ukn zU3~4Je4#E)piBcm_I5LbSCnX!p`(|)WED$Bx_csBcr7w2O~bJruSlf(A8h-eO{Bi5 z*1&gz>_zMZ`fn4?Cs64^!F%TfNYD$SYZm(mY2adOX9zb3>|w8-%WUb;@}c@{H|f0u zc;<4zDGSG02_Kzp;>UJRi7?(d#7y>08}SU-gInUKm`n-ippm91CqGOK8CD{kEjrO^ zC_X?)!ekf_Jh9?2bnZ8f5XZBb07)R(1i>8CZb}R$eW2$Ymy}|HoU>-+gUmbadAZCl zAL-h}6YN8mON0zV5WE*)LN`qi+o6${6ZGQ}m)L->#w^*+j2?LkhMf6@3q{ff$moER z{#+wZwKU17rd$AM`7nj$+?C9GdMdP4TNSB_sOgr>CCc!cGXhbVz*`*Y7F8oV1v~ms ze??LBPfXs-6okAO^1?q%rUSDv!EhBy;=trggcT41Yy#b);w1MP!7`SKDUB0lCZcg1 z?!|CJ2f5As_^<2Cv+~P#i@rBbRh;uOs0p;0}=I$C-3d+Olnc*PoSc z=>GBM^&!WxZ9iV55RT8A0#V{4J&WvYED_q)<28Q-0v|QWVax%O6Q}{k`+Op;AV&0N z0^DG%_vD_PW_82Oly*>r&S)~4CYEJq4k!oAx4)a{d24<;}`o*!^ zA8F!S^xUy1(lzC! zWTp!L=nqRPcEHy_FLSJ)WvGP&{s3PIA@k)twK3a3YQTx2zJRJZc>Q5DiU5>b6s7xweP8Y}3&tX`D1|HmrMgAz`oCY*Xq~K@CiBDWoe!QaBE*UaR^kvJVX#dW zAu2Y68W_Q*=7s)7x&9UVF703yazP40BU|7G8kok9>LGxhMYYl+Ig^A@Y%=r+mX=EOsxmr`!L$ zE3$s}w8gdIR(5+~yk(i<-IQRB^t;&9H`!>TQUje#i0YMhc8q<)sZkqqUQqNxtg{7; zyCv=J@EArKqgBRndh^d3aIrtjL3h?IY^mn+$|q0}ugYkKN<^#DjRIQ*WhM%41uF0tx3)@) zX(f_s%^a;l^$XvQ8>N{mZAg4v_s|o zgO(@ukcKdNp7hr9dAVJP)0g}Z&!!SXIZ8ViC+Sa078Qs|8|*Ae{MPV2Yx}m(%c{%S z%b-`F9SrUYyri_P3OQx^25wbWT(V4DJh{VZCcX&`)jB?88D))UdA)%#|5=q^IG;8ouRgOK){#R^m!9t4w z@=-^DXCS)!9a7f*O2n@;=Shu~#66#!)6$5Y!{Jwo+Vp8dJu4@T5TAffL;jH<2VM2R ziu4_dbqNbl1=vz2hjnOY<*j&2hXc1fl@@$yYC|a7bW0|CL|w=QTbIg$khXs>9K##{ zwU&pzVyaFlLluQj5Ji&up?q-AI55LewEjpd{^Q>zWDsQk?M>7U6=5-!lQcGC<&x#s z&+iNwD9EvLz%S1t!*a-@0<1ikSXEMr?I#4byb!}&+}zM3s@+)`kEceE7V}`OO)Btm zO|^HnV^!fY8pDwdeZziFHy=S&$+#iFlGxnIIP=`)3_HT$Hd-x?loKEn$^z8oJ=T z#0}CX9_|6=dLow?mrYC$X7X8TQ8_2gI&c^A39?>I3& zDL3CY>>&X_ZeqAUL}dlaR6M<7I9%@JqrHSLCNo#Ue;uSB^0mu|m5&fTOSruxld;Hw zL@p~%d(T{8^DM~0@)~K`p1~xFq@MdQ1VhwWw}6f{2bUmUsgzxiogujzex9~B@=l?qgE~cei?#rgSZ)ubIuFfFK=2BF9CI!r zQP&C0a++kyVyG#7LhHztY4Sk@F-LVMnn9L2a#C(Nd+Bnr(m zFR3n94fx2uHH-_;4sAGh_ig~HtKl7GjBxief&+uI7R-e$i-8o)N2CLV5t9`-xP$Rf zap*}M)MRL3=HNL@Wxr|KydA!%BW50oh6MJl;}S&~@^}nTMAbm6}(p;;jODVJHD{6e=nm zEVc`0i%aAA=0F`TU-0etHrVBC?iKise3P}mjxXh1folKfd${CZW zT*Plk_A~Xs9A*Lll)q*u^g+B?&z8k;tdwSB2<} zK4i7p|EhQK^21mOwqhd9p9O--R4j%$+yiu3UFsAi8gcv7isqY|#ZIelOc0n3RKU{oa*O{9G8FLjnRi! z@$1A>@^(x*%_OPZU14CD)k#GYjhTRJrm_rV)dAJ{&Y;vCBpC7sh0KXwTvi3F ziCvhhK!=bM3XC=+9&ONY5atENJdYI+rrU(hdRULFhoM?a3Y!_)GVZgnxzXpoWKeO1 zpUxlPiy#FSF!(<wM#bY8r$tOv5MN(j_x|wo9}~Mg66}(pwh>D7`c`kiG;<^oeESQiEDx`MhX{*A77C1^hQew?IJiY zAH>3@v)#@5kw3;76X3^>Wo>>DXV2-c@pP-83TDAwbr6)Fs|6*=VSo@Y-cC{@3fjcd zCu$=Sa>Wr1O2!J=nwK0GJF%5eaOwY|Qe2NG0o7mlAJH;2-W?O+&cyhM=)Sih?u|(- zO2qS*z=W2{=f<9>^R&ioDWvner(}^x#f|rD>!e(#HsR^=IhOAveO}%thf)$uiw`g@ zIgEk;AK9K4mk%LGhzg9<^mmYF&eioeLt-o_0F!-R;BDvWRf`qP8{frk#! zj_N=-z{|Hd$=KV56OJ5)6wEp7vu5ik2AwtsfZ@IfNtA^UIhgNgAXI6!9LCU3A`d>U zBskzT`o?{Dk1fEsYxv-=IC_>(KE-4sBm)LTuZDi(yQ_ zj0Z861mg=|6zE~$F8~opL{zsGTVXkaegGo8Ye}lFbQNi!=fzuFht-OKZ(Hpg_8Np; zYty;fPcHT(^X)|G#(7i#wSmXw=}F9QS{pu6emhag5YDCHpRJ+KEK&(?s(m=RC9}XT z_sNng<;~E91-TRO&4=3-*XSS_H)#%N?vbDmAq-;X`VWt#$*{QgAyp;)Cfhc9H9NMu z28IAfxH^||Z67$J)#wlL**w+KKPSmtGPi>{ScoKaDR~p9Q@mIzE2TZ`N15MJ7w2mp zq3A68J1g@j&DVR_o7(eA>>eIwsJAgIHK=`D0}o}E9S>IY9I5arA3J4YH;99|=Me+BX2Ap`aPh6l)Zqzg=A*)3V2RKqM>sFVI~fatAsK3Wp>-=^B4z?i z8pWr(M>vxrF8fndGN6&fBleFOBjE6rBomQ%G0@OXK1y)9BkYTa7QmIGxWpb{JI!vv zdLt_y5uvwTBgHgxi;|(7LpQ%bVydVtR_V1~PsCD|GmmQ(e>J%4a+7pAAm=({9rdhq zSNNMDmd%sxwDTms1C#Ce6Wm(1{>mzSf7dG7uu1kbD0X#p)v6xo-n2S?A9TBVN$v`C zZE;alVU^PWY*r#)GXSYpu_3O@wkUQ4jy+~=y3{;dI2{$Pc8aE>KZ8*wbvYKPR(ZG6 zv5)VBjq3JjhTP5pUfbNf6ax1AOZRN6;R&!kAg%BXCSUBP($h22!#;uc_XS2IX+o}$ z+*JW=dCa=1yo4^V)Je1YCobvsR_?8yRCDoPT<^Dp;&t>>9Z_G`!~9XzYWbjDRIJ!* z#ky~YG-lJ1T>8{%>Xe*}(L&~QTqxhOwk6;%5Y+_=aBWis1@(|E6#-Jce;01b1RyzE zd1UPedf&D!rlzhKZM%};D;uONSu0NRMZ%Z$`BO;A{q<+t)j_6CUf5VTTR<8KGgC)B z8A}tv=Yq+gQ$^$BN@Y!XgM8$217w|K4AiM^YQXQQh#QOR(qiX|{WMpQdca8(veGvpDqrZol>`q`8aupduJDHr{@JI8z?&-21qX*jahYql zh&S~Dg9(b4$ddC6qbC0>{fM}bu28uL&&WL!q#Hr<6@z8t5h$>2rxXj+y{N(t)eU+^Uem6my!6<*h%ZNS2uCN;H}IVFa)_)T$}KU&-6N+v ziT=XdXCp_oP|MMXM2zi3K-Akjw*V^RPntYa<*DW$2ZJN3PGx~x+00Ua_}hb6Z9FJ5 z9JABo41=1~MooAk)qM!ol+wYN(nnQXy$QJqTnw-2a{+=}fQhpcAMnjBs7K|(EN$r( zPV7(mQ>)@%W3@~r6FeAX4X#iJB9a!uTj3Nx9-|t53FNY}XU+t(uaGPZeQp-o@LqYz zTj31~T(nm>H;1<6hkwwUldM(Z=Lb7Xi>^P^V4kkYjfqpA@~fxJKED?!9;)QHStPJW zeU)ncEf^ki1f}4=`2Sfzm%pVz5a9s;5IFx|3uylT{{q_1)56-?;D0j)7#UmsWo~S7 zB>vRu4J@s!XsAY_Y)O($xa*|IGBtHfY0EOPv$nCifF{I`z=~QzF2GAIXKq$oD zT<_S}$XZ8$%*Xh8e1P7M^mTvSKmNVL*E93`{<^h!d06Y~_W8?{#iv2%$L-gl)BEuy z)$88u?w;vmt7GV@+&QJ0$Mr)k@1^K7ok8nX~p zNL`wi1nr%yTG{*IP-*oeP<7~-sOxN^elg`XlV_q@ac$IBImzRtecH*!)wNnvu+g|Q zaxtQmn{Av#GeuX~_>*X()$`-fxqVrvGPRw4qUY=LdwFvuKXp^?uP5$gGKeeLjYeo*+iDNE06eKG8TjJOG_C7KM z+9&)=(|9pu+O=Zyr;_S(<(#rlLC2QW#zif;)M`pK?zORWCeyZPD=RUzMOAO|gQ{q+ zDGe5}6#AoWKBH63q(m)cwv$Zx$!7y?L#}1VH$exAUL;j5=_1qBPkyL^ zZc4j`%ceeeyGNvN(OU!7Z)!@{>@KrVC#?gimgJ0o=*#TkEB5Sx%l+Q8i^__hkMCnX zRsBhE4m9_%yfqU+`mY7Wd(Bi#R(~Z4yMYEvJ zW#zh+M3um4YYm~c1pzMeiNOavt8JCmU7=jA1pNmC+Ali9Z^dIz5bzLHOiJiVkyXAO zHDyq3ZKJHz&S@sD*vunPGk2cGF8`t#zAhMH2hWyiqv)}d#?v$MyzxUB?ae@UQ7D z^S-V0n`w6z`-7%yBN>4tRhZY1aDfG_;=1(up2J7FYNqzyy+%_^Gh>|O!qrM7UHXW| z+A~4EVZ2PEn1|Jrp+}F!10Io!$v?fd%zE26Ubtet+{#Q;vV{#ddL0!~hu!Vex~eyI z%Qq|G*T4A|%SZ~#RBn2KhSQj+dfxR!ja!!Xru9)@KlMUA^d)vwe?PhovxOufhBwmM(AG4N2j$XGt>8m9ky;EJzUZ%=Lw z>s8AJ@Od5^M@PsYlixlDwfMjU<}lOy;=^igMk2MD$ysTIRpd7-;;KNCL8ywzdx?fP zle>PF9g`S2T0?Hs@fXDgMt8}1M=PgF2P(KbLMyZ(HWQ-KaPLkB7^d@iR+9Ua(f24J)Tr9oq%y)D z7zrW`x3^3N5aR5%wgMFi(YWP^db402DKnuVm-X?=zT9jnN=b z%b*}4im+t2B`&CFV<{BZ*00ks#8M7X5FCjiSLjJ#SSFakuNci;Vq6ZKx-}1Eg|ay% z_{65fDE!H(0hu4yYHQ{l4KJ=>+e=<+MzBVif&)aN4No&Jvw@&NR*y)z<;6Bd`3UHi z{v5J)G4+2s4h{8({u?!Bx;A_XJ3oxLV3_O&mHz9sB;SPW3CiEHv?1XkRxfFi(p!j6 z>%FLlNP#I4<1VS_y#O|^aFYYa7zAE+89&CuhQu?{X$F60xP!<;m?M4B+ z;SF?jFX=mRo(7uLlxKdg|4h1_5l`P(C)ysu0&~5O7Dbc1(XL0;T0oOlQj+1oEPF!kSpSiP8DD0Qb=~Jo{$vgx$f)Fyf-dU6o0uy&}B}g%-C87Ec4W|gc_!CJjNmW5E=iNTh z=Zwb}5XnAF?|~E2(l5+VRN5SAMuIO?ZovAm+NM4;Xt??aFvSj!RaQ@B=Xa1x6>GNC zw}2n1B-072YjGm!Y{33c?2Qq~)sP=s4(cJ*Ia;#bk@5phaOG&aWwc>9SGzT0?~{fa zxqM*!q$g1TL-TvcZsp4qjjJrA+We;1{GugR&$-h_0`COgpoMEnA^tfho3(WThsDqb zl=l8#GA@Gzd8CFZ8IZ7))Y{}Wq39Mc}Ck44D#^-jdKBSoi>tA zpaha_|Fvx7hj{Zh!o#MPL6!pue8jYK(2syaj2Vllj(Qt#R_X!PZu*yo0B|EK8?-I z2<|%603h>@r2CCfXT`W@HZvHRR_I~Y5C7w`d>Q1ya5|gQ&r5XK`2+b*$8sir?6&nX}%0cQyiwa zuZ?}U!)4G0CQ@bb?@e}dZ~gJ^CT>Fc0ykarrs_J`YQs}vsx!h3KmJS;H>_F(77}{m zi-44cY~bFy#}GPBxYF6Ow6m!8$fp4Bv6M)w5@K=R*zijn#FeO>TBv+cgb2_9m2QcM z;((ChyLxQv!8o6t#Fgn2;3BRO66`V{B#%x4$+H#G3d(4ycCsLZgi*MnDS~H&_nMkb z;x1-)HK7NW7Je|99j=B)FA_HI58Y7iUhi2u9>H&IU82oENMQ6f-VNNW>HLdF(>DI} zV3RBaw=VeJI46z3Y%n5pCXR(zkXjDX@{QCUSeUR9t;8Hku|{X4r$Rl_7i(6rIqsuG zJp@Yse52_G(RH=6liJ{#x7h-kH|kRinhU)wYy|dK>6hzrpMwDF25MDE*4kqf9{n*m zJ7wRgCdGZ;N&7+*q<&PJi1=x`XT>>#KDHbhjdUeO>87&Rc|!0vnn z1Z%jms5^umz!ynIDH{u&ClC7=is{A0{k0(2-cjUd1&7`y-x zqJglCFP>bs0jd*E874J{v*~#PQ%&je?rQN2l|*fG(h)NDPNHiUM=3g6>FHgBZynZq zjQnezjE2CB@d))Kf~skVWq7m6x{ZmX1qCV!>CsFCRz4X+`B6O25*J>wJdBBWO9d=N zlXMNGe%y@H#RbW%owmgF{f$wvff})N<3LS`JT@K#m;?> zS(E&nW2J}gJ zCe5TeE{#3U^w5OBXs2rTQZ->x-W38tqpoNd0_Mb1F3lMo%;{9Z_qJrdrN;?yN1aQI zy6U&&0!U{yO{Q5HeBfG!x@`ZAFvn*I$7gdv7Er}6arBWsWn7%pq^g;shpliTfmbuM zy*L;p(4__LI1#kHYWRK@D!CN8+Uj8n_^A;z@yq)h$uf+6p%GDso!wOzNi-WtG4L8_ zJ{~F1PsCM#QK`~Fj*MAV6web^9@e-}{&;)ae~Lmw5+*ig#UNaE4z!J@o2xv%?wo%j z+$=ln`F`6nGX;VOlu%P14}Xy1C#z(Fe8mtl+&Y}s9+zU&4bS{Hd^5PmSQ2C2hy>rJ zL^VLu^ZKG7X$-5YakeTuAoM^yxD6{d2HScp?(@FlFn7<>42DecF(;5WDcrC_q!KVX z;_^^rWs|R1JjVxxGB+}AgG$t4P_CX+Dm{$>65zRr)X3H(YJrwsMs=H|yXk0*T9|-p zR9X&oR30tzM(F?q0!Tm)fEC#x4#qVG$1ql#UEU`&P6qpZbp;$F-)tf!cLID_`VMc;hGac@ z&Cb|*4sx`!rfc*Vrq-sT>mu5yp_7(d%Aw=wCc;%RuXuIXz(U=1)hvzCtfSrcZ_2*{I&@Fi% zrws$(>4Kv~eIvoImegO~u2m8UDo;d32go4!UUBgFD_s-jLuNdKaiP!zhdP$mc3YnK z_9Fd%bC~_-q0=1-B!lXeBi=X9!%#bC;UEBuCqOMOj84mHEUu&B(w@b&{bv2b(j8)Y zS72=MJtQ{krmWIBC=qGZcTgXc=Eq8lUJ2b;@Wv*F3SofI@w_62&w{ zc#G;hPxXugn`0B%BL=nk`R2O-MU>y%nPtUexZV!FOuWH;Yw354ZmQ;$ra>?{5%DHxgE5 zC~LN|Mv^s>k5HXWqlPF4v$}_%-B1R-tmff{pb>kCN)j$Kse}}`C*`*CAk%?9E=>&BUt^zkrXu3@Ze zM{FwZE}T<}?1O?#CAZWDzT;Y&F;lk*?uaKHyvDZ*nE1jAwe$Z5LPkc3ZPlLCE}ZWfQEm-d*3l^IF1fl;|CRK#8uv6@J!@-Z@jLgP%CL)tEA5WEtS_Gn%*E~_d!_F+oNm2~$#-VY} z{m9iucmZUlZWVE!x>UsiXP>d9Vb$KhE!y&OS8J$yfy57&pV-4ThBYG^T+WkRW+Q9Sf z(*5UO-&*NI-|+G|(!;yH^4iJJxnXhJduo~6>ao^>BDGG{zs${?UB|ea7ck2|Un9*6 zNOFc_ie4S^+`m9K=Ou;{5G+356MeygL_SO6ERxCcRxOk$)exJQd|^SH?((X>ZL2D# z_5iAW2XQ%Ct4>bmm;D>Yg^x*?2iubTJ{m{?%M5gYXQzojl5vFHl2!z7LK_OJ%DQ=P ze53I`dE!sY$LCMwSEhW;@~UBWv&j_e8Z`$~XVazE3HGXhN*59W}%C`iB5xD7a! zbo2GVQRhx=Ox_}kISvo8*b1)TcKUPvycRt57l4!b-5?)D4C6=V!ofPmQ}MAAdivHx ztv3tiU|>SN#JPFX{Ag9^=Bpl*C%AhygWNIUwc%5VDiMwlrkV9TjbWR<1QHvKCc<1A zv+Y52l9~GnF}M^`dJl~8Pk~ha_*bjJ?YL3w0OKxOIP&lIDZckGW_dfjC8uj1RkEG~ z5%amf7;>g|K$E^6MRrD)8rC-}2U56@9A*wj4mkOrLF6*m>BSWqkfsr7F+J|Rsr&;P znAnQebN2c%inWqrhh*AhEp&bOGKY-Vb(<~3i{Hc@flpwjijo740mCxCr^p1(<0ZC& zDZ=NLk@TY$M!Bscf$cKbvu)9mps;>>n>9FKi>6gHkGTh?enydM=-4Opqy5DYi9gL| z91WXxExKtBfH`#)vTx;|tOXp_0#$C6)}#lEo60Wxq83+*;EAJ@d9~MX(@>CLt?IF* zfir@=m5!00f4cLpATb}Lo=E_0-phI{1wiJp8U(RQBJT1`{8i;o=C>)FWmu45ppD{}HWoTgBGO|U4QF!{*tpwI6TNUeBY2ayP~7o;5rm{e zx2w=l%Ojls$$HP=n}FwV066-c2L2jE?5nd%RhwmNS}R4u9J43OE(g6EkX2F;8(%CyWsAWoP?8r5~&)Dow2 z-+|XIbml0g{2W<;kxBKgHcG z_l|f@lsQrRn?Q(t()c>#Z95V}Z4OM_pZ#eKL(`&gEM_20Lx%(1{pL6DZQ6@O$HeH` z+Ac`o<|6!Onta2Imel5Gu=LZBXlF0DQNmzZAW1W4KRSv2ifi4)`XvwPFKP_(;&QVM zx;n>G?ml?9D$QDBAyD4_i>SWB1t(s>g1~(}kF2ylj4$Z4%b34yPm}(NFB3i^-NL*W zMnm@gGVXVmKDK6=Mfa~SRAq;I^#n!UaUkCft5$S9CJ07{%B74)A1N)qM>!R3ufA0H(?8S>LED-^9HEl^N+Z}$@p@QoXo%3=etl8Ml2w8 z-swTBM#Ejr0rKw8I18cSlFIhh<(w9SG<#*e{Ej0WnM%# zUct(WzPCjUHjk`fP~SiROx6^so1atkGTn)HwlZHMt!&6D$KHM8COjY%9Jgx@OT^4I zt+!!Fdsb>ffNBs*Pf)A&LLyHeJNsJYCGW8#hE?Lu7wi$nS}1ZujFG=w_N5(_QK`=XxM;%3rrvW>8UR{3ZO=uow(wVbaAqChGrh&HF%I8#-TK?%%B>!KDO1bA zv^}3vw;=_(q|sM(5`dtvn!!m09r>&3svaRp?oAzid?tLI{G#gu3zs~&WwSN5_`?-{ zQRd!1>IiwB=JM%FsYu~ckkHbI%lD-T&f_9DXb zH02RCq#jc&6trDRd`!`7w1)xsfEncUL?)nL@l0#6jF>OfWt9osv!|XzORZeFJ+1k+ z-9p{#)2hH)E45x-=#DgjzGQt|yB-gkYxF8)AY9vnsB$H}x>SRhB*bZym}@r_EiHc9 zQK}8Mjv-UVC@8I+;mg177P5AIXAXMqOwm zR^l6KA+kCLQ*V^;(IUH?TQdVYT3JLbZW^Wv)Kr~}!cMvn+nL5v8H=3|P`vK03zDZv z;bmwZi63HNfeWx_@u;78gd)#Vb-?!WUhN5C=NyIh$1dtv)$bHgRzq2QA1n+$^KJ05 zYPy*7$Y_#DKVt2%lhTN>+`026Z}O!EbEkE8Njet9<$Zpir$*$X^uCslC-5G3hz6wi zk9C_CZ=Mo;@8NU#yk0b}BN9I1DV*A)gRlY0rYE)WBR<1|A+%i^K;a+*Xiz1wBC5lo6UPgrvAh3I?PkMRAi?( zMl|IsAWvgyw{XgEDDtHpIZ7;K4Sdd?ZU6*HSybsQZS4e^eiP){Bz(KhuLn@Ga70{f zU3~?}E+gKwu+$@Raz67rEF0VOBy=Ie^EDVHG=k^UKB zP=GJh7_TAKALVoLHtM#+KEi}aUYA1n9{4zvVbm#*}m3?#461?uZA=s`kMI^uuxDy&eOJ*FdBttY)b2R_{sS~ z+$U^L0%KE1-6K4W;UY})_HQPuCoaR*o^VoR**hIC%Nx9F%b-`lGrK9*q}&Z8vKH%(c)5ca-9D24n6BGdW+E+XnU}8(!y0ZA=Qi-<9mchs%)V@r1+DX=7pq1H~in zjSjlJqvtiU=anLBr~KZ`ob~y>Jv+T@Md|te7i;evC2P~{3$|_ByKURHZS1yf+uZH$ z-R|ACZQHhOPrvV-d(X_8`@Q#kXHKp4)E`x~A}cckzle;CaR08&e6sWQ4m`XhOTCjtnTD_V4_i=BjO|a4um`UhVGv9B}sJ|+0V!K zPv)-gG!UCyu0PO^dD)x7g2dpk)R93XTSP&zwI^H0b$pCfuy=sqw>ejS^dNT0qOTd{ z7qJ4>YsZ|}&88Jry#9g_;mXKyjv;v)xqApBm~gGuV%@x#KcI$zNODNpF6+zpV~1Dl zi-WK;32SRETod;kVfqq@ZcC{+FP=aTDqwK8@|ESFc==4%U`rm5||!)wCsq-M&!Bqmc{b>I-){V%cSprc0^r zn>BsixjQ?GqIppTX4}=DJJC2VVLU~W^Wv1YR-j^ur$#{6E(+D)Fg(F3r;O;MW(VI<{G zLY6v&wo=PUxRPn381d;NtHMG-+32`}3!{Id`o!t{hv`O?&Bb=UKe@0hpp^x_wOhp| z!I<$yrUUDv=#r{^Cy+Klc&BT`fm3&iS9ZbJ-nA*U>e}_ipr*fLKzl;fqEo%BrWMy$ zk*)3^3u~%s;lYsdiH{l`-*ibS#gWUKty87!z)`Qg-d`HQ-E1lQHux8)X zl=Ii=oZ(AxSlFRX+0)#?y^jx%P7zYqiiN{>2fB*+3#)e*7cQ-@LIOdZ*sH-S{c(rZ z)-IjI(~N`N7?BS;*85itLEAoZ3DsyDY4bm#EfufRudARa!ycx}-*u{OQfQe^9nY+X ztryk*6#hKYd8>A`4$Kk7&7^ZETpLU-X^}=BP%x=n#mY&o(wG4&?R!1G=&Mv{9bK43 znU3soA}bkNx3UgCi>6rLk!)xvQ+Ef8C!70r_IX<+>MfMd#|NtJV8S+^u8<&An6)H?%F8>nInQ}$jl?iD^J>M!GH(9`Q6t;CwTtGgLQ@8it?_j>^&EEUcb|ae z5T!#@7W9kg(mhvjYvZtNv{pTUg* zTcfOm0-ch=(LAq;EkXvj;FssP)WH)d=Q;F@Cl3iRv&RvJB1?^e7!K`v*TVaNeSl((I5cwG@$(&*m=M6N>4|(juM5RisqypA#^1}MkSxiaC`ND2$nClzt zKv8g)5K&;ZWJj-nMSM`;4;<-cLJy%uW!i~$WqVnJ5*pSz{(yjmUq40-#k`b+iK5LY zZKNS)S}HS~;(C)L6A(ge7lV0=xM45_SD}m|H+Q(*bU+zt&`vXiHOwe+SzPWHu(6Y!I^;;gzdd`<6Dor-;l?1R(^upvyOFP@ub(ZOh z7zs<(=TquLa#z>d@E>kTvb2?hxG@f`8x~kut^0T?Fyis*r@)n{2EmP3;x`{VGPB9gQpKp;m?ISR)Sk7`}|4 zs}}|lJcn}fBnVdASXxZ{E+}60<@WM=;3QaE`lNne|4=EqRSLgqq<#BLOtp`TVy$J8 zQrugnb}H+6?EdijfKRE2aw!`>?@sBrl7{hHMf&#&>1Cd}l?FPu%}dBIK^&_MSElDZ zY+AC^S%l99nkIMN*UXFh$kgS&!^uy>S{3*Gn9xLeR7`Q^(IKvtJn0z z5ssWN^bB#1!)-PJinkCsQ0?$s^x?9?JFW+oquZg)u{Nm7hi3t=`KpMh1&s+QGU5PM zDBumv8U!VzFaTZ&rCZ|}kBnwe9FVIGnwv`|eb6x2$7wEjJF3D1nV*3!+5WSu`bC_Bjnr4=96m<(yS)^ z9kfF`NF3^&`@#XL_yT=5uLcvXKkd=w03Fp$Ed=}df)WMtA);cy-vv&9_>*xf)n%AL zL6hxsTfVQF6o705Z4$bcuR0Ku0Pc;se7KrFscp@U0lo>J`o@^eTK$GX^0Vhf5-+{W z)`4t^&nuc)LN_SwN+mEj4D|+K>%OZv0F={$z&UHji1VN)V!jqKE|{fk=?ObiZ5G%- zbcU&Aa|%N=oDs7jjDtyo$)3rs&d*eGwH^m}M?Qfr748-RJ3ic6W@1Fq82TuYf~}Ua@dehNiLZuv2lsto zCd|>a_viS++zANuuw+WgP++t3%CDm%ZV-Hh_NPBw&w?zDnjxO2x7Q9jafH4^562Qi z-?qRk7eGpFnz;@~-o|zd*cJx~y$O}C-F)siLEd;+CKk84N0=f}uVk2QE1A zCwtWuhWiB5?TU%r+Ab?+i-;0}|3|szqW$CYez+YvjLlU{t62=4S*fIgR&rc9jVeUH zz$J(*m^I=@#pk_#*w`ThZ5h$eIO=Cf>xiu>Lc81d%4?Y8Qd54q7nW(IDSzGDvfScq z(2jj{fvX#rtarxaQl@DsT0<_x(-{uMB^_^_BQTNFG9|s^X%=((NSsL3mv_Q9mwS=+z#Vs1kBatO>NTMM%=!ZZdk|%;pQI|p^y{~5 zb{|E#b_y~s;Hw{m1W38107BGI6zj;RLW{t=#olL){eh8muJ{}$)Q30%l^-hhV}nCy{Zfb-s6r-`-hr8gJ0$`@ zR_g}&%^-B$fp(fK*1m>|=XqtX7E!7t-f{AtY{N0*ayWo2p0GB&QFh<0Fb^cS9=;^W z8HV3C8)z{U?#xt$8{k-V%1o0Ng8c|YMd!dia`aWH86q*!_6v3#j24(fF&8UZ0ndp# za@G8DpdHoAm4FofmBK92z3<73^a%W?SmGDpU%;A^3@GCn3IHGs`=5X{$A21FE1Q{6 z2{>9)2`UNy&x&7lBjh6!HG2oOBjPgBHFXpt)FToNOsw?E*AsM7G71plG@~-(QWI1o zrS&tR;;YAj$v_Px2gS;iB!y&0NBih2l*y*XDFu}N{fYjkN|EPQj4<|TAW1bdp_ITY zu*xt82Zg4GDg zWa&Asu_ASE-BGZ&{MsxD5?-~Ln?FjMA2H$FbK#WntilWnA{Qs<0m>zLI_!J{B>6E0 zL@vfCGLx899}Y7O)XWFa_FT7oRw}tNQFcbrb2C9T)s}Lajd(Y5hl0nn`_c4%?rubD zNc0}Y6yhkc>2W5)iT}0hbXQMAbzmf# zcwR9yEd0^@iH0+Q+!IO7+OYll_IWdRapBt3#HDv%a*Q*?Fp2f)BD~nF_wegXGfX3@FBzrL$7S zm$e{)}^zI*sjl$4Md9YYuyH3RHKjk zSMQEspJroEo_=_iX1vH9^m#Fa4c3y~UA&1w?a?7r;#NvPEW!rGDqCLRs8ilHrS~RF z$!wqN6D)3;nu*Yg(bK~c@uCn-j6g|@!0-1ztbwhpfg%_%QPeT$+WE(wB_R!QE@diX zW(ZMmzxI?+JrK;PF0!D3qH(d_e$7`;MQ0V81r(|#mL**{kPkWK3tfcx_|wK(9lqX^ zsU4o;5jq$aK*+O%><=)phE9RHZ>Vt?7SUKI4B3!SfRc~}7y_z(D!)xD%RN6WtFlj< z%Z{3csP!shTQZvz@eLw{)NU%IrNutX1_N+s?Mk?7SBvT>9bifC6wbXtCo;ytnN(6$g z$zr^SpmOL%TgQ8ao9;B_1}wiClz`&qUlBi&jG^0|*`c#CCCHnt@rIys%8QEY=VOK{ zT#6^zr!vdzsxCjFalpyhZ3a3Bvqg8~4M{X)aayoF3ZVc&tRw}quLp`&FpQXk&7i~n zn1q!6gLfer6>$W$iPU}7CV+MZF@|!56kzO(jDWv|#)nJh446J?HQ^IzFZE|w`Mp`9 zf$G`W23xNNHGA|}L-9s?d^S^1{x%VWsO@Q0U{5J3dugMzw-KiX+WDsR24AjgJ$N^s zU%I29F$F^0`%HoVq!vpn~}DBcY=(|9=9*Yp8#DdDwt z7ZP24#~VhkT+Zg(Z{IOH!jbET=+7DGi4(z({HNE%G`d;HA2(+W^0G1_YWfJO2k>|i zdPL@gz%5 z+Z+6;jh|p^y4u?Ms2gXK1!~g;B)?DTTWf&a@m5bWdA(JUgKqE$?pdUQaY6-OtEwin z*~}eh!9z@e{pa$$aC4yXW2Cx6%%c*5$L6 zK3qnS>d;f5E%3#n4NnK5q^7MQbAB=*alqNL9r>THC42xeVR41lhh~O6#)=+qG50Oj zc<9@cL>3BH=C5Q>qlaFHB^C`PG3ZGRd(Z^l8W=L41dX1g_x|p4obJ3bJqY2vB~~ou zG6HMHrNGxlZ&1nI8c|BuoPsSOaLW$MvG97cv?y-`17Bm)@HV@avy`Z-`{u<#+=u>DK$PF8b12!)EwFWxapW8O zamth@FUf?J7~GJIB_b?YSplAAXrMJqAInkkUKTh+JM#+*Jm|}6$C9EPR5546jCVZg zQ1A(?4OzWYsCy>}XM6_B@(TI#*$lgP)In`tV)Bf5e6gPa3a8(<`Z@TPEU(=3oXfk$ zU*s2cy-tBOtByjqoh*#xw)CMk`AJ&`A%LhDy)kW+<8-RyL55Lk>m+hIN-mQ}uP`M~ zG69g2n3{A{*m%FcX{%&P|Cn|$P>Zmdo#s0?xfd<6rT-I>j^CB=5jRd^w3HL%r%+a+ zxcMmoppfzyfnqzsqN+#Qu~A-;rahZZxwF5ZddMk^=%|rlmNo!L7V-5EsL3?;WYn$! z@uXaM@8PC2fP*YS0(oJvR}3Vc{BbrAjN-;Dze5CW3@R#0I?eO?fFZ~xYO#Jzf4Db$ zz4SfVeCIH*_I_KDzVR_ry7WRqYL~w_U0CxFz26K=)PvWW_c5|ry`<0$bM4h$m10v> zpHq)pVC6KZm2RdVIMK;6UW5guN%oyG1ONvyf~PZ-T_)mCLe!7g!+xwaKgl=cl-Xum z@ehWE#ow%$u=a6+Va;=BFgI!fnEC8N3Ji_5-?v)cNZWcOuAv^arvmc{4N0!qkz+$6 zXZ<97ORO%-fysG-fH({F^g(9$pbaw-y&=tBgTU-EQN_IRi}kD(4$8&NR4=fAl5I*- ziD3@)?>l4iWDI>jGNqbQBM$*5IHm!TCrib3C=KA|T%o1*mte8<|s8Lab-_$3E%S#N@AvZk)7 zu*Td7Ybs+-aBz#o3{)yOb8E3eYwsm~awj-Bt{}x8>`^9%ZN_3EM5>UJME*3BMW|<5 zcs&%(>OuAXH~g-0(G#U?hte5cqqeL!rx%FpTTHE(E1Mvpu6Pl1Zv(y0RW*w{<6t69{y%TT}r&mjNok`JW&FRp~o$H z)I*f}+)HkAxpbeEoxp!TfXH&k*8Pk`FG(4>fxakOFC zLBK&#Km7+aA#E`%#e7d1Mjn9a)n%V=z}(o7?5eYmv!loQVtNBv9p(%KE#JsLxPb${ zeX>6i3tgzZ9Ik%k`Ybnly_T}7-lsLdEt_VR9=k_T3uLmpaWV=T#bV>g*K3Iw=rS*% z+)W$Kw5IFDUqt~vkdw9*vd>j)oMJV^%xhDS@BAie1790oLyi2vS832rgCgO@*9YtK zc5OqR%EnQ?V04Y9J`f}1g01`GAT2dKxgbN3jJ8)_AH^5jT;lOiDT{ErW2IOqcSz!6n}hGZq8b=xjVfoOPSZH>WkzmZydwwxab{)=PuYgEbZ|{Ym9f6|85=&v+@!!DCb$>0Oxjj;Hn^P!pcrN5KHxd~VCG3;7uhrIuV;&De^8AjH=^oAl3| z41f}!K#O_)?o!{(T(J%SML29Ah^)9cf`q!@3$mJE(~q#XJe2CI*WN+bK|@eMZ{mF; zM46LbOmA@UhX`fN4$8(rElgV!JBwq$KdJjO_1sqA-lf0%B*(B(=EnFz(oYU@ffnW+ zRVUM^@AEsW0SoULA^c@eqm*UyX0L35N5@Es6S%Z-%K{;_;FH!+bAVC2SoQR60n(*d ze2Ad%OOqy#sGqp=yst^QN?`2BrC z@Nw!6&pOe(CW~uRk&{k)!hRy_xi$sU&aS4pQSz~?UwLgf$hk8YkG2AI$=X0Ql$$c} z`K7`mFyT+tU&hT_R7GRz^EZ&bnS@nKyXy7CJ2`8!^M1&f5NZ)s$z=20Q*|bmn$k`l zmzbXsfwvC(w~QIh_2>K%%h*l1^TdPP-Kx&L%1L`LIrCQRY(eI@@ zxuM-s*a2iOolSQT@SuA}v%{(11QPp0%7^MAvRDWZr9ZG*ay1wcSA(=27@9(I7}ti@HCxJO$n%iYlsIEWEFDPZj~VZk*H0>n?kmcZmE z!3GXK;n*ibj3fs6^W~UlgBwEO`DNijqB)ud3mbOMhM}fWp(_1GIMSZk6@$+>?fmAz z*@Jf%8nS{d12G}8vgD=FA{@D5XuD4UaZ0P@D}RXV&!MyC`sxA|gmAU{Da2y5pnW^A zIRH1zy?!NAVK`JA-NoQu`c`KQ7^#IWF%qbbQA}t0GpDv%uc6OsUa;|@m-ZGq>{LwL zWR+0>pj$$TJj$1^;M_m=4;LQn#`iq$syL3k?|lFAiC=}4V%y*V0Mdv6|G_7w{LlNu zZhyJNTDE(QNPb&yR8ibnz&NwNNUS~LY-%=SB0+0K>}Ru=Kxt+ets|5rMt^<2CL~=f zuc2Xb#8aD^y4Hvn{H8f2=I9$6U-#)6HL>l9M%DCoWhe-Y#8V5G4Ib@md%jr0ADIxD z;w(}mZP?w?DR1d`{+v*2QY6vV_>@27U^-*ddw9=TOG4K!>}=m|Y;|&T|8Qg29FC%m zgg?nJmh@dpk<5zLVC=fEt-_aN+UpPcF}bxYo*>LhrqsYDbovEn`?j_P zU&z`}6Z-4P_Txdey-a;_>;3-Dw!_nghOHx~c{gNalkQ*{{d_|$*fSCl_pv_VY|V%I z<_TXF>*eRE_RW^h_bu;P>15@M@-FY@&J>E35289jq^}yMQwR4oc$2T!>knTq5Alvm zBnqgn`_SYUxvQ@QuJe~gpo-X?;Kp9_x}v(8#>Z;Ib+rLs3}-5}D$=&Gw~2}`*Nch~ z(Gu7pv@n|M7aI8^r{40tpQyUWiLmrBJ{*qKi>?w?>E>Rx&?(X{m4(sU(t_AVHTQ(k zZ}3-_K0eLFH~E|bfsiEKc63eD4t}-0ywSe+t&1A?M1qn+5Yj~XL@DH3z#a9PY7r10 z5*U?i)Q^iVPw-41{834PGiJy-`<;1&*_Ed+lgual;XsmFqMN5;C8FC+UGHtaY{=7F z3TZmHDAgFF4|P~1Pnk^3UlC+*`smLhwFM)_oUz`Wue*W+a-ATE6;qp^O}2MTD)E-RcR18 zy2e!guyWIa56jxt`^OJL;xAZZ;mrZtnkw@v|2Nsw^8pWZM{3Vu9lwcgJ9Tj6|$iZT4 zDY^tqzZ$}+gIiB`Sbf0Ddp_J5`vqVTGCo6i;AF0=OkAor^(BZUUxfk-voGXblwQ_nQVi z4Qa1z({Q@I6>QPOmggxiXOoB25TEMQONv{0&s_m&g|-_w$&Su+@y@aL!3n5Y)=m&l zwMNWwHR0GJi(Sy-gZAroWaF43WSoq`2+s;y6_#bVUP@Ve&cKW|dHgM?@e{2?bHgeX zW5(Nh+E9`FUzOKlZ1=diXL!zwJEbL}srx0oICq{D z1t`)p1vr5L;+K+f@<5k4Zqc6eWZl41{o!7+Jx2_(*ovpLg*p&CK~7+C@?_4~Njsme zeSvM%HDQ0oN)Y6VudRrp5-i3l<4j1E8_FV*G;>iVeS?%PShy0{dPW+_<=KLl-@^Vl zD~p%vNG|e`{hFz)3^cF8AQ{(EIup!jM!IsI?1u)Wkx1w{A(m*TCvoHE1#t!;w`{Rz zg2<3W>dbv*!MiJsH5v&*R%~Vo8qTH<3AYXsOMs9-?zrDeHA;J6BhV7ok`VV&kLp*% zkC1&yN=|u=^Z-1e&=Tk_aXu*K5HI*aG_7qIR;WW=hU0JvP|6)ES!o(4Z73a{DPfqL zD&4zYYa_ZJl84@ry-ox!4>h9pqhF^UDQc!8sN5a_(e(YI4ib=okODDYcFZZy(dB~h z0y}6Ptsu3gb=m>h1BWrc2U5n;Ns{j))SW6syM6dTomQ$s>Fgege~_~g3ozQhnshGC z`Ej72fjebRwSHC42#s+k98jYgeW9SQjD58}VjnQ=TA7e<`|K0A6$3UzE%3}hNJ6Zu zTz-4XKgF!jZMRHpa2!e<%K>DW&`&^#pusU8jK?f^niIqtoi@eFOAm3|9S~-YuE52@ zLUkFb`}~gR+RK?Ckn>|X?jUyiG+?bVfuK31N9JAGw+@B=?vIpTZG;HNFfZz4`Ppr1 zEjMI%Az_aUTb^BPXNZenXGw6W5r6~(>o`AL89_d}0Z9P#4@U&>h%D-r0`-NsFw-Sn zSREsmh5X~7EUmK!US`-EQ8XmN=`!WpxivL8kk?_tn?oM>P_Hk-ub;LId41Wc4m!oO zX_W9(c_xxBUBi?Uhu2}oH`5;8^S%%iD@VztiE>Qy#8teci@{X4YeHXpbWh%26l8dv zc^wcZI07*R9LC*HLyFik;2-I7^J-I#SDEOJ6Z6imP$u141Zt@rZNT*bStyM>`j0G( zXFyEHy&SV10-8mYbnfeUVv44MP(wX;yTL~KX9cV)7iYN~y+jM)g9Hr_{($jOdkUAg;H5sCRKH;43&&gR;@`cZCLV z1VFL9`V~PEaI2(Ba?pf1jW7HSa0%|bnCT7~7z*sx1aAtSNsmw=HE^rHMN`Ggm6m%S zxy0;_Kr3Uwglus4LU=A=MtZD}NFIs$VVX2)`FU|Yn;Q$e8FZ$7&OxYZC8(qNCnGTo zNYf%fndOiZ&fr>7!D&EE#9=$xkN4~?oIa%z&AFY!y)UT!M5ORh*W8JOCR{p?*8_+yx^CM~4l1LDVge76G0*^Dbmv$#qwQK?2d5(9l@N}9}{+Ky~>f~Kg z(wgL$_y{AO4|=vY*y#eO9l2d10-%O1Em#8mu{5I1E*=mNZ5(a9uaw#x&=)_N1#Ui;JuEVhTwv-|`v5N=t@ zrL!@7rxT0-c-cb5q%07RV`x$yJuFjOAOUO=Nx~_UM-^0`75Qhmy97ufi7v+y(6qc_ zF&(ns{K~?4n66)1Lpl-CLAMR+GQOYfmZeS;t=oq%e_oh@D`6|vo3NHLwVXJmRgX4M zVcS;(|%RKY}a-*)h8sw+yo=gnnxrmFU z1{z1U0Kb&uRlaxilT*y>dfR2VoNC-J5)Go9soN==Uf4x;Sf5I6_-wx2j+&cTp54+0 zJ%j2fib5Q2bpgMcAeU_1d2yCYtIjUr?WCw;Ia93`!8XRW`oia71r?FRwGeNV+jLOs z1M)AAs`Pro=@kY50GITiJSwbz_PXK`adi#F;>+?$d?{ELN9hd&5 zWMSZ9@NbbL`ahF1xBa&$QvatY+S+}$hcYw&>GW^WX8t#6f48G@bTV=Hx5kkAFODJj zKgJTUv->_UHgGbxwW0lMH=>m`lwX_9S4K6kuQV(Vu&8ff&2`bM}DYKY||(xWw8)ZUy6R+al_wa~mOIN+?l~lUpRv(jB|5!<0Qb=`PNg>wQ%O06wquXBiai!< z{0JRqR7D|zNGKE&zd zjY_n91}rBHvcE_ZDgI{(JT#ISmL@XQrcOsH6+~ft|2xxloJ3Ue87d8j2F4zy&hCsg z2zNvtGpOo=-7$+sq!$(uEQik*;))BQ|92(Gv^_^(_^y12{gX)EW^xnv`f^J`1*lyM z&bRc59b%Zu8gpqF+mDQ%5?jZ5g{V+ig9(MZW4{-P>tl72-@d&?q&(UnPHW8hIyW~D zn?n9y^dAk^3FSv6@k5@|{=}i{oFBGdM#HGi4;Gcae;d*tYnd@L-|_(akMf}K-^8OL zHpX_g<~B}$^QyIyj@%wSg4a})`T>Oq;f`B#B0pJ!8kF!*gSHYsck2i#3rXXY3)Uax zuaCuwvCv9)vy6?K^Kp-KJWx9jqf*xNB`WA*GQCc`xgoYxBgm!k!MJcDFjC3wynRbu zmvVnWsIr&ZI>n4244e^II(ZDvg>WR6Wz=5rnt)C(vJlVt5Glao5lCS;gjZE|c2^Ya z6@f8Uf`Z^l0((1PR9l4WLVgnoplBPFzBFvQIs@NAOm|y?>-XX-z{jo?q59raUvrq(AFK{9Nl3mBNhhiS2nV%|B-v@dY3skn~|-y>)Kbm)XNyEmgELYa_TD-Ys% zsA!)nx&pbl1H0eOkcj9`;Jl2)!8)hjHa~DxHxDZMeeBajO5PsrRT~{iQew)A86SH~ z=7euF+D**Cd$e%=MLmH3N5)jTKYQ}&wE z{!V0DS@iWMzE_)&pwhExjKIf_2P++>dML%LQy!l75!5FafZn?}G{D)6*3&M5v$C3G zJ(?!L6V*#yxZS4O`e3#@k{HBEL1-}0H2WyB$+h;%n5wdAao>p;&cH@$nCU1pU~v|i zPJ#2Qz3q{CnKbT1eGDAfWg0th+6Oai0`rhuJNEt2E5p6oamft+u}a=S_3R71mE@YE zoMd7ZbD?yCFyQz%a|RCCdYcbNRJywNbeBb0k1{?}db%;m=j+}QMPl&h6V|*qXg@m%ZC3)6#cxA>SN5a&8rsJtL-O2UR;`1!7 zTAUTSi?ce>0yglt4y$1CPJv`%)5sgk>Y+{ySR0%n8{q*>dZA8}%Fw^0t~HhDCyM&j zPxnQt=m39F(=mdu0203|O-A&h#*x4b7XDt322{!Y35Qxv)H0~80g@!~JM0ueR!x6p z{bfZNg8-%iLk^z2mfsvU2}~k*TZybtMcbr%7^Ng+7DZBPIQ~@zDzS|`(*zS^9=c~H zXqqlU`kE3vNf}t!nxF@g$KBXM41Mr`KV0d#-_@U%nWfe>pNgZe4ZaUiS~9IVQ_(1m zgMhzMa(9qJj@dBJ!GY9?xCkj#dbwe%{14ij2_7cX_s*9C=<$XOb(D9FH7dyjwNMkhLAdLSL~GlEn_tdA2dxE zDHs_uj|g1B$)v5gcJ^aqM|Y%_fq0WTcWADzE%tcPEd6lOv8qN=QJrUo%N6Tx-HfcF z!p5!?G3YVt)QGeiOxaN`r7%&0*i*|(6iLI#FniR_(-jHbG2r6X%z2m1LEh#Z=jg(_UaQ-iNwBW|vOKZ5RM8usY1tA-q1#Yr6Ou{RW-*)mU=0#Q z{(LNXi{37F#%2-Hl=JE|32H#?4ls|Ket7J3&)5kt0l9miD%W~yYB=#>7xCn1Z?OSE zL?!>@x#xPc1iKA847?2TTX#9A6lwLM=;!fZ=?=XRQ5Lgd?QP5i=P}<_HhqDO=5*nd zUGH#P&7v~erE5k-iHAf>Q;P4=7xZ7Md%Mm;7WG?gzk&agO8b}51gGy-%>R}K`x_uDh_@Rp2ai!*{`TOWuUB?6|R&yC!CML)l8?{I{YYu@B`39;^6@N4p< z>ErWfoq?BF3Wd_c+2X__UtymDD`pnb4(+z=q8Saw`wWE8z+_W53nJxnrrDww@F+kP zOu__(oSRV)a&1J2iuMHcOXCazJbCq! zl!OKKuwe2MW(}5h!IF8b=z<9Td=1DmE{hL8w^YsYpgkMc`#jp568yOFEuI*8X>(59 zh+ref!g3)d2q2=uDBv>%s4HPB+@?mt1`XLQi6@(}7HQR8 z_FqZK8qAh?!IQ0NmJetr8v+7g= zN}{21{bIHAlH%wOU;b^`1xO^IXho$9ce#p+8Sg7;@?U)Cj2< zI{CP`BuOW)k>9(5Num!jZz^c9=2K|dOD@cqs_nfyGDZ_-QYig0s5-g=)r|F}>W&KG z*`sPd2+5vL^i>h|%q33>5=9NdpH~bC#mo4W_wI_Rl`ckUk&lD+X}A(=&ldc)3f^OM z{kI}4$;7;0`Npu=VE?2D1^GSCX2ObIRAr$0HS0Z*(iIE3#8>CXEuI`T}vKRN; z^-B_8Cw~Cwx@0Yu!1mVMDg6%DCD&K^{+c&_Apm&}DzAew0`LJQ+b zy}l6;ylGAoW-k;|`r80IcBmor&i={z>Ugf{kX+|smZU(%1&HTNBcZ773O1RFf=NV9 zk+aSz`GLglJ^4Ok5)E38-#bmW@(>AN$1Dntyjd}AeoZx6*^`p1dD{#hr{4L`cbt$+Q(6zP0rpDZMrl=G;GTmtjoaQsXD3aE&-S(IG zxU*m7yJI9^4Uz;iL+nrs?Ky8mRBvuw?7M=535hn0= zJh{8l0BW_?!E>QTvikFyXhgUL$tUneSW?Rr54h7SH8lv8e@3d_2~X#4kRRF3 zzkuGDSTrb*l)`_o{jz0-T|Ok!6T>vXf~!)IAYvLsT#Y2qCpQYep}c8ZhzPQ75T!~` zt#S*96!N#Ec1%*Wsb+eVFeYz6E*y8Ka}~7M%+D6#9&R0IQi>)NI2M227&JvPuWH_X zPUy2G#XoqM&k4CN2tBHy1^=8e(B5xwvcb{Dd%|)~ow!%k$Y(2o?Cia1QOC`K?tIS} zh}GjmA9288wjNxA@HS~?YAN@I(&PF~izAGAg^KOez{b6LRmoQRs{;h^+HnP&6>6(v zzB9ni>}58XZJPz>35j%7a@W$BAHNHO5uLjJPj`nId}6{-s5EE0-0n>3TKBbj!Q!a^ zq1zd2g6Ph5-FZe8=KZ@jqUsoxEfVej=++7U7ezwuJ0P$0 zS3q7u`ETozrS!k7OAnkxJcSNCcC{h@M(ppw2#~NjRGwK@wz^e z(PTT*c#Ew>xks56XpjyMjg`#lnYjzvE>AGj0+8HrIIKn}?2>{sZ4V3xao{sQ96#Jy zE!R{H$W%3&(o}fHr!Eu9GTc4xbV1-DpNfdCdS<3XxhPoIfES6#hop^Fmjj&ru*Hy! zutAz+>sT`=+}aM&a6!`r-!{A1d~o+A7KQ-qVPOA9%=(vodchq3ZCtqx`V*B~*sn3S zPDvX@b?O}phAvsv5kuOxDugNg9WBPLY@l#02Y8+(T4e%8XS;-m$;PDP=%9v+A1~<+ z9g8hVKUraIAXr_*CdEbM6W1*8IZyliK++{`S%_W5zUEPB(?#N+--!{-%dBXQ3U%v7 z%O9jKxg&&=onhpfg-pU0K5j4H?Z_t-j{9FJqx?oQqGH$uc_O0bX2ptk(OBpz*q`-I zbPl&%`Ainyj3SB$%~Wr$0-KI$kFkt^^o;NdfEBj~t~p|23zUyPNd9CIQVVNf zCHfnLeC&z-S|5DBc@p5EUB#L#kZgV&KjKD2sjnW>Y=6j~xBR$l z|GZ(+AzC#<_ZJFwvkw+_`{wk3f8=zMf8_N4aP0q`00!fKlBR)!z4LcB8FK?0+V2d= z=(rx6KzbPds}HCoF31fV2=)ucQm%(uEfYoHG{J9S9uZEzUa zqsv5!+F{n*VXfNROtl{QZfSU|;Dfb~$dWn9v`(2b-3`WvF& z<2f*D&?poEq8*5mJR%S`M(s1J74^<-VK>^CC#!|QD+cy>M1gX|j_s!q4ZH+Jvv`Tp z;ix|-gdiAA^1{V4mBI!e+|PKvs^=fxmDhRat$6>wG`c7DaCh~+SPy{zWS{@#dEMXW z_dmAC%GT7-z{ry3uaEy)P!+j0#eRC2^DC+#&mnEG_;qJ5z-g{VLvHrPXyc=2FJnAV z3+B4jP?t`hOHerD5oL78Y&=+fSQJN@NOy1dM!7=|jtT$M6eZKGBv%gq$xKUf9wK@u zXSimJ-TnQ+KO4(eZe*W!R0@v4ii%F>3*ev~+XW+F>s2fI1VSn+O;h*TYWt_yvY~Vw zucB7D+x{jDEjG*r^nB{jw!W?yGcw&mzrpGS`WwiW75d3g!o1tTMtkn(K(Hd9$`>Lo zeTV*L<6XHx*52`J#R)en(@)euR3N{$m7X%U#nOk?fgls{d8ttB! ziyzu|xWDY6D5$ZC=h1Y{FM5ADuak@%yt~9#P1>p=tE=?(wmSRm9J9K?H=tb6c}mb^O_0tYi-K&1V(iJi{P?P)U^MrwzGk1;>zOq z11myNbg{HRQLC(=rl6ogl&UQdt%!i4E>>HTCPPTg*CyesE32RctsoviWsw7d^sFxR zqgWBCR4gi#TI(um54tQB5Jb0ib$5Fds(W8#Ix{aH4)*kVa+sWBe*gPE=4R&In>W4o z*Y|HZ&{TVPbJuG(ehli!8)*LDR{^PCOIvb-X2*;Wb+4WIRkiz=+rp4}A%6CkCw?Ms zZ?-Qww668$lNdMG(*U%<)B3wM3H@Spkd(GRjK zW|#RND8CZxvCmtkOdEaX$(6#^^x%jL`GmUzTf~(a4VP};YL3V+=t}ssuEFV=ctU-> zeZ4T$E^A%+`jT74)n{EVzUM5W1knL&y07^j&Fq*Vz8g{=QGdMN;iCJy!D_GSVf*^- zIhHgC)^6|b86~>DEpu~F&wsvHSGsbAYR(%yvLzdL+aEh_q-MKKYYfP(ZaY6$mO;f8 zZ1CAxMg2QdT)j{u9htCcdc!6+P5;id)f;* z*DieY&f6cf&4^t7;mgJ2&*i6zO7Hr;(VF+K=>9zeKk4^+v{(B1hxL8Bb-(kjs6CBk zmAT8;mrcq%HK(-hVSnE7hd2A)uX&WJpMR=1Z)$^pO>89P^H zb-uDPvOOhK;;?V8i@NS=`?yoHDr#%(_6GlPd-h@B?_0JOXV<$NiuXKl`oGbi_gqi& z^ttf)nGGM7Yz!%^n&*E)Tz7>BdHQsUbRL_3+u%}36+1jDaQ+-z3_r(%dyM|J0O_%0wq%zG`go< zK(ZW8pDM)TyBc2Hq4~kt5=*WyDCBC5jv_(W3uvUtULO4W^v`A}EHZaWm8>=!Ui|-Q z2Df1?Rv9Te$iqN&4C&9&H&L-8+;^w_4k5hl17q%^tocK;mP(Q-^&g&s!!;>trA8v7 zbf!BBQpVw&%Qw;rgf5;$XgZ?-N7*n(EjOE%QDGUs!FNE{k?{1yt~=3y(!(o=17B1# zG&qx=A~iny?50sQ8lm?f0p-rocw|Wm{lyz0H;y|S;7ZM`KVcT7kcefs{yhE=oV(R94LvxBqJAp~f2m4F zVqEMlI5HuTAArzX82JXjSI)Qc^@8uFGRZ5aTAy%P+61M~eC8I@2#kT2*!;ZXy&|5JGtzhKf z=zIuY#W0OZrBMsQsbos2(W;>L1QNAO5UzlAamD*dxW0~-7X+BK+3vL0qmCeiqAN)c z9>@MB9t4nmuuNfG3tRM{oplIhar!{K?YHnCEId5Y)I*D+R+7&+O%4>KgefI@y;fpK z6o^u#lot0N>9X?hv_u(T0M_q6A!zI5>l`t%_2?2T0M<8v8% zEaZ*1_Ap&ijJ>(kOhyTgT-NXvjQl zI+~hFKS(gUejNYqma*7m-e3z?x|lPt z7Hkqjf}{DHZ8>FvLFU*N4=%!3wu2Xs$s5}u<5eui?hcVmXN^e(cGd0@1`kIuS$z6} z@tsyM&lOv|?#5d5h{6{X%cg93K4H2YCcJMEJyb*UZZAAxZRdKe60+Y+>u0fp&Kr-V=RX!(Q?5Zse`$+=iDIoS{^^o z2P@r3FuSY;7tJyDr=fwF5;{@>BWd5c@$Nx^72i#Z(6%_-csH-m7H5d@F6Y^>A;r6P zUOXmd*lIR6-p$?l%w~h944IBbqyjsmkE>!BD}7D{9yKzg6YLynDB}Sf4HP|JGr6S% zq#iqy#l80$UGjW-(L|n>RK$&<&jW7sd01*o(R%b@r+RRHjIpI<{D|Ca8R;=QO~Rde tC42et$@CGaz+Rw*TMd>qlv_|>C0}Be42Oj Date: Thu, 13 Sep 2018 14:27:35 +0200 Subject: [PATCH 131/258] Code review Signed-off-by: Jeff MAURY --- .../internal/restclient/DefaultClient.java | 66 ++++--------------- .../internal/restclient/model/Build.java | 11 +++- .../restclient/model/BuildConfig.java | 6 +- .../model/build/BuildConfigBuilder.java | 2 +- .../model/build/IBinaryBuildSource.java | 4 -- 5 files changed, 26 insertions(+), 63 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index be96ed61..f695ca2b 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -262,49 +262,21 @@ public T execute(String method, String kind, String namesp return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload, params); } + @SuppressWarnings("unchecked") + public T execute(ITypeFactory factory, String method, String kind, String version, String namespace, String name, + String subresource, String subContext, InputStream payload, Map params) { + return execute(factory, method, kind, version, namespace, name, subresource, subContext, getPayload(method, payload), params); + } + @SuppressWarnings("unchecked") public T execute(ITypeFactory factory, String method, String kind, String namespace, String name, String subresource, String subContext, JSONSerializeable payload, Map params) { - if (factory == null) { - throw new OpenShiftException("ITypeFactory is null while trying to call IClient#execute"); - } - - if (params == null) { - params = Collections.emptyMap(); - } - - if (ResourceKind.LIST.equals(kind)) { - throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); - } - - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) - .apiVersion(getApiVersion(payload)) - .kind(kind) - .name(name) - .namespace(namespace) - .subresource(subresource) - .subContext(subContext) - .addParameters(params) - .build(); - - try { - Request request = newRequestBuilderTo(endpoint.toString()) - .method(method, getPayload(method, payload)) - .build(); - LOGGER.debug("About to make {} request: {}", request.method(), request); - try (Response result = client.newCall(request).execute()) { - String response = result.body().string(); - LOGGER.debug("Response: {}", response); - return (T) factory.createInstanceFrom(response); - } - } catch (IOException e) { - throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); - } + return execute(factory, method, kind, getApiVersion(payload), namespace, name, subresource, subContext, + getPayload(method, payload), params); } - @SuppressWarnings("unchecked") - public T execute(ITypeFactory factory, String method, String kind, String version, String namespace, String name, - String subresource, String subContext, InputStream payload, Map params) { + private T execute(ITypeFactory factory, String method, String kind, String version, String namespace, + String name, String subresource, String subContext, RequestBody requestBody, Map params) { if (factory == null) { throw new OpenShiftException("ITypeFactory is null while trying to call IClient#execute"); } @@ -316,21 +288,12 @@ public T execute(ITypeFactory factory, String method, String kind, String ve if (ResourceKind.LIST.equals(kind)) { throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); } - - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) - .apiVersion(version) - .kind(kind) - .name(name) - .namespace(namespace) - .subresource(subresource) - .subContext(subContext) - .addParameters(params) - .build(); + + final URL endpoint = new URLBuilder(this.baseUrl, typeMapper).apiVersion(version).kind(kind).name(name) + .namespace(namespace).subresource(subresource).subContext(subContext).addParameters(params).build(); try { - Request request = newRequestBuilderTo(endpoint.toString()) - .method(method, getPayload(method, payload)) - .build(); + Request request = newRequestBuilderTo(endpoint.toString()).method(method, requestBody).build(); LOGGER.debug("About to make {} request: {}", request.method(), request); try (Response result = client.newCall(request).execute()) { String response = result.body().string(); @@ -341,7 +304,6 @@ public T execute(ITypeFactory factory, String method, String kind, String ve throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); } } - private String getApiVersion(JSONSerializeable payload) { String apiVersion = null; if (payload instanceof IResource) { diff --git a/src/main/java/com/openshift/internal/restclient/model/Build.java b/src/main/java/com/openshift/internal/restclient/model/Build.java index d804bdcf..8a1a676d 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Build.java +++ b/src/main/java/com/openshift/internal/restclient/model/Build.java @@ -9,6 +9,11 @@ package com.openshift.internal.restclient.model; +import static com.openshift.internal.restclient.model.BuildConfig.BUILDCONFIG_SOURCE_BINARY_ASFILE; +import static com.openshift.internal.restclient.model.BuildConfig.BUILDCONFIG_SOURCE_CONTEXTDIR; +import static com.openshift.internal.restclient.model.BuildConfig.BUILDCONFIG_SOURCE_REF; +import static com.openshift.internal.restclient.model.BuildConfig.BUILDCONFIG_SOURCE_URI; + import java.util.Map; import org.jboss.dmr.ModelNode; @@ -91,10 +96,10 @@ public String getOutputKind() { public T getBuildSource() { switch (asString("spec.source.type")) { case BuildSourceType.GIT: - return (T) new GitBuildSource(asString("spec.source.git.uri"), asString("spec.source.git.ref"), - asString("spec.source.contextDir")); + return (T) new GitBuildSource(asString(BUILDCONFIG_SOURCE_URI), asString(BUILDCONFIG_SOURCE_REF), + asString(BUILDCONFIG_SOURCE_CONTEXTDIR)); case BuildSourceType.BINARY: - return (T) new BinaryBuildSource(asString("spec.source.binary.asFile"), asString("spec.source.contextDir")); + return (T) new BinaryBuildSource(asString(BUILDCONFIG_SOURCE_BINARY_ASFILE), asString(BUILDCONFIG_SOURCE_CONTEXTDIR)); default: } return null; diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index d95c862b..9e41a7fa 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -47,9 +47,9 @@ public class BuildConfig extends KubernetesResource implements IBuildConfig { public static final String BUILDCONFIG_SOURCE_CONTEXTDIR = "spec.source.contextDir"; public static final String BUILDCONFIG_SOURCE_TYPE = "spec.source.type"; - private static final String BUILDCONFIG_SOURCE_URI = "spec.source.git.uri"; - private static final String BUILDCONFIG_SOURCE_REF = "spec.source.git.ref"; - private static final String BUILDCONFIG_SOURCE_BINARY_ASFILE = "spec.source.binary.asFile"; + public static final String BUILDCONFIG_SOURCE_URI = "spec.source.git.uri"; + public static final String BUILDCONFIG_SOURCE_REF = "spec.source.git.ref"; + public static final String BUILDCONFIG_SOURCE_BINARY_ASFILE = "spec.source.binary.asFile"; public static final String BUILDCONFIG_TYPE = "spec.strategy.type"; private static final String BUILDCONFIG_CUSTOM_IMAGE = "spec.strategy.customStrategy.image"; diff --git a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java index 2444fa0a..9d4a8b69 100644 --- a/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/model/build/BuildConfigBuilder.java @@ -230,7 +230,7 @@ private BinaryBuildSource build() { } @Override - public BinarySourceBuilder fromAsFile(String asFile) { + public IBinarySourceBuilder fromAsFile(String asFile) { this.asFile = asFile; return this; } diff --git a/src/main/java/com/openshift/restclient/model/build/IBinaryBuildSource.java b/src/main/java/com/openshift/restclient/model/build/IBinaryBuildSource.java index f41d1dce..b64bc585 100644 --- a/src/main/java/com/openshift/restclient/model/build/IBinaryBuildSource.java +++ b/src/main/java/com/openshift/restclient/model/build/IBinaryBuildSource.java @@ -11,9 +11,5 @@ public interface IBinaryBuildSource extends IBuildSource { - /** - * The asFile - * - */ String getAsFile(); } From 981a4e9bddaa4ef0c9033e07a64a947d1a6e7fe3 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 13 Sep 2018 16:29:35 +0200 Subject: [PATCH 132/258] Fix Checkstyle error Signed-off-by: Jeff MAURY --- .../java/com/openshift/internal/restclient/DefaultClient.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index f695ca2b..eacfa349 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -304,6 +304,7 @@ private T execute(ITypeFactory factory, String method, String kind, String v throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); } } + private String getApiVersion(JSONSerializeable payload) { String apiVersion = null; if (payload instanceof IResource) { From 2f894b4ace8fba45aaafc1eae06aa178b5148754 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Tue, 18 Sep 2018 17:41:24 +0200 Subject: [PATCH 133/258] Fix failing integration tests on OCP3.9+ Signed-off-by: Jeff MAURY --- .../api/capabilities/PodExecIntegrationTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java index f42f1e51..3f789118 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java @@ -40,7 +40,6 @@ public class PodExecIntegrationTest { private IntegrationTestHelper helper = new IntegrationTestHelper(); - private Exception ex; private IPod pod; public static class TestExecListener implements IPodExec.IPodExecOutputListener { @@ -63,7 +62,7 @@ public void onOpen() { public void onStdOut(String message) { LOG.debug("onStdOut: " + message); message = message.trim(); - if (message.isEmpty() == false) { // Observing that actual output appears after empty newline + if (!message.isEmpty()) { // Observing that actual output appears after empty newline messages.add(PodExec.CHANNEL_STDOUT + message); } } @@ -72,7 +71,9 @@ public void onStdOut(String message) { public void onStdErr(String message) { LOG.debug("onStdErr: " + message); message = message.trim(); - messages.add(PodExec.CHANNEL_STDERR + message); + if (!message.isEmpty()) { + messages.add(PodExec.CHANNEL_STDERR + message); + } } @Override @@ -80,7 +81,9 @@ public void onExecErr(String message) { LOG.debug("onExecError: " + message); execErrCalled.set(true); message = message.trim(); - messages.add(PodExec.CHANNEL_EXECERR + message); + if (!message.isEmpty()) { + messages.add(PodExec.CHANNEL_EXECERR + message); + } } @Override From 909a998652f5aea3e17ab0ffe258906ae62412ae Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 21 Sep 2018 19:09:51 +0200 Subject: [PATCH 134/258] bump to 6.1.3.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 05572089..fac21cc4 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.3-SNAPSHOT + 6.1.3.Final jar OpenShift Java REST Client http://openshift.redhat.com From 79569d22f0d48bc7a7dd8bb9df321c564e90ebd4 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 21 Sep 2018 19:19:41 +0200 Subject: [PATCH 135/258] bump to 6.1.4-SNAPSHOT after release of 6.1.3.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fac21cc4..32bc0b29 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.3.Final + 6.1.4-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From a60de055fa225e4e8f51c28192fa3a2caca56f2f Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Mon, 17 Sep 2018 14:50:42 +0200 Subject: [PATCH 136/258] Move to latest okhttp - See #348 Signed-off-by: Jeff MAURY --- pom.xml | 7 +-- .../restclient/api/capabilities/PodExec.java | 48 +++++++++++-------- .../resources/PodLogRetrievalAsync.java | 31 ++++++------ .../okhttp/OpenShiftAuthenticator.java | 4 +- .../restclient/okhttp/WatchClient.java | 40 ++++------------ .../restclient/okhttp/WebSocketAdapter.java | 48 ------------------- .../restclient/api/capabilities/IPodExec.java | 7 ++- .../resources/IPodLogRetrievalAsync.java | 7 ++- .../restclient/TypeMapperFixture.java | 4 +- .../capabilities/PodExecIntegrationTest.java | 5 +- .../api/capabilities/PodExecTest.java | 9 ++-- .../PodLogRetrievalAsyncIntegrationTest.java | 7 ++- .../resources/PodLogRetrievalAsyncTest.java | 9 ++-- .../restclient/okhttp/WatchClientTest.java | 8 ++-- 14 files changed, 84 insertions(+), 150 deletions(-) delete mode 100644 src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java diff --git a/pom.xml b/pom.xml index 32bc0b29..82052409 100755 --- a/pom.xml +++ b/pom.xml @@ -161,12 +161,7 @@ com.squareup.okhttp3 okhttp - 3.3.1 - - - com.squareup.okhttp3 - okhttp-ws - 3.3.1 + 3.11.0 org.yaml diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java index df2be371..deb19f54 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -11,7 +11,6 @@ package com.openshift.internal.restclient.api.capabilities; -import java.io.IOException; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; @@ -22,7 +21,6 @@ import com.openshift.internal.restclient.URLBuilder; import com.openshift.internal.restclient.capability.AbstractCapability; import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; -import com.openshift.internal.restclient.okhttp.WebSocketAdapter; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; import com.openshift.restclient.api.capabilities.IPodExec; @@ -33,9 +31,9 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import okhttp3.ResponseBody; -import okhttp3.ws.WebSocket; -import okhttp3.ws.WebSocketCall; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; public class PodExec extends AbstractCapability implements IPodExec { @@ -104,44 +102,51 @@ public IStoppable start(IPodExecOutputListener listener, Options options, String .tag(new ResponseCodeInterceptor.Ignore() { }).build(); - WebSocketCall call = WebSocketCall.create(okClient, request); - ExecOutputListenerAdapter adapter = new ExecOutputListenerAdapter(call, listener); - call.enqueue(adapter); + ExecOutputListenerAdapter adapter = new ExecOutputListenerAdapter(listener); + okClient.newWebSocket(request, adapter); return adapter; } - static class ExecOutputListenerAdapter extends WebSocketAdapter implements IStoppable { + static class ExecOutputListenerAdapter extends WebSocketListener implements IStoppable { private final IPodExecOutputListener listener; - private final WebSocketCall call; + private WebSocket call; private AtomicBoolean open = new AtomicBoolean(false); + private boolean shouldStop = false; - public ExecOutputListenerAdapter(WebSocketCall call, IPodExecOutputListener listener) { - this.call = call; + public ExecOutputListenerAdapter(IPodExecOutputListener listener) { this.listener = listener; } @Override public void stop() { - call.cancel(); + if (call != null) { + call.cancel(); + } else { + shouldStop = true; + } } @Override public void onOpen(WebSocket webSocket, Response response) { if (open.compareAndSet(false, true)) { + this.call = webSocket; listener.onOpen(); + if (shouldStop) { + webSocket.cancel(); + } } } @Override - public void onClose(int code, String reason) { + public void onClosing(WebSocket socket, int code, String reason) { if (open.compareAndSet(true, false)) { listener.onClose(code, reason); } } @Override - public void onFailure(IOException e, Response response) { + public void onFailure(WebSocket socket, Throwable e, Response response) { listener.onFailure(e); } @@ -162,7 +167,12 @@ public void deliver(int channel, String msg) { } @Override - public void onMessage(ResponseBody message) throws IOException { + public void onMessage(WebSocket webSocket, String text) { + throw new IllegalStateException("Should not receive text message on pod exec sockets"); + } + + @Override + public void onMessage(WebSocket socket, ByteString message) { /** * https://godoc.org/k8s.io/kubernetes/pkg/util/wsstream The Websocket @@ -175,8 +185,8 @@ public void onMessage(ResponseBody message) throws IOException { * - writes are sent as they are received by the server. */ - int channel = message.byteStream().read(); - String msg = message.string(); + int channel = message.getByte(0); + String msg = message.substring(1).utf8(); deliver(channel, msg); } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java index af435cdd..04c802f3 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -11,7 +11,6 @@ package com.openshift.internal.restclient.capability.resources; -import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; @@ -22,7 +21,6 @@ import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.URLBuilder; import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; -import com.openshift.internal.restclient.okhttp.WebSocketAdapter; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; import com.openshift.restclient.UnsupportedEndpointException; @@ -34,9 +32,9 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import okhttp3.ResponseBody; -import okhttp3.ws.WebSocket; -import okhttp3.ws.WebSocketCall; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; +import okio.ByteString; /** * Impl of Pod log retrieval using websocket @@ -89,13 +87,11 @@ public IStoppable start(IPodLogListener listener, Options options) { .websocket(); Request request = client.newRequestBuilderTo(endpoint).tag(new ResponseCodeInterceptor.Ignore() { }).build(); - WebSocketCall call = WebSocketCall.create(okClient, request); - call.enqueue(adapter); - + okClient.newWebSocket(request, adapter); return adapter; } - static class PodLogListenerAdapter extends WebSocketAdapter implements IStoppable { + static class PodLogListenerAdapter extends WebSocketListener implements IStoppable { private final IPodLogListener listener; private WebSocket wsClient; @@ -127,20 +123,25 @@ public void onOpen(WebSocket webSocket, Response response) { } @Override - public void onClose(int code, String reason) { + public void onClosing(WebSocket socket, int code, String reason) { if (open.compareAndSet(true, false)) { listener.onClose(code, reason); } } @Override - public void onMessage(ResponseBody message) throws IOException { - listener.onMessage(message.string()); + public void onMessage(WebSocket socket, String message) { + listener.onMessage(message); + } + + @Override + public void onMessage(WebSocket webSocket, ByteString bytes) { + listener.onMessage(bytes.utf8()); } @Override - public void onFailure(IOException e, Response response) { - listener.onFailure(e); + public void onFailure(WebSocket socket, Throwable t, Response response) { + listener.onFailure(t); } } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java index 7cb64f77..6b5fdc8a 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java @@ -54,8 +54,8 @@ public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { public Request authenticate(Route route, Response response) throws IOException { if (unauthorizedForCluster(response)) { String requestUrl = response.request().url().toString(); - Request authRequest = new Request.Builder().addHeader(CSRF_TOKEN, "1").url(route.address().url().toString() - + "oauth/authorize?response_type=token&client_id=openshift-challenging-client").build(); + Request authRequest = new Request.Builder().addHeader(CSRF_TOKEN, "1").url(response.request().url().resolve( + "/oauth/authorize?response_type=token&client_id=openshift-challenging-client").toString()).build(); try (Response authResponse = tryAuth(authRequest)) { if (authResponse.isSuccessful()) { String token = extractAndSetAuthContextToken(authResponse); diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index 9dd39c45..c94f2e28 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -42,11 +42,8 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import okhttp3.ResponseBody; -import okhttp3.ws.WebSocket; -import okhttp3.ws.WebSocketCall; -import okhttp3.ws.WebSocketListener; -import okio.Buffer; +import okhttp3.WebSocket; +import okhttp3.WebSocketListener; public class WatchClient implements IWatcher, IHttpConstants { @@ -91,10 +88,8 @@ public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatc Request request = client.newRequestBuilderTo(endpoint) .header(PROPERTY_ORIGIN, client.getBaseURL().toString()) .header(PROPERTY_USER_AGENT, "openshift-restclient-java").build(); - WebSocketCall call = WebSocketCall.create(okClient.newBuilder().build(), request); - socket.setCall(call); + okClient.newWebSocket(request, socket); endpointMap.put(kind, socket); - call.enqueue(socket); } status.set(Status.Started); } catch (Exception e) { @@ -121,14 +116,13 @@ private String getResourceVersion(String kind, String namespace, WatchEndpoint e return list.getResourceVersion(); } - static class WatchEndpoint implements WebSocketListener { + static class WatchEndpoint extends WebSocketListener { private IOpenShiftWatchListener listener; private List resources; private final String kind; private final IClient client; private WebSocket wsClient; - private WebSocketCall call; public WatchEndpoint(IClient client, IOpenShiftWatchListener listener, String kind) { this.listener = listener; @@ -136,19 +130,12 @@ public WatchEndpoint(IClient client, IOpenShiftWatchListener listener, String ki this.client = client; } - public void setCall(WebSocketCall call) { - this.call = call; - } - void close() { try { if (wsClient != null) { wsClient.close(STATUS_NORMAL_STOP, "Client was asked to stop."); wsClient = null; } - if (call != null) { - call.cancel(); - } listener.disconnected(); } catch (Exception e) { LOGGER.debug("Unable to stop the watch client", e); @@ -162,14 +149,14 @@ public void setResources(List resources) { } @Override - public void onClose(int statusCode, String reason) { + public void onClosing(WebSocket socket, int statusCode, String reason) { LOGGER.debug("WatchSocket closed for kind: {}, code: {}, reason: {}", new Object[] { kind, statusCode, reason }); listener.disconnected(); } @Override - public void onFailure(IOException err, Response response) { + public void onFailure(WebSocket socket, Throwable err, Response response) { LOGGER.debug("WatchSocket Error for kind {}: {}", kind, err); try { if (response == null) { @@ -191,10 +178,9 @@ public void onFailure(IOException err, Response response) { } @Override - public void onMessage(ResponseBody body) throws IOException { - String message = body.string(); - LOGGER.debug(message); - ModelNode node = ModelNode.fromJSONString(message); + public void onMessage(WebSocket socket, String body) { + LOGGER.debug(body); + ModelNode node = ModelNode.fromJSONString(body); IOpenShiftWatchListener.ChangeType event = new ChangeType(node.get("type").asString()); IResource resource = client.getResourceFactory().create(node.get("object").toJSONString(true)); if (StringUtils.isEmpty(resource.getKind())) { @@ -209,11 +195,5 @@ public void onOpen(WebSocket socket, Response response) { wsClient = socket; listener.connected(resources); } - - @Override - public void onPong(Buffer buffer) { - } - } - } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java b/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java deleted file mode 100644 index 8ea9642e..00000000 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WebSocketAdapter.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ - -package com.openshift.internal.restclient.okhttp; - -import java.io.IOException; - -import okhttp3.Response; -import okhttp3.ResponseBody; -import okhttp3.ws.WebSocket; -import okhttp3.ws.WebSocketListener; -import okio.Buffer; - -/** - * Adapter to WebSocketListener - * - */ -public class WebSocketAdapter implements WebSocketListener { - - @Override - public void onOpen(WebSocket webSocket, Response response) { - } - - @Override - public void onFailure(IOException e, Response response) { - } - - @Override - public void onMessage(ResponseBody message) throws IOException { - } - - @Override - public void onPong(Buffer payload) { - } - - @Override - public void onClose(int code, String reason) { - } - -} \ No newline at end of file diff --git a/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java b/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java index 173346f5..43b773b4 100644 --- a/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java +++ b/src/main/java/com/openshift/restclient/api/capabilities/IPodExec.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -11,7 +11,6 @@ package com.openshift.restclient.api.capabilities; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -69,10 +68,10 @@ interface IPodExecOutputListener { /** * Called by lower level errors * - * @param e + * @param t * Exception causing failure */ - void onFailure(IOException e); + void onFailure(Throwable t); /** * Callback received when the connection to the pod is terminated from the diff --git a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java index 687191ac..d4149ddb 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IPodLogRetrievalAsync.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -11,7 +11,6 @@ package com.openshift.restclient.capability.resources; -import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -77,10 +76,10 @@ interface IPodLogListener { /** * Callback received when the web socket connection fails * - * @param e + * @param t * the exception which occurred */ - void onFailure(IOException e); + void onFailure(Throwable t); } diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 2aa6b309..2ae3faec 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -91,7 +91,7 @@ static Request requestTo(String url) { protected static Response responseOf(String response) { return new Response.Builder().request(new Request.Builder().url("https://someurlfortesting").build()) - .protocol(Protocol.HTTP_1_1).code(IHttpConstants.STATUS_OK).body(ResponseBody.create(null, response)) + .protocol(Protocol.HTTP_1_1).code(IHttpConstants.STATUS_OK).message("").body(ResponseBody.create(null, response)) .build(); } diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java index 3f789118..4d9d0af6 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java @@ -15,7 +15,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -93,9 +92,9 @@ public void onClose(int code, String reason) { } @Override - public void onFailure(IOException e) { + public void onFailure(Throwable t) { failureCalled.set(true); - LOG.error("Potentially expected error occurred", e); + LOG.error("Potentially expected error occurred", t); testDone.countDown(); } diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java index 86dfb6f9..a7bc8922 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -25,6 +25,7 @@ import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.TypeMapperFixture; +import com.openshift.internal.restclient.api.capabilities.PodExec.ExecOutputListenerAdapter; import com.openshift.internal.restclient.capability.resources.PodLogRetrievalAsync; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.api.capabilities.IPodExec; @@ -50,7 +51,7 @@ public void setUp() throws Exception { client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); pod = new MocksFactory().mock(IPod.class); capability = new PodLogRetrievalAsync(pod, client); - adapter = new PodExec.ExecOutputListenerAdapter(null, listener); + adapter = new PodExec.ExecOutputListenerAdapter(listener); } @Test @@ -79,8 +80,8 @@ public void testAdapterCallsListenerCycle() throws Exception { verify(listener).onStdErr("ImStdErr"); verify(listener).onExecErr("ImExecErr"); - adapter.onClose(1986, "the reason"); - adapter.onClose(1986, "the reason"); + adapter.onClosed(null, 1986, "the reason"); + adapter.onClosed(null, 1986, "the reason"); verify(listener).onClose(1986, "the reason"); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java index 9c0a67cc..2aa28002 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -14,7 +14,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; -import java.io.IOException; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -75,8 +74,8 @@ public void onClose(int code, String reason) { } @Override - public void onFailure(IOException e) { - LOG.error("Unexpected websocket failure", e); + public void onFailure(Throwable t) { + LOG.error("Unexpected websocket failure", t); fail("Unexpected websocket failure"); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java index 86e2b465..9c98ee34 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java @@ -38,7 +38,7 @@ import okhttp3.MediaType; import okhttp3.ResponseBody; -import okhttp3.ws.WebSocket; +import okhttp3.WebSocket; @RunWith(MockitoJUnitRunner.class) public class PodLogRetrievalAsyncTest extends TypeMapperFixture { @@ -81,12 +81,11 @@ public void testAdapterCallsListenerCycle() throws Exception { adapter.onOpen(null, null); verify(listener).onOpen(); - ResponseBody body = ResponseBody.create(MediaType.parse("text"), "a body"); - adapter.onMessage(body); + adapter.onMessage(null, "a body"); verify(listener).onMessage("a body"); - adapter.onClose(1986, "the reason"); - adapter.onClose(1986, "the reason"); + adapter.onClosed(null, 1986, "the reason"); + adapter.onClosed(null, 1986, "the reason"); verify(listener).onClose(1986, "the reason"); } diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java index a57f7cb1..534a5f0d 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -47,7 +47,7 @@ public void testOnFailureCallBackNotifiesListener() { IOpenShiftWatchListener listener = mock(IOpenShiftWatchListener.class); WatchEndpoint endpoint = new WatchEndpoint(client, listener, ResourceKind.BUILD); - endpoint.onFailure(new IOException(), null); + endpoint.onFailure(null, new IOException(), null); verify(listener).error(any(Throwable.class)); } @@ -58,9 +58,9 @@ public void shouldIgnoreUnsupportedFeatureResponseOnFailure() { WatchEndpoint endpoint = new WatchEndpoint(client, listener, ResourceKind.BUILD); Response.Builder responseBuilder = new Response.Builder(); - responseBuilder.code(IHttpConstants.STATUS_OK).protocol(Protocol.HTTP_2) + responseBuilder.code(IHttpConstants.STATUS_OK).message("").protocol(Protocol.HTTP_2) .request(new Request.Builder().url("http://localhost").build()); - endpoint.onFailure(new ProtocolException(), responseBuilder.build()); + endpoint.onFailure(null, new ProtocolException(), responseBuilder.build()); verify(listener, never()).error(any()); } From 5bf4becec79f6513cda76ee5cfb116044a5d0320 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Tue, 18 Sep 2018 21:54:07 +0200 Subject: [PATCH 137/258] Fix failing tests Signed-off-by: Jeff MAURY --- .../internal/restclient/api/capabilities/PodExecTest.java | 4 ++-- .../capability/resources/PodLogRetrievalAsyncTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java index a7bc8922..a1adc56f 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java @@ -80,8 +80,8 @@ public void testAdapterCallsListenerCycle() throws Exception { verify(listener).onStdErr("ImStdErr"); verify(listener).onExecErr("ImExecErr"); - adapter.onClosed(null, 1986, "the reason"); - adapter.onClosed(null, 1986, "the reason"); + adapter.onClosing(null, 1986, "the reason"); + adapter.onClosing(null, 1986, "the reason"); verify(listener).onClose(1986, "the reason"); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java index 9c98ee34..eb7882e5 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java @@ -84,8 +84,8 @@ public void testAdapterCallsListenerCycle() throws Exception { adapter.onMessage(null, "a body"); verify(listener).onMessage("a body"); - adapter.onClosed(null, 1986, "the reason"); - adapter.onClosed(null, 1986, "the reason"); + adapter.onClosing(null, 1986, "the reason"); + adapter.onClosing(null, 1986, "the reason"); verify(listener).onClose(1986, "the reason"); } From d7b6f147f1e5e5978e5299b0f702befae405db41 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Wed, 19 Sep 2018 10:27:43 +0200 Subject: [PATCH 138/258] Switch version to 7.0.0-SNAPSHOT Signed-off-by: Jeff MAURY --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 82052409..937e8618 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 6.1.4-SNAPSHOT + 7.0.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From e6be8c9df3308d1ea54f94fa32fb3da12f9a34e6 Mon Sep 17 00:00:00 2001 From: "Roland T. Lichti" Date: Sat, 6 Oct 2018 18:27:50 +0200 Subject: [PATCH 139/258] Added user.openshift.io/v1/identities. --- .../model/user/OpenShiftIdentity.java | 60 ++++++++++++++++ .../openshift/restclient/ResourceKind.java | 2 + .../restclient/model/user/IIdentity.java | 55 +++++++++++++++ .../restclient/model/v1/IdentityTest.java | 69 +++++++++++++++++++ .../openshift/restclient/utils/Samples.java | 1 + .../samples/openshift3/v1_identity.json | 17 +++++ 6 files changed, 204 insertions(+) create mode 100644 src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java create mode 100644 src/main/java/com/openshift/restclient/model/user/IIdentity.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/v1/IdentityTest.java create mode 100644 src/test/resources/samples/openshift3/v1_identity.json diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java new file mode 100644 index 00000000..97dab963 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + * Roland T. Lichti - implementation of user.openshift.io/v1/identities + ******************************************************************************/ + +package com.openshift.internal.restclient.model.user; + +import java.util.Map; + +import com.openshift.internal.restclient.model.KubernetesResource; +import com.openshift.internal.restclient.model.ObjectReference; +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.IObjectReference; +import com.openshift.restclient.model.user.IIdentity; +import org.jboss.dmr.ModelNode; + +public class OpenShiftIdentity extends KubernetesResource implements IIdentity { + + private static final String PROVIDER_NAME = "providerName"; + private static final String PROVIDER_USER_NAME = "providerUserName"; + private static final String EXTRA = "extra"; + private static final String USER = "user"; + + public OpenShiftIdentity(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } + + @Override + public String getUserName() { + return asString(PROVIDER_USER_NAME); + } + + @Override + public String getUID() { + return asString("metadata.uid"); + } + + @Override + public String getProviderName() { + return asString(PROVIDER_NAME); + } + + @Override + public Map getExtra() { + return asMap(EXTRA); + } + + @Override + public IObjectReference getUser() { + return new ObjectReference(get(USER)); + } +} diff --git a/src/main/java/com/openshift/restclient/ResourceKind.java b/src/main/java/com/openshift/restclient/ResourceKind.java index 1fa5a90b..2c9af8c0 100644 --- a/src/main/java/com/openshift/restclient/ResourceKind.java +++ b/src/main/java/com/openshift/restclient/ResourceKind.java @@ -44,6 +44,7 @@ public final class ResourceKind { public static final String ROUTE = "Route"; public static final String TEMPLATE = "Template"; public static final String USER = "User"; + public static final String IDENTITY = "Identity"; // Kubernetes Kinds public static final String ENDPOINTS = "Endpoints"; @@ -124,6 +125,7 @@ public static String pluralize(String kind, boolean lowercase, boolean uncapital set.add(ROUTE); set.add(TEMPLATE); set.add(USER); + set.add(IDENTITY); // Kubernetes Kinds set.add(EVENT); diff --git a/src/main/java/com/openshift/restclient/model/user/IIdentity.java b/src/main/java/com/openshift/restclient/model/user/IIdentity.java new file mode 100644 index 00000000..378daa47 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/user/IIdentity.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + * Roland T. Lichti - implementation of user.openshift.io/v1/identities + ******************************************************************************/ + +package com.openshift.restclient.model.user; + +import java.util.Map; + +import com.openshift.restclient.model.IObjectReference; +import com.openshift.restclient.model.IResource; + +/** + * The identity as specified by the identity provider. + */ +public interface IIdentity extends IResource { + + /** + * + * @return the username as specified by the idententity provider. + */ + String getUserName(); + + /** + * + * @return the identity uid as specified in the metadata + */ + String getUID(); + + /** + * + * @return the name of the identity provider + */ + String getProviderName(); + + /** + * + * @return a map of the identity provider specific data. + */ + Map getExtra(); + + /** + * + * @return A resource link to the user. + */ + IObjectReference getUser(); +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/IdentityTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/IdentityTest.java new file mode 100644 index 00000000..7721b31d --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/v1/IdentityTest.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + * Roland T. Lichti - implementation of user.openshift.io/v1/identities + ******************************************************************************/ + +package com.openshift.internal.restclient.model.v1; + +import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; +import com.openshift.internal.restclient.model.user.OpenShiftIdentity; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.user.IIdentity; +import com.openshift.restclient.utils.Samples; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +/** + * Test to validate the lookup paths are correct for the version + */ +public class IdentityTest { + + private static final String VERSION = "v1"; + private IIdentity identity; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_IDENTITY.getContentAsString()); + identity = new OpenShiftIdentity(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.IDENTITY)); + } + + @Test + public void testUserName() { + assertEquals("test-admin", identity.getUserName()); + } + + @Test + public void testUid() { + assertEquals("94b42e96-0faa-11e5-9467-080027893417", identity.getUID()); + } + + @Test + public void testProviderName() { + assertEquals("anypassword", identity.getProviderName()); + } + + @Test + public void testUserReferenceName() { + assertEquals("test-admin", identity.getUser().getName()); + } + + @Test + public void testUserReferenceUid() { + assertEquals("94b42e96-0faa-11e5-9467-080027893417", identity.getUser().getUID()); + } +} diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 5603bd79..15c08fdd 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -60,6 +60,7 @@ public enum Samples { V1_Status("openshift3/v1_status.json"), V1_TEMPLATE("openshift3/v1_template.json"), V1_USER("openshift3/v1_user.json"), + V1_IDENTITY("openshift3/v1_identity.json"), V1_SECRET("openshift3/v1_secret.json"), V1_UNRECOGNIZED("openshift3/v1_unrecognized.json"), V1_CONFIG_MAP("openshift3/v1_config_map.json"), diff --git a/src/test/resources/samples/openshift3/v1_identity.json b/src/test/resources/samples/openshift3/v1_identity.json new file mode 100644 index 00000000..3aca2678 --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_identity.json @@ -0,0 +1,17 @@ +{ + "kind": "Identity", + "apiVersion": "user.openshift.io/v1", + "metadata": { + "creationTimestamp": "2018-10-06T13:13:14Z", + "name": "anypassword:test-admin", + "resourceVersion": "13524", + "selfLink": "/apis/user.openshift.io/v1/identities/anypassword%3Atest-admin", + "uid": "94b42e96-0faa-11e5-9467-080027893417" + }, + "providerName": "anypassword", + "providerUserName": "test-admin", + "user": { + "name": "test-admin", + "uid": "94b42e96-0faa-11e5-9467-080027893417" + } +} From 74f97f94c4a1ebf3a1c92d4f59037c8471b942d0 Mon Sep 17 00:00:00 2001 From: "Roland T. Lichti" Date: Sat, 6 Oct 2018 18:51:19 +0200 Subject: [PATCH 140/258] Added user.openshift.io/v1/groups. --- .../restclient/model/user/OpenShiftGroup.java | 43 ++++++++++++ .../restclient/model/user/OpenShiftUser.java | 14 +++- .../openshift/restclient/ResourceKind.java | 2 + .../restclient/model/user/IGroup.java | 36 ++++++++++ .../restclient/model/user/IUser.java | 14 ++++ .../restclient/model/v1/GroupTest.java | 65 +++++++++++++++++++ .../restclient/model/v1/UserTest.java | 28 ++++++-- .../openshift/restclient/utils/Samples.java | 1 + .../samples/openshift3/v1_group.json | 14 ++++ .../resources/samples/openshift3/v1_user.json | 4 +- 10 files changed, 212 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java create mode 100644 src/main/java/com/openshift/restclient/model/user/IGroup.java create mode 100644 src/test/java/com/openshift/internal/restclient/model/v1/GroupTest.java create mode 100644 src/test/resources/samples/openshift3/v1_group.json diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java new file mode 100644 index 00000000..92c8e3b5 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java @@ -0,0 +1,43 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + * Roland T. Lichti - implementation of user.openshift.io/v1/groups + ******************************************************************************/ + +package com.openshift.internal.restclient.model.user; + +import java.util.Map; +import java.util.Set; + +import com.openshift.internal.restclient.model.KubernetesResource; +import com.openshift.restclient.IClient; +import com.openshift.restclient.model.user.IGroup; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; + +public class OpenShiftGroup extends KubernetesResource implements IGroup { + + private static final String USERS = "users"; + + public OpenShiftGroup(ModelNode node, IClient client, Map propertyKeys) { + super(node, client, propertyKeys); + } + + @Override + public String getUID() { + return asString("metadata.uid"); + } + + @Override + public Set getUsers() { + //noinspection unchecked + return (Set) asSet(USERS, ModelType.STRING); + } +} diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java index 6c0cd952..8efe32d2 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java @@ -12,12 +12,13 @@ package com.openshift.internal.restclient.model.user; import java.util.Map; - -import org.jboss.dmr.ModelNode; +import java.util.Set; import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.restclient.IClient; import com.openshift.restclient.model.user.IUser; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; public class OpenShiftUser extends KubernetesResource implements IUser { @@ -37,4 +38,13 @@ public String getUID() { return asString("metadata.uid"); } + @Override + public Set getGroups() { + return asSet("groups", ModelType.STRING); + } + + @Override + public Set getIdentities() { + return asSet("identities", ModelType.STRING); + } } diff --git a/src/main/java/com/openshift/restclient/ResourceKind.java b/src/main/java/com/openshift/restclient/ResourceKind.java index 2c9af8c0..0df79bc1 100644 --- a/src/main/java/com/openshift/restclient/ResourceKind.java +++ b/src/main/java/com/openshift/restclient/ResourceKind.java @@ -44,6 +44,7 @@ public final class ResourceKind { public static final String ROUTE = "Route"; public static final String TEMPLATE = "Template"; public static final String USER = "User"; + public static final String GROUP = "Group"; public static final String IDENTITY = "Identity"; // Kubernetes Kinds @@ -125,6 +126,7 @@ public static String pluralize(String kind, boolean lowercase, boolean uncapital set.add(ROUTE); set.add(TEMPLATE); set.add(USER); + set.add(GROUP); set.add(IDENTITY); // Kubernetes Kinds diff --git a/src/main/java/com/openshift/restclient/model/user/IGroup.java b/src/main/java/com/openshift/restclient/model/user/IGroup.java new file mode 100644 index 00000000..93dbf9a7 --- /dev/null +++ b/src/main/java/com/openshift/restclient/model/user/IGroup.java @@ -0,0 +1,36 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + * Roland T. Lichti - implementation of user.openshift.io/v1/groups + ******************************************************************************/ + +package com.openshift.restclient.model.user; + +import java.util.Set; + +import com.openshift.restclient.model.IResource; + +/** + * The group definition within OpenShift. + */ +public interface IGroup extends IResource { + + /** + * + * @return the group uid as specified in the metadata + */ + String getUID(); + + /** + * + * @return the users of this group + */ + Set getUsers(); +} diff --git a/src/main/java/com/openshift/restclient/model/user/IUser.java b/src/main/java/com/openshift/restclient/model/user/IUser.java index bd5d3711..a78434c8 100644 --- a/src/main/java/com/openshift/restclient/model/user/IUser.java +++ b/src/main/java/com/openshift/restclient/model/user/IUser.java @@ -11,6 +11,8 @@ package com.openshift.restclient.model.user; +import java.util.Set; + import com.openshift.restclient.model.IResource; public interface IUser extends IResource { @@ -26,4 +28,16 @@ public interface IUser extends IResource { * */ String getUID(); + + /** + * Returns the name of the groups this user belongs to + * + */ + Set getGroups(); + + /** + * Returns the identities that point to this user + * + */ + Set getIdentities(); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/GroupTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/GroupTest.java new file mode 100644 index 00000000..0b05bed0 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/v1/GroupTest.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat, Inc. + * + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + * Roland T. Lichti - implementation of user.openshift.io/v1/groups + ******************************************************************************/ + +package com.openshift.internal.restclient.model.v1; + +import java.util.HashSet; +import java.util.Set; + +import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; +import com.openshift.internal.restclient.model.user.OpenShiftGroup; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.user.IGroup; +import com.openshift.restclient.utils.Samples; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +/** + * Test to validate the lookup paths are correct for the version + */ +public class GroupTest { + + private static final String VERSION = "v1"; + private IGroup group; + + @Before + public void setUp() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_GROUP.getContentAsString()); + group = new OpenShiftGroup(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.GROUP)); + } + + @Test + public void testGroupName() { + assertEquals("test-group", group.getName()); + } + + @Test + public void testUid() { + assertEquals("5374bc7a-c985-11e8-8799-525400d45cd2", group.getUID()); + } + + @Test + public void testUsers() { + Set userlist = new HashSet<>(1); + userlist.add("test-admin"); + + assertEquals(group.getUsers(), userlist); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java index a128b9fd..9a0d7bfc 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java @@ -9,12 +9,7 @@ package com.openshift.internal.restclient.model.v1; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; - -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; +import java.util.HashSet; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.internal.restclient.model.user.OpenShiftUser; @@ -22,6 +17,12 @@ import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.user.IUser; import com.openshift.restclient.utils.Samples; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; /** * Test to validate the lookup paths are correct for the version @@ -49,4 +50,19 @@ public void testUid() { assertEquals("94b42e96-0faa-11e5-9467-080027893417", user.getUID()); } + @Test + public void testIdentities() { + HashSet identities = new HashSet<>(1); + identities.add("anypassword:test-admin"); + + assertEquals(identities, user.getIdentities()); + } + + @Test + public void testGroups() { + HashSet groups = new HashSet<>(1); + groups.add("test-group"); + + assertEquals(groups, user.getGroups()); + } } diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 15c08fdd..46bdd391 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -61,6 +61,7 @@ public enum Samples { V1_TEMPLATE("openshift3/v1_template.json"), V1_USER("openshift3/v1_user.json"), V1_IDENTITY("openshift3/v1_identity.json"), + V1_GROUP("openshift3/v1_group.json"), V1_SECRET("openshift3/v1_secret.json"), V1_UNRECOGNIZED("openshift3/v1_unrecognized.json"), V1_CONFIG_MAP("openshift3/v1_config_map.json"), diff --git a/src/test/resources/samples/openshift3/v1_group.json b/src/test/resources/samples/openshift3/v1_group.json new file mode 100644 index 00000000..d7eda2e3 --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_group.json @@ -0,0 +1,14 @@ +{ + "apiVersion": "user.openshift.io/v1", + "kind": "Group", + "metadata": { + "creationTimestamp": "2018-10-06T16:31:50Z", + "name": "test-group", + "resourceVersion": "33097", + "selfLink": "/apis/user.openshift.io/v1/groups/clusteradmins", + "uid": "5374bc7a-c985-11e8-8799-525400d45cd2" + }, + "users": [ + "test-admin" + ] +} \ No newline at end of file diff --git a/src/test/resources/samples/openshift3/v1_user.json b/src/test/resources/samples/openshift3/v1_user.json index 182deeb3..87034680 100644 --- a/src/test/resources/samples/openshift3/v1_user.json +++ b/src/test/resources/samples/openshift3/v1_user.json @@ -12,5 +12,7 @@ "identities": [ "anypassword:test-admin" ], - "groups": null + "groups": [ + "test-group" + ] } From e7dba58e070231537020e041daa9b931025c1a37 Mon Sep 17 00:00:00 2001 From: "Roland T. Lichti" Date: Sat, 6 Oct 2018 19:06:56 +0200 Subject: [PATCH 141/258] Needed to change import order to fulfill the checkstyle. --- .../restclient/model/user/OpenShiftGroup.java | 5 +++-- .../restclient/model/user/OpenShiftIdentity.java | 3 ++- .../restclient/model/user/OpenShiftUser.java | 5 +++-- .../internal/restclient/model/v1/GroupTest.java | 13 +++++++------ .../internal/restclient/model/v1/IdentityTest.java | 13 +++++++------ .../internal/restclient/model/v1/UserTest.java | 13 +++++++------ 6 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java index 92c8e3b5..51b0d958 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java @@ -16,11 +16,12 @@ import java.util.Map; import java.util.Set; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; + import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.restclient.IClient; import com.openshift.restclient.model.user.IGroup; -import org.jboss.dmr.ModelNode; -import org.jboss.dmr.ModelType; public class OpenShiftGroup extends KubernetesResource implements IGroup { diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java index 97dab963..c37111d0 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java @@ -15,12 +15,13 @@ import java.util.Map; +import org.jboss.dmr.ModelNode; + import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.internal.restclient.model.ObjectReference; import com.openshift.restclient.IClient; import com.openshift.restclient.model.IObjectReference; import com.openshift.restclient.model.user.IIdentity; -import org.jboss.dmr.ModelNode; public class OpenShiftIdentity extends KubernetesResource implements IIdentity { diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java index 8efe32d2..99e3c449 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java @@ -14,11 +14,12 @@ import java.util.Map; import java.util.Set; +import org.jboss.dmr.ModelNode; +import org.jboss.dmr.ModelType; + import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.restclient.IClient; import com.openshift.restclient.model.user.IUser; -import org.jboss.dmr.ModelNode; -import org.jboss.dmr.ModelType; public class OpenShiftUser extends KubernetesResource implements IUser { diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/GroupTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/GroupTest.java index 0b05bed0..ee57ad18 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/GroupTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/GroupTest.java @@ -13,21 +13,22 @@ package com.openshift.internal.restclient.model.v1; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + import java.util.HashSet; import java.util.Set; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.internal.restclient.model.user.OpenShiftGroup; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.user.IGroup; import com.openshift.restclient.utils.Samples; -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; /** * Test to validate the lookup paths are correct for the version diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/IdentityTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/IdentityTest.java index 7721b31d..67d5f881 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/IdentityTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/IdentityTest.java @@ -13,18 +13,19 @@ package com.openshift.internal.restclient.model.v1; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.internal.restclient.model.user.OpenShiftIdentity; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.user.IIdentity; import com.openshift.restclient.utils.Samples; -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; /** * Test to validate the lookup paths are correct for the version diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java index 9a0d7bfc..15fb0ce0 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/UserTest.java @@ -9,20 +9,21 @@ package com.openshift.internal.restclient.model.v1; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; + import java.util.HashSet; +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.internal.restclient.model.user.OpenShiftUser; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.user.IUser; import com.openshift.restclient.utils.Samples; -import org.jboss.dmr.ModelNode; -import org.junit.Before; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.mock; /** * Test to validate the lookup paths are correct for the version From 0dad350902a845bb48a4383ad52eeda18cc60291 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 9 Oct 2018 16:13:26 +0200 Subject: [PATCH 142/258] bumped common-compress to 1.18 (sec vulnerability in 1.8.1) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 937e8618..1692cad8 100755 --- a/pom.xml +++ b/pom.xml @@ -181,7 +181,7 @@ org.apache.commons commons-compress - 1.8.1 + 1.18 junit From 1cf06a8166877b4af90f1d3ab2b3d4732db6f851 Mon Sep 17 00:00:00 2001 From: "Roland T. Lichti" Date: Wed, 10 Oct 2018 23:36:56 +0200 Subject: [PATCH 143/258] Extracted the metadata.uid as proposed to ResourcePropertyKeys. --- .../restclient/model/properties/ResourcePropertyKeys.java | 1 + .../internal/restclient/model/user/OpenShiftGroup.java | 2 +- .../internal/restclient/model/user/OpenShiftIdentity.java | 2 +- .../internal/restclient/model/user/OpenShiftUser.java | 8 +++++--- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java b/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java index 9cfc9400..3321495e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java +++ b/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java @@ -24,6 +24,7 @@ public interface ResourcePropertyKeys { static final String METADATA_NAME = "metadata.name"; static final String METADATA_RESOURCE_VERSION = "metadata.resourceVersion"; static final String METADATA_NAMESPACE = "metadata.namespace"; + static final String METADATA_UID = "metadata.uid"; static final String FROM = "from"; static final String NAME = "name"; diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java index 51b0d958..bc5d85c8 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftGroup.java @@ -33,7 +33,7 @@ public OpenShiftGroup(ModelNode node, IClient client, Map prop @Override public String getUID() { - return asString("metadata.uid"); + return asString(METADATA_UID); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java index c37111d0..2dc21c90 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftIdentity.java @@ -41,7 +41,7 @@ public String getUserName() { @Override public String getUID() { - return asString("metadata.uid"); + return asString(METADATA_UID); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java index 99e3c449..89e1f6fe 100644 --- a/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java +++ b/src/main/java/com/openshift/internal/restclient/model/user/OpenShiftUser.java @@ -24,6 +24,8 @@ public class OpenShiftUser extends KubernetesResource implements IUser { private static final String USER_FULLNAME = "fullName"; + private static final String GROUPS = "groups"; + private static final String IDENTITES = "identities"; public OpenShiftUser(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); @@ -36,16 +38,16 @@ public String getFullName() { @Override public String getUID() { - return asString("metadata.uid"); + return asString(METADATA_UID); } @Override public Set getGroups() { - return asSet("groups", ModelType.STRING); + return asSet(GROUPS, ModelType.STRING); } @Override public Set getIdentities() { - return asSet("identities", ModelType.STRING); + return asSet(IDENTITES, ModelType.STRING); } } From 96db8ebec8dbe4474ddad55c7c7876d6a1e1f4f3 Mon Sep 17 00:00:00 2001 From: Alex P Date: Mon, 22 Oct 2018 21:41:47 +0300 Subject: [PATCH 144/258] added setter and getter for nodePort tests changed --- .../restclient/model/ServicePort.java | 20 +++++++++++++++++++ .../restclient/model/IServicePort.java | 8 ++++++++ .../restclient/model/PortFactory.java | 7 ++++--- .../restclient/model/v1/ServiceTest.java | 6 +++--- .../samples/openshift3/v1_service.json | 12 +++++------ 5 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/ServicePort.java b/src/main/java/com/openshift/internal/restclient/model/ServicePort.java index 56ed35b1..64b8f785 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ServicePort.java +++ b/src/main/java/com/openshift/internal/restclient/model/ServicePort.java @@ -28,6 +28,7 @@ public class ServicePort extends ModelNodeAdapter implements IServicePort { private static final String PROPERTY_PORT = "port"; private static final String PROPERTY_PROTOCOL = "protocol"; private static final String PROPERTY_TARGET_PORT = "targetPort"; + private static final String PROPERTY_NODE_PORT = "nodePort"; private static final Map KEY_MAP = new HashMap<>(); static { @@ -35,6 +36,7 @@ public class ServicePort extends ModelNodeAdapter implements IServicePort { KEY_MAP.put(PROPERTY_PORT, new String[] { PROPERTY_PORT }); KEY_MAP.put(PROPERTY_PROTOCOL, new String[] { PROPERTY_PROTOCOL }); KEY_MAP.put(PROPERTY_TARGET_PORT, new String[] { PROPERTY_TARGET_PORT }); + KEY_MAP.put(PROPERTY_NODE_PORT, new String[] { PROPERTY_NODE_PORT }); } public ServicePort(ModelNode node) { @@ -53,6 +55,7 @@ public ServicePort(ModelNode node, IServicePort port) { setPort(port.getPort()); setProtocol(port.getProtocol()); setTargetPort(port.getTargetPort()); + setNodePort(port.getNodePort()); } @Override @@ -103,6 +106,16 @@ public void setProtocol(String proto) { set(getNode(), KEY_MAP, PROPERTY_PROTOCOL, proto); } + @Override + public String getNodePort() { + return asString(getNode(), KEY_MAP, PROPERTY_NODE_PORT); + } + + @Override + public void setNodePort(String nodePort) { + set(getNode(), KEY_MAP, PROPERTY_NODE_PORT, nodePort); + } + @Override public int hashCode() { final int prime = 31; @@ -150,6 +163,13 @@ public boolean equals(Object obj) { } else if (!getProtocol().equals(other.getProtocol())) { return false; } + if (getNodePort() == null) { + if (other.getNodePort() != null) { + return false; + } + } else if (!getNodePort().equals(other.getNodePort())) { + return false; + } return true; } diff --git a/src/main/java/com/openshift/restclient/model/IServicePort.java b/src/main/java/com/openshift/restclient/model/IServicePort.java index 6e39cb07..14e6b027 100644 --- a/src/main/java/com/openshift/restclient/model/IServicePort.java +++ b/src/main/java/com/openshift/restclient/model/IServicePort.java @@ -48,4 +48,12 @@ public interface IServicePort { String getProtocol(); void setProtocol(String proto); + + /** + * External service port + */ + + String getNodePort(); + + void setNodePort(String nodePort); } diff --git a/src/test/java/com/openshift/internal/restclient/model/PortFactory.java b/src/test/java/com/openshift/internal/restclient/model/PortFactory.java index f59cbbbe..3004ba64 100644 --- a/src/test/java/com/openshift/internal/restclient/model/PortFactory.java +++ b/src/test/java/com/openshift/internal/restclient/model/PortFactory.java @@ -15,16 +15,17 @@ public class PortFactory { - public static ServicePort createServicePort(String name, String proto, int port, int targetPort) { - return createServicePort(name, proto, port, String.valueOf(targetPort)); + public static ServicePort createServicePort(String name, String proto, int port, int targetPort,int nodePort) { + return createServicePort(name, proto, port, String.valueOf(targetPort),String.valueOf(nodePort)); } - public static ServicePort createServicePort(String name, String proto, int port, String targetPort) { + public static ServicePort createServicePort(String name, String proto, int port, String targetPort, String nodePort) { ModelNode node = new ModelNode(); node.get("name").set(name); node.get("protocol").set(proto); node.get("port").set(port); node.get("targetPort").set(targetPort); + node.get("nodePort").set(nodePort); return new ServicePort(node); } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java index 3867aee8..fec2e086 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ServiceTest.java @@ -121,13 +121,13 @@ public void testSetNamespace() { public void testGetPorts() { IServicePort[] ports = service.getPorts().toArray(new IServicePort[] {}); assertEquals(2, ports.length); - assertEquals(PortFactory.createServicePort("db", "TCP", 5434, 3306), ports[0]); - assertEquals(PortFactory.createServicePort("other", "TCP", 9999, 8888), ports[1]); + assertEquals(PortFactory.createServicePort("db", "TCP", 5434, 3306,45678), ports[0]); + assertEquals(PortFactory.createServicePort("other", "TCP", 9999, 8888,56789), ports[1]); } @Test public void testSetPorts() { - IServicePort port = PortFactory.createServicePort("newport", "TCP", 4444, 5555); + IServicePort port = PortFactory.createServicePort("newport", "TCP", 4444, 5555,6666); service.setPorts(Arrays.asList(port)); IServicePort[] ports = service.getPorts().toArray(new IServicePort[] {}); assertEquals(1, service.getPorts().size()); diff --git a/src/test/resources/samples/openshift3/v1_service.json b/src/test/resources/samples/openshift3/v1_service.json index 44738f64..57454ad4 100644 --- a/src/test/resources/samples/openshift3/v1_service.json +++ b/src/test/resources/samples/openshift3/v1_service.json @@ -20,14 +20,14 @@ "protocol": "TCP", "port": 5434, "targetPort": 3306, - "nodePort": 0 + "nodePort": 45678 }, { - "name": "other", - "protocol": "TCP", - "port": 9999, - "targetPort": 8888, - "nodePort": 0 + "name": "other", + "protocol": "TCP", + "port": 9999, + "targetPort": 8888, + "nodePort": 56789 } ], "selector": { From 01efe213c46448194dc4d5538f43757292a0268c Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 23 Nov 2018 11:36:54 +0100 Subject: [PATCH 145/258] bump to 7.0.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1692cad8..ef63e593 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 7.0.0-SNAPSHOT + 7.0.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From fee040f2872a406504a058fe67ab13ad4e061314 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 23 Nov 2018 19:09:50 +0100 Subject: [PATCH 146/258] bump to 7.0.1-SNAPSHOT after release of 7.0.0.Final --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ef63e593..3b4ff55e 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 7.0.0.Final + 7.0.1-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 0e207e9ce1b18f1f7372d261bc2f53ee315787cd Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 7 Dec 2018 21:29:01 +0100 Subject: [PATCH 147/258] using java.util.Base64 instead of javax.xml.bind.DatatypeConverter ...to allow us to run on jdk9+ Signed-off-by: Andre Dietisheim --- .../restclient/utils/Base64Coder.java | 78 ++++++++++++------- .../restclient/model/v1/SecretTest.java | 2 +- .../samples/openshift3/v1_secret.json | 2 +- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/openshift/restclient/utils/Base64Coder.java b/src/main/java/com/openshift/restclient/utils/Base64Coder.java index d605b28f..bb8a1b91 100644 --- a/src/main/java/com/openshift/restclient/utils/Base64Coder.java +++ b/src/main/java/com/openshift/restclient/utils/Base64Coder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Red Hat, Inc. +4 * Copyright (c) 2013-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -11,9 +11,10 @@ package com.openshift.restclient.utils; -import javax.xml.bind.DatatypeConverter; +import java.nio.charset.Charset; +import java.util.Base64; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.ArrayUtils; /** * A utility class that offers methods to encode and decode strings from and to @@ -28,19 +29,36 @@ private Base64Coder() { } /** - * Encodes the given byte array to a base64 encoded String + * Encodes the given byte array to a base64 encoded String. returns {@code null} + * if the given byte array is null, empty string if the given byte array is + * empty. * - * @param unencoded - * the array of unencoded bytes that shall get encoded - * @return the encoded string + * @param unencoded the array of unencoded bytes that shall get encoded + * @return the encoded string created using the platform standard charset + * + * @see Charset#defaultCharset */ public static String encode(byte[] unencoded) { + return encode(unencoded, Charset.defaultCharset()); + } + + /** + * Encodes the given byte array to a base64 encoded String. returns {@code null} + * if the given byte array is null, empty string if the given byte array is + * empty. + * + * @param unencoded the array of unencoded bytes that shall get encoded + * @return the encoded string created using the platform standard charset + * + * @see Charset#defaultCharset + */ + public static String encode(byte[] unencoded, Charset charset) { if (unencoded == null) { return null; } else if (unencoded.length == 0) { - return new String(); + return ""; } - return DatatypeConverter.printBase64Binary(unencoded); + return new String(Base64.getEncoder().encode(unencoded), charset); } /** @@ -49,21 +67,28 @@ public static String encode(byte[] unencoded) { * */ public static String encode(String unencoded) { - if (StringUtils.isEmpty(unencoded)) { - return unencoded; + if (unencoded == null) { + return null; + } + return encode(unencoded.getBytes(), Charset.defaultCharset()); + } + + public static String encode(String unencoded, Charset charset) { + if (unencoded == null) { + return null; } - return encode(unencoded.getBytes()); + return encode(unencoded.getBytes(), charset); } - public static String decode(byte[] encoded) { - if (encoded == null || encoded.length == 0) { - return new String(); + public static String decode(byte[] encoded, Charset charset) { + if (ArrayUtils.isEmpty(encoded)) { + return ""; } - return decode(new String(encoded)); + return new String(Base64.getDecoder().decode(encoded), charset); } /** - * Decodes the given base64 encoded string. Returns null if the + * Decodes the given base64 encoded string assuming the default charset. Returns null if the * given string is null. * * @param encoded @@ -71,22 +96,21 @@ public static String decode(byte[] encoded) { * @return the decoded string */ public static String decode(String encoded) { - byte[] encodedBytes = decodeBinary(encoded); - return (encodedBytes == null) ? encoded : new String(DatatypeConverter.parseBase64Binary(encoded)); + if (encoded == null) { + return null; + } + return decode(encoded.getBytes(Charset.defaultCharset()), Charset.defaultCharset()); } /** - * Decodes the given base64 encoded string. Returns null if the - * given string is null. + * Decodes the given base64 encoded string using the default charset. Returns + * null if the given string is null. * - * @param encoded - * the base64 encoded string + * @param encoded the base64 encoded string * @return the decoded binary data */ public static byte[] decodeBinary(String encoded) { - if (StringUtils.isEmpty(encoded)) { - return null; - } - return DatatypeConverter.parseBase64Binary(encoded); + Charset charset = Charset.defaultCharset(); + return decode(encoded.getBytes(charset), charset).getBytes(charset); } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java index 6bbb1e1d..77a16a80 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java @@ -52,7 +52,7 @@ public void testSecretType() { @Test public void testGetData() { - assertTrue(StringUtils.isNotBlank(new String(secret.getData(".dockercfg")))); + assertEquals("value-1", new String(secret.getData(".dockercfg"))); } @Test diff --git a/src/test/resources/samples/openshift3/v1_secret.json b/src/test/resources/samples/openshift3/v1_secret.json index 19330d2d..19a73f7d 100644 --- a/src/test/resources/samples/openshift3/v1_secret.json +++ b/src/test/resources/samples/openshift3/v1_secret.json @@ -15,7 +15,7 @@ } }, "data": { - ".dockercfg": "value-1" + ".dockercfg": "dmFsdWUtMQ==" }, "type": "kubernetes.io/dockercfg" } \ No newline at end of file From 7f0283e78128e72fc075743a2318e793ee08821a Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 6 Feb 2019 09:43:29 +0100 Subject: [PATCH 148/258] removed unnecessary casts. Signed-off-by: Andre Dietisheim --- .../internal/restclient/DefaultClient.java | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index eacfa349..5c70ee88 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -74,7 +74,7 @@ public class DefaultClient implements IClient, IHttpConstants { private URL baseUrl; private OkHttpClient client; private IResourceFactory factory; - private Map, ICapability> capabilities = new HashMap, ICapability>(); + private Map, ICapability> capabilities = new HashMap<>(); private boolean capabilitiesInitialized = false; private static final String OS_API_ENDPOINT = "oapi"; @@ -169,7 +169,7 @@ public List list(String kind, String namespace, String @Override public Collection create(IList list, String namespace) { - List results = new ArrayList(list.getItems().size()); + List results = new ArrayList<>(list.getItems().size()); for (IResource resource : list.getItems()) { try { results.add(create(resource, namespace)); @@ -224,51 +224,44 @@ private T execute(HttpMethod method, String kind, String v return execute(method.toString(), kind, version, namespace, name, subresource, payload, parameters); } - @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, String subContext) { - return (T) execute(this.factory, method, kind, namespace, name, subresource, subContext, payload, + return execute(this.factory, method, kind, namespace, name, subresource, subContext, payload, Collections.emptyMap()); } @Override - @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload) { - return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload, + return execute(this.factory, method, kind, namespace, name, subresource, null, payload, Collections.emptyMap()); } @Override - @SuppressWarnings("unchecked") public T execute(String method, String kind, String version, String namespace, String name, String subresource, InputStream payload) { - return (T) execute(this.factory, method, kind, version, namespace, name, subresource, null, payload, + return execute(this.factory, method, kind, version, namespace, name, subresource, null, payload, Collections.emptyMap()); } @Override - @SuppressWarnings("unchecked") public T execute(String method, String kind, String version, String namespace, String name, String subresource, InputStream payload, Map parameters) { - return (T) execute(this.factory, method, kind, version, namespace, name, subresource, null, payload, + return execute(this.factory, method, kind, version, namespace, name, subresource, null, payload, parameters); } @Override - @SuppressWarnings("unchecked") public T execute(String method, String kind, String namespace, String name, String subresource, IResource payload, Map params) { - return (T) execute(this.factory, method, kind, namespace, name, subresource, null, payload, params); + return execute(this.factory, method, kind, namespace, name, subresource, null, payload, params); } - @SuppressWarnings("unchecked") public T execute(ITypeFactory factory, String method, String kind, String version, String namespace, String name, String subresource, String subContext, InputStream payload, Map params) { return execute(factory, method, kind, version, namespace, name, subresource, subContext, getPayload(method, payload), params); } - @SuppressWarnings("unchecked") public T execute(ITypeFactory factory, String method, String kind, String namespace, String name, String subresource, String subContext, JSONSerializeable payload, Map params) { return execute(factory, method, kind, getApiVersion(payload), namespace, name, subresource, subContext, @@ -317,7 +310,6 @@ private RequestBody getPayload(String method, JSONSerializeable payload) { switch (method.toUpperCase()) { case "GET": case "DELETE": - return null; default: String json = payload == null ? "" : payload.toJson(true); LOGGER.debug("About to send payload: {}", json); @@ -329,7 +321,6 @@ private RequestBody getPayload(String method, InputStream payload) { switch (method.toUpperCase()) { case "GET": case "DELETE": - return null; default: LOGGER.debug("About to send binary payload"); RequestBody requestBody = new RequestBody() { @@ -367,7 +358,7 @@ public Request.Builder newRequestBuilderTo(String endpoint) { } public Request.Builder newRequestBuilderTo(String endpoint, String acceptMediaType) { - Request.Builder builder = new Request.Builder().url(endpoint.toString()).header(PROPERTY_ACCEPT, + Request.Builder builder = new Request.Builder().url(endpoint).header(PROPERTY_ACCEPT, acceptMediaType); String token = null; @@ -430,7 +421,7 @@ public R accept(CapabilityVisitor visitor, R un } if (capabilities.containsKey(visitor.getCapabilityType())) { T capability = (T) capabilities.get(visitor.getCapabilityType()); - return (R) visitor.visit(capability); + return visitor.visit(capability); } return unsupportedCapabililityValue; } From 161992370aad8ab4dc498e0b97dfec9d77513992 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 6 Feb 2019 16:56:01 +0100 Subject: [PATCH 149/258] added missing override in ModelNodeAdapter Signed-off-by: Andre Dietisheim --- .../openshift/internal/restclient/model/ModelNodeAdapter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java b/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java index 1a83dab2..bc35e76f 100644 --- a/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java +++ b/src/main/java/com/openshift/internal/restclient/model/ModelNodeAdapter.java @@ -41,6 +41,7 @@ public String toJson() { return toJson(false); } + @Override public String toJson(boolean compact) { return JBossDmrExtentions.toJsonString(node, compact); } From 47e77aba1a52fd53e01fc8720a7efbc4c36c6991 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 6 Feb 2019 16:57:30 +0100 Subject: [PATCH 150/258] remove duplicate ResourceKind.pluralize in ApiTypeMapper Signed-off-by: Andre Dietisheim --- .../java/com/openshift/internal/restclient/ApiTypeMapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index 9bea7335..bd918722 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -101,7 +101,7 @@ private IVersionedApiResource endpointFor(String version, String kind) { .map(api -> formatEndpointFor(api, (split.length == 0 ? preferedVersion.get(api) : split[0]), kind)) .filter(e -> resourceEndpoints.contains(e)).findFirst(); } else { - result = Optional.of(formatEndpointFor(API_GROUPS_API, version, ResourceKind.pluralize(kind, true, true))); + result = Optional.of(formatEndpointFor(API_GROUPS_API, version, kind)); } if (result.isPresent()) { int index = resourceEndpoints.indexOf(result.get()); From 0968abdd1ff777da2d97dbbc7c18d2a49b642cd4 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 6 Feb 2019 16:58:22 +0100 Subject: [PATCH 151/258] Make sure http delete is using payload Signed-off-by: Andre Dietisheim --- .../internal/restclient/DefaultClient.java | 79 +++++----- .../restclient/DefaultClientTest.java | 142 +++++++++++++++++- 2 files changed, 184 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 5c70ee88..ac7db2bb 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -211,7 +211,7 @@ public T create(String kind, String version, String namesp } enum HttpMethod { - GET, PUT, POST, DELETE + GET, PUT, POST, DELETE, HEAD } private T execute(HttpMethod method, String kind, String namespace, String name, @@ -259,13 +259,14 @@ public T execute(String method, String kind, String namesp public T execute(ITypeFactory factory, String method, String kind, String version, String namespace, String name, String subresource, String subContext, InputStream payload, Map params) { - return execute(factory, method, kind, version, namespace, name, subresource, subContext, getPayload(method, payload), params); + return execute(factory, method, kind, version, namespace, name, subresource, subContext, + getPayload(payload, method), params); } public T execute(ITypeFactory factory, String method, String kind, String namespace, String name, String subresource, String subContext, JSONSerializeable payload, Map params) { return execute(factory, method, kind, getApiVersion(payload), namespace, name, subresource, subContext, - getPayload(method, payload), params); + getPayload(payload, method), params); } private T execute(ITypeFactory factory, String method, String kind, String version, String namespace, @@ -286,7 +287,9 @@ private T execute(ITypeFactory factory, String method, String kind, String v .namespace(namespace).subresource(subresource).subContext(subContext).addParameters(params).build(); try { - Request request = newRequestBuilderTo(endpoint.toString()).method(method, requestBody).build(); + Request request = newRequestBuilderTo(endpoint.toString()) + .method(method, requestBody) + .build(); LOGGER.debug("About to make {} request: {}", request.method(), request); try (Response result = client.newCall(request).execute()) { String response = result.body().string(); @@ -306,44 +309,48 @@ private String getApiVersion(JSONSerializeable payload) { return apiVersion; } - private RequestBody getPayload(String method, JSONSerializeable payload) { - switch (method.toUpperCase()) { - case "GET": - case "DELETE": - default: - String json = payload == null ? "" : payload.toJson(true); - LOGGER.debug("About to send payload: {}", json); - return RequestBody.create(MediaType.parse(MEDIATYPE_APPLICATION_JSON), json); - } - } - - private RequestBody getPayload(String method, InputStream payload) { - switch (method.toUpperCase()) { - case "GET": - case "DELETE": - default: - LOGGER.debug("About to send binary payload"); - RequestBody requestBody = new RequestBody() { - @Override - public void writeTo(BufferedSink sink) throws IOException { - Source source = Okio.source(payload); - sink.writeAll(source); - } - - @Override - public MediaType contentType() { - return MediaType.parse(MEDIATYPE_APPLICATION_OCTET_STREAM); - } - }; - return requestBody; + private RequestBody getPayload(JSONSerializeable payload, String method) { + if(isPayloadlessMethod(method)) { + return null; + } + String json = payload == null ? "" : payload.toJson(true); + LOGGER.debug("About to send payload: {}", json); + return RequestBody.create(MediaType.parse(MEDIATYPE_APPLICATION_JSON), json); + } + + + private RequestBody getPayload(InputStream payload, String method) { + if(isPayloadlessMethod(method)) { + return null; } + LOGGER.debug("About to send binary payload"); + return new RequestBody() { + @Override + public void writeTo(BufferedSink sink) throws IOException { + Source source = Okio.source(payload); + sink.writeAll(source); + } + + @Override + public MediaType contentType() { + return MediaType.parse(MEDIATYPE_APPLICATION_OCTET_STREAM); + } + }; + } + + private boolean isPayloadlessMethod(String method) { + String uppercaseMethod = StringUtils.upperCase(method); + return HttpMethod.GET.name().equals(uppercaseMethod) + || HttpMethod.HEAD.name().equals(uppercaseMethod); } @Override public String getServerReadyStatus() { try { - Request request = new Request.Builder().url(new URL(this.baseUrl, URL_HEALTH_CHECK)) - .header(PROPERTY_ACCEPT, "*/*").build(); + Request request = new Request.Builder() + .url(new URL(this.baseUrl, URL_HEALTH_CHECK)) + .header(PROPERTY_ACCEPT, "*/*") + .build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 937b026c..b13f3da6 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014-2016 Red Hat, Inc. + * Copyright (c) 2014-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -12,19 +12,37 @@ package com.openshift.internal.restclient; import static org.fest.assertions.Assertions.assertThat; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import java.io.IOException; import java.net.URL; +import org.apache.commons.io.output.ByteArrayOutputStream; import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; import org.mockito.runners.MockitoJUnitRunner; +import com.openshift.internal.restclient.DefaultClient.HttpMethod; import com.openshift.internal.restclient.authorization.AuthorizationContext; import com.openshift.internal.restclient.model.Pod; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.api.ITypeFactory; +import com.openshift.restclient.model.JSONSerializeable; + +import okhttp3.Request; +import okhttp3.Request.Builder; +import okhttp3.RequestBody; +import okio.Buffer; /** * @author Jeff Cantrill @@ -91,6 +109,16 @@ private DefaultClient givenClient(URL baseUrl, String token, String user) { return client; } + private ITypeFactory givenTypeFactory() { + return mock(ITypeFactory.class); + } + + private JSONSerializeable givenJsonPayload(String string) { + JSONSerializeable json = mock(JSONSerializeable.class); + when(json.toJson(anyBoolean())).thenReturn(string); + return json; + } + @Test public void clientShouldEqualClientWithSameUrl() throws Exception { assertThat(givenClient(baseUrl, null, null)).isEqualTo(givenClient(baseUrl, null, null)); @@ -102,6 +130,7 @@ public void clientShouldNotEqualClientWithDifferentUrl() throws Exception { .isNotEqualTo(givenClient(new URL("http://localhost:8443"), null, null)); } + @Test public void client_should_equal_client_with_same_user_with_different_token() throws Exception { DefaultClient tokenClientOne = givenClient(baseUrl, "tokenOne", "aUser"); @@ -118,5 +147,116 @@ public void client_should_not_equal_client_with_different_username() throws Exce assertThat(tokenClientOne).isNotEqualTo(tokenClientTwo); } + + @Test + public void should_use_paylod_in_delete_request() throws IOException { + // given + DefaultClient client = spy(this.client); + + Builder builder = givenRequestBuilder(client); + ArgumentCaptor builderCaptor = ArgumentCaptor.forClass(RequestBody.class); + String payload = "{prop1:\"val1\"}"; + + // when + client.execute(givenTypeFactory(), HttpMethod.DELETE.toString(), + ResourceKind.BUILD, null, null, null, null, + givenJsonPayload(payload), null); + + // then + String requestBodyPayload = getPayload(builder, builderCaptor); + assertThat(requestBodyPayload).isEqualTo(payload); + } + + @Test + public void should_use_paylod_in_post_request() throws IOException { + // given + DefaultClient client = spy(this.client); + + Builder builder = givenRequestBuilder(client); + ArgumentCaptor builderCaptor = ArgumentCaptor.forClass(RequestBody.class); + String payload = "{prop1:\"val1\"}"; + + // when + client.execute(givenTypeFactory(), HttpMethod.POST.toString(), + ResourceKind.BUILD, null, null, null, null, + givenJsonPayload(payload), null); + + // then + String requestBodyPayload = getPayload(builder, builderCaptor); + assertThat(requestBodyPayload).isEqualTo(payload); + } + + @Test + public void should_use_paylod_in_put_request() throws IOException { + // given + DefaultClient client = spy(this.client); + + Builder builder = givenRequestBuilder(client); + ArgumentCaptor builderCaptor = ArgumentCaptor.forClass(RequestBody.class); + String payload = "{prop1:\"val1\"}"; + + // when + client.execute(givenTypeFactory(), HttpMethod.PUT.toString(), + ResourceKind.BUILD, null, null, null, null, + givenJsonPayload(payload), null); + + // then + String requestBodyPayload = getPayload(builder, builderCaptor); + assertThat(requestBodyPayload).isEqualTo(payload); + } + + @Test + public void should_not_use_paylod_in_get_request() throws IOException { + // given + DefaultClient client = spy(this.client); + + Builder builder = givenRequestBuilder(client); + ArgumentCaptor builderCaptor = ArgumentCaptor.forClass(RequestBody.class); + + // when + client.execute(givenTypeFactory(), HttpMethod.GET.toString(), + ResourceKind.BUILD, null, null, null, null, + givenJsonPayload("{prop1:\"val1\"}"), null); + + // then + verify(builder).method(anyString(), builderCaptor.capture()); + assertThat(builderCaptor.getValue()).isNull(); + } + + @Test + public void should_not_use_paylod_in_head_request() throws IOException { + // given + DefaultClient client = spy(this.client); + + Builder builder = givenRequestBuilder(client); + ArgumentCaptor builderCaptor = ArgumentCaptor.forClass(RequestBody.class); + + // when + client.execute(givenTypeFactory(), HttpMethod.HEAD.toString(), + ResourceKind.BUILD, null, null, null, null, + givenJsonPayload("{prop1:\"val1\"}"), null); + + // then + verify(builder).method(anyString(), builderCaptor.capture()); + assertThat(builderCaptor.getValue()).isNull(); + } + + private String getPayload(Builder builder, ArgumentCaptor builderCaptor) throws IOException { + verify(builder).method(anyString(), builderCaptor.capture()); + RequestBody requestBody = builderCaptor.getValue(); + assertThat(requestBody).isNotNull(); + Buffer buffer = new Buffer(); + requestBody.writeTo(buffer); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + buffer.copyTo(out); + String requestBodyPayload = new String(out.toByteArray()); + return requestBodyPayload; + } + + private Builder givenRequestBuilder(DefaultClient client) { + Builder builder = spy(new Request.Builder().url(this.baseUrl)); + doReturn(builder).when(client).newRequestBuilderTo(anyString(), anyString()); + return builder; + } } From d852d1d97247eae0ad201393e307a3f515081699 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 12 Feb 2019 13:43:14 +0100 Subject: [PATCH 152/258] [363] dont send resource in payload when DefaultClient#delete(IResource) Signed-off-by: Andre Dietisheim --- .../internal/restclient/DefaultClient.java | 21 ++-- .../restclient/DefaultClientTest.java | 112 ++++++++++++------ .../restclient/TypeMapperFixture.java | 14 ++- 3 files changed, 98 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index ac7db2bb..d32eb6f7 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -54,6 +54,7 @@ import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; +import okhttp3.Request.Builder; import okhttp3.RequestBody; import okhttp3.Response; import okio.BufferedSink; @@ -272,7 +273,7 @@ public T execute(ITypeFactory factory, String method, String kind, String na private T execute(ITypeFactory factory, String method, String kind, String version, String namespace, String name, String subresource, String subContext, RequestBody requestBody, Map params) { if (factory == null) { - throw new OpenShiftException("ITypeFactory is null while trying to call IClient#execute"); + throw new OpenShiftException(ITypeFactory.class.getSimpleName() + " is null while trying to call IClient#execute"); } if (params == null) { @@ -360,21 +361,25 @@ public String getServerReadyStatus() { } } - public Request.Builder newRequestBuilderTo(String endpoint) { + public Builder newRequestBuilderTo(String endpoint) { return newRequestBuilderTo(endpoint, MEDIATYPE_APPLICATION_JSON); } - public Request.Builder newRequestBuilderTo(String endpoint, String acceptMediaType) { - Request.Builder builder = new Request.Builder().url(endpoint).header(PROPERTY_ACCEPT, - acceptMediaType); + public Builder newRequestBuilderTo(String endpoint, String acceptMediaType) { + Builder builder = new Builder() + .url(endpoint) + .header(PROPERTY_ACCEPT, acceptMediaType); + addAuthorizationHeader(builder); + return builder; + } + private void addAuthorizationHeader(Builder builder) { String token = null; if (this.authContext != null && StringUtils.isNotBlank(this.authContext.getToken())) { token = this.authContext.getToken(); } builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)); - return builder; } @Override @@ -385,7 +390,7 @@ public T update(T resource) { @Override public void delete(T resource) { - execute(HttpMethod.DELETE, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, resource); + execute(HttpMethod.DELETE, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, null); } @Override @@ -440,7 +445,7 @@ public String getOpenShiftAPIVersion() { private void initMasterVersion(String versionInfoType, Callback callback) { try { - Request request = new Request.Builder().url(new URL(this.baseUrl, versionInfoType)) + Request request = new Builder().url(new URL(this.baseUrl, versionInfoType)) .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON).build(); client.newCall(request).enqueue(callback); } catch (IOException e) { diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index b13f3da6..6a8edd72 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -14,7 +14,7 @@ import static org.fest.assertions.Assertions.assertThat; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -22,6 +22,9 @@ import java.io.IOException; import java.net.URL; +import java.util.AbstractMap; +import java.util.Arrays; +import java.util.Map; import org.apache.commons.io.output.ByteArrayOutputStream; import org.jboss.dmr.ModelNode; @@ -29,7 +32,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; +import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; import com.openshift.internal.restclient.DefaultClient.HttpMethod; import com.openshift.internal.restclient.authorization.AuthorizationContext; @@ -39,7 +44,6 @@ import com.openshift.restclient.api.ITypeFactory; import com.openshift.restclient.model.JSONSerializeable; -import okhttp3.Request; import okhttp3.Request.Builder; import okhttp3.RequestBody; import okio.Buffer; @@ -59,50 +63,56 @@ public class DefaultClientTest extends TypeMapperFixture { private Pod podBackEnd; private IResourceFactory factory; private URL baseUrl; + private String podsResourceUrl = TypeMapperFixture.base + "/api/v1/namespaces/aNamespace/pods"; + private String podFrontEndResourceUrl = TypeMapperFixture.base + "/api/v1/namespaces/aNamespace/pods/frontend"; @Before public void setUp() throws Exception { super.setUp(); - this.baseUrl = new URL("http://myopenshift"); + this.baseUrl = new URL(TypeMapperFixture.base); givenAClient(); - givenAPodList(); - getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api/v1/namespaces/aNamespace/pods") + givenAPodListResponse(); + getHttpClient().whenRequestTo(podsResourceUrl) .thenReturn(responseOf(response.toJSONString(false))); } private void givenAClient() throws Exception { - factory = new ResourceFactory(null); - client = (DefaultClient) getIClient(); - factory = client.getResourceFactory(); + this.client = (DefaultClient) getIClient(); + this.factory = client.getResourceFactory(); } - private void givenAPodList() { - this.podFrontEnd = factory.create(VERSION, ResourceKind.POD); - podFrontEnd.setName("frontend"); - podFrontEnd.setNamespace("aNamespace"); - podFrontEnd.addLabel("name", "frontend"); - podFrontEnd.addLabel("env", "production"); - - this.podBackEnd = factory.create(VERSION, ResourceKind.POD); - podBackEnd.setName("backend"); - podBackEnd.setNamespace("aNamespace"); - podBackEnd.addLabel("name", "backend"); - podBackEnd.addLabel("env", "production"); - - Pod otherPod = factory.create(VERSION, ResourceKind.POD); - otherPod.setName("other"); - otherPod.setNamespace("aNamespace"); - otherPod.addLabel("env", "production"); - + private void givenAPodListResponse() { this.response = new ModelNode(); response.get("apiVersion").set(VERSION); response.get("kind").set("PodList"); ModelNode items = response.get("items"); + + this.podFrontEnd = givenAPod("frontend", "aNamespace", + new AbstractMap.SimpleEntry("name", "frontend"), + new AbstractMap.SimpleEntry("env", "production")); items.add(podFrontEnd.getNode()); + + Pod otherPod = givenAPod("other", "aNamespace", + new AbstractMap.SimpleEntry("env", "production")); items.add(otherPod.getNode()); + + this.podBackEnd = givenAPod("backend", "aNamespace", + new AbstractMap.SimpleEntry("name", "backend"), + new AbstractMap.SimpleEntry("env", "production")); items.add(podBackEnd.getNode()); } + @SafeVarargs + private final Pod givenAPod(final String name, final String namespace, final Map.Entry... labels) { + Pod pod = factory.create(VERSION, ResourceKind.POD); + pod.setName(name); + pod.setNamespace(namespace); + if (labels != null) { + Arrays.stream(labels).forEach(entry -> pod.addLabel(entry.getKey(), entry.getValue())); + } + return pod; + } + private DefaultClient givenClient(URL baseUrl, String token, String user) { DefaultClient client = new DefaultClient(baseUrl, getHttpClient(), null, null, new AuthorizationContext(token, user, null)); @@ -211,7 +221,7 @@ public void should_not_use_paylod_in_get_request() throws IOException { DefaultClient client = spy(this.client); Builder builder = givenRequestBuilder(client); - ArgumentCaptor builderCaptor = ArgumentCaptor.forClass(RequestBody.class); + ArgumentCaptor bodyCaptor = ArgumentCaptor.forClass(RequestBody.class); // when client.execute(givenTypeFactory(), HttpMethod.GET.toString(), @@ -219,8 +229,8 @@ public void should_not_use_paylod_in_get_request() throws IOException { givenJsonPayload("{prop1:\"val1\"}"), null); // then - verify(builder).method(anyString(), builderCaptor.capture()); - assertThat(builderCaptor.getValue()).isNull(); + verify(builder).method(anyString(), bodyCaptor.capture()); + assertThat(bodyCaptor.getValue()).isNull(); } @Test @@ -229,7 +239,7 @@ public void should_not_use_paylod_in_head_request() throws IOException { DefaultClient client = spy(this.client); Builder builder = givenRequestBuilder(client); - ArgumentCaptor builderCaptor = ArgumentCaptor.forClass(RequestBody.class); + ArgumentCaptor bodyCaptor = ArgumentCaptor.forClass(RequestBody.class); // when client.execute(givenTypeFactory(), HttpMethod.HEAD.toString(), @@ -237,10 +247,29 @@ public void should_not_use_paylod_in_head_request() throws IOException { givenJsonPayload("{prop1:\"val1\"}"), null); // then - verify(builder).method(anyString(), builderCaptor.capture()); - assertThat(builderCaptor.getValue()).isNull(); + verify(builder).method(anyString(), bodyCaptor.capture()); + assertThat(bodyCaptor.getValue()).isNull(); } + @Test + public void should_not_send_resource_payload_when_deleting() throws IOException { + // given + DefaultClient client = spy(this.client); + getHttpClient() + .whenRequestTo(podFrontEndResourceUrl) + .thenReturn(responseOf(response.toJSONString(false))); + + Builder builder = givenRequestBuilder(client); + ArgumentCaptor bodyCaptor = ArgumentCaptor.forClass(RequestBody.class); + + // when + client.delete(this.podFrontEnd); + + // then + verify(builder).method(anyString(), bodyCaptor.capture()); + assertThat(bodyCaptor.getValue().contentLength()).isEqualTo(0); + } + private String getPayload(Builder builder, ArgumentCaptor builderCaptor) throws IOException { verify(builder).method(anyString(), builderCaptor.capture()); RequestBody requestBody = builderCaptor.getValue(); @@ -249,13 +278,24 @@ private String getPayload(Builder builder, ArgumentCaptor builderCa requestBody.writeTo(buffer); ByteArrayOutputStream out = new ByteArrayOutputStream(); buffer.copyTo(out); - String requestBodyPayload = new String(out.toByteArray()); - return requestBodyPayload; + return new String(out.toByteArray()); } private Builder givenRequestBuilder(DefaultClient client) { - Builder builder = spy(new Request.Builder().url(this.baseUrl)); - doReturn(builder).when(client).newRequestBuilderTo(anyString(), anyString()); + final Builder builder = spy(new Builder()); + doAnswer(new Answer() { + + @Override + public Builder answer(InvocationOnMock invocation) throws Throwable { + assertThat(invocation.getArguments()).isNotNull().hasSize(2); + + // set builder url that was given as parameter + String endpoint = (String) invocation.getArguments()[0]; + builder.url(endpoint); + return builder; + } + }) + .when(client).newRequestBuilderTo(anyString(), anyString()); return builder; } diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 2ae3faec..ff077127 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -40,7 +40,7 @@ public class TypeMapperFixture { protected static final String VERSIONS = "{ \"versions\": [\"v1\"]}"; protected static final String base = "https://localhost:8443"; - private static final String ANY = "--any--"; + protected static final String ANY_URL = "--any--"; private TestOkHttpClient client = spy(new TestOkHttpClient()); protected IApiTypeMapper mapper; @@ -59,7 +59,7 @@ protected IClient getIClient() throws Exception { @Before public void setUp() throws Exception { - client.whenRequestTo(ANY).thenReturn(responseOf("")); + client.whenRequestTo(ANY_URL).thenReturn(responseOf("")); client.whenRequestTo(base + "/api").thenReturn(responseOf(VERSIONS)); client.whenRequestTo(base + "/oapi").thenReturn(responseOf(VERSIONS)); client.whenRequestTo(base + "/apis").thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS.getContentAsString())); @@ -90,8 +90,12 @@ static Request requestTo(String url) { } protected static Response responseOf(String response) { - return new Response.Builder().request(new Request.Builder().url("https://someurlfortesting").build()) - .protocol(Protocol.HTTP_1_1).code(IHttpConstants.STATUS_OK).message("").body(ResponseBody.create(null, response)) + return new Response.Builder() + .request(new Request.Builder().url("https://someurlfortesting").build()) + .protocol(Protocol.HTTP_1_1) + .code(IHttpConstants.STATUS_OK) + .message("") + .body(ResponseBody.create(null, response)) .build(); } @@ -105,7 +109,7 @@ public RequestMatcher(String url) { @Override public boolean matches(Object argument) { - if (ANY.equals(this.url)) { + if (ANY_URL.equals(this.url)) { return true; } if (argument == null || !(argument instanceof Request)) { From 69f65a8e17ebd088bfb17721354245c71d8eee9b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 13 Feb 2019 20:31:51 +0100 Subject: [PATCH 153/258] [365] fixes integration-tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * corrected rsync log assertion: removed é from filename since log reports name as octal utf8 by rsync * killing resources - not project - upon test teardown (project removal is async, prohibits new test from creating test resources) * wait for pod to be ready before testing against it * make sure new test resource has unique name (add random string to it) * various cleanups for easier IT maintenance: - unified docker-reg pod retrieval - unify resource creation in tests - centralized test timeouts in integration test helper - unified resource stubbing - removed statics in ITHelper, updated date in heade Signed-off-by: Andre Dietisheim --- .../internal/restclient/DefaultClient.java | 9 +- .../api/capabilities/ScaleCapability.java | 8 +- .../com/openshift/restclient/IClient.java | 11 + .../DefaultClientFilterIntegrationTest.java | 84 +++--- .../DefaultClientIntegrationTest.java | 154 +++++------ .../restclient/IntegrationTestHelper.java | 261 +++++++++++++++--- .../capabilities/PodExecIntegrationTest.java | 7 +- .../ScaleCapabilityIntegrationTest.java | 47 ++-- .../AuthorizationKindsIntegrationTest.java | 8 +- ...inaryBuildCapabilitiesIntegrationTest.java | 37 +-- .../BuildCapabilitiesIntegrationTest.java | 39 +-- ...StreamImportCapabilityIntegrationTest.java | 23 +- .../OpenShiftBinaryPodLogRetrievalTest.java | 91 ------ ...BinaryPortForwardingIntegrationTest2.java} | 25 +- ...inaryPodLogRetrievalIntegrationTest2.java} | 48 ++-- ...ftBinaryRSyncRetrievalIntegrationTest.java | 26 +- .../PodLogRetrievalAsyncIntegrationTest.java | 7 +- .../resources/UpdateableCapabilityTest.java | 9 +- ...rverTemplateProcessingIntegrationTest.java | 76 ++--- .../kubeconfig/KubeClientConfigTest.java | 5 +- .../WatchClientIntegrationTest.java | 67 +++-- .../openshiftv3IntegrationTest.properties | 15 +- 22 files changed, 575 insertions(+), 482 deletions(-) delete mode 100644 src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java rename src/test/java/com/openshift/internal/restclient/capability/resources/{OpenshiftBinaryPortForwardingIntegrationTest.java => OpenShiftBinaryPortForwardingIntegrationTest2.java} (83%) rename src/test/java/com/openshift/internal/restclient/capability/resources/{OpenshiftBinaryPodLogRetrievalIntegrationTest.java => OpenshiftBinaryPodLogRetrievalIntegrationTest2.java} (62%) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index d32eb6f7..7e3046cd 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -145,7 +145,6 @@ public List list(String kind, String namespace) { @Override public List list(String kind, String namespace, Map labels) { - String labelQuery = ""; if (labels != null && !labels.isEmpty()) { labelQuery = labels.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue()).collect(joining(",")); @@ -156,7 +155,6 @@ public List list(String kind, String namespace, Map List list(String kind, String namespace, String labelQuery) { - Map params = new HashMap<>(); if (labelQuery != null && !labelQuery.isEmpty()) { params.put("labelSelector", labelQuery); @@ -390,7 +388,12 @@ public T update(T resource) { @Override public void delete(T resource) { - execute(HttpMethod.DELETE, resource.getKind(), resource.getNamespaceName(), resource.getName(), null, null); + delete(resource.getKind(), resource.getNamespaceName(), resource.getName()); + } + + @Override + public void delete(String resourceKind, String namespaceName, String name) { + execute(HttpMethod.DELETE, resourceKind, namespaceName, name, null, null); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java index 6cca3f02..11a87dd5 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/ScaleCapability.java @@ -60,11 +60,11 @@ public String getName() { @Override public IScale scaleTo(int replicas) { replicas = replicas >= MIN_VALUE ? replicas : MIN_VALUE; - IScale arg = (IScale) factory.stubKind(ARG_KINDS.get(rc.getKind()), Optional.of(rc.getName()), + IScale scale = (IScale) factory.stubKind(ARG_KINDS.get(rc.getKind()), Optional.of(rc.getName()), Optional.of(rc.getNamespaceName())); - arg.setSpecReplicas(replicas); - return (IScale) client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespaceName(), rc.getName(), - CAPABILITY, null, arg, Collections.emptyMap()); + scale.setSpecReplicas(replicas); + return client.execute(factory, IHttpConstants.PUT, rc.getKind(), rc.getNamespaceName(), rc.getName(), + CAPABILITY, null, scale, Collections.emptyMap()); } } diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index 5b765eb3..b4d93798 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -213,6 +213,17 @@ public interface IClient extends ICapable, Cloneable { */ void delete(T resource); + /** + * Deletes a resource of given name and kind in the given namespace. + * + * @param kind the kind of resource + * @param namespace the namespace + * @param name the name of the resource + * @throws UnsupportedOperationException + * if the resource is a list + */ + void delete(String kind, String namespace, String name); + /** * Raw execution of a request * diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java index 57d70939..49d16162 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java @@ -1,10 +1,19 @@ +/******************************************************************************* +* Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. +* All rights reserved. This program is 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: Red Hat, Inc. +******************************************************************************/ + package com.openshift.internal.restclient; -import static com.openshift.internal.restclient.IntegrationTestHelper.cleanUpResource; import static com.openshift.restclient.ResourceKind.BUILD_CONFIG; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Set; @@ -16,68 +25,48 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.openshift.internal.restclient.model.build.BuildConfigBuilder; -import com.openshift.internal.restclient.model.project.OpenshiftProjectRequest; import com.openshift.restclient.IClient; -import com.openshift.restclient.IResourceFactory; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IResource; public class DefaultClientFilterIntegrationTest { - private static final String VERSION = "v1"; - private static final Logger LOG = LoggerFactory.getLogger(DefaultClientFilterIntegrationTest.class); private static IClient client; - - private static IResourceFactory factory; - private static IProject project; - + private static Collection bcs; private static IntegrationTestHelper helper = new IntegrationTestHelper(); @BeforeClass public static void setup() { - client = helper.createClientForBasicAuth(); - factory = new ResourceFactory(client); - OpenshiftProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); - projectRequest.setName(helper.generateNamespace()); - project = (IProject) client.create(projectRequest); - - createBuildConfigWithLabels(project, "build1", new HashMap() { - { - put("foo", "yes"); - put("bar", "no"); - put("baz", "no"); - } - }); - - createBuildConfigWithLabels(project, "build2", new HashMap() { - { - put("foo", "no"); - put("bar", "yes"); - - } - }); - - createBuildConfigWithLabels(project, "build3", new HashMap() { - { - put("foo", "yes"); - put("bar", "yes"); - } - }); - - createBuildConfigWithLabels(project, "build4", new HashMap<>()); + project = helper.getOrCreateIntegrationTestProject(client); + bcs = helper.createResources(client, + helper.stubBuildConfig(client, project.getNamespaceName(), "build1", null, new HashMap() {{ + put("foo", "yes"); + put("bar", "no"); + put("baz", "no"); + } + }), + helper.stubBuildConfig(client, project.getNamespaceName(), "build2", null, new HashMap() {{ + put("foo", "no"); + put("bar", "yes"); + } + }), + helper.stubBuildConfig(client, project.getNamespaceName(), "build3", null, new HashMap() {{ + put("foo", "yes"); + put("bar", "yes"); + } + }), + helper.stubBuildConfig(client, project.getNamespaceName(), "build4", null, new HashMap<>())); } @AfterClass public static void cleanup() { - cleanUpResource(client, project); + helper.cleanUpResources(client, bcs); } @Test @@ -92,7 +81,6 @@ public void testFilteringWithOneLabel() { Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); assertTrue("Should contain build1", names.contains("build1")); assertTrue("Should contain build3", names.contains("build3")); - } @Test @@ -150,14 +138,4 @@ public void testFilteringWithLabelCombinedLabelQuery() { IBuildConfig bc = list.get(0); assertEquals("build1", bc.getName()); } - - private static IBuildConfig createBuildConfigWithLabels(IProject project, String name, - HashMap labelFilter) { - - IBuildConfig bc = new BuildConfigBuilder(client).named(name).inNamespace(project.getNamespaceName()) - .usingSourceStrategy().fromDockerImage("centos/ruby-22-centos7:latest").end() - .toImageStreamTag("ruby-hello-world:latest").withLabels(labelFilter).build(); - return client.create(bc); - } - } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index 045db75a..115df3db 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. +* Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -10,12 +10,11 @@ package com.openshift.internal.restclient; import static com.openshift.internal.restclient.IntegrationTestHelper.MILLISECONDS_PER_SECOND; -import static com.openshift.internal.restclient.IntegrationTestHelper.cleanUpResource; -import static com.openshift.internal.restclient.IntegrationTestHelper.waitForResource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.util.Collections; import java.util.List; import org.junit.Before; @@ -23,9 +22,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.openshift.internal.restclient.model.Project; -import com.openshift.internal.restclient.model.Service; -import com.openshift.internal.restclient.model.project.OpenshiftProjectRequest; import com.openshift.internal.restclient.model.template.Template; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; @@ -33,25 +29,25 @@ import com.openshift.restclient.authorization.UnauthorizedException; import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IProject; -import com.openshift.restclient.model.build.IBuildConfigBuilder; -import com.openshift.restclient.model.project.IProjectRequest; +import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.IService; import com.openshift.restclient.model.template.ITemplate; public class DefaultClientIntegrationTest { private static final String VERSION = "v1"; - private static final Logger LOG = LoggerFactory.getLogger(DefaultClientIntegrationTest.class); - private IClient client; private IntegrationTestHelper helper = new IntegrationTestHelper(); - + private IClient client; private IResourceFactory factory; + private IProject project; @Before public void setup() { - client = helper.createClientForBasicAuth(); - factory = new ResourceFactory(client); + this.client = helper.createClientForBasicAuth(); + this.factory = new ResourceFactory(client); + this.project = helper.getOrCreateIntegrationTestProject(client); } @Test @@ -69,8 +65,9 @@ public void testAuthContextIsAuthorizedWithoutPasswordThrows() { client.getAuthorizationContext().isAuthorized(); } + @Test public void testListprojects() { - assertTrue(client.list(ResourceKind.PROJECT, "default").size() > 0); + assertTrue(client.list(ResourceKind.PROJECT, IntegrationTestHelper.getDefaultNamespace()).size() > 0); } @Test @@ -81,17 +78,13 @@ public void testReady() { @Test public void testListTemplates() { Template template = null; - IProject project = null; + IProject project = helper.getOrCreateIntegrationTestProject(client); try { - OpenshiftProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); - projectRequest.setName(helper.generateNamespace()); template = factory.stub(ResourceKind.TEMPLATE, "mytemplate"); - - project = (IProject) client.create(projectRequest); template = client.create(template, project.getNamespaceName()); - assertNotNull("Exp. the template to be found but was not", waitForResource(client, ResourceKind.TEMPLATE, + assertNotNull("Exp. the template to be found but was not", helper.waitForResource(client, ResourceKind.TEMPLATE, project.getName(), template.getName(), 5 * MILLISECONDS_PER_SECOND)); List list = client.list(ResourceKind.TEMPLATE, project.getName()); @@ -100,88 +93,69 @@ public void testListTemplates() { LOG.debug(t.toString()); } } finally { - cleanUpResource(client, template); - cleanUpResource(client, project); + helper.cleanUpResource(client, template); } } @Test public void testResourceLifeCycle() { - - IProjectRequest projectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); - ((OpenshiftProjectRequest) projectRequest).setName(helper.generateNamespace()); - LOG.debug(String.format("Stubbing project request: %s", projectRequest)); - - IProjectRequest otherProjectRequest = factory.create(VERSION, ResourceKind.PROJECT_REQUEST); - ((OpenshiftProjectRequest) otherProjectRequest).setName(helper.generateNamespace()); - LOG.debug(String.format("Stubbing project request: %s", otherProjectRequest)); - - Service service = factory.create(VERSION, ResourceKind.SERVICE); - service.setNamespace(projectRequest.getName()); // this will be the project's namespace - service.setName("some-service"); - service.setTargetPort(6767); - service.setPort(6767); - service.setSelector("name", "barpod"); - LOG.debug(String.format("Stubbing service: %s", service)); - - Service otherService = factory.create(VERSION, ResourceKind.SERVICE); - otherService.setNamespace(otherProjectRequest.getName()); // this will be the project's namespace - otherService.setName("some-other-service"); - otherService.setTargetPort(8787); - otherService.setPort(8787); - otherService.setSelector("name", "foopod"); - - LOG.debug(String.format("Stubbing service: %s", otherService)); - - IProject project = null; - IProject other = null; + IService service = null; + IService otherService = null; + IBuildConfig bc = null; try { - project = (IProject) client.create(projectRequest); - LOG.debug(String.format("Created project: %s", project)); - - other = (IProject) client.create(otherProjectRequest); - LOG.debug(String.format("Created project: %s", project)); - - LOG.debug(String.format("Creating service: %s", service)); - service = client.create(service); - LOG.debug(String.format("Created service: %s", service)); - - LOG.debug(String.format("Creating service: %s", otherService)); - otherService = client.create(otherService); - LOG.debug(String.format("Created service: %s", otherService)); - - LOG.debug("Listing projects"); - List projects = client.list(ResourceKind.PROJECT); - LOG.debug(String.format("Listed projects: %s", projects)); - - LOG.debug(String.format("Listing services with namespace: %s", project.getNamespaceName())); - List services = client.list(ResourceKind.SERVICE, project.getNamespaceName()); - LOG.debug(String.format("Listed services: %s", services)); - - LOG.debug(String.format("Getting service: %s", otherService.getName())); - Service s = client.get(ResourceKind.SERVICE, otherService.getName(), otherService.getNamespaceName()); - LOG.debug(String.format("Retrieved service: %s", s.getName())); - - assertEquals("Expected there to be only one service returned", 1, services.size()); - assertEquals("Expected to get the service with the correct name", service.getName(), - services.get(0).getName()); - - IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); - IBuildConfig bc = builder.named("test").fromGitSource() - .fromGitUrl("https://github.com/openshift/origin.git").inContextDir("examples/hello-openshift") - .end().usingSourceStrategy().fromDockerImage("foo/bar").end().toImageStreamTag("foo/bar:latest") - .build(); - bc = client.create(bc, project.getNamespaceName()); + IService stub = helper.stubService(client, + project.getNamespaceName(), + IntegrationTestHelper.appendRandom("some-service"), + 6767, 6767, + "barpod"); + service = createAndAssert(stub); + assertServiceEquals(stub, service); + + IService otherStub = helper.stubService(client, + project.getNamespaceName(), + IntegrationTestHelper.appendRandom("some-other-service"), + 8787, 8787, + "foopod"); + otherService = createAndAssert(otherStub); + + bc = client.create( + helper.stubBuildConfig(client, + project.getNamespaceName(), + "test", + "https://github.com/openshift/origin.git", + Collections.emptyMap())); LOG.debug(String.format("Created bc: %s", bc.getName())); LOG.debug(String.format("Trying to delete bc: %s", bc.getName())); client.delete(bc); + bc = null; } finally { - cleanUpResource(client, project); - cleanUpResource(client, other); - cleanUpResource(client, service); - cleanUpResource(client, otherService); + helper.cleanUpResources(client, service, otherService, bc); } + } + + private R createAndAssert(R stub) { + // given + int numberOfServices = client.list(stub.getKind(), project.getNamespaceName()).size(); + // when + R resource = client.create(stub); + // then + List resources = client.list(stub.getKind(), project.getNamespaceName()); + assertNotNull(resources); + int newNumberOfServices = resources.size(); + assertEquals(numberOfServices + 1, newNumberOfServices); + assertTrue(resources.contains(resource)); + R queriedResource = client.get(stub.getKind(), stub.getName(), stub.getNamespaceName()); + assertEquals("Expected to get the service with the correct name", + stub.getName(), + queriedResource.getName()); + return resource; + } + private void assertServiceEquals(IService stub, IService service) { + assertEquals(stub.getName(), service.getName()); + assertEquals(stub.getNamespace(), service.getNamespace()); + assertEquals(stub.getSelector(), service.getSelector()); + assertEquals(stub.getPort(), service.getPort()); } } diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index 622e553b..14916698 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -12,12 +12,18 @@ import static org.junit.Assert.fail; import java.io.IOException; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Properties; import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,34 +32,46 @@ import com.openshift.internal.restclient.model.ModelNodeBuilder; import com.openshift.internal.restclient.model.Pod; import com.openshift.internal.restclient.model.ReplicationController; +import com.openshift.internal.restclient.model.Service; +import com.openshift.internal.restclient.model.build.BuildConfigBuilder; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.ClientBuilder; import com.openshift.restclient.IClient; +import com.openshift.restclient.IWatcher; import com.openshift.restclient.NotFoundException; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.images.DockerImageURI; +import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IDeploymentConfig; import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IReplicationController; import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.IService; import com.openshift.restclient.model.deploy.DeploymentTriggerType; public class IntegrationTestHelper implements ResourcePropertyKeys { + public static final long TEST_TIMEOUT = 6 * 1000; + public static final long TEST_LONG_TIMEOUT = 3 * 60 * 1000; + public static final long MILLISECONDS_PER_SECOND = 1000; public static final long MILLISECONDS_PER_MIN = MILLISECONDS_PER_SECOND * 60; - private static final String KEY_DEFAULT_PROJECT = "default.project"; + private static final String KEY_INTEGRATION_TEST_PROJECT = "integrationtest.project"; private static final String KEY_SERVER_URL = "serverURL"; private static final String KEY_PASSWORD = "default.clusteradmin.password"; private static final String KEY_USER = "default.clusteradmin.user"; - private static final String KEY_OPENSHIFT_LOCATION = "default.openshift.location"; + private static final String KEY_OPENSHIFT_LOCATION = "ocbinary.location"; private static final String INTEGRATIONTEST_PROPERTIES = "/openshiftv3IntegrationTest.properties"; private static final Logger LOG = LoggerFactory.getLogger(IntegrationTestHelper.class); - + private static final String POD_NAME_DEPLOY = "deploy"; + private static final String POD_DOCKER_REGISTRY = "docker-registry"; + private static final String DEFAULT_PROJECT = "default"; + private final Properties prop; public IntegrationTestHelper() { @@ -61,39 +79,107 @@ public IntegrationTestHelper() { } public IClient createClient() { - return new ClientBuilder(prop.getProperty(KEY_SERVER_URL)).build(); + return new ClientBuilder(getServer()).build(); + } + + private String getServer() { + return prop.getProperty(KEY_SERVER_URL); } public IClient createClientForBasicAuth() { - IClient client = new ClientBuilder(prop.getProperty(KEY_SERVER_URL)).withUserName(getDefaultClusterAdminUser()) - .withPassword(getDefaultClusterAdminPassword()).build(); - return client; + return new ClientBuilder(getServer()) + .withUserName(getDefaultClusterAdminUser()) + .withPassword(getDefaultClusterAdminPassword()) + .build(); } - public String getDefaultNamespace() { - return prop.getProperty(KEY_DEFAULT_PROJECT); + public String getIntegrationTestNamespace() { + return prop.getProperty(KEY_INTEGRATION_TEST_PROJECT); } - public String generateNamespace() { - return String.format("%s-%s", getDefaultNamespace(), new Random().nextInt(9999)); + public static String getDefaultNamespace() { + return DEFAULT_PROJECT; } - public IProject generateProject(IClient client) { - IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, generateNamespace()); + public IProject createProject(String name, IClient client) { + IResource request = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, name); return (IProject) client.create(request); } + public IProject getOrCreateIntegrationTestProject(IClient client) { + return getOrCreateProject(getIntegrationTestNamespace(), client); + } + + /** + * Returns the existing project if it is present. If not, it'll create a new project and return + * it. + * + * @param name the name of the project + * @param client the client to be used + * @return the existing/new project + */ + public IProject getOrCreateProject(String name, IClient client) { + IProject project = null; + try { + project = client.get(ResourceKind.PROJECT, name, ""); + } catch (NotFoundException e ) { + project = createProject(name, client); + } + return project; + } + + public static String appendRandom(String string) { + return String.format("%s-%s", string, new Random().nextInt(9999)); + } + + public static boolean isDockerRegistry(IPod pod) { + return pod != null + && pod.getName().startsWith(POD_DOCKER_REGISTRY); + } + + public IPod getDockerRegistryPod(Collection pods) { + return pods.stream() + .filter(p -> isDockerRegistry(p)) + .findFirst() + .orElse(null); + } + + + public Collection createResources(IClient client, R... resources) { + if (ArrayUtils.isEmpty(resources)) { + return Collections.emptyList(); + } + return Stream.of(resources) + .map(r -> client.create(r)) + .filter(r -> r != null) + .collect(Collectors.toList()); + } + + public R createResource(IClient client, R resource) { + if (resource == null) { + return null; + } + return client.create(resource); + } + + public IPod createPod(IClient client, String namespace, String name) { + return client.create(stubPod(client, namespace, name)); + } + /** * Stub a pod definition to the openshift/hello-openshift image for purposes of * testing. * + * @param client the client to use + * @param namespace the namespace to stub the pod for + * @param name the name of the pod + * * @return a pod definition that needs to be further created using the client */ - public static IPod stubPod(IClient client, IProject project) { - // cluster shouldnt allow us to create pods directly + public IPod stubPod(IClient client, String namespace, String name) { ModelNode builder = new ModelNodeBuilder().set(ResourcePropertyKeys.KIND, ResourceKind.POD) - .set(ResourcePropertyKeys.METADATA_NAME, "hello-openshift") - .set(ResourcePropertyKeys.METADATA_NAMESPACE, project.getName()) + .set(ResourcePropertyKeys.METADATA_NAME, name) + .set(ResourcePropertyKeys.METADATA_NAMESPACE, namespace) .add("spec.containers", new ModelNodeBuilder().set(ResourcePropertyKeys.NAME, "hello-openshift") .set("image", "openshift/hello-openshift") @@ -102,29 +188,63 @@ public static IPod stubPod(IClient client, IProject project) { return new Pod(builder, client, new HashMap<>()); } - public static IDeploymentConfig stubDeploymentConfig(IClient client, IProject project) { + public IDeploymentConfig stubDeploymentConfig(IClient client, String namespace, String name) { IDeploymentConfig dc = new ResourceFactory(client).create("v1", ResourceKind.DEPLOYMENT_CONFIG); - ((DeploymentConfig) dc).setName("hello-openshift"); - ((DeploymentConfig) dc).setNamespace(project.getName()); + ((DeploymentConfig) dc).setName(name); + ((DeploymentConfig) dc).setNamespace(namespace); dc.setReplicas(1); dc.setReplicaSelector("foo", "bar"); - dc.addContainer(dc.getName(), new DockerImageURI("openshift/hello-openshift"), new HashSet<>(), - Collections.emptyMap(), Collections.emptyList()); + dc.addContainer(dc.getName(), + new DockerImageURI("openshift/hello-openshift"), + new HashSet<>(), + Collections.emptyMap(), + Collections.emptyList()); dc.addTrigger(DeploymentTriggerType.CONFIG_CHANGE); return dc; } - public static IReplicationController stubReplicationController(IClient client, IProject project) { + public IReplicationController stubReplicationController(IClient client, String namespace, String name) { IReplicationController rc = new ResourceFactory(client).create("v1", ResourceKind.REPLICATION_CONTROLLER); - ((ReplicationController) rc).setName("hello-openshift-rc"); - ((ReplicationController) rc).setNamespace(project.getName()); + ((ReplicationController) rc).setName(name); + ((ReplicationController) rc).setNamespace(namespace); rc.setReplicas(1); rc.setReplicaSelector("foo", "bar"); - rc.addContainer(rc.getName(), new DockerImageURI("openshift/hello-openshift"), new HashSet<>(), - Collections.emptyMap(), Collections.emptyList()); + rc.addContainer(rc.getName(), + new DockerImageURI("openshift/hello-openshift"), + new HashSet<>(), + Collections.emptyMap(), + Collections.emptyList()); return rc; } + public IBuildConfig stubBuildConfig(IClient client, String namespace, String name, String gitUrl, Map labels) { + BuildConfigBuilder builder = new BuildConfigBuilder(client); + builder.named(name) + .inNamespace(namespace); + if (!StringUtils.isEmpty(gitUrl)) { + builder + .fromGitSource() + .fromGitUrl(gitUrl) + .end(); + } + builder.usingSourceStrategy() + .fromDockerImage("centos/ruby-22-centos7:latest") + .end() + .toImageStreamTag("ruby-hello-world:latest") + .withLabels(labels); + return builder.build(); + } + + public IService stubService(IClient client, String namespace, String name, int remotePort, int port, String selector) { + Service service = client.getResourceFactory().create("v1", ResourceKind.SERVICE); + service.setName(name); + service.setNamespace(namespace); + service.setTargetPort(remotePort); + service.setPort(port); + service.setSelector("name", selector); + return service; + } + /** * Loads the properties from the given {@code propertyFileName}, then overrides * from the System properties if any was given (this is a convenient way to @@ -134,7 +254,7 @@ public static IReplicationController stubReplicationController(IClient client, I * @return the properties to use in the test * @throws IOException an io exception */ - private static Properties loadProperties(final String propertyFileName) { + private Properties loadProperties(final String propertyFileName) { final Properties properties = new Properties(); try { properties.load(IntegrationTestHelper.class.getResourceAsStream(propertyFileName)); @@ -143,14 +263,14 @@ private static Properties loadProperties(final String propertyFileName) { fail("Failed to load properties from file " + INTEGRATIONTEST_PROPERTIES + ": " + e.getMessage()); } overrideIfExists(properties, KEY_SERVER_URL); - overrideIfExists(properties, KEY_DEFAULT_PROJECT); + overrideIfExists(properties, KEY_INTEGRATION_TEST_PROJECT); overrideIfExists(properties, KEY_OPENSHIFT_LOCATION); overrideIfExists(properties, KEY_USER); overrideIfExists(properties, KEY_PASSWORD); return properties; } - private static void overrideIfExists(final Properties properties, final String propertyName) { + private void overrideIfExists(final Properties properties, final String propertyName) { // then override with the VM arguments (if any) final String propertyValue = System.getProperty(propertyName); if (propertyValue != null) { @@ -162,6 +282,10 @@ public String getOpenShiftLocation() { return prop.getProperty(KEY_OPENSHIFT_LOCATION); } + public void setOpenShiftBinarySystemProperty() { + System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, getOpenShiftLocation()); + } + public String getDefaultClusterAdminUser() { return prop.getProperty(KEY_USER); } @@ -171,17 +295,44 @@ public String getDefaultClusterAdminPassword() { } public String getServerUrl() { - return prop.getProperty(KEY_SERVER_URL); + return getServer(); + } + + public void cleanUpResources(IClient client, R... resources) { + if (ArrayUtils.isEmpty(resources)) { + return; + } + Stream.of(resources).forEach(resource -> cleanUpResource(client, resource)); } - public static void cleanUpResource(IClient client, IResource resource) { + public void cleanUpResources(IClient client, Collection resources) { + if (resources == null || resources.isEmpty()) { + return; + } + resources.forEach(resource -> cleanUpResource(client, resource)); + } + + public void cleanUpResource(IClient client, R resource) { if (client == null || resource == null) { - LOG.debug("Skipping cleanup as client %s or resource %s is null", client, resource); + LOG.debug("Skipping cleanup as client to {} or resource {} are null", + client == null ? "" : client.getBaseURL(), + resource == null ? "" : resource.getName()); + return; + } + LOG.debug(String.format("Deleting resource: %s", resource)); + cleanUpResource(client, resource.getKind(), resource.getNamespaceName(), resource.getName()); + } + + public void cleanUpResource(IClient client, String kind, String namespace, String name) { + if (client == null || StringUtils.isEmpty(name) || StringUtils.isEmpty(namespace)) { + LOG.debug("Skipping cleanup as client to {} or resource {} are null", + client == null ? "" : client.getBaseURL(), + StringUtils.isEmpty(name) ? "" : name); + return; } try { - Thread.sleep(1000); - LOG.debug(String.format("Deleting resource: %s", resource)); - client.delete(resource); + LOG.debug(String.format("Deleting resource: %s", name)); + client.delete(kind, namespace, name); } catch (Exception e) { LOG.warn("Exception deleting", e); } @@ -194,7 +345,7 @@ public static void cleanUpResource(IClient client, IResource resource) { * @return The resource or null if the maxWaitMillis was exceeded or the * resource doesnt exist */ - public static IResource waitForResource(IClient client, String kind, String namespace, String name, + public IResource waitForResource(IClient client, String kind, String namespace, String name, long maxWaitMillis) { return waitForResource(client, kind, namespace, name, maxWaitMillis, new ReadyConditional() { @Override @@ -205,14 +356,19 @@ public boolean isReady(IResource resource) { }); } + public R waitForResource(IClient client, R resource, + long maxWaitMillis, ReadyConditional conditional) { + return waitForResource(client, resource.getKind(), resource.getNamespaceName(), resource.getName(), maxWaitMillis, conditional); + } + /** * Wait for the resource to exist for cases where the test is faster then the * server in reconciling its existence; * */ - public static IResource waitForResource(IClient client, String kind, String namespace, String name, + public R waitForResource(IClient client, String kind, String namespace, String name, long maxWaitMillis, ReadyConditional conditional) { - IResource resource = null; + R resource = null; final long timeout = System.currentTimeMillis() + maxWaitMillis; do { try { @@ -236,7 +392,6 @@ public static IResource waitForResource(IClient client, String kind, String name /** * Interface that can evaluate a resource to determine if its ready - * */ public static interface ReadyConditional { @@ -247,4 +402,28 @@ public static interface ReadyConditional { boolean isReady(IResource resource); } + public boolean waitForDisappearance(IClient client, IResource resource, long maxWaitMillis) { + final long timeout = System.currentTimeMillis() + maxWaitMillis; + do { + try { + resource = client.get(resource.getKind(), resource.getName(), resource.getNamespaceName()); + Thread.sleep(1000); + } catch (NotFoundException e) { + return true; + } catch (InterruptedException e) { + return false; + } + } while (resource == null && System.currentTimeMillis() <= timeout); + return false; + } + + public void stopWatcher(IWatcher watcher) { + if (watcher != null) { + watcher.stop(); + } + } + + public boolean isDeployPod(IPod pod) { + return pod.getName().endsWith(POD_NAME_DEPLOY); + } } diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java index 4d9d0af6..8a2a866e 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015-2018 Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -34,7 +34,6 @@ import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IStoppable; import com.openshift.restclient.model.IPod; -import com.openshift.restclient.model.IResource; public class PodExecIntegrationTest { @@ -103,8 +102,8 @@ public void onFailure(Throwable t) { @Before public void setUp() throws Exception { IClient client = helper.createClientForBasicAuth(); - List pods = client.list(ResourceKind.POD, "default"); - pod = (IPod) pods.stream().filter(p -> p.getName().startsWith("docker-registry")).findFirst().orElse(null); + List allPods = client.list(ResourceKind.POD, IntegrationTestHelper.getDefaultNamespace()); + this.pod = helper.getDockerRegistryPod(allPods); assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); } diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java index 910aa652..deb78286 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/ScaleCapabilityIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -32,6 +32,7 @@ import com.openshift.restclient.api.capabilities.IScalable; import com.openshift.restclient.apis.autoscaling.models.IScale; import com.openshift.restclient.capability.CapabilityVisitor; +import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IProject; import com.openshift.restclient.model.IReplicationController; import com.openshift.restclient.model.IResource; @@ -45,42 +46,40 @@ public class ScaleCapabilityIntegrationTest { private IWatcher watch; private CountDownLatch initializationLatch = new CountDownLatch(2); private CountDownLatch replicaLatch = new CountDownLatch(1); - private IReplicationController dc; + private IReplicationController rc; private AtomicBoolean foundFirstPod = new AtomicBoolean(false); private PodStatusRunningConditional conditional = new PodStatusRunningConditional(); @Before public void setUp() throws Exception { - client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); + this.client = helper.createClientForBasicAuth(); + this.project = helper.getOrCreateIntegrationTestProject(client); } @After public void teardown() throws Exception { - if (watch != null) { - try { - watch.stop(); - } catch (Exception e) { - // swallow - } - } - IntegrationTestHelper.cleanUpResource(client, project); + helper.stopWatcher(watch); + helper.cleanUpResource(client, rc); + // remove all pods that were created by the rc/dc + helper.cleanUpResource(client, client.get(ResourceKind.POD, project.getNamespaceName())); } - @Test(timeout = 3 * 1000 * 60) + @Test(timeout = IntegrationTestHelper.TEST_LONG_TIMEOUT) public void testScalingReplicationController() throws Exception { - dc = client.create(IntegrationTestHelper.stubReplicationController(client, project)); + this.rc = client.create(helper.stubReplicationController(client, + project.getNamespaceName(), IntegrationTestHelper.appendRandom("test-rc"))); runTest(); } - @Test(timeout = 3 * 1000 * 60) + @Test(timeout = IntegrationTestHelper.TEST_LONG_TIMEOUT) public void testScalingDeploymentConfig() throws Exception { - dc = client.create(IntegrationTestHelper.stubDeploymentConfig(client, project)); + this.rc = client.create(helper.stubDeploymentConfig(client, + project.getNamespaceName(), IntegrationTestHelper.appendRandom("test-dc"))); runTest(); } private void runTest() throws Exception { - watch = client.watch(project.getName(), new IOpenShiftWatchListener() { + this.watch = client.watch(project.getName(), new IOpenShiftWatchListener() { @Override public void connected(List resources) { @@ -89,12 +88,15 @@ public void connected(List resources) { @Override public void disconnected() { - } @Override public void received(IResource resource, ChangeType change) { - if (ChangeType.MODIFIED.equals(change) && !resource.getName().endsWith("deploy") + if (!(resource instanceof IPod) + || helper.isDeployPod(((IPod) resource))) { + return; + } + if (ChangeType.MODIFIED.equals(change) && conditional.isReady(resource)) { if (foundFirstPod.get()) { replicaLatch.countDown(); @@ -107,22 +109,19 @@ public void received(IResource resource, ChangeType change) { @Override public void error(Throwable err) { - } }, ResourceKind.POD); if (initializationLatch.await(1, TimeUnit.MINUTES)) { scaleTo(REPLICAS); - assertTrue("The pods either did not scale as expected or the test timed out", + assertTrue("The pods either did not scale to " + REPLICAS + " replicas or the test timed out", replicaLatch.await(2, TimeUnit.MINUTES)); } - ; - } private void scaleTo(int replicas) { - IScale result = dc.accept(new CapabilityVisitor() { + IScale result = rc.accept(new CapabilityVisitor() { @Override public IScale visit(IScalable capability) { diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java index 07c43140..61556805 100644 --- a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (c) 2016 Red Hat, Inc. Distributed under license by Red Hat, Inc. +* Copyright (c) 2016-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -33,18 +33,18 @@ public void setup() { @Test public void testListRolesAssumingClusterAdmin() { - List roles = client.list(ResourceKind.ROLE, "default"); + List roles = client.list(ResourceKind.ROLE, IntegrationTestHelper.getDefaultNamespace()); assertThat(roles).isNotEmpty(); } @Test public void testListPoliciesAssumingClusterAdmin() { - client.list(ResourceKind.POLICY, "default"); + client.list(ResourceKind.POLICY, IntegrationTestHelper.getDefaultNamespace()); } @Test public void testListPolicyBindingsAssumingClusterAdmin() { - client.list(ResourceKind.POLICY_BINDING, "default"); + client.list(ResourceKind.POLICY_BINDING, IntegrationTestHelper.getDefaultNamespace()); } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/BinaryBuildCapabilitiesIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/BinaryBuildCapabilitiesIntegrationTest.java index 17dd5b56..8f740525 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/BinaryBuildCapabilitiesIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/BinaryBuildCapabilitiesIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2018 Red Hat, Inc. + * Copyright (c) 2018-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -25,12 +25,10 @@ import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.restclient.IClient; import com.openshift.restclient.IOpenShiftWatchListener; -import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.resources.IBinaryBuildTriggerable; import com.openshift.restclient.capability.resources.IBuildCancelable; -import com.openshift.restclient.capability.resources.IBuildTriggerable; import com.openshift.restclient.model.IBuild; import com.openshift.restclient.model.IBuildConfig; import com.openshift.restclient.model.IImageStream; @@ -41,42 +39,47 @@ public class BinaryBuildCapabilitiesIntegrationTest { private static final Logger LOG = LoggerFactory.getLogger(BinaryBuildCapabilitiesIntegrationTest.class); - private IBuildConfig config; private IntegrationTestHelper helper = new IntegrationTestHelper(); - private IProject project; private IClient client; + private IProject project; + private IImageStream is; + private IBuildConfig bc; + private IBuild build; @Before public void setUp() throws Exception { client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); + project = helper.getOrCreateIntegrationTestProject(client); // an output imagestream IImageStream is = client.getResourceFactory().stub(ResourceKind.IMAGE_STREAM, "rest-spring-boot", project.getName()); LOG.debug("Creating imagestream {}", is); - is = client.create(is); + this.is = client.create(is); LOG.debug("Generated imagestream {}", is); // a buildconfig IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); assertNotNull("Exp. the client to be able to use a buildconfigbuilder", builder); - config = builder.named("rest-spring-boot").inNamespace(project.getName()).fromBinarySource().end() + IBuildConfig bcStup = builder.named(IntegrationTestHelper.appendRandom("rest-spring-boot")) + .inNamespace(project.getName()) + .fromBinarySource() + .end() .usingSourceStrategy() .fromDockerImage("registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift").end() - .toImageStreamTag("rest-spring-boot:latest").build(); - LOG.debug("Creating BuildConfig {}", config); - config = client.create(config); - LOG.debug("Created BuildConfig {}", config); - assertNotNull(config); + .toImageStreamTag("rest-spring-boot:latest") + .build(); + LOG.debug("Creating BuildConfig {}", bcStup); + this.bc = client.create(bcStup); + LOG.debug("Created BuildConfig {}", bc); + assertNotNull(bc); } @Test public void testBuildActions() throws InterruptedException { - // trigger the build LOG.debug("Triggering build from the buildconfig..."); - IBuild build = config.accept(new CapabilityVisitor() { + IBuild build = bc.accept(new CapabilityVisitor() { @Override public IBuild visit(IBinaryBuildTriggerable capability) { return capability.triggerBinary( @@ -99,7 +102,7 @@ public IBuild visit(IBuildCancelable cap) { LOG.debug("Canceled build {}", build); // trigger a new build and wait for completion - build = config.accept(new CapabilityVisitor() { + this.build = bc.accept(new CapabilityVisitor() { @Override public IBuild visit(IBinaryBuildTriggerable capability) { return capability.triggerBinary( @@ -123,7 +126,7 @@ public void received(IResource resource, ChangeType change) { @After public void tearDown() { - IntegrationTestHelper.cleanUpResource(client, project); + helper.cleanUpResources(client, build, bc, is); } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java index 04867cd0..8a260e2f 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -13,6 +13,8 @@ import static org.junit.Assert.assertNotNull; +import java.util.Collections; + import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -34,42 +36,43 @@ public class BuildCapabilitiesIntegrationTest { private static final Logger LOG = LoggerFactory.getLogger(BuildCapabilitiesIntegrationTest.class); - private IBuildConfig config; + private IBuildConfig bc; + private IImageStream is; private IntegrationTestHelper helper = new IntegrationTestHelper(); private IProject project; private IClient client; @Before public void setUp() throws Exception { - client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); + this.client = helper.createClientForBasicAuth(); + this.project = helper.getOrCreateIntegrationTestProject(client); // an output imagestream - IImageStream is = client.getResourceFactory().stub(ResourceKind.IMAGE_STREAM, "ruby-hello-world", - project.getName()); + IImageStream is = client.getResourceFactory().stub( + ResourceKind.IMAGE_STREAM, IntegrationTestHelper.appendRandom("ruby-hello-world"), project.getName()); LOG.debug("Creating imagestream {}", is); - is = client.create(is); + this.is = client.create(is); LOG.debug("Generated imagestream {}", is); // a buildconfig IBuildConfigBuilder builder = client.adapt(IBuildConfigBuilder.class); assertNotNull("Exp. the client to be able to use a buildconfigbuilder", builder); - config = builder.named("hello-openshift").inNamespace(project.getName()).fromGitSource() - .fromGitUrl("https://github.com/openshift/ruby-hello-world.git").end().usingSourceStrategy() - .fromDockerImage("centos/ruby-22-centos7:latest").end().toImageStreamTag("ruby-hello-world:latest") - .build(); - LOG.debug("Creating BuildConfig {}", config); - config = client.create(config); - LOG.debug("Created BuildConfig {}", config); - assertNotNull(config); + LOG.debug("Creating BuildConfig {}", bc); + this.bc = client.create( + helper.stubBuildConfig(client, + project.getNamespaceName(), + IntegrationTestHelper.appendRandom("test-bc"), + "https://github.com/openshift/ruby-hello-world.git", + Collections.emptyMap())); + LOG.debug("Created BuildConfig {}", bc); + assertNotNull(bc); } @Test public void testBuildActions() { - // trigger the build LOG.debug("Triggering build from the buildconfig..."); - IBuild build = config.accept(new CapabilityVisitor() { + IBuild build = bc.accept(new CapabilityVisitor() { @Override public IBuild visit(IBuildTriggerable capability) { return capability.trigger(); @@ -116,7 +119,7 @@ public IBuild visit(IBuildTriggerable capability) { @After public void tearDown() { - IntegrationTestHelper.cleanUpResource(client, project); + helper.cleanUpResources(client, bc, is); } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java index 53a53791..7a010bbe 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -36,34 +36,35 @@ public class ImageStreamImportCapabilityIntegrationTest { private IProject project; private IClient client; private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IImageStreamImport imageStreamImport; @Before public void setUp() throws Exception { - client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); - cap = new ImageStreamImportCapability(project, client); + this.client = helper.createClientForBasicAuth(); + this.project = helper.getOrCreateIntegrationTestProject(client); + this.cap = new ImageStreamImportCapability(project, client); } @After public void tearDown() { - IntegrationTestHelper.cleanUpResource(client, project); + helper.cleanUpResource(client, imageStreamImport); } @Test public void testImportImageForExistingImage() { DockerImageURI image = new DockerImageURI("openshift/hello-openshift"); - IImageStreamImport imported = cap.importImageMetadata(image); - assertNotNull(imported); - IStatus status = imported.getImageStatus().iterator().next(); + this.imageStreamImport = cap.importImageMetadata(image); + assertNotNull(imageStreamImport); + IStatus status = imageStreamImport.getImageStatus().iterator().next(); assertTrue(status.isSuccess()); } @Test public void testImportImageForUnknownImage() { DockerImageURI image = new DockerImageURI("openshift/hello-openshifts"); - IImageStreamImport imported = cap.importImageMetadata(image); - Assert.assertNotNull(imported); - IStatus status = imported.getImageStatus().iterator().next(); + this.imageStreamImport = cap.importImageMetadata(image); + Assert.assertNotNull(imageStreamImport); + IStatus status = imageStreamImport.getImageStatus().iterator().next(); assertEquals(IHttpConstants.STATUS_UNAUTHORIZED, status.getCode()); // exp code when image does not exist } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java deleted file mode 100644 index 8e1c2687..00000000 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPodLogRetrievalTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2018 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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: - * Red Hat, Inc. - initial API and implementation - ******************************************************************************/ - -package com.openshift.internal.restclient.capability.resources; - -import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.OC_LOCATION; -import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.POD_NAME; -import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.POD_NAMESPACE; -import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.SERVER_URL; -import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.TOKEN; -import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockClient; -import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockPod; -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -import java.net.MalformedURLException; -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import com.openshift.internal.restclient.capability.resources.OpenShiftBinaryPodLogRetrieval.PodLogs; -import com.openshift.restclient.IClient; -import com.openshift.restclient.capability.IBinaryCapability; -import com.openshift.restclient.capability.IBinaryCapability.OpenShiftBinaryOption; -import com.openshift.restclient.model.IPod; - -public class OpenShiftBinaryPodLogRetrievalTest { - - private static final String CONTAINER_NAME = "smurfland"; - - private IClient client; - private IPod pod; - - @Before - public void before() throws MalformedURLException { - this.client = mockClient(); - this.pod = mockPod(); - } - - private OpenShiftBinaryPodLogRetrieval.PodLogs createPodLogs(boolean follow, IPod pod, IClient client, - OpenShiftBinaryOption... options) { - OpenShiftBinaryPodLogRetrieval.PodLogs podLogs = spy( - new OpenShiftBinaryPodLogRetrieval(pod, client).new PodLogs(client, true, CONTAINER_NAME, options)); - doReturn(OC_LOCATION).when(podLogs).getOpenShiftBinaryLocation(); - doReturn(null).when(podLogs).startProcess(any(ProcessBuilder.class)); - return podLogs; - } - - @Test - public void shouldBuildCommandLineWithoutSkipTlsVerify() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - PodLogs podLogs = createPodLogs(false, pod, client); - // when - podLogs.getLogs(); - // then - verify(podLogs).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList(OC_LOCATION, PodLogs.LOGS_COMMAND, "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), POD_NAME, "-n", POD_NAMESPACE, "-f", "-c", CONTAINER_NAME)); - } - - @Test - public void shouldBuildCommandLineWithSkipTlsVerify() { - // given - ArgumentCaptor processBuilderArgument = ArgumentCaptor.forClass(ProcessBuilder.class); - PodLogs podLogs = createPodLogs(false, pod, client, IBinaryCapability.SKIP_TLS_VERIFY); - // when - podLogs.getLogs(); - // then - verify(podLogs).startProcess(processBuilderArgument.capture()); - ProcessBuilder builder = processBuilderArgument.getValue(); - assertThat(builder.command()).isEqualTo(Arrays.asList(OC_LOCATION, PodLogs.LOGS_COMMAND, "--token=" + TOKEN, - "--server=" + SERVER_URL.toString(), "--insecure-skip-tls-verify=true", POD_NAME, "-n", POD_NAMESPACE, - "-f", "-c", CONTAINER_NAME)); - } - -} diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java similarity index 83% rename from src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java rename to src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java index e712d37d..4011c0a0 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPortForwardingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -25,7 +25,6 @@ import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.internal.restclient.PodStatusRunningConditional; -import com.openshift.internal.restclient.model.Pod; import com.openshift.internal.restclient.model.Port; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.restclient.IClient; @@ -34,33 +33,37 @@ import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; import com.openshift.restclient.capability.resources.IPortForwardable; import com.openshift.restclient.capability.resources.IPortForwardable.PortPair; +import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.IProject; -public class OpenshiftBinaryPortForwardingIntegrationTest implements ResourcePropertyKeys { +public class OpenShiftBinaryPortForwardingIntegrationTest2 implements ResourcePropertyKeys { private IntegrationTestHelper helper = new IntegrationTestHelper(); private IClient client; private IProject project; + private IPod pod; @Before public void setUp() throws Exception { System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - client = helper.createClientForBasicAuth(); - project = helper.generateProject(client); + this.client = helper.createClientForBasicAuth(); + this.project = helper.getOrCreateIntegrationTestProject(client); + IPod pod = helper.createPod(client, project.getNamespaceName(), IntegrationTestHelper.appendRandom("test-pod")); + this.pod = helper.waitForResource( + client, + pod, + 5 * IntegrationTestHelper.MILLISECONDS_PER_MIN, + new PodStatusRunningConditional()); + } @After public void teardown() throws Exception { - IntegrationTestHelper.cleanUpResource(client, project); + helper.cleanUpResource(client, pod); } @Test public void testPortForwarding() { - Pod pod = (Pod) IntegrationTestHelper.stubPod(client, project); - pod = (Pod) client.create(pod); - pod = (Pod) IntegrationTestHelper.waitForResource(client, pod.getKind(), pod.getNamespaceName(), pod.getName(), - 5 * IntegrationTestHelper.MILLISECONDS_PER_MIN, new PodStatusRunningConditional()); - assertNotNull("The test timed out before the pod was in a running state", pod); final Port port = new Port(new ModelNode()); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest2.java similarity index 62% rename from src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java rename to src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest2.java index 59235e06..f45cd5c3 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest2.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -11,40 +11,53 @@ package com.openshift.internal.restclient.capability.resources; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import java.io.BufferedInputStream; -import java.util.List; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.internal.restclient.PodStatusRunningConditional; import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; -import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; import com.openshift.restclient.capability.resources.IPodLogRetrieval; import com.openshift.restclient.model.IPod; -import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.IProject; -public class OpenshiftBinaryPodLogRetrievalIntegrationTest { - private static final Logger LOG = LoggerFactory.getLogger(OpenshiftBinaryPodLogRetrievalIntegrationTest.class); +public class OpenshiftBinaryPodLogRetrievalIntegrationTest2 { + private static final Logger LOG = LoggerFactory.getLogger(OpenshiftBinaryPodLogRetrievalIntegrationTest2.class); private IntegrationTestHelper helper = new IntegrationTestHelper(); - private Exception ex; + private IClient client; + private IProject project; + private IPod pod; + + @Before + public void before() { + helper.setOpenShiftBinarySystemProperty(); + this.client = helper.createClientForBasicAuth(); + this.project = helper.getOrCreateIntegrationTestProject(client); + IPod pod = helper.createPod(client, project.getNamespaceName(), IntegrationTestHelper.appendRandom("test-pod")); + this.pod = helper.waitForResource( + client, + pod, + 5 * IntegrationTestHelper.MILLISECONDS_PER_MIN, + new PodStatusRunningConditional()); + } + + @After + public void after() { + helper.cleanUpResource(client, pod); + } @Test public void testLogRetrieval() { - System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - IClient client = helper.createClientForBasicAuth(); - List pods = client.list(ResourceKind.POD, "default"); - IPod pod = (IPod) pods.stream().filter(p -> p.getName().startsWith("docker-registry")).findFirst().orElse(null); - assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); - - ex = pod.accept(new CapabilityVisitor() { + Exception ex = pod.accept(new CapabilityVisitor() { @Override public Exception visit(IPodLogRetrieval cap) { @@ -56,7 +69,7 @@ public Exception visit(IPodLogRetrieval cap) { builder.append((char) c); } } catch (Exception e) { - LOG.error("There was an error:", e); + LOG.error("There was an error: ", e); return e; } finally { LOG.info(builder.toString()); @@ -66,6 +79,7 @@ public Exception visit(IPodLogRetrieval cap) { } }, null); + assertNull("Expected no exception", ex); } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java index de49e7fb..6fbe28d5 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java @@ -1,6 +1,6 @@ package com.openshift.internal.restclient.capability.resources; /******************************************************************************* - * Copyright (c) 2015-2018 Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -33,19 +33,17 @@ import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.internal.restclient.api.capabilities.PodExecIntegrationTest; -import com.openshift.internal.restclient.model.Pod; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.capability.CapabilityVisitor; -import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; import com.openshift.restclient.capability.IStoppable; import com.openshift.restclient.capability.resources.IRSyncable; import com.openshift.restclient.capability.resources.IRSyncable.LocalPeer; import com.openshift.restclient.capability.resources.IRSyncable.Peer; import com.openshift.restclient.capability.resources.IRSyncable.PodPeer; -import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.IPod; /** * @@ -53,9 +51,10 @@ * */ public class OpenshiftBinaryRSyncRetrievalIntegrationTest { - private static final String TARGET_FOLDER_WITH_SPECIAL_CHARS = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/with sp@cé/"; - private static final String FILE_NAME_SPECIAL_CHARS = "test with spéci@l characters and spaces"; - private static final String SOURCE_FOLDER_WITH_SPECIAL_CHARS = "with sp@cé in path"; + // rsync now reports special characters as octal UTF-8: 'é' -> octal utf8: \\0303\\0251, hex utf8: \u00e9 + private static final String TARGET_FOLDER_WITH_SPECIAL_CHARS = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/with sp@ce/"; + private static final String FILE_NAME_SPECIAL_CHARS = "test with speci@l characters and spaces"; + private static final String SOURCE_FOLDER_WITH_SPECIAL_CHARS = "with sp@ce in path"; private static final String NORMAL_TARGET_TMP = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/withoutspace/"; private static final String NORMAL_FILE_NAME = "normalFileName"; @@ -69,17 +68,16 @@ public class OpenshiftBinaryRSyncRetrievalIntegrationTest { @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); - private Pod pod; - private String podFolderToClean = null; + private IPod pod; + private String podFolderToClean; @Before public void setUp() throws Exception { // given - System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); - client = helper.createClientForBasicAuth(); - - List pods = client.list(ResourceKind.POD, "default"); - pod = (Pod) pods.stream().filter(p -> p.getName().startsWith("docker-registry")).findFirst().orElse(null); + this.helper.setOpenShiftBinarySystemProperty(); + this.client = helper.createClientForBasicAuth(); + List allPods = client.list(ResourceKind.POD, IntegrationTestHelper.getDefaultNamespace()); + this.pod = helper.getDockerRegistryPod(allPods); assertNotNull("Did not find the registry pod to which to rsync", pod); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java index 2aa28002..738b8045 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015-2018 Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -31,7 +31,6 @@ import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.IPodLogListener; import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.Options; import com.openshift.restclient.model.IPod; -import com.openshift.restclient.model.IResource; public class PodLogRetrievalAsyncIntegrationTest { @@ -44,8 +43,8 @@ public class PodLogRetrievalAsyncIntegrationTest { public void testAsyncLogRetrieval() throws Exception { latch = new CountDownLatch(2); DefaultClient client = (DefaultClient) helper.createClientForBasicAuth(); - List pods = client.list(ResourceKind.POD, "default"); - IPod pod = (IPod) pods.stream().filter(p -> p.getName().startsWith("docker-registry")).findFirst().orElse(null); + List allPods = client.list(ResourceKind.POD, IntegrationTestHelper.getDefaultNamespace()); + IPod pod = helper.getDockerRegistryPod(allPods); assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); final String container = pod.getContainers().iterator().next().getName(); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java index 02a18b49..9f93000a 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -19,6 +19,7 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.internal.restclient.ResourceFactory; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; @@ -38,14 +39,14 @@ public class UpdateableCapabilityTest { @Before public void setup() { when(client.getOpenShiftAPIVersion()).thenReturn("v1"); - factory = new ResourceFactory(client); - service = factory.stub(ResourceKind.SERVICE, "foo", "default"); + this.factory = new ResourceFactory(client); + this.service = factory.stub(ResourceKind.SERVICE, "foo", IntegrationTestHelper.getDefaultNamespace()); service.setAnnotation("foo", "bar"); } @Test public void testUpdateCapability() { - IService target = factory.stub(ResourceKind.SERVICE, "foo", "default"); + IService target = factory.stub(ResourceKind.SERVICE, "foo", IntegrationTestHelper.getDefaultNamespace()); target.setAnnotation("foo", "xyz"); service.accept(new CapabilityVisitor() { diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java index 341c637f..18220a39 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -15,17 +15,19 @@ import java.net.MalformedURLException; import java.util.ArrayList; import java.util.Collection; +import java.util.stream.Collectors; import org.jboss.dmr.ModelNode; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.internal.restclient.model.template.Template; import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.server.ITemplateProcessing; import com.openshift.restclient.model.IProject; @@ -37,51 +39,57 @@ public class ServerTemplateProcessingIntegrationTest { private static final Logger LOG = LoggerFactory.getLogger(ServerTemplateProcessingIntegrationTest.class); - private IClient client; private IntegrationTestHelper helper = new IntegrationTestHelper(); - + private IClient client; private IProject project; + private Collection resources = new ArrayList(); @Before - public void setup() throws MalformedURLException { - client = helper.createClientForBasicAuth(); - String namespace = helper.generateNamespace(); - client.create(client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, namespace)); - project = client.get(ResourceKind.PROJECT, namespace, ""); + public void before() throws MalformedURLException { + this.client = helper.createClientForBasicAuth(); + this.project = helper.getOrCreateIntegrationTestProject(client); + } + + @After + public void after() { + helper.cleanUpResources(client, resources); } @Test public void testProcessAndApplyTemplate() throws Exception { - final Collection results = new ArrayList(); ModelNode node = ModelNode.fromJSONString(Samples.V1_TEMPLATE.getContentAsString()); final Template template = new Template(node, client, null); template.setNamespace(null); - try { - client.accept(new CapabilityVisitor() { + client.accept(new CapabilityVisitor() { - @Override - public Object visit(ITemplateProcessing capability) { + @Override + public Object visit(ITemplateProcessing capability) { - LOG.debug("Processing template: {}", template.toJson()); - assertFalse("Exp. the template to have items for this test be interesting", - template.getObjects().isEmpty()); - final int items = template.getObjects().size(); - ITemplate processedTemplate = capability.process(template, project.getName()); + LOG.debug("Processing template: {}", template.toJson()); + assertFalse("Exp. the template to have items for this test be interesting", + template.getObjects().isEmpty()); + final int items = template.getObjects().size(); + ITemplate processedTemplate = capability.process(template, project.getName()); - LOG.debug("Applying template: {}", processedTemplate.toJson()); - LOG.debug("Applied template"); - assertEquals("Exp. the pre and post item count to be the same", items, - template.getObjects().size()); - for (IResource resource : processedTemplate.getObjects()) { - LOG.debug("creating: {}", resource); - results.add(client.create(resource, project.getName())); - LOG.debug("created: {}", resource.toJson()); - } - return null; - } - }, new Object()); - } finally { - IntegrationTestHelper.cleanUpResource(client, project); - } + LOG.debug("Applying template: {}", processedTemplate.toJson()); + LOG.debug("Applied template"); + assertEquals("Exp. the pre and post item count to be the same", + items, + template.getObjects().size()); + Collection stubs = processedTemplate.getObjects(); + ServerTemplateProcessingIntegrationTest.this.resources = + stubs.stream() + .map(stub -> { + // resources as in template dont have a namespace + ((KubernetesResource) stub).setNamespace(project.getNamespaceName()); + LOG.debug("creating: {}", stub); + IResource resource = client.create(stub); + LOG.debug("created: {}", resource.toJson()); + return resource; + }) + .collect(Collectors.toList()); + return null; + } + }, new Object()); } } diff --git a/src/test/java/com/openshift/internal/restclient/model/kubeconfig/KubeClientConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/kubeconfig/KubeClientConfigTest.java index 66b4e283..7b882419 100644 --- a/src/test/java/com/openshift/internal/restclient/model/kubeconfig/KubeClientConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/kubeconfig/KubeClientConfigTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -19,6 +19,7 @@ import org.junit.Before; import org.junit.Test; +import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.restclient.model.kubeclient.ICluster; import com.openshift.restclient.model.kubeclient.IContext; import com.openshift.restclient.model.kubeclient.IKubeClientConfig; @@ -53,7 +54,7 @@ public void testDeserialization() { assertEquals(4, config.getContexts().size()); IContext context = config.getContexts().iterator().next(); assertNotNull(context); - assertEquals("default", context.getNamespace()); + assertEquals(IntegrationTestHelper.getDefaultNamespace(), context.getNamespace()); assertEquals("10-3-9-15:8443", context.getCluster()); assertEquals("jcantril@redhat.com/10-3-9-15:8443", context.getUser()); diff --git a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java index 1f440db9..9c16e254 100644 --- a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java +++ b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -11,8 +11,7 @@ package com.openshift.restclient; -import static com.openshift.internal.restclient.IntegrationTestHelper.cleanUpResource; -import static org.junit.Assert.assertArrayEquals; +import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -40,36 +39,41 @@ public class WatchClientIntegrationTest { private IntegrationTestHelper helper = new IntegrationTestHelper(); private IClient client; private IResource project; - public static final String[] KINDS = new String[] { ResourceKind.BUILD_CONFIG, ResourceKind.DEPLOYMENT_CONFIG, - ResourceKind.SERVICE, ResourceKind.POD, ResourceKind.REPLICATION_CONTROLLER, ResourceKind.BUILD, - ResourceKind.IMAGE_STREAM, ResourceKind.ROUTE }; + public static final String[] KINDS = new String[] { + ResourceKind.BUILD_CONFIG, + ResourceKind.DEPLOYMENT_CONFIG, + ResourceKind.SERVICE, + ResourceKind.POD, + ResourceKind.REPLICATION_CONTROLLER, + ResourceKind.BUILD, + ResourceKind.IMAGE_STREAM, + ResourceKind.ROUTE + }; - private ExecutorService service; + private ExecutorService executor; private boolean isError; + private IService service; + @Before public void setup() { - service = Executors.newSingleThreadScheduledExecutor(); - client = helper.createClientForBasicAuth(); - IResource projRequest = client.getResourceFactory().stub(ResourceKind.PROJECT_REQUEST, - helper.generateNamespace()); - project = client.create(projRequest); + this.executor = Executors.newSingleThreadScheduledExecutor(); + this.client = helper.createClientForBasicAuth(); + this.project = helper.getOrCreateIntegrationTestProject(client); + // kill existing service to avoid name clash } @After public void teardown() { - cleanUpResource(client, project); - service.shutdownNow(); + executor.shutdownNow(); } - @SuppressWarnings("rawtypes") - @Test(timeout = 60000) + @Test(timeout = IntegrationTestHelper.TEST_TIMEOUT) public void test() throws Exception { - List results = new ArrayList(); + List results = new ArrayList<>(); CountDownLatch latch = new CountDownLatch(KINDS.length); IOpenShiftWatchListener listener = new IOpenShiftWatchListener() { - @SuppressWarnings("unchecked") @Override public void received(IResource resource, ChangeType change) { results.add(change); @@ -98,20 +102,23 @@ public void error(Throwable err) { watcher = client.watch(project.getName(), listener, KINDS); latch.await(); assertFalse("Expected connection without error", isError); - IService service = client.getResourceFactory().stub(ResourceKind.SERVICE, "hello-world", project.getName()); - service.addPort(8080, 8080); - service = client.create(service); - service.addLabel("foo", "bar"); - service = client.update(service); - client.delete(service); - assertArrayEquals(new ChangeType[] { ChangeType.ADDED, ChangeType.MODIFIED, ChangeType.DELETED }, - results.toArray()); + IService stub = helper.stubService(client, + project.getNamespaceName(), + IntegrationTestHelper.appendRandom("hello-openshift"), + 8787, 8787, + ""); + this.service = client.create(stub); + this.service.addLabel("foo", "bar"); + this.service = client.update(service); + client.delete(stub); + this.service = null; + assertThat(results).containsExactly( + ChangeType.ADDED, + ChangeType.MODIFIED, + ChangeType.DELETED); assertEquals(0, latch.getCount()); } finally { - if (watcher != null) { - watcher.stop(); - } + helper.stopWatcher(watcher); } } - } diff --git a/src/test/resources/openshiftv3IntegrationTest.properties b/src/test/resources/openshiftv3IntegrationTest.properties index fafe0864..7e9d4c5c 100644 --- a/src/test/resources/openshiftv3IntegrationTest.properties +++ b/src/test/resources/openshiftv3IntegrationTest.properties @@ -1,10 +1,13 @@ -serverURL=https://localhost:8443 +serverURL=https://192.168.64.69:8443 +#serverURL=https://console.rh-us-east-1.openshift.com - -#osadm policy add-cluster-role-to-user cluster-admin $ADMIN_USER --config=openshift.local.config/master/admin.kubeconfig default.clusteradmin.user=admin -default.clusteradmin.password=admin +default.clusteradmin.password=system + +integrationtest.project=int-test +ocbinary.location=/usr/local/bin/oc + +# to allow policy and roles integration tests to pass, in cdk enable admin-user.addon or execute +#oc adm policy add-cluster-role-to-user cluster-admin admin -default.project=int-test -default.openshift.location=/home/jeff.cantrill/scripts/oc From 95bbb06a7480194085c33f6ceadeccd8bbfe5b3f Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 25 Feb 2019 19:57:39 +0100 Subject: [PATCH 154/258] [365] ignoring ITs for deprecated authorization endpoints * Role * PolicyBinding * Policy Signed-off-by: Andre Dietisheim --- .../authorization/AuthorizationKindsIntegrationTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java index 61556805..52b3ec35 100644 --- a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java @@ -14,6 +14,7 @@ import java.util.List; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import com.openshift.internal.restclient.IntegrationTestHelper; @@ -31,17 +32,20 @@ public void setup() { client = helper.createClientForBasicAuth(); } + @Ignore("Role endpoint was deprecated in v1") @Test public void testListRolesAssumingClusterAdmin() { List roles = client.list(ResourceKind.ROLE, IntegrationTestHelper.getDefaultNamespace()); assertThat(roles).isNotEmpty(); } + @Ignore("Policy endpoint was deprecated in v1") @Test public void testListPoliciesAssumingClusterAdmin() { client.list(ResourceKind.POLICY, IntegrationTestHelper.getDefaultNamespace()); } + @Ignore("PolicyBinding endpoint was deprecated in v1") @Test public void testListPolicyBindingsAssumingClusterAdmin() { client.list(ResourceKind.POLICY_BINDING, IntegrationTestHelper.getDefaultNamespace()); From 959219e80fa92d29a1b59c96203630a55d665207 Mon Sep 17 00:00:00 2001 From: dean1013 Date: Wed, 13 Mar 2019 12:13:25 +0300 Subject: [PATCH 155/258] allow configuration of ping interval and its time unit for OkHttpClient via ClientBuilder --- .../java/com/openshift/restclient/ClientBuilder.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 8c1fdd4d..381ecd04 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -78,6 +78,8 @@ public class ClientBuilder { private TimeUnit connectTimeoutUnit = TimeUnit.MILLISECONDS; private int writeTimeout = IHttpConstants.DEFAULT_READ_TIMEOUT; private TimeUnit writeTimeoutUnit = TimeUnit.MILLISECONDS; + private int pingInterval = 0; + private TimeUnit pingIntervalUnit = TimeUnit.MILLISECONDS; public ClientBuilder() { this(null); @@ -169,6 +171,12 @@ public ClientBuilder withWriteTimeout(int timeout, TimeUnit unit) { return this; } + public ClientBuilder withPingInterval(int pingInterval, TimeUnit unit) { + this.pingInterval = pingInterval; + this.pingIntervalUnit = unit; + return this; + } + public ClientBuilder proxy(Proxy proxy) { this.proxy = proxy; return this; @@ -242,6 +250,7 @@ public Response intercept(Chain chain) throws IOException { } }).authenticator(authenticator).dispatcher(dispatcher).readTimeout(readTimeout, readTimeoutUnit) .writeTimeout(writeTimeout, writeTimeoutUnit).connectTimeout(connectTimeout, connectTimeoutUnit) + .pingInterval(pingInterval, pingIntervalUnit) .sslSocketFactory(sslContext.getSocketFactory(), trustManager); if (!this.sslCertCallbackWithDefaultHostnameVerifier) { From 57130f8d648a8d76fe89a580dc26bafc128b02ab Mon Sep 17 00:00:00 2001 From: dean1013 Date: Thu, 14 Mar 2019 13:02:29 +0300 Subject: [PATCH 156/258] raise minor version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3b4ff55e..a7351bed 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 7.0.1-SNAPSHOT + 7.1.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 7a982cb33fa450880c6d861a3de0612b6038f6c1 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 18 Mar 2019 10:40:54 +0100 Subject: [PATCH 157/258] bump to 7.1.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a7351bed..992cd571 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 7.1.0-SNAPSHOT + 7.1.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From 1599d399e1df1bf258648b2b906223eb4f14ed37 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 21 Mar 2019 09:54:27 +0100 Subject: [PATCH 158/258] bump to 7.1.1-SNAPSHOT after releasing 7.1.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 992cd571..dd33905e 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 7.1.0.Final + 7.1.1-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 5b1eb29beb59d8c0eccac417abbebda1c774ba3c Mon Sep 17 00:00:00 2001 From: Ladislav Thon Date: Fri, 15 Mar 2019 14:45:10 +0100 Subject: [PATCH 159/258] [373] silence errors when determining master version --- .../internal/restclient/DefaultClient.java | 22 +++++++--- .../DefaultClientConstructionTest.java | 41 +++++++++++++++++++ .../restclient/TypeMapperFixture.java | 28 +++++++++++-- 3 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 7e3046cd..80d771db 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.authorization.AuthorizationContext; +import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; import com.openshift.internal.restclient.okhttp.WatchClient; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; @@ -93,8 +94,8 @@ public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, if (this.factory != null) { this.factory.setClient(this); } - initMasterVersion("version/openshift", new VersionCallback(version -> this.openShiftVersion = version)); - initMasterVersion("version", new VersionCallback(version -> this.kubernetesVersion = version)); + initMasterVersion("version/openshift", new VersionCallback("OpenShift", version -> this.openShiftVersion = version)); + initMasterVersion("version", new VersionCallback("Kubernetes", version -> this.kubernetesVersion = version)); this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client); this.authContext = authContext; } @@ -449,7 +450,9 @@ public String getOpenShiftAPIVersion() { private void initMasterVersion(String versionInfoType, Callback callback) { try { Request request = new Builder().url(new URL(this.baseUrl, versionInfoType)) - .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON).build(); + .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON) + .tag(new ResponseCodeInterceptor.Ignore() {}) + .build(); client.newCall(request).enqueue(callback); } catch (IOException e) { LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); @@ -457,22 +460,29 @@ private void initMasterVersion(String versionInfoType, Callback callback) { } private class VersionCallback implements Callback { + String description; Consumer versionSetter; - public VersionCallback(Consumer versionSetter) { + public VersionCallback(String description, Consumer versionSetter) { + this.description = description; this.versionSetter = versionSetter; } @Override public void onFailure(Call call, IOException e) { versionSetter.accept(""); - LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); + LOGGER.warn("Exception while trying to determine " + description + " master version", e); } @Override public void onResponse(Call call, Response response) throws IOException { try { - versionSetter.accept(ModelNode.fromJSONString(response.body().string()).get("gitVersion").asString()); + if (response.isSuccessful()) { + versionSetter.accept(ModelNode.fromJSONString(response.body().string()).get("gitVersion").asString()); + } else { + versionSetter.accept(""); + LOGGER.warn("Failed to determine " + description + " master version: got " + response.code()); + } } finally { response.close(); } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java new file mode 100644 index 00000000..78458190 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java @@ -0,0 +1,41 @@ +package com.openshift.internal.restclient; + +import static org.fest.assertions.Assertions.assertThat; + +import org.junit.Test; + +import com.openshift.restclient.utils.Samples; + +public class DefaultClientConstructionTest extends TypeMapperFixture { + @Test + public void testKubernetesMasterVersionOk() throws Exception { + getHttpClient().mockAsyncRequest(base + "/version", + () -> responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); + + assertThat(getIClient().getKubernetesMasterVersion()).isEqualTo("v1.6.1+5115d708d7"); + } + + @Test + public void testKubernetesMasterVersion404() throws Exception { + getHttpClient().mockAsyncRequest(base + "/version", + () -> responseOf(404, "something wrong")); + + assertThat(getIClient().getKubernetesMasterVersion()).isEqualTo(""); + } + + @Test + public void testOpenShiftMasterVersionOk() throws Exception { + getHttpClient().mockAsyncRequest(base + "/version/openshift", + () -> responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); + + assertThat(getIClient().getOpenshiftMasterVersion()).isEqualTo("v3.6.0-alpha.2+3c221d5"); + } + + @Test + public void testOpenShiftMasterVersion404() throws Exception { + getHttpClient().mockAsyncRequest(base + "/version/openshift", + () -> responseOf(404, "something wrong")); + + assertThat(getIClient().getOpenshiftMasterVersion()).isEqualTo(""); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index ff077127..c3a9c25a 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -12,6 +12,7 @@ package com.openshift.internal.restclient; import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -19,8 +20,10 @@ import java.io.IOException; import java.net.URL; +import java.util.function.Supplier; import org.junit.Before; +import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.stubbing.OngoingStubbing; @@ -30,6 +33,7 @@ import com.openshift.restclient.utils.Samples; import okhttp3.Call; +import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Protocol; import okhttp3.Request; @@ -69,9 +73,10 @@ public void setUp() throws Exception { .thenReturn(responseOf(Samples.GROUP_ENDPONT_OAPI_V1.getContentAsString())); client.whenRequestTo(base + "/apis/extensions/v1beta1") .thenReturn(responseOf(Samples.GROUP_ENDPONT_APIS_EXTENSIONS.getContentAsString())); - client.whenRequestTo(base + "/version").thenReturn(responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); - client.whenRequestTo(base + "/version/openshift") - .thenReturn(responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); + client.mockAsyncRequest(base + "/version", + () -> responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); + client.mockAsyncRequest(base + "/version/openshift", + () -> responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); mapper = new ApiTypeMapper(base, client); } @@ -83,6 +88,17 @@ OngoingStubbing whenRequestTo(String url) throws IOException { return when(call.execute()); } + void mockAsyncRequest(String url, Supplier response) throws IOException { + Call call = mock(Call.class); + doReturn(call).when(this).newCall(requestTo(url)); + + ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Callback.class); + doAnswer(invocation -> { + Callback callback = argumentCaptor.getValue(); + callback.onResponse(call, response.get()); + return null; + }).when(call).enqueue(argumentCaptor.capture()); + } } static Request requestTo(String url) { @@ -90,10 +106,14 @@ static Request requestTo(String url) { } protected static Response responseOf(String response) { + return responseOf(IHttpConstants.STATUS_OK, response); + } + + protected static Response responseOf(int statusCode, String response) { return new Response.Builder() .request(new Request.Builder().url("https://someurlfortesting").build()) .protocol(Protocol.HTTP_1_1) - .code(IHttpConstants.STATUS_OK) + .code(statusCode) .message("") .body(ResponseBody.create(null, response)) .build(); From 3e260ce00825910eac6d14102828a2995713cadd Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 8 Feb 2019 14:27:02 +0100 Subject: [PATCH 160/258] added TODO to retrieve the pod status for ALL containers. Cleaned code. Signed-off-by: Andre Dietisheim --- .../internal/restclient/model/Pod.java | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index 523367f9..364e9c34 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -12,6 +12,7 @@ import static com.openshift.internal.restclient.capability.CapabilityInitializer.initializeCapabilities; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -43,14 +44,11 @@ public class Pod extends KubernetesResource implements IPod { private static final String POD_STATUS_CONTAINER_STATUSES = "status.containerStatuses"; // container reasons fields and corresponding status prefixes - private static final List POD_STATUS_CONTAINER_STATES = new ArrayList() { - { - add(new String[] { "state.waiting.reason", "" }); - add(new String[] { "state.terminated.reason", "" }); - add(new String[] { "state.terminated.signal", "Signal: " }); - add(new String[] { "state.terminated.exitCode", "Exit Code: " }); - } - }; + private static final List POD_STATUS_CONTAINER_STATES = Arrays.asList( + new String[] { "state.waiting.reason", "" }, + new String[] { "state.terminated.reason", "" }, + new String[] { "state.terminated.signal", "Signal: " }, + new String[] { "state.terminated.exitCode", "Exit Code: " }); public Pod(ModelNode node, IClient client, Map propertyKeys) { super(node, client, propertyKeys); @@ -69,7 +67,7 @@ public String getHost() { @Override public Collection getImages() { - Collection images = new ArrayList(); + Collection images = new ArrayList<>(); ModelNode node = get(POD_CONTAINERS); if (node.getType() != ModelType.LIST) { return images; @@ -84,7 +82,6 @@ public Collection getImages() { * The logic of the method is a copied from 'podStatus' function of * [app/scripts/filters/resources.js] of [openshift/origin-web-console] */ - @Override public String getStatus() { if (has(POD_DELETION_TIMESTAMP)) { @@ -94,6 +91,8 @@ public String getStatus() { if (node.getType() == ModelType.LIST) { for (ModelNode containerStatus : node.asList()) { String status = getContainerStatusStringIfExist(containerStatus); + // TODO: take all containers into account + // -> fetch all status and merge them, currently we're returning the 1st one. if (status != null) { return status; } @@ -116,7 +115,7 @@ private String getContainerStatusStringIfExist(ModelNode containerStatus) { @Override public Set getContainerPorts() { - Set ports = new HashSet(); + Set ports = new HashSet<>(); ModelNode node = get(POD_CONTAINERS); if (node.getType() == ModelType.LIST) { for (ModelNode container : node.asList()) { From d22077d59040a191f88532a25d23af01c40021ce Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 8 Feb 2019 14:29:53 +0100 Subject: [PATCH 161/258] inversed expected/actual values for erroneous assertions Signed-off-by: Andre Dietisheim --- .../internal/restclient/model/v1/PodTest.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index c0d520f3..ebf2ede5 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -64,21 +64,21 @@ public void testGetStatusPhase() { @Test public void testGetStatusDeletion() { ((Pod) pod).getNode().get("metadata", "deletionTimestamp").set("2016-11-02T16:31:55Z"); - assertEquals(pod.getStatus(), "Terminating"); + assertEquals("Terminating", pod.getStatus()); } @Test public void testGetStatusWaitingReason() { ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("waiting", new ModelNode().set("reason", "ReasonNotToWork")); - assertEquals(pod.getStatus(), "ReasonNotToWork"); + assertEquals("ReasonNotToWork", pod.getStatus()); } @Test public void testGetStatusTerminateReason() { ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", new ModelNode().set("reason", "ReasonToTerminate")); - assertEquals(pod.getStatus(), "ReasonToTerminate"); + assertEquals("ReasonToTerminate", pod.getStatus()); } /** @@ -90,14 +90,14 @@ public void testGetStatusTerminateReasonAndExit() { node.get("reason").set("ReasonToTerminate"); node.get("exitCode").set("Let's go! Time to exit!"); ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", node); - assertEquals(pod.getStatus(), "ReasonToTerminate"); + assertEquals("ReasonToTerminate", pod.getStatus()); } @Test public void testGetStatusTerminatedSignal() { ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", new ModelNode().set("signal", "Alarm! Terminate!")); - assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); + assertEquals("Signal: Alarm! Terminate!", pod.getStatus()); } /** @@ -109,14 +109,14 @@ public void testGetStatusTerminatedSignalAndExit() { node.get("signal").set("Alarm! Terminate!"); node.get("exitCode").set("Let's go! Time to exit!"); ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", node); - assertEquals(pod.getStatus(), "Signal: Alarm! Terminate!"); + assertEquals("Signal: Alarm! Terminate!", pod.getStatus()); } @Test public void testGetStatusTerminatedExit() { ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", new ModelNode().set("exitCode", "Let's go! Time to exit!")); - assertEquals(pod.getStatus(), "Exit Code: Let's go! Time to exit!"); + assertEquals("Exit Code: Let's go! Time to exit!", pod.getStatus()); } @Test @@ -163,9 +163,9 @@ public void testAddContainer() { public void getContainerCommands() { List cmd = container1.getCommand(); List cmdArgs = container1.getCommandArgs(); - assertEquals(cmd.get(0), "/bin/sh"); - assertEquals(cmdArgs.get(0), "-c"); - assertEquals(cmdArgs.get(1), "echo 'hello'"); + assertEquals("/bin/sh", cmd.get(0)); + assertEquals("-c", cmdArgs.get(0)); + assertEquals("echo 'hello'", cmdArgs.get(1)); } @Test From e1f3fc9529e5ab190a980b70c5827f1f706c7401 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 8 Feb 2019 14:30:30 +0100 Subject: [PATCH 162/258] corrected and completed javadocs Signed-off-by: Andre Dietisheim --- .../com/openshift/restclient/model/IPod.java | 39 ++++++++++++++----- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/openshift/restclient/model/IPod.java b/src/main/java/com/openshift/restclient/model/IPod.java index 10e1a8ea..5d870d82 100644 --- a/src/main/java/com/openshift/restclient/model/IPod.java +++ b/src/main/java/com/openshift/restclient/model/IPod.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -15,45 +15,64 @@ public interface IPod extends IResource { /** - * Gets the IP of the Pod + * Returns the IP of this pod. * + * @return ip of this pod. */ String getIP(); /** - * Gets the name of the host on which the pod is running + * Returns the hostname of the host on which the pod is running. + * + * @return the hostname of this pod. * */ String getHost(); /** - * Gets the collection of image names for the pod containers + * Returns the names of the images that the containers of this pod are using. * + * @return the image names for the containers of this pod. */ Collection getImages(); /** - * Gets the status of the pod + * Returns the status of the pod. The pod status is derived from the status of + * all it's containers. The current implementation is limited to the status of + * the 1st container though. The string that's returned is built out of + * different properties of the container: + *

    + *
  • state.waiting.reason
  • + *
  • state.terminated.reason
  • , + *
  • state.terminated.signal
  • + *
  • state.terminated.exitCode
  • + *
* + * @return the status of this pod */ String getStatus(); /** - * Retrieve the set of ports that the containers are using + * Returns the ports that the containers of this pod are using. + * + * @returns the ports of the containers for this pod. */ Set getContainerPorts(); /** - * Add a container with the given name. This is useful if creating a pod - * directly without a resource controller + * Adds a container with the given name. This is useful if creating a pod + * directly without a resource controller. Returns the container for the given name. + * + * @param the name of the container * + * @return the container that was added. */ IContainer addContainer(String name); /** - * Retrieve all the containers spec'd for the pod + * Returns all the containers for this pod. * - * @return collection of containers + * @return the containers for this pod. */ Collection getContainers(); } From 626c05364e14fc6d5faa09705f7b4b06d43e117f Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 8 Feb 2019 17:37:10 +0100 Subject: [PATCH 163/258] [360] impl'd IPod#isReady that relies on all containers to be ready Signed-off-by: Andre Dietisheim --- .../internal/restclient/model/Pod.java | 14 + .../com/openshift/restclient/model/IPod.java | 8 + .../internal/restclient/model/v1/PodTest.java | 118 ++++-- .../openshift/restclient/utils/Samples.java | 1 + .../v1_pod_multiContainer_ready.json | 392 ++++++++++++++++++ 5 files changed, 492 insertions(+), 41 deletions(-) create mode 100644 src/test/resources/samples/openshift3/v1_pod_multiContainer_ready.json diff --git a/src/main/java/com/openshift/internal/restclient/model/Pod.java b/src/main/java/com/openshift/internal/restclient/model/Pod.java index 364e9c34..0d7caa57 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Pod.java +++ b/src/main/java/com/openshift/internal/restclient/model/Pod.java @@ -42,6 +42,7 @@ public class Pod extends KubernetesResource implements IPod { private static final String POD_STATUS_PHASE = "status.phase"; private static final String POD_STATUS_REASON = "status.reason"; private static final String POD_STATUS_CONTAINER_STATUSES = "status.containerStatuses"; + private static final String CONTAINER_STATUS_READY = "ready"; // container reasons fields and corresponding status prefixes private static final List POD_STATUS_CONTAINER_STATES = Arrays.asList( @@ -148,4 +149,17 @@ public Collection getContainers() { return Collections.emptyList(); } + @Override + public boolean isReady() { + ModelNode node = get(POD_STATUS_CONTAINER_STATUSES); + if (node.getType() != ModelType.LIST) { + return false; + } + boolean allContainersReady = true; + for (ModelNode containerStatus : node.asList()) { + String ready = containerStatus.get(CONTAINER_STATUS_READY).asString(); + allContainersReady &= Boolean.parseBoolean(ready); + } + return allContainersReady; + } } diff --git a/src/main/java/com/openshift/restclient/model/IPod.java b/src/main/java/com/openshift/restclient/model/IPod.java index 5d870d82..8d281324 100644 --- a/src/main/java/com/openshift/restclient/model/IPod.java +++ b/src/main/java/com/openshift/restclient/model/IPod.java @@ -75,4 +75,12 @@ public interface IPod extends IResource { * @return the containers for this pod. */ Collection getContainers(); + + /** + * Returns {@code true} if all containers of this pod are ready. {@code false} + * otherwise. + * + * @return true if all containers are ready, false otherwise. + */ + boolean isReady(); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index ebf2ede5..81ae8acb 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -9,6 +9,7 @@ package com.openshift.internal.restclient.model.v1; +import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -40,45 +41,52 @@ public class PodTest { private static final String VERSION = "v1"; - private IPod pod; - private IContainer container1; + + private IClient client; + private IPod pod1; + private IContainer pod1container1; + + private IPod pod2; @Before public void setup() { - IClient client = mock(IClient.class); + this.client = mock(IClient.class); ModelNode node = ModelNode.fromJSONString(Samples.V1_POD.getContentAsString()); - this.pod = new Pod(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.POD)); - this.container1 = pod.getContainers().stream().findFirst().orElse(null); + this.pod1 = createPod(node); + this.pod1container1 = pod1.getContainers().stream().findFirst().orElse(null); + + node = ModelNode.fromJSONString(Samples.V1_POD_MULTICONTAINER_READY.getContentAsString()); + this.pod2 = createPod(node); } @Test public void testGetHost() { - assertEquals("127.0.0.1", pod.getHost()); + assertEquals("127.0.0.1", pod1.getHost()); } @Test public void testGetStatusPhase() { - assertEquals("Running", pod.getStatus()); + assertEquals("Running", pod1.getStatus()); } @Test public void testGetStatusDeletion() { - ((Pod) pod).getNode().get("metadata", "deletionTimestamp").set("2016-11-02T16:31:55Z"); - assertEquals("Terminating", pod.getStatus()); + ((Pod) pod1).getNode().get("metadata", "deletionTimestamp").set("2016-11-02T16:31:55Z"); + assertEquals("Terminating", pod1.getStatus()); } @Test public void testGetStatusWaitingReason() { - ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("waiting", + ((Pod) pod1).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("waiting", new ModelNode().set("reason", "ReasonNotToWork")); - assertEquals("ReasonNotToWork", pod.getStatus()); + assertEquals("ReasonNotToWork", pod1.getStatus()); } @Test public void testGetStatusTerminateReason() { - ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", + ((Pod) pod1).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", new ModelNode().set("reason", "ReasonToTerminate")); - assertEquals("ReasonToTerminate", pod.getStatus()); + assertEquals("ReasonToTerminate", pod1.getStatus()); } /** @@ -89,15 +97,15 @@ public void testGetStatusTerminateReasonAndExit() { ModelNode node = new ModelNode(); node.get("reason").set("ReasonToTerminate"); node.get("exitCode").set("Let's go! Time to exit!"); - ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", node); - assertEquals("ReasonToTerminate", pod.getStatus()); + ((Pod) pod1).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", node); + assertEquals("ReasonToTerminate", pod1.getStatus()); } @Test public void testGetStatusTerminatedSignal() { - ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", + ((Pod) pod1).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", new ModelNode().set("signal", "Alarm! Terminate!")); - assertEquals("Signal: Alarm! Terminate!", pod.getStatus()); + assertEquals("Signal: Alarm! Terminate!", pod1.getStatus()); } /** @@ -108,26 +116,26 @@ public void testGetStatusTerminatedSignalAndExit() { ModelNode node = new ModelNode(); node.get("signal").set("Alarm! Terminate!"); node.get("exitCode").set("Let's go! Time to exit!"); - ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", node); - assertEquals("Signal: Alarm! Terminate!", pod.getStatus()); + ((Pod) pod1).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", node); + assertEquals("Signal: Alarm! Terminate!", pod1.getStatus()); } @Test public void testGetStatusTerminatedExit() { - ((Pod) pod).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", + ((Pod) pod1).getNode().get("status", "containerStatuses").asList().get(0).get("state").set("terminated", new ModelNode().set("exitCode", "Let's go! Time to exit!")); - assertEquals("Exit Code: Let's go! Time to exit!", pod.getStatus()); + assertEquals("Exit Code: Let's go! Time to exit!", pod1.getStatus()); } @Test public void testGetImages() { String[] exp = new String[] { "openshift/origin-deployer:v0.6" }; - assertArrayEquals(exp, pod.getImages().toArray()); + assertArrayEquals(exp, pod1.getImages().toArray()); } @Test public void getIP() { - assertEquals("1.2.3.4", pod.getIP()); + assertEquals("1.2.3.4", pod1.getIP()); } @Test @@ -138,18 +146,18 @@ public void getContainerPorts() { port.setContainerPort(8080); Set ports = new HashSet<>(); ports.add(port); - assertEquals(ports, pod.getContainerPorts()); + assertEquals(ports, pod1.getContainerPorts()); } @Test public void testAddContainer() { - Collection initial = pod.getContainers(); - IContainer foo = pod.addContainer("foo"); + Collection initial = pod1.getContainers(); + IContainer foo = pod1.addContainer("foo"); foo.setLifecycle(new Lifecycle.Builder() .preStop(new ExecAction.Builder().command("cmd1").command("cmd2").build()).build()); - Collection containers = pod.getContainers(); + Collection containers = pod1.getContainers(); assertEquals(initial.size() + 1, containers.size()); Optional container = containers.stream() @@ -161,8 +169,8 @@ public void testAddContainer() { @Test public void getContainerCommands() { - List cmd = container1.getCommand(); - List cmdArgs = container1.getCommandArgs(); + List cmd = pod1container1.getCommand(); + List cmdArgs = pod1container1.getCommandArgs(); assertEquals("/bin/sh", cmd.get(0)); assertEquals("-c", cmdArgs.get(0)); assertEquals("echo 'hello'", cmdArgs.get(1)); @@ -170,21 +178,49 @@ public void getContainerCommands() { @Test public void getContainerResourceRequirements() { - assertEquals("1", container1.getRequestsCPU()); - assertEquals("128Mi", container1.getRequestsMemory()); - assertEquals("4", container1.getLimitsCPU()); - assertEquals("1Gi", container1.getLimitsMemory()); + assertEquals("1", pod1container1.getRequestsCPU()); + assertEquals("128Mi", pod1container1.getRequestsMemory()); + assertEquals("4", pod1container1.getLimitsCPU()); + assertEquals("1Gi", pod1container1.getLimitsMemory()); } @Test public void resetContainerResourceRequirements() { - container1.setRequestsMemory(null); - container1.setRequestsCPU(null); - container1.setLimitsMemory(null); - container1.setLimitsCPU(null); - assertEquals("", container1.getRequestsCPU()); - assertEquals("", container1.getRequestsMemory()); - assertEquals("", container1.getLimitsCPU()); - assertEquals("", container1.getLimitsMemory()); + pod1container1.setRequestsMemory(null); + pod1container1.setRequestsCPU(null); + pod1container1.setLimitsMemory(null); + pod1container1.setLimitsCPU(null); + assertEquals("", pod1container1.getRequestsCPU()); + assertEquals("", pod1container1.getRequestsMemory()); + assertEquals("", pod1container1.getLimitsCPU()); + assertEquals("", pod1container1.getLimitsMemory()); + } + + @Test + public void shouldBeReadyIfAllContainersAreReady() { + assertThat(pod2.isReady()).isTrue(); + } + + @Test + public void shouldNotBeReadyIfAtLeast1ContainerIsNotReady() { + IPod nonReadyPod = setContainerReady(1, false, pod2, client); + + assertThat(nonReadyPod.isReady()).isFalse(); + } + + private IPod setContainerReady(int index, boolean ready, IPod pod, IClient client) { + ModelNode node = ModelNode.fromJSONString(pod.toJson()); + ModelNode podStatusNode = node.get("status"); + ModelNode allContainerStatusNode = podStatusNode.get("containerStatuses"); + assertThat(allContainerStatusNode.isDefined()).isTrue(); + assertThat(allContainerStatusNode.get(index).isDefined()).isTrue();; + ModelNode statusNode = allContainerStatusNode.get(index); + ModelNode readyNode = statusNode.get("ready"); + readyNode.set(ready); + return createPod(node); + } + + private Pod createPod(ModelNode node) { + return new Pod(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.POD)); } } diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 46bdd391..30e089d7 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -45,6 +45,7 @@ public enum Samples { V1_OBJECT_REF("openshift3/v1_objectref.json"), V1_NAMESPACE("openshift3/v1_namespace.json"), V1_POD("openshift3/v1_pod.json"), + V1_POD_MULTICONTAINER_READY("openshift3/v1_pod_multiContainer_ready.json"), V1_PROJECT("openshift3/v1_project.json"), V1_PROJECT_REQUEST("openshift3/v1_project_request.json"), V1_PVC("openshift3/v1_pvc.json"), diff --git a/src/test/resources/samples/openshift3/v1_pod_multiContainer_ready.json b/src/test/resources/samples/openshift3/v1_pod_multiContainer_ready.json new file mode 100644 index 00000000..b4b60c5d --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_pod_multiContainer_ready.json @@ -0,0 +1,392 @@ +{ + "kind" : "Pod", + "apiVersion" : "v1", + "metadata" : { + "name" : "nodejs-mongo-persistent-1-g4vbs", + "generateName" : "nodejs-mongo-persistent-1-", + "namespace" : "jbide25000-2", + "selfLink" : "/api/v1/namespaces/jbide25000-2/pods/nodejs-mongo-persistent-1-g4vbs", + "uid" : "5a44638d-2b8b-11e9-9384-06d3e3320f22", + "resourceVersion" : "442694201", + "creationTimestamp" : "2019-02-08T10:21:52Z", + "deletionTimestamp" : "2019-02-08T10:23:52Z", + "deletionGracePeriodSeconds" : 0, + "labels" : { + "deployment" : "nodejs-mongo-persistent-1", + "deploymentconfig" : "nodejs-mongo-persistent", + "name" : "nodejs-mongo-persistent" + }, + "annotations" : { + "kubernetes.io/limit-ranger" : "LimitRanger plugin set: cpu request for container nodejs-mongo-persistent; cpu limit for container nodejs-mongo-persistent", + "openshift.io/deployment-config.latest-version" : "1", + "openshift.io/deployment-config.name" : "nodejs-mongo-persistent", + "openshift.io/deployment.name" : "nodejs-mongo-persistent-1", + "openshift.io/scc" : "restricted" + }, + "ownerReferences" : [{ + "apiVersion" : "v1", + "kind" : "ReplicationController", + "name" : "nodejs-mongo-persistent-1", + "uid" : "5641d4f6-2b8b-11e9-a209-02dd5d026c14", + "controller" : true, + "blockOwnerDeletion" : true + }] + }, + "spec" : { + "volumes" : [{ + "name" : "default-token-xv9r6", + "secret" : { + "secretName" : "default-token-xv9r6", + "defaultMode" : 420 + } + }], + "containers" : [{ + "name" : "nodejs-mongo-persistent", + "image" : "docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "ports" : [{ + "containerPort" : 8080, + "protocol" : "TCP" + }], + "env" : [ + { + "name" : "DATABASE_SERVICE_NAME", + "value" : "mongodb" + }, + { + "name" : "MONGODB_USER", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-user" + }} + }, + { + "name" : "MONGODB_PASSWORD", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-password" + }} + }, + { + "name" : "MONGODB_DATABASE", + "value" : "sampledb" + }, + { + "name" : "MONGODB_ADMIN_PASSWORD", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-admin-password" + }} + } + ], + "resources" : { + "limits" : { + "cpu" : "300m", + "memory" : "512Mi" + }, + "requests" : { + "cpu" : "75m", + "memory" : "512Mi" + } + }, + "volumeMounts" : [{ + "name" : "default-token-xv9r6", + "readOnly" : true, + "mountPath" : "/var/run/secrets/kubernetes.io/serviceaccount" + }], + "livenessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 30, + "timeoutSeconds" : 3, + "periodSeconds" : 10, + "successThreshold" : 1, + "failureThreshold" : 3 + }, + "readinessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 3, + "timeoutSeconds" : 3, + "periodSeconds" : 10, + "successThreshold" : 1, + "failureThreshold" : 3 + }, + "terminationMessagePath" : "/dev/termination-log", + "terminationMessagePolicy" : "File", + "imagePullPolicy" : "IfNotPresent", + "securityContext" : { + "capabilities" : {"drop" : [ + "KILL", + "MKNOD", + "SETGID", + "SETUID" + ]}, + "runAsUser" : 1003800000 + } + }, + { + "name" : "nodejs-mongo-persistent-2", + "image" : "docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "ports" : [{ + "containerPort" : 8080, + "protocol" : "TCP" + }], + "env" : [ + { + "name" : "DATABASE_SERVICE_NAME", + "value" : "mongodb" + }, + { + "name" : "MONGODB_USER", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-user" + }} + }, + { + "name" : "MONGODB_PASSWORD", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-password" + }} + }, + { + "name" : "MONGODB_DATABASE", + "value" : "sampledb" + }, + { + "name" : "MONGODB_ADMIN_PASSWORD", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-admin-password" + }} + } + ], + "resources" : { + "limits" : { + "cpu" : "300m", + "memory" : "512Mi" + }, + "requests" : { + "cpu" : "75m", + "memory" : "512Mi" + } + }, + "volumeMounts" : [{ + "name" : "default-token-xv9r6", + "readOnly" : true, + "mountPath" : "/var/run/secrets/kubernetes.io/serviceaccount" + }], + "livenessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 30, + "timeoutSeconds" : 3, + "periodSeconds" : 10, + "successThreshold" : 1, + "failureThreshold" : 3 + }, + "readinessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 3, + "timeoutSeconds" : 3, + "periodSeconds" : 10, + "successThreshold" : 1, + "failureThreshold" : 3 + }, + "terminationMessagePath" : "/dev/termination-log", + "terminationMessagePolicy" : "File", + "imagePullPolicy" : "IfNotPresent", + "securityContext" : { + "capabilities" : {"drop" : [ + "KILL", + "MKNOD", + "SETGID", + "SETUID" + ]}, + "runAsUser" : 1003800000 + } + }, + { + "name" : "nodejs-mongo-persistent-3", + "image" : "docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "ports" : [{ + "containerPort" : 8080, + "protocol" : "TCP" + }], + "env" : [ + { + "name" : "DATABASE_SERVICE_NAME", + "value" : "mongodb" + }, + { + "name" : "MONGODB_USER", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-user" + }} + }, + { + "name" : "MONGODB_PASSWORD", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-password" + }} + }, + { + "name" : "MONGODB_DATABASE", + "value" : "sampledb" + }, + { + "name" : "MONGODB_ADMIN_PASSWORD", + "valueFrom" : {"secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-admin-password" + }} + } + ], + "resources" : { + "limits" : { + "cpu" : "300m", + "memory" : "512Mi" + }, + "requests" : { + "cpu" : "75m", + "memory" : "512Mi" + } + }, + "volumeMounts" : [{ + "name" : "default-token-xv9r6", + "readOnly" : true, + "mountPath" : "/var/run/secrets/kubernetes.io/serviceaccount" + }], + "livenessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 30, + "timeoutSeconds" : 3, + "periodSeconds" : 10, + "successThreshold" : 1, + "failureThreshold" : 3 + }, + "readinessProbe" : { + "httpGet" : { + "path" : "/pagecount", + "port" : 8080, + "scheme" : "HTTP" + }, + "initialDelaySeconds" : 3, + "timeoutSeconds" : 3, + "periodSeconds" : 10, + "successThreshold" : 1, + "failureThreshold" : 3 + }, + "terminationMessagePath" : "/dev/termination-log", + "terminationMessagePolicy" : "File", + "imagePullPolicy" : "IfNotPresent", + "securityContext" : { + "capabilities" : {"drop" : [ + "KILL", + "MKNOD", + "SETGID", + "SETUID" + ]}, + "runAsUser" : 1003800000 + } + }], + "restartPolicy" : "Always", + "terminationGracePeriodSeconds" : 30, + "dnsPolicy" : "ClusterFirst", + "nodeSelector" : { + "servicecomponent" : "nodeint", + "servicephase" : "hostedprod", + "vpc" : "vpc-8055ade5" + }, + "serviceAccountName" : "default", + "serviceAccount" : "default", + "nodeName" : "opennode-66-103.hosted.a3.vary.redhat.com", + "securityContext" : { + "seLinuxOptions" : {"level" : "s0:c62,c9"}, + "fsGroup" : 1003800000 + }, + "imagePullSecrets" : [{"name" : "default-dockercfg-jtlcb"}], + "schedulerName" : "default-scheduler", + "tolerations" : [{ + "key" : "node.kubernetes.io/memory-pressure", + "operator" : "Exists", + "effect" : "NoSchedule" + }] + }, + "status" : { + "phase" : "Running", + "conditions" : [ + { + "type" : "Initialized", + "status" : "True", + "lastTransitionTime" : "2019-02-08T10:21:52Z" + }, + { + "type" : "Ready", + "status" : "False", + "lastTransitionTime" : "2019-02-08T10:23:53Z", + "reason" : "ContainersNotReady", + "message" : "containers with unready status: [nodejs-mongo-persistent]" + }, + { + "type" : "PodScheduled", + "status" : "True", + "lastTransitionTime" : "2019-02-08T10:21:52Z" + } + ], + "hostIP" : "10.29.66.103", + "podIP" : "172.20.68.204", + "startTime" : "2019-02-08T10:21:52Z", + "containerStatuses" : [{ + "name" : "nodejs-mongo-persistent", + "state" : {"running" : {"startedAt" : "2019-02-08T10:23:59Z"}}, + "lastState" : {}, + "ready" : true, + "restartCount" : 0, + "image" : "docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "imageID" : "docker-pullable://docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "containerID" : "docker://dd892f0393cca8702553a2d4152fb848c98602687b1d9f21663b97ae800efb6a" + }, + { + "name" : "nodejs-mongo-persistent-2", + "state" : {"running" : {"startedAt" : "2019-02-08T10:24:59Z"}}, + "lastState" : {}, + "ready" : true, + "restartCount" : 0, + "image" : "docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "imageID" : "docker-pullable://docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "containerID" : "docker://dd892f0393cca8702553a2d4152fb848c98602687b1d9f21663b97ae800efb6a" + }, + { + "name" : "nodejs-mongo-persistent-3", + "state" : {"running" : {"startedAt" : "2019-02-08T10:25:59Z"}}, + "lastState" : {}, + "ready" : true, + "restartCount" : 0, + "image" : "docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "imageID" : "docker-pullable://docker-registry.default.svc:5000/jbide25000-2/nodejs-mongo-persistent@sha256:4f2b1c1b85a61918ace38a90cd7e31f833891fb81cb84c104fbe43d5e1091103", + "containerID" : "docker://fd892f0393cca8702553a2d4152fb848c98602687b1d9f21663b97ae800efb6a" + }], + "qosClass" : "Burstable" + } +} From 721b7e04f8c0004eee3a785d313579a50f71d4e1 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 9 May 2019 22:11:44 +0200 Subject: [PATCH 164/258] OSJC-284: Authorize URL is computed from baseURL use /.well-known/oauth-authorization-server Signed-off-by: Jeff MAURY --- .../internal/restclient/DefaultClient.java | 73 ++++++++++++++++++- .../authorization/AuthorizationContext.java | 4 +- .../okhttp/OpenShiftAuthenticator.java | 7 +- .../com/openshift/restclient/IClient.java | 12 ++- 4 files changed, 89 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 80d771db..5c7d2a43 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -14,6 +14,7 @@ import java.io.IOException; import java.io.InputStream; +import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; @@ -22,6 +23,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.function.Consumer; import org.apache.commons.lang.ObjectUtils; @@ -74,6 +77,9 @@ public class DefaultClient implements IClient, IHttpConstants { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); private URL baseUrl; + private CompletableFuture authorizationEndpoint = new CompletableFuture<>(); + private CompletableFuture tokenEndpoint = new CompletableFuture<>(); + private OkHttpClient client; private IResourceFactory factory; private Map, ICapability> capabilities = new HashMap<>(); @@ -96,6 +102,7 @@ public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, } initMasterVersion("version/openshift", new VersionCallback("OpenShift", version -> this.openShiftVersion = version)); initMasterVersion("version", new VersionCallback("Kubernetes", version -> this.kubernetesVersion = version)); + initMasterVersion(".well-known/oauth-authorization-server", new AuthorizationCallback()); this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client); this.authContext = authContext; } @@ -489,6 +496,36 @@ public void onResponse(Call call, Response response) throws IOException { } } + private class AuthorizationCallback implements Callback { + + private void setDefaults() { + DefaultClient.this.authorizationEndpoint.complete(DefaultClient.this.getDefaultAuthorizationEndpoint()); + DefaultClient.this.tokenEndpoint.complete(DefaultClient.this.getDefaultTokenEndpoint()); + } + + @Override + public void onFailure(Call call, IOException e) { + setDefaults(); + LOGGER.warn("Exception while trying to get authorization endpoint", e); + } + + @Override + public void onResponse(Call call, Response response) throws IOException { + try { + if (response.isSuccessful()) { + ModelNode node = ModelNode.fromJSONString(response.body().string()); + DefaultClient.this.authorizationEndpoint.complete(new URL(node.get("authorization_endpoint").asString())); + DefaultClient.this.tokenEndpoint.complete(new URL(node.get("token_endpoint").asString())); + } else { + setDefaults(); + LOGGER.warn("Failed to determine authorization endpoint: got " + response.code()); + } + } finally { + response.close(); + } + } + } + @Override public String getOpenshiftMasterVersion() { return this.openShiftVersion; @@ -505,6 +542,40 @@ public URL getBaseURL() { } @Override + public URL getAuthorizationEndpoint() { + try { + return authorizationEndpoint.get(); + } catch (InterruptedException | ExecutionException e) { + throw new OpenShiftException(e, e.getLocalizedMessage()); + } + } + + protected URL getDefaultAuthorizationEndpoint() { + try { + return new URL(getBaseURL(), "oauth/authorize"); + } catch (MalformedURLException e) { + throw new OpenShiftException(e, e.getLocalizedMessage()); + } + } + + @Override + public URL getTokenEndpoint() { + try { + return tokenEndpoint.get(); + } catch (InterruptedException | ExecutionException e) { + throw new OpenShiftException(e, e.getLocalizedMessage()); + } + } + + protected URL getDefaultTokenEndpoint() { + try { + return new URL(getBaseURL(), "oauth/token"); + } catch (MalformedURLException e) { + throw new OpenShiftException(e, e.getLocalizedMessage()); + } + } + + @Override public IAuthorizationContext getAuthorizationContext() { return this.authContext; } diff --git a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java index 6062c74f..ca3df0db 100644 --- a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java +++ b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -68,7 +68,7 @@ public boolean isAuthorized() { @Override public IAuthorizationDetails getAuthorizationDetails() { - return new AuthorizationDetails(String.format("%s/oauth/token/request", client.getBaseURL())); + return new AuthorizationDetails(String.format("%s/request", client.getTokenEndpoint())); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java index 6b5fdc8a..3ea581e3 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -12,6 +12,7 @@ package com.openshift.internal.restclient.okhttp; import java.io.IOException; +import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Map; @@ -54,8 +55,8 @@ public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { public Request authenticate(Route route, Response response) throws IOException { if (unauthorizedForCluster(response)) { String requestUrl = response.request().url().toString(); - Request authRequest = new Request.Builder().addHeader(CSRF_TOKEN, "1").url(response.request().url().resolve( - "/oauth/authorize?response_type=token&client_id=openshift-challenging-client").toString()).build(); + Request authRequest = new Request.Builder().addHeader(CSRF_TOKEN, "1").url(new URL(client.getAuthorizationEndpoint().toExternalForm() + + "?response_type=token&client_id=openshift-challenging-client").toString()).build(); try (Response authResponse = tryAuth(authRequest)) { if (authResponse.isSuccessful()) { String token = extractAndSetAuthContextToken(authResponse); diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index b4d93798..f75f2389 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -312,6 +312,16 @@ T execute(ITypeFactory factory, String httpMethod, String kin * @return the base URL of this endpoint */ URL getBaseURL(); + + /** + * @return the authentication endpoint to be used when login + */ + URL getAuthorizationEndpoint(); + + /** + * @return the token endpoint to be used when login + */ + URL getTokenEndpoint(); /** * From bcba05759f2705bc78ab1262590df06f991932e0 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 10 May 2019 07:48:15 +0200 Subject: [PATCH 165/258] Fix Checkstyle issues Signed-off-by: Jeff MAURY --- .../internal/restclient/DefaultClient.java | 84 +++++++++---------- .../okhttp/OpenShiftAuthenticator.java | 4 +- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 5c7d2a43..3c5a21ea 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -498,14 +498,14 @@ public void onResponse(Call call, Response response) throws IOException { private class AuthorizationCallback implements Callback { - private void setDefaults() { - DefaultClient.this.authorizationEndpoint.complete(DefaultClient.this.getDefaultAuthorizationEndpoint()); - DefaultClient.this.tokenEndpoint.complete(DefaultClient.this.getDefaultTokenEndpoint()); - } + private void setDefaults() { + DefaultClient.this.authorizationEndpoint.complete(DefaultClient.this.getDefaultAuthorizationEndpoint()); + DefaultClient.this.tokenEndpoint.complete(DefaultClient.this.getDefaultTokenEndpoint()); + } - @Override + @Override public void onFailure(Call call, IOException e) { - setDefaults(); + setDefaults(); LOGGER.warn("Exception while trying to get authorization endpoint", e); } @@ -513,11 +513,11 @@ public void onFailure(Call call, IOException e) { public void onResponse(Call call, Response response) throws IOException { try { if (response.isSuccessful()) { - ModelNode node = ModelNode.fromJSONString(response.body().string()); - DefaultClient.this.authorizationEndpoint.complete(new URL(node.get("authorization_endpoint").asString())); - DefaultClient.this.tokenEndpoint.complete(new URL(node.get("token_endpoint").asString())); + ModelNode node = ModelNode.fromJSONString(response.body().string()); + DefaultClient.this.authorizationEndpoint.complete(new URL(node.get("authorization_endpoint").asString())); + DefaultClient.this.tokenEndpoint.complete(new URL(node.get("token_endpoint").asString())); } else { - setDefaults(); + setDefaults(); LOGGER.warn("Failed to determine authorization endpoint: got " + response.code()); } } finally { @@ -542,40 +542,40 @@ public URL getBaseURL() { } @Override - public URL getAuthorizationEndpoint() { - try { - return authorizationEndpoint.get(); - } catch (InterruptedException | ExecutionException e) { - throw new OpenShiftException(e, e.getLocalizedMessage()); - } - } + public URL getAuthorizationEndpoint() { + try { + return authorizationEndpoint.get(); + } catch (InterruptedException | ExecutionException e) { + throw new OpenShiftException(e, e.getLocalizedMessage()); + } + } - protected URL getDefaultAuthorizationEndpoint() { - try { - return new URL(getBaseURL(), "oauth/authorize"); - } catch (MalformedURLException e) { - throw new OpenShiftException(e, e.getLocalizedMessage()); - } - } - - @Override - public URL getTokenEndpoint() { - try { - return tokenEndpoint.get(); - } catch (InterruptedException | ExecutionException e) { - throw new OpenShiftException(e, e.getLocalizedMessage()); - } - } + protected URL getDefaultAuthorizationEndpoint() { + try { + return new URL(getBaseURL(), "oauth/authorize"); + } catch (MalformedURLException e) { + throw new OpenShiftException(e, e.getLocalizedMessage()); + } + } + + @Override + public URL getTokenEndpoint() { + try { + return tokenEndpoint.get(); + } catch (InterruptedException | ExecutionException e) { + throw new OpenShiftException(e, e.getLocalizedMessage()); + } + } - protected URL getDefaultTokenEndpoint() { - try { - return new URL(getBaseURL(), "oauth/token"); - } catch (MalformedURLException e) { - throw new OpenShiftException(e, e.getLocalizedMessage()); - } - } - - @Override + protected URL getDefaultTokenEndpoint() { + try { + return new URL(getBaseURL(), "oauth/token"); + } catch (MalformedURLException e) { + throw new OpenShiftException(e, e.getLocalizedMessage()); + } + } + + @Override public IAuthorizationContext getAuthorizationContext() { return this.authContext; } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java index 3ea581e3..e0ac4c6e 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java @@ -55,8 +55,8 @@ public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { public Request authenticate(Route route, Response response) throws IOException { if (unauthorizedForCluster(response)) { String requestUrl = response.request().url().toString(); - Request authRequest = new Request.Builder().addHeader(CSRF_TOKEN, "1").url(new URL(client.getAuthorizationEndpoint().toExternalForm() + - "?response_type=token&client_id=openshift-challenging-client").toString()).build(); + Request authRequest = new Request.Builder().addHeader(CSRF_TOKEN, "1").url(new URL(client.getAuthorizationEndpoint().toExternalForm() + + "?response_type=token&client_id=openshift-challenging-client").toString()).build(); try (Response authResponse = tryAuth(authRequest)) { if (authResponse.isSuccessful()) { String token = extractAndSetAuthContextToken(authResponse); From 8880307e1c5e86403018d76b60312037eb717ccc Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 10 May 2019 08:11:31 +0200 Subject: [PATCH 166/258] Use JDK11 instead of JDK9 Signed-off-by: Jeff MAURY --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index ab39bb25..403bd877 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java jdk: - oraclejdk8 - - oraclejdk9 + - oraclejdk11 script: mvn clean verify From 800e829ec3cb5a58ced6290f03042e0fcbddec05 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Mon, 20 May 2019 16:07:19 +0200 Subject: [PATCH 167/258] OSJC-285: fix CVE-2018-20200 - Updated okhttp from 3.11.0 to 3.14.2 Signed-off-by: Jeff MAURY --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index dd33905e..f36b3d63 100755 --- a/pom.xml +++ b/pom.xml @@ -161,7 +161,7 @@ com.squareup.okhttp3 okhttp - 3.11.0 + 3.14.2 org.yaml From 3828826d40e4b568d006e21aef0e34c042eaf532 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 20 May 2019 17:56:54 +0200 Subject: [PATCH 168/258] releasing 7.1.1.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f36b3d63..410171b7 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 7.1.1-SNAPSHOT + 7.1.1.Final jar OpenShift Java REST Client http://openshift.redhat.com From 213f0682c1972f9fd8fc396e73e40871ab0e2aec Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 20 May 2019 18:33:43 +0200 Subject: [PATCH 169/258] bumping to 7.1.2-SNAPSHOT after releasing 7.1.1.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 410171b7..da3e58b5 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 7.1.1.Final + 7.1.2-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From d3f184beb795d6d6779eace66d94af396dd05c1d Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Wed, 22 May 2019 11:18:47 +0200 Subject: [PATCH 170/258] Bumping to 8.0.0-SNAPSHOT as we are going to support OpenShift 4 Signed-off-by: Jeff MAURY --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index da3e58b5..2814731e 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 7.1.2-SNAPSHOT + 8.0.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 4f5b2e41afd3e1f904b694bf13d5d3ccdc25ebc1 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 9 May 2019 16:01:24 +0200 Subject: [PATCH 171/258] OSJC-286: OCP4 support - Protect /oapi loading - Change resource version lookup algorithm - Implementation classes are now registered dynamically though k8stypes.properties Signed-off-by: Jeff MAURY --- .../internal/restclient/ApiTypeMapper.java | 145 ++++- .../internal/restclient/DefaultClient.java | 3 + .../internal/restclient/ResourceFactory.java | 120 +--- .../internal/restclient/TypeRegistry.java | 112 ++++ .../restclient/apis/TypeMetaFactory.java | 27 +- .../capability/CapabilityInitializer.java | 2 +- .../properties/ResourcePropertyKeys.java | 5 +- .../openshift/restclient/ClientBuilder.java | 4 +- .../openshift/restclient/IApiTypeMapper.java | 49 +- .../openshift/restclient/ResourceKind.java | 22 +- src/main/resources/k8stypes.properties | 43 ++ .../restclient/ApiTypeMapperTest.java | 2 +- .../restclient/IntegrationTestHelper.java | 29 +- .../restclient/ResourceFactoryTest.java | 48 +- .../capabilities/PodExecIntegrationTest.java | 4 +- ...ftBinaryRSyncRetrievalIntegrationTest.java | 7 +- .../PodLogRetrievalAsyncIntegrationTest.java | 5 +- .../resources/UpdateableCapabilityTest.java | 29 + ...rverTemplateProcessingIntegrationTest.java | 59 +- .../restclient/model/ServiceTest.java | 32 +- .../WatchClientIntegrationTest.java | 2 +- .../openshift/restclient/utils/Samples.java | 5 +- .../samples/openshift3/api_v1_endpoint.json | 389 +++++++++-- .../openshift3/apis_endpoint_extensions.json | 204 ++++-- .../samples/openshift3/group_template.json | 450 +++++++++++++ .../samples/openshift3/oapi_v1_endpoint.json | 604 ++++++++++++++++-- 26 files changed, 2042 insertions(+), 359 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/TypeRegistry.java create mode 100644 src/main/resources/k8stypes.properties create mode 100644 src/test/resources/samples/openshift3/group_template.json diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index bd918722..555d54c3 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -19,9 +19,9 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; -import java.util.stream.Stream; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; @@ -52,6 +52,7 @@ public class ApiTypeMapper implements IApiTypeMapper, ResourcePropertyKeys { private final String baseUrl; private final OkHttpClient client; private List resourceEndpoints; + private List types; private final Map preferedVersion = new HashMap<>(2); private boolean initialized = false; @@ -95,11 +96,14 @@ public IVersionedApiResource getEndpointFor(String apiVersion, String kind) { private IVersionedApiResource endpointFor(String version, String kind) { String[] split = StringUtils.isBlank(version) ? new String[] {} : version.split(FWD_SLASH); - Optional result = null; + Optional result = null; if (split.length <= 1) { - result = Stream.of(KUBE_API, OS_API) - .map(api -> formatEndpointFor(api, (split.length == 0 ? preferedVersion.get(api) : split[0]), kind)) - .filter(e -> resourceEndpoints.contains(e)).findFirst(); + result = resourceEndpoints.stream().filter(e -> { + return e.getName().equals(ResourceKind.pluralize(kind, true, true)) + && (split.length == 0 || e.getVersion().equals(split[split.length - 1])) + && (split.length < 2 || e.getApiGroupName().equals(split[0])); + + }).findFirst(); } else { result = Optional.of(formatEndpointFor(API_GROUPS_API, version, kind)); } @@ -116,25 +120,48 @@ private IVersionedApiResource formatEndpointFor(String prefix, String version, S return new VersionedApiResource(prefix, version, ResourceKind.pluralize(kind, true, true)); } + @Override + public IVersionedType getType(String apiVersion, String kind) { + init(); + IVersionedType type = typeFor(apiVersion, kind); + if (type == null) { + throw new UnsupportedEndpointException("No endpoint found for %s, version %s", kind, apiVersion); + } + return type; + } + + private IVersionedType typeFor(String version, String kind) { + String[] split = StringUtils.isBlank(version) ? new String[] {} : version.split(FWD_SLASH); + Optional result = null; + result = types.stream().filter(e -> { + return e.getKind().equals(kind) && (split.length == 0 || split[split.length - 1].equals(e.getVersion())) + && (split.length < 2 || split[0].equals(e.getApiGroupName())); + + }).findFirst(); + return result.orElse(null); + } + private synchronized void init() { if (!this.initialized) { List resourceEndpoints = new ArrayList<>(); + List types = new ArrayList<>(); Collection groups = getLegacyGroups(); groups.addAll(getApiGroups()); groups.forEach(g -> { Collection versions = g.getVersions(); versions.forEach(v -> { Collection resources = getResources(g, v); - addEndpoints(resourceEndpoints, g.getPrefix(), g.getName(), v, resources); + addEndpoints(resourceEndpoints, types, g.getPrefix(), g.getName(), v, resources); }); }); this.resourceEndpoints = resourceEndpoints; + this.types = types; this.initialized = true; } } - private void addEndpoints(List endpoints, final String prefix, final String apiGroupName, - final String version, final Collection nodes) { + private void addEndpoints(List endpoints, List types, final String prefix, + final String apiGroupName, final String version, final Collection nodes) { for (ModelNode node : nodes) { String name = node.get(NAME).asString(); String capability = null; @@ -143,15 +170,27 @@ private void addEndpoints(List endpoints, final String pre capability = name.substring(first + 1); name = name.substring(0, first); } + String kind = node.get(KIND).asString(); + String typeApiGroupName = node.has(GROUP) ? node.get(GROUP).asString() : null; + String typeVersion = node.has(VERSION) ? node.get(VERSION).asString() : null; boolean namespaced = node.get("namespaced").asBoolean(); - VersionedApiResource resource = new VersionedApiResource(prefix, apiGroupName, version, name, - node.get(KIND).asString(), namespaced); - if (!endpoints.contains(resource)) { - endpoints.add(resource); + VersionedApiResource resource = new VersionedApiResource(prefix, apiGroupName, version, name, kind, + namespaced); + VersionedType type = new VersionedType(prefix, typeApiGroupName != null ? typeApiGroupName : apiGroupName, + typeVersion != null ? typeVersion : version, kind); + if (capability == null && node.has(VERBS) && !node.get(VERBS).asList().isEmpty()) { + if (!endpoints.contains(resource)) { + endpoints.add(resource); + } + } + if (!types.contains(type)) { + types.add(type); } if (capability != null) { int index = endpoints.indexOf(resource); - endpoints.get(index).addCapability(capability); + if (index != (-1)) { + endpoints.get(index).addCapability(capability); + } } } } @@ -163,20 +202,29 @@ private Collection getApiGroups() { } private Collection getResources(IApiGroup group, String version) { - String json = readEndpoint(group.pathFor(version)); - if (StringUtils.isBlank(json)) { + try { + String json = readEndpoint(group.pathFor(version)); + if (StringUtils.isBlank(json)) { + return new ArrayList<>(); + } + ModelNode node = ModelNode.fromJSONString(json); + return node.get("resources").asList(); + } catch (Exception e) { + LOGGER.error("Can't load api group {}", group.pathFor(version)); return new ArrayList<>(); } - ModelNode node = ModelNode.fromJSONString(json); - return node.get("resources").asList(); } private Collection getLegacyGroups() { Collection groups = new ArrayList<>(); for (String e : Arrays.asList(KUBE_API, OS_API)) { - String json = readEndpoint(e); - ModelNode n = ModelNode.fromJSONString(json); - groups.add(new LegacyApiGroup(e, n)); + try { + String json = readEndpoint(e); + ModelNode n = ModelNode.fromJSONString(json); + groups.add(new LegacyApiGroup(e, n)); + } catch (Exception ex) { + LOGGER.error("Can't access legacy endpoint {}", e); + } } return groups; } @@ -401,4 +449,59 @@ public boolean equals(Object obj) { } } + + static class VersionedType implements IVersionedType { + private String prefix; + private String apiGroupName; + private String version; + private String kind; + + VersionedType(String prefix, String apiGroupName, String version, String kind) { + this.prefix = prefix; + this.apiGroupName = apiGroupName; + this.version = version; + this.kind = kind; + } + + @Override + public String getPrefix() { + return prefix; + } + + @Override + public String getApiGroupName() { + return apiGroupName; + } + + @Override + public String getVersion() { + return version; + } + + @Override + public String getKind() { + return kind; + } + + @Override + public int hashCode() { + return Objects.hash(apiGroupName, kind, version); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof VersionedType)) { + return false; + } + VersionedType other = (VersionedType) obj; + return Objects.equals(apiGroupName, other.apiGroupName) && Objects.equals(kind, other.kind) + && Objects.equals(version, other.version); + } + } } diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 3c5a21ea..f80fa719 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -658,6 +658,9 @@ public T adapt(Class klass) { if (ICapability.class.isAssignableFrom(klass) && this.supports((Class) klass)) { return (T) getCapability((Class) klass); } + if (IResourceFactory.class.equals(klass)) { + return (T) this.factory; + } return null; } diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 1246f204..60f3ff44 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -24,42 +24,10 @@ import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; -import com.openshift.internal.restclient.model.Build; -import com.openshift.internal.restclient.model.BuildConfig; -import com.openshift.internal.restclient.model.ConfigMap; -import com.openshift.internal.restclient.model.DeploymentConfig; -import com.openshift.internal.restclient.model.ImageStream; -import com.openshift.internal.restclient.model.KubernetesEvent; import com.openshift.internal.restclient.model.KubernetesResource; -import com.openshift.internal.restclient.model.LimitRange; -import com.openshift.internal.restclient.model.Namespace; -import com.openshift.internal.restclient.model.Pod; -import com.openshift.internal.restclient.model.Project; -import com.openshift.internal.restclient.model.ReplicationController; -import com.openshift.internal.restclient.model.ResourceQuota; -import com.openshift.internal.restclient.model.Route; -import com.openshift.internal.restclient.model.Secret; -import com.openshift.internal.restclient.model.Service; -import com.openshift.internal.restclient.model.ServiceAccount; -import com.openshift.internal.restclient.model.Status; -import com.openshift.internal.restclient.model.authorization.OpenshiftPolicy; -import com.openshift.internal.restclient.model.authorization.OpenshiftRole; -import com.openshift.internal.restclient.model.authorization.PolicyBinding; -import com.openshift.internal.restclient.model.authorization.RoleBinding; -import com.openshift.internal.restclient.model.build.BuildRequest; -import com.openshift.internal.restclient.model.image.ImageStreamImport; -import com.openshift.internal.restclient.model.oauth.OAuthAccessToken; -import com.openshift.internal.restclient.model.oauth.OAuthAuthorizeToken; -import com.openshift.internal.restclient.model.oauth.OAuthClient; -import com.openshift.internal.restclient.model.oauth.OAuthClientAuthorization; -import com.openshift.internal.restclient.model.project.OpenshiftProjectRequest; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; -import com.openshift.internal.restclient.model.template.Template; -import com.openshift.internal.restclient.model.user.OpenShiftUser; -import com.openshift.internal.restclient.model.volume.PersistentVolume; -import com.openshift.internal.restclient.model.volume.PersistentVolumeClaim; import com.openshift.restclient.IApiTypeMapper; -import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceFactoryException; @@ -77,49 +45,6 @@ public class ResourceFactory implements IResourceFactory { private static final String APIVERSION = "apiVersion"; private static final Map> IMPL_MAP = new HashMap<>(); - static { - // OpenShift kinds - IMPL_MAP.put(ResourceKind.BUILD, Build.class); - IMPL_MAP.put(ResourceKind.BUILD_CONFIG, BuildConfig.class); - IMPL_MAP.put(ResourceKind.BUILD_REQUEST, BuildRequest.class); - IMPL_MAP.put(ResourceKind.DEPLOYMENT_CONFIG, DeploymentConfig.class); - IMPL_MAP.put(ResourceKind.IMAGE_STREAM, ImageStream.class); - IMPL_MAP.put(ResourceKind.IMAGE_STREAM_IMPORT, ImageStreamImport.class); - IMPL_MAP.put(ResourceKind.LIST, com.openshift.internal.restclient.model.List.class); - IMPL_MAP.put(ResourceKind.NAMESPACE, Namespace.class); - IMPL_MAP.put(ResourceKind.OAUTH_ACCESS_TOKEN, OAuthAccessToken.class); - IMPL_MAP.put(ResourceKind.OAUTH_AUTHORIZE_TOKEN, OAuthAuthorizeToken.class); - IMPL_MAP.put(ResourceKind.OAUTH_CLIENT, OAuthClient.class); - IMPL_MAP.put(ResourceKind.OAUTH_CLIENT_AUTHORIZATION, OAuthClientAuthorization.class); - IMPL_MAP.put(ResourceKind.PROJECT, Project.class); - IMPL_MAP.put(ResourceKind.PROJECT_REQUEST, OpenshiftProjectRequest.class); - IMPL_MAP.put(ResourceKind.POLICY, OpenshiftPolicy.class); - IMPL_MAP.put(ResourceKind.POLICY_BINDING, PolicyBinding.class); - IMPL_MAP.put(ResourceKind.ROLE, OpenshiftRole.class); - IMPL_MAP.put(ResourceKind.ROLE_BINDING, RoleBinding.class); - IMPL_MAP.put(ResourceKind.ROUTE, Route.class); - IMPL_MAP.put(ResourceKind.TEMPLATE, Template.class); - IMPL_MAP.put(ResourceKind.USER, OpenShiftUser.class); - - // Kubernetes Kinds - IMPL_MAP.put(ResourceKind.EVENT, KubernetesEvent.class); - IMPL_MAP.put(ResourceKind.LIMIT_RANGE, LimitRange.class); - IMPL_MAP.put(ResourceKind.POD, Pod.class); - IMPL_MAP.put(ResourceKind.PVC, PersistentVolumeClaim.class); - IMPL_MAP.put(ResourceKind.PERSISTENT_VOLUME, PersistentVolume.class); - IMPL_MAP.put(ResourceKind.RESOURCE_QUOTA, ResourceQuota.class); - IMPL_MAP.put(ResourceKind.REPLICATION_CONTROLLER, ReplicationController.class); - IMPL_MAP.put(ResourceKind.STATUS, Status.class); - IMPL_MAP.put(ResourceKind.SERVICE, Service.class); - IMPL_MAP.put(ResourceKind.SECRET, Secret.class); - IMPL_MAP.put(ResourceKind.SERVICE_ACCOUNT, ServiceAccount.class); - IMPL_MAP.put(ResourceKind.CONFIG_MAP, ConfigMap.class); - - // fallback - IMPL_MAP.put(ResourceKind.UNRECOGNIZED, KubernetesResource.class); - - } - private IClient client; public ResourceFactory(IClient client) { @@ -226,28 +151,13 @@ public Object createInstanceFrom(String response) { @SuppressWarnings("unchecked") private Class getResourceClass(String version, String kind) { - if (IMPL_MAP.containsKey(kind)) { - return IMPL_MAP.get(kind); - } IApiTypeMapper mapper = this.client.adapt(IApiTypeMapper.class); if (mapper != null) { - IVersionedApiResource endpoint = mapper.getEndpointFor(version, kind); - String extension = ""; - switch (endpoint.getPrefix()) { - case IApiTypeMapper.KUBE_API: - case IApiTypeMapper.OS_API: - break; - default: - String extPlusVersion = endpoint.getApiGroupName(); - extension = StringUtils.split(extPlusVersion, IApiTypeMapper.FWD_SLASH)[0]; - } try { - String classname = String.format("com.openshift.internal.restclient.%s%s.models.%s", - endpoint.getPrefix(), extension, endpoint.getKind()); - return (Class) Class.forName(classname); - } catch (ClassNotFoundException e) { - // class doesnt exist in the exp location. - // fallback to an explicit registration + IVersionedType type = mapper.getType(version, kind); + return (Class) TypeRegistry.getInstance().getRegisteredType(type.getApiGroupNameAndVersion() + IApiTypeMapper.DOT + type.getKind()); + } catch (Exception e) { + return (Class) TypeRegistry.getInstance().getRegisteredType(version + IApiTypeMapper.DOT + kind); } } return null; @@ -256,15 +166,19 @@ private Class getResourceClass(String version, String kind) @SuppressWarnings("unchecked") @Override public T stub(String kind, String name, String namespace) { - // TODO get k8e or os - String version = client.getOpenShiftAPIVersion(); - KubernetesResource resource = (KubernetesResource) create(version, kind); - resource.setName(name); - resource.setNamespace(namespace); - if (StringUtils.isNotEmpty(namespace)) { + String[] elements = ResourceKind.parse(kind); + IVersionedType type = client.adapt(IApiTypeMapper.class).getType(elements[0], elements[1]); + if (type != null) { + KubernetesResource resource = (KubernetesResource) create(type.getApiGroupNameAndVersion(), elements[1]); + resource.setName(name); resource.setNamespace(namespace); + if (StringUtils.isNotEmpty(namespace)) { + resource.setNamespace(namespace); + } + return (T) resource; + } else { + throw new ResourceFactoryException(null, "Unable to create resource from kind %s", kind); } - return (T) resource; } @Override diff --git a/src/main/java/com/openshift/internal/restclient/TypeRegistry.java b/src/main/java/com/openshift/internal/restclient/TypeRegistry.java new file mode 100644 index 00000000..52af0741 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/TypeRegistry.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import org.jboss.dmr.ModelNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.api.models.ITypeMeta; +import com.openshift.restclient.model.IResource; + +/** + * Registry for types implemented by custom classes + * + */ +public class TypeRegistry { + + private static final Logger LOGGER = LoggerFactory.getLogger(TypeRegistry.class); + + private static final String RESOURCE_NAME = "k8stypes.properties"; + + private static TypeRegistry instance; + + public static final TypeRegistry getInstance() { + if (instance == null) { + instance = new TypeRegistry(); + } + return instance; + } + + private Map> registeredTypes = new HashMap<>(); + + private TypeRegistry() { + load(); + } + + private void load() { + try { + Enumeration urls = TypeRegistry.class.getClassLoader().getResources(RESOURCE_NAME); + while (urls.hasMoreElements()) { + URL url = urls.nextElement(); + try (InputStream is = url.openStream()) { + load(is); + } catch (IOException e) { + LOGGER.error("Can't load resource from " + url, e); + } + } + } catch (IOException e) { + LOGGER.error("Can't load resources from " + RESOURCE_NAME, e); + } + } + + private void load(InputStream stream) throws IOException { + Properties p = new Properties(); + p.load(stream); + for (Entry entry : p.entrySet()) { + try { + String className = (String) entry.getKey(); + Class clazz = Class.forName(className); + if (check(clazz)) { + String types = (String) entry.getValue(); + for (String type : types.split(",")) { + registeredTypes.put(type, clazz); + } + } + } catch (ClassNotFoundException e) { + LOGGER.warn("Can't load class", e); + } + } + } + + private boolean check(Class clazz) { + boolean valid = false; + if (IResource.class.isAssignableFrom(clazz)) { + try { + clazz.getConstructor(ModelNode.class, IClient.class, Map.class); + valid = true; + } catch (NoSuchMethodException | SecurityException e) { + LOGGER.error(e.getLocalizedMessage(), e); + } + } else if (ITypeMeta.class.isAssignableFrom(clazz)) { + try { + clazz.getConstructor(ModelNode.class, Map.class); + valid = true; + } catch (NoSuchMethodException | SecurityException e) { + LOGGER.error(e.getLocalizedMessage(), e); + } + } + return valid; + } + + public Class getRegisteredType(String kind) { + return registeredTypes.get(kind); + } +} diff --git a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java index b0251d08..ed9f6c23 100644 --- a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java +++ b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -12,19 +12,18 @@ package com.openshift.internal.restclient.apis; import java.lang.reflect.Constructor; -import java.util.HashMap; import java.util.Map; import java.util.Optional; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; +import com.openshift.internal.restclient.TypeRegistry; import com.openshift.internal.restclient.api.models.TypeMeta; -import com.openshift.internal.restclient.apis.autoscaling.models.Scale; -import com.openshift.internal.restclient.model.deploy.DeploymentRequest; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; import com.openshift.internal.util.JBossDmrExtentions; +import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceFactoryException; import com.openshift.restclient.UnsupportedVersionException; @@ -36,14 +35,7 @@ public class TypeMetaFactory implements ITypeFactory, ResourcePropertyKeys { private static final String DELIMITER = "."; - private static final Map> IMPL_MAP = new HashMap<>(); - - static { - IMPL_MAP.put("Scale", Scale.class); - // its own factory? - IMPL_MAP.put("DeploymentRequest", DeploymentRequest.class); - } - + @Override public Object stubKind(String kind, Optional name, Optional namespace) { if (StringUtils.isEmpty(kind)) { @@ -62,8 +54,9 @@ public Object stubKind(String kind, Optional name, Optional name JBossDmrExtentions.set(node, properyKeyMap, KIND, kind); ITypeMeta instance = null; - if (IMPL_MAP.containsKey(kind)) { - Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, + Class clazz = (Class) TypeRegistry.getInstance().getRegisteredType(version + IApiTypeMapper.DOT + kind); + if (clazz != null) { + Constructor constructor = clazz.getConstructor(ModelNode.class, Map.class); instance = constructor.newInstance(node, properyKeyMap); } else { @@ -93,8 +86,10 @@ public Object createInstanceFrom(String response) { String kind = node.get(KIND).asString(); Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); - if (IMPL_MAP.containsKey(kind)) { - Constructor constructor = IMPL_MAP.get(kind).getConstructor(ModelNode.class, + Class clazz = (Class) TypeRegistry.getInstance().getRegisteredType(version + IApiTypeMapper.DOT + kind); + + if (clazz != null) { + Constructor constructor = clazz.getConstructor(ModelNode.class, Map.class); return constructor.newInstance(node, properyKeyMap); } diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index 16d60632..3927fe6d 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 diff --git a/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java b/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java index 3321495e..483b281e 100644 --- a/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java +++ b/src/main/java/com/openshift/internal/restclient/model/properties/ResourcePropertyKeys.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -16,6 +16,8 @@ public interface ResourcePropertyKeys { static final String APIVERSION = "apiVersion"; static final String KIND = "kind"; + static final String GROUP = "group"; + static final String VERSION = "version"; static final String ANNOTATIONS = "metadata.annotations"; static final String CREATION_TIMESTAMP = "metadata.creationTimestamp"; @@ -35,4 +37,5 @@ public interface ResourcePropertyKeys { static final String RESOURCE_VERSION = "resourceVersion"; static final String VALUE = "value"; static final String TYPE = "type"; + static final String VERBS = "verbs"; } diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 381ecd04..46330a8f 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -263,6 +263,8 @@ public Response intercept(Chain chain) throws IOException { if (proxySelector != null) { builder.proxySelector(proxySelector); + } else { + builder.proxySelector(ProxySelector.getDefault()); } if (proxyAuthenticator != null) { @@ -279,7 +281,7 @@ public Response intercept(Chain chain) throws IOException { responseCodeInterceptor.setClient(client); authenticator.setClient(client); authenticator.setOkClient(okClient); - + factory.setClient(client); return client; } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) { diff --git a/src/main/java/com/openshift/restclient/IApiTypeMapper.java b/src/main/java/com/openshift/restclient/IApiTypeMapper.java index 9ae19e49..1fa0c4da 100644 --- a/src/main/java/com/openshift/restclient/IApiTypeMapper.java +++ b/src/main/java/com/openshift/restclient/IApiTypeMapper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -25,6 +25,7 @@ public interface IApiTypeMapper { static final String OS_API = "oapi"; static final String API_GROUPS_API = "apis"; static final String FWD_SLASH = "/"; + static final char DOT = '.'; String getPreferedVersionFor(String endpoint); @@ -66,6 +67,15 @@ public interface IApiTypeMapper { * @return true if supported; false otherwise */ boolean isSupported(String version, String kind); + + /** + * Get the type information best matching the version and kind arguments + * + * @param apiVersion the optional version (with or without group) + * @param kind the type kind + * @return the registered type or null + */ + IVersionedType getType(String apiVersion, String kind); /** * The api group for a given set of resources and the versions it supports. @@ -157,4 +167,41 @@ interface IVersionedApiResource { boolean isSupported(String capability); } + + interface IVersionedType { + /** + * The prefix of the resource type (e.g. extensions of extensions/v1beta1) + * + */ + String getPrefix(); + + /** + * The groupname of the resource type (e.g. extensions of extensions/v1beta1) + * + */ + String getApiGroupName(); + + /** + * The version of the resource type (e.g. v1) + * + */ + String getVersion(); + + /** + * The optional groupname and version of the resource type (e.g. extensions of extensions/v1beta1) + * + */ + default String getApiGroupNameAndVersion() { + if (getApiGroupName() != null) { + return getApiGroupName() + IApiTypeMapper.FWD_SLASH + getVersion(); + } + return getVersion(); + } + + /** + * the kind used with this resource type + * + */ + String getKind(); + } } diff --git a/src/main/java/com/openshift/restclient/ResourceKind.java b/src/main/java/com/openshift/restclient/ResourceKind.java index 0df79bc1..d0b0ecfb 100644 --- a/src/main/java/com/openshift/restclient/ResourceKind.java +++ b/src/main/java/com/openshift/restclient/ResourceKind.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -155,4 +155,24 @@ public static String pluralize(String kind, boolean lowercase, boolean uncapital private ResourceKind() { } + + public static String[] parse(String kind) { + String[] result = new String[2]; + result[0] = ""; + if (kind.contains(IApiTypeMapper.FWD_SLASH)) { + result[0] = kind.substring(0, kind.indexOf(IApiTypeMapper.FWD_SLASH)); + kind = kind.substring(kind.indexOf(IApiTypeMapper.FWD_SLASH) + 1); + } + if (kind.indexOf(IApiTypeMapper.DOT) != (-1)) { + String version = kind.substring(0, kind.indexOf(IApiTypeMapper.DOT)); + if (!result[0].isEmpty()) { + result[0] += IApiTypeMapper.FWD_SLASH + version; + } else { + result[0] = version; + } + kind = kind.substring(kind.indexOf(IApiTypeMapper.DOT) + 1); + } + result[1] = kind; + return result; + } } diff --git a/src/main/resources/k8stypes.properties b/src/main/resources/k8stypes.properties new file mode 100644 index 00000000..42bcde8e --- /dev/null +++ b/src/main/resources/k8stypes.properties @@ -0,0 +1,43 @@ +# Dynamic K8S types registration +# +# Syntax is: +# classname=kind1,kind2,... +# ex: +# com.openshift.internal.restclient.model.Build=v1.Build,build.openshift.io/v1.Build +# +# Kubernetes API +com.openshift.internal.restclient.model.ConfigMap=v1.ConfigMap +com.openshift.internal.restclient.model.KubernetesEvent=v1.Event,events.k8s.io/v1beta1.Event +com.openshift.internal.restclient.model.LimitRange=v1.LimitRange +com.openshift.internal.restclient.model.Namespace=v1.Namespace +com.openshift.internal.restclient.model.volume.PersistentVolume=v1.PersistentVolume +com.openshift.internal.restclient.model.volume.PersistentVolumeClaim=v1.PersistentVolumeClaim +com.openshift.internal.restclient.model.Pod=v1.Pod +com.openshift.internal.restclient.model.ReplicationController=v1.ReplicationController +com.openshift.internal.restclient.model.ResourceQuota=v1.ResourceQuota +com.openshift.internal.restclient.model.Secret=v1.Secret +com.openshift.internal.restclient.model.Service=v1.Service +com.openshift.internal.restclient.model.ServiceAccount=v1.ServiceAccount +com.openshift.internal.restclient.model.Status=v1.Status + +# OpenShift API +com.openshift.internal.restclient.model.Build=v1.Build,build.openshift.io/v1.Build +com.openshift.internal.restclient.model.BuildConfig=v1.BuildConfig,build.openshift.io/v1.BuildConfig +com.openshift.internal.restclient.model.build.BuildRequest=v1.BuildRequest,build.openshift.io/v1.BuildRequest +com.openshift.internal.restclient.model.DeploymentConfig=v1.DeploymentConfig,apps.openshift.io/v1.DeploymentConfig +com.openshift.internal.restclient.model.ImageStream=v1.ImageStream,image.openshift.io/v1.ImageStream +com.openshift.internal.restclient.model.image.ImageStreamImport=v1.ImageStreamImport,image.openshift.io/v1.ImageStreamImport +com.openshift.internal.restclient.model.oauth.OAuthAccessToken=v1.OAuthAccessToken,oauth.openshift.io/v1.OAuthAccessToken +com.openshift.internal.restclient.model.oauth.OAuthAuthorizeToken=v1.OAuthAuthorizeToken,oauth.openshift.io/v1.OAuthAuthorizeToken +com.openshift.internal.restclient.model.oauth.OAuthClient=v1.OAuthClient,oauth.openshift.io/v1.OAuthClient +com.openshift.internal.restclient.model.oauth.OAuthClientAuthorization=v1.OAuthClientAuthorization,oauth.openshift.io/v1.OAuthClientAuthorization +com.openshift.internal.restclient.model.user.OpenShiftIdentity=v1.Identity,user.openshift.io/v1.Identity +com.openshift.internal.restclient.model.project.OpenshiftProjectRequest=v1.ProjectRequest,project.openshift.io/v1.ProjectRequest +com.openshift.internal.restclient.model.authorization.OpenshiftRole=v1.Role,authorization.openshift.io/v1.Role +com.openshift.internal.restclient.model.user.OpenShiftUser=v1.User,user.openshift.io/v1.User +com.openshift.internal.restclient.model.Project=v1.Project,project.openshift.io/v1.Project +com.openshift.internal.restclient.model.authorization.RoleBinding=v1.RoleBinding,authorization.openshift.io/v1.RoleBinding +com.openshift.internal.restclient.model.Route=v1.Route,route.openshift.io/v1.Route +com.openshift.internal.restclient.model.template.Template=v1.Template,template.openshift.io/v1.Template +com.openshift.internal.restclient.model.deploy.DeploymentRequest=v1.DeploymentRequest,apps.openshift.io/v1.DeploymentRequest +com.openshift.internal.restclient.apis.autoscaling.models.Scale=autoscaling/v1.Scale,extensions/v1beta1.Scale diff --git a/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java b/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java index c6fe5fd7..612c9b34 100644 --- a/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java +++ b/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java @@ -38,7 +38,7 @@ public void testKubernetesResourceIsSupportedAfterInitiallyErrorIsThrown() throw IService resource = factory.stub(ResourceKind.SERVICE); try { getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api").thenThrow(new RuntimeException()); - assertTrue("Exp. Kube support", mapper.isSupported(resource)); + assertFalse("Exp. Kube support", mapper.isSupported(resource)); } catch (RuntimeException e) { getHttpClient().whenRequestTo(TypeMapperFixture.base + "/api") .thenReturn(responseOf(TypeMapperFixture.VERSIONS)); diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index 14916698..daac68a8 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -16,7 +16,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Properties; import java.util.Random; import java.util.stream.Collectors; @@ -28,7 +30,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.openshift.internal.restclient.model.DeploymentConfig; import com.openshift.internal.restclient.model.ModelNodeBuilder; import com.openshift.internal.restclient.model.Pod; import com.openshift.internal.restclient.model.ReplicationController; @@ -71,6 +72,8 @@ public class IntegrationTestHelper implements ResourcePropertyKeys { private static final String POD_NAME_DEPLOY = "deploy"; private static final String POD_DOCKER_REGISTRY = "docker-registry"; private static final String DEFAULT_PROJECT = "default"; + private static final String OPENSHIFT4_REGISTRY_PROJECT = "openshift-image-registry"; + private static final String POD_IMAGE_REGISTRY = "image-registry"; private final Properties prop; @@ -132,16 +135,24 @@ public static String appendRandom(String string) { return String.format("%s-%s", string, new Random().nextInt(9999)); } - public static boolean isDockerRegistry(IPod pod) { + public static boolean isDockerRegistry(IPod pod, String podPrefix) { return pod != null - && pod.getName().startsWith(POD_DOCKER_REGISTRY); + && pod.getName().startsWith(podPrefix); } - public IPod getDockerRegistryPod(Collection pods) { + private Optional getDockerRegistryPod(IClient client, String project, String podPrefix) { + List pods = client.list(ResourceKind.POD, project); return pods.stream() - .filter(p -> isDockerRegistry(p)) - .findFirst() - .orElse(null); + .filter(p -> isDockerRegistry(p, podPrefix)) + .findFirst(); + } + + public IPod getDockerRegistryPod(IClient client) { + Optional pod = getDockerRegistryPod(client, DEFAULT_PROJECT, POD_DOCKER_REGISTRY); + if (!pod.isPresent()) { + pod = getDockerRegistryPod(client, OPENSHIFT4_REGISTRY_PROJECT, POD_IMAGE_REGISTRY); + } + return pod.orElse(null); } @@ -189,9 +200,7 @@ public IPod stubPod(IClient client, String namespace, String name) { } public IDeploymentConfig stubDeploymentConfig(IClient client, String namespace, String name) { - IDeploymentConfig dc = new ResourceFactory(client).create("v1", ResourceKind.DEPLOYMENT_CONFIG); - ((DeploymentConfig) dc).setName(name); - ((DeploymentConfig) dc).setNamespace(namespace); + IDeploymentConfig dc = (IDeploymentConfig) new ResourceFactory(client).stubKind(ResourceKind.DEPLOYMENT_CONFIG, Optional.of(name), Optional.of(namespace)); dc.setReplicas(1); dc.setReplicaSelector("foo", "bar"); dc.addContainer(dc.getName(), diff --git a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java index 45349687..0e0f4dad 100644 --- a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java +++ b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -12,15 +12,16 @@ package com.openshift.internal.restclient; import static junit.framework.Assert.assertEquals; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.util.Arrays; -import java.util.List; - import org.junit.Before; import org.junit.Test; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IService; @@ -32,23 +33,32 @@ public class ResourceFactoryTest { @Before public void setup() { IClient client = mock(IClient.class); + IApiTypeMapper mapper = mock(IApiTypeMapper.class); when(client.getOpenShiftAPIVersion()).thenReturn(OpenShiftAPIVersion.v1.toString()); - factory = new ResourceFactory(client); - } - - /* - * Validate the implementation classes implemented the expected constructor - */ - @Test - public void testV1Beta3Implementations() { - List v1beta3Exlusions = Arrays - .asList(new String[] { ResourceKind.CONFIG, ResourceKind.PROCESSED_TEMPLATES }); - final String version = OpenShiftAPIVersion.v1beta3.toString(); - for (String kind : ResourceKind.values()) { - if (!v1beta3Exlusions.contains(kind)) { - factory.create(version, kind); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.SERVICE))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; } - } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.SERVICE; + } + + @Override + public String getApiGroupName() { + return null; + } + }); + factory = new ResourceFactory(client); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java index 8a2a866e..5e2cf096 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java @@ -29,7 +29,6 @@ import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IStoppable; @@ -102,8 +101,7 @@ public void onFailure(Throwable t) { @Before public void setUp() throws Exception { IClient client = helper.createClientForBasicAuth(); - List allPods = client.list(ResourceKind.POD, IntegrationTestHelper.getDefaultNamespace()); - this.pod = helper.getDockerRegistryPod(allPods); + this.pod = helper.getDockerRegistryPod(client); assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java index 6fbe28d5..e39f4085 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java @@ -1,4 +1,3 @@ -package com.openshift.internal.restclient.capability.resources; /******************************************************************************* * Copyright (c) 2015-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. @@ -10,6 +9,8 @@ * Red Hat, Inc. - initial API and implementation ******************************************************************************/ +package com.openshift.internal.restclient.capability.resources; + import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -34,7 +35,6 @@ import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.internal.restclient.api.capabilities.PodExecIntegrationTest; import com.openshift.restclient.IClient; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.api.capabilities.IPodExec; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IBinaryCapability.SkipTlsVerify; @@ -76,8 +76,7 @@ public void setUp() throws Exception { // given this.helper.setOpenShiftBinarySystemProperty(); this.client = helper.createClientForBasicAuth(); - List allPods = client.list(ResourceKind.POD, IntegrationTestHelper.getDefaultNamespace()); - this.pod = helper.getDockerRegistryPod(allPods); + this.pod = helper.getDockerRegistryPod(client); assertNotNull("Did not find the registry pod to which to rsync", pod); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java index 738b8045..1d981539 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java @@ -14,7 +14,6 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; -import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -24,7 +23,6 @@ import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.IntegrationTestHelper; -import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IStoppable; import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync; @@ -43,8 +41,7 @@ public class PodLogRetrievalAsyncIntegrationTest { public void testAsyncLogRetrieval() throws Exception { latch = new CountDownLatch(2); DefaultClient client = (DefaultClient) helper.createClientForBasicAuth(); - List allPods = client.list(ResourceKind.POD, IntegrationTestHelper.getDefaultNamespace()); - IPod pod = helper.getDockerRegistryPod(allPods); + IPod pod = helper.getDockerRegistryPod(client); assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); final String container = pod.getContainers().iterator().next().getName(); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java index 9f93000a..d4601d8c 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java @@ -11,6 +11,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.when; import org.junit.Before; @@ -21,6 +23,8 @@ import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.internal.restclient.ResourceFactory; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceKind; @@ -33,12 +37,37 @@ public class UpdateableCapabilityTest { @Mock private IClient client; + @Mock + private IApiTypeMapper mapper; private IService service; private IResourceFactory factory; @Before public void setup() { when(client.getOpenShiftAPIVersion()).thenReturn("v1"); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.SERVICE))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.SERVICE; + } + + @Override + public String getApiGroupName() { + return null; + } + }); this.factory = new ResourceFactory(client); this.service = factory.stub(ResourceKind.SERVICE, "foo", IntegrationTestHelper.getDefaultNamespace()); service.setAnnotation("foo", "bar"); diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java index 18220a39..9fc4ddcb 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/ServerTemplateProcessingIntegrationTest.java @@ -28,6 +28,7 @@ import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.internal.restclient.model.template.Template; import com.openshift.restclient.IClient; +import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.server.ITemplateProcessing; import com.openshift.restclient.model.IProject; @@ -59,37 +60,47 @@ public void after() { public void testProcessAndApplyTemplate() throws Exception { ModelNode node = ModelNode.fromJSONString(Samples.V1_TEMPLATE.getContentAsString()); final Template template = new Template(node, client, null); + node = ModelNode.fromJSONString(Samples.GROUP_TEMPLATE.getContentAsString()); + final Template groupTemplate = new Template(node, client, null); template.setNamespace(null); client.accept(new CapabilityVisitor() { @Override public Object visit(ITemplateProcessing capability) { - LOG.debug("Processing template: {}", template.toJson()); - assertFalse("Exp. the template to have items for this test be interesting", - template.getObjects().isEmpty()); - final int items = template.getObjects().size(); - ITemplate processedTemplate = capability.process(template, project.getName()); - - LOG.debug("Applying template: {}", processedTemplate.toJson()); - LOG.debug("Applied template"); - assertEquals("Exp. the pre and post item count to be the same", - items, - template.getObjects().size()); - Collection stubs = processedTemplate.getObjects(); - ServerTemplateProcessingIntegrationTest.this.resources = - stubs.stream() - .map(stub -> { - // resources as in template dont have a namespace - ((KubernetesResource) stub).setNamespace(project.getNamespaceName()); - LOG.debug("creating: {}", stub); - IResource resource = client.create(stub); - LOG.debug("created: {}", resource.toJson()); - return resource; - }) - .collect(Collectors.toList()); - return null; + try { + return processTemplate(template, capability); + } catch (OpenShiftException e) { + return processTemplate(groupTemplate, capability); + } } }, new Object()); } + + private Object processTemplate(final Template template, ITemplateProcessing capability) { + LOG.debug("Processing template: {}", template.toJson()); + assertFalse("Exp. the template to have items for this test be interesting", + template.getObjects().isEmpty()); + final int items = template.getObjects().size(); + ITemplate processedTemplate = capability.process(template, project.getName()); + + LOG.debug("Applying template: {}", processedTemplate.toJson()); + LOG.debug("Applied template"); + assertEquals("Exp. the pre and post item count to be the same", + items, + template.getObjects().size()); + Collection stubs = processedTemplate.getObjects(); + ServerTemplateProcessingIntegrationTest.this.resources = + stubs.stream() + .map(stub -> { + // resources as in template dont have a namespace + ((KubernetesResource) stub).setNamespace(project.getNamespaceName()); + LOG.debug("creating: {}", stub); + IResource resource = client.create(stub); + LOG.debug("created: {}", resource.toJson()); + return resource; + }) + .collect(Collectors.toList()); + return null; + } } diff --git a/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java index ca82ff8f..2c1a74bf 100644 --- a/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -27,6 +27,8 @@ import com.openshift.internal.restclient.OpenShiftAPIVersion; import com.openshift.internal.restclient.ResourceFactory; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceKind; @@ -38,13 +40,37 @@ public class ServiceTest { private IService service; private IClient client; + private IApiTypeMapper mapper; @Before public void setup() { client = mock(IClient.class); + mapper = mock(IApiTypeMapper.class); when(client.getOpenShiftAPIVersion()).thenReturn(OpenShiftAPIVersion.v1.name()); - IResourceFactory factory = new ResourceFactory(client) { - }; + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.SERVICE))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.SERVICE; + } + + @Override + public String getApiGroupName() { + return null; + } + }); + IResourceFactory factory = new ResourceFactory(client); service = factory.stub(ResourceKind.SERVICE, OpenShiftAPIVersion.v1.name()); } diff --git a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java index 9c16e254..c1e148af 100644 --- a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java +++ b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java @@ -68,7 +68,7 @@ public void teardown() { executor.shutdownNow(); } - @Test(timeout = IntegrationTestHelper.TEST_TIMEOUT) + @Test(timeout = IntegrationTestHelper.TEST_LONG_TIMEOUT) public void test() throws Exception { List results = new ArrayList<>(); CountDownLatch latch = new CountDownLatch(KINDS.length); diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 30e089d7..d5d54bee 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014-2015 Red Hat, Inc. + * Copyright (c) 2014-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -59,7 +59,8 @@ public enum Samples { V1_SERVICE("openshift3/v1_service.json"), V1_SERVICE_ACCOUNT("openshift3/v1_service_account.json"), V1_Status("openshift3/v1_status.json"), - V1_TEMPLATE("openshift3/v1_template.json"), + V1_TEMPLATE("openshift3/v1_template.json"), + GROUP_TEMPLATE("openshift3/group_template.json"), V1_USER("openshift3/v1_user.json"), V1_IDENTITY("openshift3/v1_identity.json"), V1_GROUP("openshift3/v1_group.json"), diff --git a/src/test/resources/samples/openshift3/api_v1_endpoint.json b/src/test/resources/samples/openshift3/api_v1_endpoint.json index 416b8031..ca080238 100644 --- a/src/test/resources/samples/openshift3/api_v1_endpoint.json +++ b/src/test/resources/samples/openshift3/api_v1_endpoint.json @@ -4,183 +4,492 @@ "resources": [ { "name": "bindings", + "singularName": "", "namespaced": true, - "kind": "Binding" + "kind": "Binding", + "verbs": [ + "create" + ] }, { "name": "componentstatuses", + "singularName": "", "namespaced": false, - "kind": "ComponentStatus" + "kind": "ComponentStatus", + "verbs": [ + "get", + "list" + ], + "shortNames": [ + "cs" + ] }, { "name": "configmaps", + "singularName": "", "namespaced": true, - "kind": "ConfigMap" + "kind": "ConfigMap", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "cm" + ] }, { "name": "endpoints", + "singularName": "", "namespaced": true, - "kind": "Endpoints" + "kind": "Endpoints", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "ep" + ] }, { "name": "events", + "singularName": "", "namespaced": true, - "kind": "Event" + "kind": "Event", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "ev" + ] }, { "name": "limitranges", + "singularName": "", "namespaced": true, - "kind": "LimitRange" + "kind": "LimitRange", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "limits" + ] }, { "name": "namespaces", + "singularName": "", "namespaced": false, - "kind": "Namespace" + "kind": "Namespace", + "verbs": [ + "create", + "delete", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "ns" + ] }, { "name": "namespaces/finalize", + "singularName": "", "namespaced": false, - "kind": "Namespace" + "kind": "Namespace", + "verbs": [ + "update" + ] }, { "name": "namespaces/status", + "singularName": "", "namespaced": false, - "kind": "Namespace" + "kind": "Namespace", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "nodes", + "singularName": "", "namespaced": false, - "kind": "Node" + "kind": "Node", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "no" + ] }, { "name": "nodes/proxy", + "singularName": "", "namespaced": false, - "kind": "Node" + "kind": "Node", + "verbs": [] }, { "name": "nodes/status", + "singularName": "", "namespaced": false, - "kind": "Node" + "kind": "Node", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "persistentvolumeclaims", + "singularName": "", "namespaced": true, - "kind": "PersistentVolumeClaim" + "kind": "PersistentVolumeClaim", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "pvc" + ] }, { "name": "persistentvolumeclaims/status", + "singularName": "", "namespaced": true, - "kind": "PersistentVolumeClaim" + "kind": "PersistentVolumeClaim", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "persistentvolumes", + "singularName": "", "namespaced": false, - "kind": "PersistentVolume" + "kind": "PersistentVolume", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "pv" + ] }, { "name": "persistentvolumes/status", + "singularName": "", "namespaced": false, - "kind": "PersistentVolume" + "kind": "PersistentVolume", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "pods", + "singularName": "", "namespaced": true, - "kind": "Pod" + "kind": "Pod", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "po" + ], + "categories": [ + "all" + ] }, { "name": "pods/attach", + "singularName": "", "namespaced": true, - "kind": "Pod" + "kind": "Pod", + "verbs": [] }, { "name": "pods/binding", + "singularName": "", "namespaced": true, - "kind": "Binding" + "kind": "Binding", + "verbs": [ + "create" + ] + }, + { + "name": "pods/eviction", + "singularName": "", + "namespaced": true, + "group": "policy", + "version": "v1beta1", + "kind": "Eviction", + "verbs": [ + "create" + ] }, { "name": "pods/exec", + "singularName": "", "namespaced": true, - "kind": "Pod" + "kind": "Pod", + "verbs": [] }, { "name": "pods/log", + "singularName": "", "namespaced": true, - "kind": "Pod" + "kind": "Pod", + "verbs": [ + "get" + ] }, { "name": "pods/portforward", + "singularName": "", "namespaced": true, - "kind": "Pod" + "kind": "Pod", + "verbs": [] }, { "name": "pods/proxy", + "singularName": "", "namespaced": true, - "kind": "Pod" + "kind": "Pod", + "verbs": [] }, { "name": "pods/status", + "singularName": "", "namespaced": true, - "kind": "Pod" + "kind": "Pod", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "podtemplates", + "singularName": "", "namespaced": true, - "kind": "PodTemplate" + "kind": "PodTemplate", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "replicationcontrollers", + "singularName": "", "namespaced": true, - "kind": "ReplicationController" + "kind": "ReplicationController", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "rc" + ], + "categories": [ + "all" + ] }, { "name": "replicationcontrollers/scale", + "singularName": "", "namespaced": true, - "kind": "Scale" + "group": "autoscaling", + "version": "v1", + "kind": "Scale", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "replicationcontrollers/status", + "singularName": "", "namespaced": true, - "kind": "ReplicationController" + "kind": "ReplicationController", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "resourcequotas", + "singularName": "", "namespaced": true, - "kind": "ResourceQuota" + "kind": "ResourceQuota", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "quota" + ] }, { "name": "resourcequotas/status", + "singularName": "", "namespaced": true, - "kind": "ResourceQuota" + "kind": "ResourceQuota", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "secrets", + "singularName": "", "namespaced": true, - "kind": "Secret" - }, - { - "name": "securitycontextconstraints", - "namespaced": false, - "kind": "SecurityContextConstraints" + "kind": "Secret", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "serviceaccounts", + "singularName": "", "namespaced": true, - "kind": "ServiceAccount" + "kind": "ServiceAccount", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "sa" + ] }, { "name": "services", + "singularName": "", "namespaced": true, - "kind": "Service" + "kind": "Service", + "verbs": [ + "create", + "delete", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "svc" + ], + "categories": [ + "all" + ] }, { "name": "services/proxy", + "singularName": "", "namespaced": true, - "kind": "Service" + "kind": "Service", + "verbs": [] }, { "name": "services/status", + "singularName": "", "namespaced": true, - "kind": "Service" + "kind": "Service", + "verbs": [ + "get", + "patch", + "update" + ] } ] } \ No newline at end of file diff --git a/src/test/resources/samples/openshift3/apis_endpoint_extensions.json b/src/test/resources/samples/openshift3/apis_endpoint_extensions.json index b4c64c5c..16fc80cf 100644 --- a/src/test/resources/samples/openshift3/apis_endpoint_extensions.json +++ b/src/test/resources/samples/openshift3/apis_endpoint_extensions.json @@ -4,88 +4,214 @@ "resources": [ { "name": "daemonsets", - "namespaced": true, - "kind": "DaemonSet" + "singularName": "", + "namespaced": true, + "kind": "DaemonSet", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "ds" + ] }, { "name": "daemonsets/status", + "singularName": "", "namespaced": true, - "kind": "DaemonSet" + "kind": "DaemonSet", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "deployments", - "namespaced": true, - "kind": "Deployment" + "singularName": "", + "namespaced": true, + "kind": "Deployment", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "deploy" + ] }, { "name": "deployments/rollback", + "singularName": "", "namespaced": true, - "kind": "DeploymentRollback" + "kind": "DeploymentRollback", + "verbs": [ + "create" + ] }, { "name": "deployments/scale", + "singularName": "", "namespaced": true, - "kind": "Scale" + "group": "extensions", + "version": "v1beta1", + "kind": "Scale", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "deployments/status", + "singularName": "", "namespaced": true, - "kind": "Deployment" - }, - { - "name": "horizontalpodautoscalers", - "namespaced": true, - "kind": "HorizontalPodAutoscaler" - }, - { - "name": "horizontalpodautoscalers/status", - "namespaced": true, - "kind": "HorizontalPodAutoscaler" + "kind": "Deployment", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "ingresses", - "namespaced": true, - "kind": "Ingress" + "singularName": "", + "namespaced": true, + "kind": "Ingress", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "ing" + ] }, { "name": "ingresses/status", - "namespaced": true, - "kind": "Ingress" - }, - { - "name": "jobs", - "namespaced": true, - "kind": "Job" - }, - { - "name": "jobs/status", - "namespaced": true, - "kind": "Job" + "singularName": "", + "namespaced": true, + "kind": "Ingress", + "verbs": [ + "get", + "patch", + "update" + ] + }, + { + "name": "networkpolicies", + "singularName": "", + "namespaced": true, + "kind": "NetworkPolicy", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "netpol" + ] + }, + { + "name": "podsecuritypolicies", + "singularName": "", + "namespaced": false, + "kind": "PodSecurityPolicy", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "psp" + ] }, { "name": "replicasets", - "namespaced": true, - "kind": "ReplicaSet" + "singularName": "", + "namespaced": true, + "kind": "ReplicaSet", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "rs" + ] }, { "name": "replicasets/scale", + "singularName": "", "namespaced": true, - "kind": "Scale" + "group": "extensions", + "version": "v1beta1", + "kind": "Scale", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "replicasets/status", + "singularName": "", "namespaced": true, - "kind": "ReplicaSet" + "kind": "ReplicaSet", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "replicationcontrollers", + "singularName": "", "namespaced": true, - "kind": "ReplicationControllerDummy" + "kind": "ReplicationControllerDummy", + "verbs": [] }, { "name": "replicationcontrollers/scale", - "namespaced": true, - "kind": "Scale" + "singularName": "", + "namespaced": true, + "kind": "Scale", + "verbs": [ + "get", + "patch", + "update" + ] } ] } \ No newline at end of file diff --git a/src/test/resources/samples/openshift3/group_template.json b/src/test/resources/samples/openshift3/group_template.json new file mode 100644 index 00000000..306845e5 --- /dev/null +++ b/src/test/resources/samples/openshift3/group_template.json @@ -0,0 +1,450 @@ +{ + "kind": "Template", + "apiVersion": "template.openshift.io/v1", + "metadata": { + "name": "ruby-helloworld-sample", + "namespace": "myproject", + "selfLink": "/oapi/v1/namespaces/myproject/templates/ruby-helloworld-sample", + "uid": "870dab76-38c7-11e6-8e5e-3c970e32f15a", + "resourceVersion": "86618", + "creationTimestamp": "2016-06-22T22:20:29Z", + "labels": { + "abc": "xyz", + "foo": "bar" + }, + "annotations": { + "description": "This example shows how to create a simple ruby application in openshift origin v3", + "iconClass": "icon-ruby", + "tags": "instant-app,ruby,mysql" + } + }, + "objects": [ + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "frontend", + "creationTimestamp": null + }, + "spec": { + "ports": [ + { + "name": "web", + "protocol": "TCP", + "port": 5432, + "targetPort": 8080, + "nodePort": 0 + } + ], + "selector": { + "name": "frontend" + }, + "portalIP": "", + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "Route", + "apiVersion": "v1", + "metadata": { + "name": "route-edge", + "creationTimestamp": null + }, + "spec": { + "host": "www.example.com", + "to": { + "kind": "Service", + "name": "frontend" + }, + "tls": { + "termination": "edge", + "certificate": "-----BEGIN CERTIFICATE-----\nMIIDIjCCAgqgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBoTELMAkGA1UEBhMCVVMx\nCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0Rl\nZmF1bHQgQ29tcGFueSBMdGQxEDAOBgNVBAsMB1Rlc3QgQ0ExGjAYBgNVBAMMEXd3\ndy5leGFtcGxlY2EuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFtcGxlQGV4YW1wbGUu\nY29tMB4XDTE1MDExMjE0MTk0MVoXDTE2MDExMjE0MTk0MVowfDEYMBYGA1UEAwwP\nd3d3LmV4YW1wbGUuY29tMQswCQYDVQQIDAJTQzELMAkGA1UEBhMCVVMxIjAgBgkq\nhkiG9w0BCQEWE2V4YW1wbGVAZXhhbXBsZS5jb20xEDAOBgNVBAoMB0V4YW1wbGUx\nEDAOBgNVBAsMB0V4YW1wbGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMrv\ngu6ZTTefNN7jjiZbS/xvQjyXjYMN7oVXv76jbX8gjMOmg9m0xoVZZFAE4XyQDuCm\n47VRx5Qrf/YLXmB2VtCFvB0AhXr5zSeWzPwaAPrjA4ebG+LUo24ziS8KqNxrFs1M\nmNrQUgZyQC6XIe1JHXc9t+JlL5UZyZQC1IfaJulDAgMBAAGjDTALMAkGA1UdEwQC\nMAAwDQYJKoZIhvcNAQEFBQADggEBAFCi7ZlkMnESvzlZCvv82Pq6S46AAOTPXdFd\nTMvrh12E1sdVALF1P1oYFJzG1EiZ5ezOx88fEDTW+Lxb9anw5/KJzwtWcfsupf1m\nV7J0D3qKzw5C1wjzYHh9/Pz7B1D0KthQRATQCfNf8s6bbFLaw/dmiIUhHLtIH5Qc\nyfrejTZbOSP77z8NOWir+BWWgIDDB2//3AkDIQvT20vmkZRhkqSdT7et4NmXOX/j\njhPti4b2Fie0LeuvgaOdKjCpQQNrYthZHXeVlOLRhMTSk3qUczenkKTOhvP7IS9q\n+Dzv5hqgSfvMG392KWh5f8xXfJNs4W5KLbZyl901MeReiLrPH3w=\n-----END CERTIFICATE-----", + "key": "-----BEGIN PRIVATE KEY-----\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAMrvgu6ZTTefNN7j\njiZbS/xvQjyXjYMN7oVXv76jbX8gjMOmg9m0xoVZZFAE4XyQDuCm47VRx5Qrf/YL\nXmB2VtCFvB0AhXr5zSeWzPwaAPrjA4ebG+LUo24ziS8KqNxrFs1MmNrQUgZyQC6X\nIe1JHXc9t+JlL5UZyZQC1IfaJulDAgMBAAECgYEAnxOjEj/vrLNLMZE1Q9H7PZVF\nWdP/JQVNvQ7tCpZ3ZdjxHwkvf//aQnuxS5yX2Rnf37BS/TZu+TIkK4373CfHomSx\nUTAn2FsLmOJljupgGcoeLx5K5nu7B7rY5L1NHvdpxZ4YjeISrRtEPvRakllENU5y\ngJE8c2eQOx08ZSRE4TkCQQD7dws2/FldqwdjJucYijsJVuUdoTqxP8gWL6bB251q\nelP2/a6W2elqOcWId28560jG9ZS3cuKvnmu/4LG88vZFAkEAzphrH3673oTsHN+d\nuBd5uyrlnGjWjuiMKv2TPITZcWBjB8nJDSvLneHF59MYwejNNEof2tRjgFSdImFH\nmi995wJBAMtPjW6wiqRz0i41VuT9ZgwACJBzOdvzQJfHgSD9qgFb1CU/J/hpSRIM\nkYvrXK9MbvQFvG6x4VuyT1W8mpe1LK0CQAo8VPpffhFdRpF7psXLK/XQ/0VLkG3O\nKburipLyBg/u9ZkaL0Ley5zL5dFBjTV2Qkx367Ic2b0u9AYTCcgi2DsCQQD3zZ7B\nv7BOm7MkylKokY2MduFFXU0Bxg6pfZ7q3rvg8gqhUFbaMStPRYg6myiDiW/JfLhF\nTcFT4touIo7oriFJ\n-----END PRIVATE KEY-----", + "caCertificate": "-----BEGIN CERTIFICATE-----\nMIIEFzCCAv+gAwIBAgIJALK1iUpF2VQLMA0GCSqGSIb3DQEBBQUAMIGhMQswCQYD\nVQQGEwJVUzELMAkGA1UECAwCU0MxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoG\nA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEQMA4GA1UECwwHVGVzdCBDQTEaMBgG\nA1UEAwwRd3d3LmV4YW1wbGVjYS5jb20xIjAgBgkqhkiG9w0BCQEWE2V4YW1wbGVA\nZXhhbXBsZS5jb20wHhcNMTUwMTEyMTQxNTAxWhcNMjUwMTA5MTQxNTAxWjCBoTEL\nMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkx\nHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQxEDAOBgNVBAsMB1Rlc3QgQ0Ex\nGjAYBgNVBAMMEXd3dy5leGFtcGxlY2EuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFt\ncGxlQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\nw2rK1J2NMtQj0KDug7g7HRKl5jbf0QMkMKyTU1fBtZ0cCzvsF4CqV11LK4BSVWaK\nrzkaXe99IVJnH8KdOlDl5Dh/+cJ3xdkClSyeUT4zgb6CCBqg78ePp+nN11JKuJlV\nIG1qdJpB1J5O/kCLsGcTf7RS74MtqMFo96446Zvt7YaBhWPz6gDaO/TUzfrNcGLA\nEfHVXkvVWqb3gqXUztZyVex/gtP9FXQ7gxTvJml7UkmT0VAFjtZnCqmFxpLZFZ15\n+qP9O7Q2MpsGUO/4vDAuYrKBeg1ZdPSi8gwqUP2qWsGd9MIWRv3thI2903BczDc7\nr8WaIbm37vYZAS9G56E4+wIDAQABo1AwTjAdBgNVHQ4EFgQUugLrSJshOBk5TSsU\nANs4+SmJUGwwHwYDVR0jBBgwFoAUugLrSJshOBk5TSsUANs4+SmJUGwwDAYDVR0T\nBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaMJ33zAMV4korHo5aPfayV3uHoYZ\n1ChzP3eSsF+FjoscpoNSKs91ZXZF6LquzoNezbfiihK4PYqgwVD2+O0/Ty7UjN4S\nqzFKVR4OS/6lCJ8YncxoFpTntbvjgojf1DEataKFUN196PAANc3yz8cWHF4uvjPv\nWkgFqbIjb+7D1YgglNyovXkRDlRZl0LD1OQ0ZWhd4Ge1qx8mmmanoBeYZ9+DgpFC\nj9tQAbS867yeOryNe7sEOIpXAAqK/DTu0hB6+ySsDfMo4piXCc2aA/eI2DCuw08e\nw17Dz9WnupZjVdwTKzDhFgJZMLDqn37HQnT6EemLFqbcR0VPEnfyhDtZIQ==\n-----END CERTIFICATE-----" + } + }, + "status": {} + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "origin-ruby-sample", + "creationTimestamp": null + }, + "spec": {}, + "status": { + "dockerImageRepository": "" + } + }, + { + "kind": "ImageStream", + "apiVersion": "v1", + "metadata": { + "name": "ruby-20-centos7", + "creationTimestamp": null + }, + "spec": { + "dockerImageRepository": "openshift/ruby-20-centos7" + }, + "status": { + "dockerImageRepository": "" + } + }, + { + "kind": "BuildConfig", + "apiVersion": "v1", + "metadata": { + "name": "ruby-sample-build", + "creationTimestamp": null, + "labels": { + "name": "ruby-sample-build" + } + }, + "spec": { + "triggers": [ + { + "type": "github", + "github": { + "secret": "secret101" + } + }, + { + "type": "generic", + "generic": { + "secret": "secret101" + } + }, + { + "type": "imageChange", + "imageChange": {} + } + ], + "source": { + "type": "Git", + "git": { + "uri": "git://github.com/openshift/ruby-hello-world.git" + } + }, + "strategy": { + "type": "Source", + "sourceStrategy": { + "from": { + "kind": "ImageStreamTag", + "name": "ruby-20-centos7:latest" + }, + "incremental": true + } + }, + "output": { + "to": { + "kind": "ImageStreamTag", + "name": "origin-ruby-sample:latest" + } + }, + "resources": {} + }, + "status": { + "lastVersion": 0 + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "frontend", + "creationTimestamp": null + }, + "spec": { + "strategy": { + "type": "Rolling", + "rollingParams": { + "updatePeriodSeconds": 1, + "intervalSeconds": 1, + "timeoutSeconds": 120, + "pre": { + "failurePolicy": "Abort", + "execNewPod": { + "command": [ + "/bin/true" + ], + "env": [ + { + "name": "CUSTOM_VAR1", + "value": "custom_value1" + } + ], + "containerName": "ruby-helloworld" + } + }, + "post": { + "failurePolicy": "Ignore", + "execNewPod": { + "command": [ + "/bin/false" + ], + "env": [ + { + "name": "CUSTOM_VAR2", + "value": "custom_value2" + } + ], + "containerName": "ruby-helloworld" + } + } + }, + "resources": {} + }, + "triggers": [ + { + "type": "ImageChange", + "imageChangeParams": { + "automatic": true, + "containerNames": [ + "ruby-helloworld" + ], + "from": { + "kind": "ImageStreamTag", + "name": "origin-ruby-sample:latest" + }, + "lastTriggeredImage": "" + } + }, + { + "type": "ConfigChange" + } + ], + "replicas": 2, + "selector": { + "name": "frontend" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "name": "frontend" + } + }, + "spec": { + "containers": [ + { + "name": "ruby-helloworld", + "image": "origin-ruby-sample", + "ports": [ + { + "containerPort": 8080, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "ADMIN_USERNAME", + "value": "${ADMIN_USERNAME}" + }, + { + "name": "ADMIN_PASSWORD", + "value": "${ADMIN_PASSWORD}" + }, + { + "name": "MYSQL_USER", + "value": "${MYSQL_USER}" + }, + { + "name": "MYSQL_PASSWORD", + "value": "${MYSQL_PASSWORD}" + }, + { + "name": "MYSQL_DATABASE", + "value": "${MYSQL_DATABASE}" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "imagePullPolicy": "IfNotPresent", + "capabilities": {}, + "securityContext": { + "capabilities": {}, + "privileged": false + } + } + ], + "restartPolicy": "Always", + "dnsPolicy": "ClusterFirst", + "serviceAccount": "" + } + } + }, + "status": {} + }, + { + "kind": "Service", + "apiVersion": "v1", + "metadata": { + "name": "database", + "creationTimestamp": null + }, + "spec": { + "ports": [ + { + "name": "db", + "protocol": "TCP", + "port": 5434, + "targetPort": 3306, + "nodePort": 0 + } + ], + "selector": { + "name": "database" + }, + "portalIP": "", + "type": "ClusterIP", + "sessionAffinity": "None" + }, + "status": { + "loadBalancer": {} + } + }, + { + "kind": "DeploymentConfig", + "apiVersion": "v1", + "metadata": { + "name": "database", + "creationTimestamp": null + }, + "spec": { + "strategy": { + "type": "Recreate", + "recreateParams": { + "pre": { + "failurePolicy": "Abort", + "execNewPod": { + "command": [ + "/bin/true" + ], + "env": [ + { + "name": "CUSTOM_VAR1", + "value": "custom_value1" + } + ], + "containerName": "ruby-helloworld-database" + } + }, + "post": { + "failurePolicy": "Ignore", + "execNewPod": { + "command": [ + "/bin/false" + ], + "env": [ + { + "name": "CUSTOM_VAR2", + "value": "custom_value2" + } + ], + "containerName": "ruby-helloworld-database" + } + } + }, + "resources": {} + }, + "triggers": [ + { + "type": "ConfigChange" + } + ], + "replicas": 1, + "selector": { + "name": "database" + }, + "template": { + "metadata": { + "creationTimestamp": null, + "labels": { + "name": "database" + } + }, + "spec": { + "containers": [ + { + "name": "ruby-helloworld-database", + "image": "openshift/mysql-55-centos7:latest", + "ports": [ + { + "containerPort": 3306, + "protocol": "TCP" + } + ], + "env": [ + { + "name": "MYSQL_USER", + "value": "${MYSQL_USER}" + }, + { + "name": "MYSQL_PASSWORD", + "value": "${MYSQL_PASSWORD}" + }, + { + "name": "MYSQL_DATABASE", + "value": "${MYSQL_DATABASE}" + } + ], + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "imagePullPolicy": "Always", + "capabilities": {}, + "securityContext": { + "capabilities": {}, + "privileged": false + } + } + ], + "restartPolicy": "Always", + "dnsPolicy": "ClusterFirst", + "serviceAccount": "" + } + } + }, + "status": {} + } + ], + "parameters": [ + { + "name": "ADMIN_USERNAME", + "description": "administrator username", + "generate": "expression", + "from": "admin[A-Z0-9]{3}" + }, + { + "name": "ADMIN_PASSWORD", + "description": "administrator password", + "generate": "expression", + "from": "[a-zA-Z0-9]{8}" + }, + { + "name": "MYSQL_USER", + "description": "database username", + "generate": "expression", + "from": "user[A-Z0-9]{3}" + }, + { + "name": "MYSQL_PASSWORD", + "description": "database password", + "generate": "expression", + "from": "[a-zA-Z0-9]{8}", + "required": true + }, + { + "name": "MYSQL_DATABASE", + "description": "database name", + "value": "root" + } + ], + "labels": { + "template": "application-template-stibuild" + } +} diff --git a/src/test/resources/samples/openshift3/oapi_v1_endpoint.json b/src/test/resources/samples/openshift3/oapi_v1_endpoint.json index 02826428..6f5e16a6 100644 --- a/src/test/resources/samples/openshift3/oapi_v1_endpoint.json +++ b/src/test/resources/samples/openshift3/oapi_v1_endpoint.json @@ -3,254 +3,730 @@ "groupVersion": "v1", "resources": [ { - "name": "buildconfigs", + "name": "appliedclusterresourcequotas", + "singularName": "", "namespaced": true, - "kind": "BuildConfig" + "kind": "AppliedClusterResourceQuota", + "verbs": [ + "get", + "list" + ] + }, + { + "name": "buildconfigs", + "singularName": "", + "namespaced": true, + "kind": "BuildConfig", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "bc" + ] }, { "name": "buildconfigs/instantiate", + "singularName": "", "namespaced": true, - "kind": "BuildRequest" + "kind": "BuildRequest", + "verbs": [ + "create" + ] }, { "name": "buildconfigs/instantiatebinary", + "singularName": "", "namespaced": true, - "kind": "BinaryBuildRequestOptions" + "kind": "BinaryBuildRequestOptions", + "verbs": [] }, { "name": "buildconfigs/webhooks", + "singularName": "", "namespaced": true, - "kind": "Status" + "kind": "Build", + "verbs": [] }, { "name": "builds", + "singularName": "", "namespaced": true, - "kind": "Build" + "kind": "Build", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "builds/clone", + "singularName": "", "namespaced": true, - "kind": "BuildRequest" + "kind": "BuildRequest", + "verbs": [ + "create" + ] }, { "name": "builds/details", + "singularName": "", "namespaced": true, - "kind": "Build" + "kind": "Build", + "verbs": [ + "update" + ] }, { "name": "builds/log", + "singularName": "", "namespaced": true, - "kind": "BuildLog" + "kind": "BuildLog", + "verbs": [ + "get" + ] }, { "name": "clusternetworks", + "singularName": "", "namespaced": false, - "kind": "ClusterNetwork" - }, - { - "name": "clusterpolicies", + "kind": "ClusterNetwork", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, + { + "name": "clusterresourcequotas", + "singularName": "", "namespaced": false, - "kind": "ClusterPolicy" - }, - { - "name": "clusterpolicybindings", + "kind": "ClusterResourceQuota", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "clusterquota" + ] + }, + { + "name": "clusterresourcequotas/status", + "singularName": "", "namespaced": false, - "kind": "ClusterPolicyBinding" + "kind": "ClusterResourceQuota", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "clusterrolebindings", + "singularName": "", "namespaced": false, - "kind": "ClusterRoleBinding" + "kind": "ClusterRoleBinding", + "verbs": [ + "create", + "delete", + "get", + "list", + "patch", + "update" + ] }, { "name": "clusterroles", + "singularName": "", "namespaced": false, - "kind": "ClusterRole" + "kind": "ClusterRole", + "verbs": [ + "create", + "delete", + "get", + "list", + "patch", + "update" + ] }, { - "name": "deploymentconfigrollbacks", + "name": "deploymentconfigs", + "singularName": "", "namespaced": true, - "kind": "DeploymentConfigRollback" + "kind": "DeploymentConfig", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "dc" + ] }, { - "name": "deploymentconfigs", + "name": "deploymentconfigs/instantiate", + "singularName": "", "namespaced": true, - "kind": "DeploymentConfig" + "kind": "DeploymentRequest", + "verbs": [ + "create" + ] }, { "name": "deploymentconfigs/log", + "singularName": "", + "namespaced": true, + "kind": "DeploymentLog", + "verbs": [ + "get" + ] + }, + { + "name": "deploymentconfigs/rollback", + "singularName": "", "namespaced": true, - "kind": "DeploymentLog" + "kind": "DeploymentConfigRollback", + "verbs": [ + "create" + ] }, { "name": "deploymentconfigs/scale", + "singularName": "", + "namespaced": true, + "group": "extensions", + "version": "v1beta1", + "kind": "Scale", + "verbs": [ + "get", + "patch", + "update" + ] + }, + { + "name": "deploymentconfigs/status", + "singularName": "", "namespaced": true, - "kind": "Scale" + "kind": "DeploymentConfig", + "verbs": [ + "get", + "patch", + "update" + ] }, { - "name": "generatedeploymentconfigs", + "name": "egressnetworkpolicies", + "singularName": "", "namespaced": true, - "kind": "DeploymentConfig" + "kind": "EgressNetworkPolicy", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "groups", + "singularName": "", "namespaced": false, - "kind": "Group" + "kind": "Group", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "hostsubnets", + "singularName": "", "namespaced": false, - "kind": "HostSubnet" + "kind": "HostSubnet", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "identities", + "singularName": "", "namespaced": false, - "kind": "Identity" + "kind": "Identity", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "images", + "singularName": "", "namespaced": false, - "kind": "Image" + "kind": "Image", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, + { + "name": "imagesignatures", + "singularName": "", + "namespaced": false, + "kind": "ImageSignature", + "verbs": [ + "create", + "delete" + ] }, { "name": "imagestreamimages", + "singularName": "", "namespaced": true, - "kind": "ImageStreamImage" + "kind": "ImageStreamImage", + "verbs": [ + "get" + ], + "shortNames": [ + "isimage" + ] }, { "name": "imagestreamimports", + "singularName": "", "namespaced": true, - "kind": "ImageStreamImport" + "kind": "ImageStreamImport", + "verbs": [ + "create" + ] }, { "name": "imagestreammappings", + "singularName": "", "namespaced": true, - "kind": "ImageStreamMapping" + "kind": "ImageStreamMapping", + "verbs": [ + "create" + ] }, { "name": "imagestreams", - "namespaced": true, - "kind": "ImageStream" + "singularName": "", + "namespaced": true, + "kind": "ImageStream", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ], + "shortNames": [ + "is" + ] }, { "name": "imagestreams/secrets", + "singularName": "", "namespaced": true, - "kind": "SecretList" + "kind": "SecretList", + "verbs": [ + "get" + ] }, { "name": "imagestreams/status", + "singularName": "", "namespaced": true, - "kind": "ImageStream" + "kind": "ImageStream", + "verbs": [ + "get", + "patch", + "update" + ] }, { "name": "imagestreamtags", - "namespaced": true, - "kind": "ImageStreamTag" + "singularName": "", + "namespaced": true, + "kind": "ImageStreamTag", + "verbs": [ + "create", + "delete", + "get", + "list", + "patch", + "update" + ], + "shortNames": [ + "istag" + ] }, { "name": "localresourceaccessreviews", + "singularName": "", "namespaced": true, - "kind": "LocalResourceAccessReview" + "kind": "LocalResourceAccessReview", + "verbs": [ + "create" + ] }, { "name": "localsubjectaccessreviews", + "singularName": "", "namespaced": true, - "kind": "LocalSubjectAccessReview" + "kind": "LocalSubjectAccessReview", + "verbs": [ + "create" + ] }, { "name": "netnamespaces", + "singularName": "", "namespaced": false, - "kind": "NetNamespace" + "kind": "NetNamespace", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "oauthaccesstokens", + "singularName": "", "namespaced": false, - "kind": "OAuthAccessToken" + "kind": "OAuthAccessToken", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "oauthauthorizetokens", + "singularName": "", "namespaced": false, - "kind": "OAuthAuthorizeToken" + "kind": "OAuthAuthorizeToken", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "oauthclientauthorizations", + "singularName": "", "namespaced": false, - "kind": "OAuthClientAuthorization" + "kind": "OAuthClientAuthorization", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "oauthclients", + "singularName": "", "namespaced": false, - "kind": "OAuthClient" + "kind": "OAuthClient", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] + }, + { + "name": "podsecuritypolicyreviews", + "singularName": "", + "namespaced": true, + "kind": "PodSecurityPolicyReview", + "verbs": [ + "create" + ] }, { - "name": "policies", + "name": "podsecuritypolicyselfsubjectreviews", + "singularName": "", "namespaced": true, - "kind": "Policy" + "kind": "PodSecurityPolicySelfSubjectReview", + "verbs": [ + "create" + ] }, { - "name": "policybindings", + "name": "podsecuritypolicysubjectreviews", + "singularName": "", "namespaced": true, - "kind": "PolicyBinding" + "kind": "PodSecurityPolicySubjectReview", + "verbs": [ + "create" + ] }, { "name": "processedtemplates", + "singularName": "", "namespaced": true, - "kind": "Template" + "kind": "Template", + "verbs": [ + "create" + ] }, { "name": "projectrequests", + "singularName": "", "namespaced": false, - "kind": "ProjectRequest" + "kind": "ProjectRequest", + "verbs": [ + "create", + "list" + ] }, { "name": "projects", + "singularName": "", "namespaced": false, - "kind": "Project" + "kind": "Project", + "verbs": [ + "create", + "delete", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "resourceaccessreviews", + "singularName": "", "namespaced": true, - "kind": "ResourceAccessReview" + "kind": "ResourceAccessReview", + "verbs": [ + "create" + ] + }, + { + "name": "rolebindingrestrictions", + "singularName": "", + "namespaced": true, + "kind": "RoleBindingRestriction", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "rolebindings", + "singularName": "", "namespaced": true, - "kind": "RoleBinding" + "kind": "RoleBinding", + "verbs": [ + "create", + "delete", + "get", + "list", + "patch", + "update" + ] }, { "name": "roles", + "singularName": "", "namespaced": true, - "kind": "Role" + "kind": "Role", + "verbs": [ + "create", + "delete", + "get", + "list", + "patch", + "update" + ] }, { "name": "routes", + "singularName": "", "namespaced": true, - "kind": "Route" + "kind": "Route", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "routes/status", + "singularName": "", + "namespaced": true, + "kind": "Route", + "verbs": [ + "get", + "patch", + "update" + ] + }, + { + "name": "selfsubjectrulesreviews", + "singularName": "", "namespaced": true, - "kind": "Route" + "kind": "SelfSubjectRulesReview", + "verbs": [ + "create" + ] }, { "name": "subjectaccessreviews", + "singularName": "", + "namespaced": true, + "kind": "SubjectAccessReview", + "verbs": [ + "create" + ] + }, + { + "name": "subjectrulesreviews", + "singularName": "", "namespaced": true, - "kind": "SubjectAccessReview" + "kind": "SubjectRulesReview", + "verbs": [ + "create" + ] }, { "name": "templates", + "singularName": "", "namespaced": true, - "kind": "Template" + "kind": "Template", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] }, { "name": "useridentitymappings", + "singularName": "", "namespaced": false, - "kind": "UserIdentityMapping" + "kind": "UserIdentityMapping", + "verbs": [ + "create", + "delete", + "get", + "patch", + "update" + ] }, { "name": "users", + "singularName": "", "namespaced": false, - "kind": "User" + "kind": "User", + "verbs": [ + "create", + "delete", + "deletecollection", + "get", + "list", + "patch", + "update", + "watch" + ] } ] } \ No newline at end of file From 2d0147eb637f4752513c19406db56e7da9830e3b Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Mon, 17 Jun 2019 12:47:31 +0200 Subject: [PATCH 172/258] Fix failing unit tests Signed-off-by: Jeff MAURY --- .../restclient/apis/TypeMetaFactory.java | 13 ++- src/main/resources/k8stypes.properties | 1 + .../ProjectTemplateProcessingTest.java | 91 ++++++++++++++++++- .../restclient/model/ProjectTest.java | 29 +++++- .../restclient/model/v1/BuildConfigTest.java | 30 +++++- .../restclient/model/v1/ConfigMapTest.java | 31 ++++++- .../internal/restclient/model/v1/PVCTest.java | 32 ++++++- .../restclient/model/MocksFactory.java | 31 ++++++- 8 files changed, 247 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java index ed9f6c23..b51a7000 100644 --- a/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java +++ b/src/main/java/com/openshift/internal/restclient/apis/TypeMetaFactory.java @@ -88,13 +88,16 @@ public Object createInstanceFrom(String response) { Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); Class clazz = (Class) TypeRegistry.getInstance().getRegisteredType(version + IApiTypeMapper.DOT + kind); - if (clazz != null) { - Constructor constructor = clazz.getConstructor(ModelNode.class, - Map.class); - return constructor.newInstance(node, properyKeyMap); + try { + if (clazz != null) { + Constructor constructor = clazz.getConstructor(ModelNode.class, + Map.class); + return constructor.newInstance(node, properyKeyMap); + } + } catch (Exception e) { + return new TypeMeta(node, properyKeyMap); } return new TypeMeta(node, properyKeyMap); - } catch (UnsupportedVersionException e) { throw e; } catch (Exception e) { diff --git a/src/main/resources/k8stypes.properties b/src/main/resources/k8stypes.properties index 42bcde8e..b864e2ca 100644 --- a/src/main/resources/k8stypes.properties +++ b/src/main/resources/k8stypes.properties @@ -7,6 +7,7 @@ # # Kubernetes API com.openshift.internal.restclient.model.ConfigMap=v1.ConfigMap +com.openshift.internal.restclient.api.models.Endpoints=v1.Endpoints com.openshift.internal.restclient.model.KubernetesEvent=v1.Event,events.k8s.io/v1beta1.Event com.openshift.internal.restclient.model.LimitRange=v1.LimitRange com.openshift.internal.restclient.model.Namespace=v1.Namespace diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java index 40fefef2..02b750f5 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -28,7 +28,11 @@ import org.mockito.runners.MockitoJUnitRunner; import com.openshift.internal.restclient.ResourceFactory; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; import com.openshift.restclient.capability.resources.IProjectTemplateProcessing; import com.openshift.restclient.capability.server.ITemplateProcessing; import com.openshift.restclient.model.IList; @@ -93,6 +97,91 @@ public void applyTemplateShouldUseTheClientToCreateTheResources() { when(client.create(any(IList.class), anyString())).thenReturn(resources); when(client.getResourceFactory()).thenReturn(new ResourceFactory(client) { }); + IApiTypeMapper mapper = mock(IApiTypeMapper.class); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.TEMPLATE))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.TEMPLATE; + } + + @Override + public String getApiGroupName() { + return null; + } + }); + when(mapper.getType(anyString(), eq(ResourceKind.DEPLOYMENT_CONFIG))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.DEPLOYMENT_CONFIG; + } + + @Override + public String getApiGroupName() { + return null; + } + }); + when(mapper.getEndpointFor(anyString(), eq(ResourceKind.DEPLOYMENT_CONFIG))).thenReturn(new IVersionedApiResource() { + + @Override + public boolean isSupported(String capability) { + return true; + } + + @Override + public boolean isNamespaced() { + return true; + } + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getName() { // TODO Auto-generated method stub + return null; + } + + @Override + public String getKind() { + return ResourceKind.DEPLOYMENT_CONFIG; + } + + @Override + public String getApiGroupName() { + return "v1"; + } + }); + + ITemplate template = new ResourceFactory(client) { }.create(Samples.V1_TEMPLATE.getContentAsString()); diff --git a/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java b/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java index 17bb54b8..69780e56 100644 --- a/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -12,6 +12,7 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -26,6 +27,8 @@ import com.openshift.internal.restclient.OpenShiftAPIVersion; import com.openshift.internal.restclient.ResourceFactory; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IService; @@ -39,6 +42,30 @@ public class ProjectTest { @Before public void setup() { + IApiTypeMapper mapper = mock(IApiTypeMapper.class); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.PROJECT))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.PROJECT; + } + + @Override + public String getApiGroupName() { + return null; + } + }); project = new ResourceFactory(client) { }.create(OpenShiftAPIVersion.v1.toString(), ResourceKind.PROJECT); project.setName("aprojectname"); diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java index eb2c1402..ebce4e6b 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015-2018 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -12,6 +12,8 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -31,6 +33,8 @@ import com.openshift.internal.restclient.model.build.ImageChangeTrigger; import com.openshift.internal.restclient.model.build.SourceBuildStrategy; import com.openshift.internal.restclient.model.build.WebhookTrigger; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.images.DockerImageURI; @@ -55,6 +59,30 @@ public class BuildConfigTest { @BeforeClass public static void setup() throws Exception { client = mock(IClient.class); + IApiTypeMapper mapper = mock(IApiTypeMapper.class); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.PVC))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.BUILD_CONFIG; + } + + @Override + public String getApiGroupName() { + return null; + } + }); when(client.getBaseURL()).thenReturn(new URL("https://localhost:8443")); when(client.getOpenShiftAPIVersion()).thenReturn(VERSION); ModelNode node = ModelNode.fromJSONString(Samples.V1_BUILD_CONFIG.getContentAsString()); diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java index 31f828bc..4e7c8c02 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -10,7 +10,10 @@ package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.util.Collections; @@ -21,6 +24,8 @@ import com.openshift.internal.restclient.ResourceFactory; import com.openshift.internal.restclient.model.ConfigMap; import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IConfigMap; @@ -38,6 +43,30 @@ public class ConfigMapTest { @Before public void setUp() { client = mock(IClient.class); + IApiTypeMapper mapper = mock(IApiTypeMapper.class); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.CONFIG_MAP))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.CONFIG_MAP; + } + + @Override + public String getApiGroupName() { + return null; + } + }); ModelNode node = ModelNode.fromJSONString(Samples.V1_CONFIG_MAP.getContentAsString()); configMap = new ConfigMap(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.CONFIG_MAP)); diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java index f03ec7f9..70b148b9 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -11,7 +11,10 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import java.util.Collections; @@ -19,7 +22,10 @@ import org.junit.Test; import com.openshift.internal.restclient.ResourceFactory; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.volume.IPersistentVolumeClaim; import com.openshift.restclient.model.volume.PVCAccessModes; import com.openshift.restclient.utils.Samples; @@ -32,6 +38,30 @@ public class PVCTest { @Before public void setup() { IClient client = mock(IClient.class); + IApiTypeMapper mapper = mock(IApiTypeMapper.class); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.PVC))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.PVC; + } + + @Override + public String getApiGroupName() { + return null; + } + }); claim = new ResourceFactory(client).create(Samples.V1_PVC.getContentAsString()); assertEquals(V1, claim.getApiVersion()); } diff --git a/src/test/java/com/openshift/restclient/model/MocksFactory.java b/src/test/java/com/openshift/restclient/model/MocksFactory.java index 58dd7a47..e5fd3d71 100644 --- a/src/test/java/com/openshift/restclient/model/MocksFactory.java +++ b/src/test/java/com/openshift/restclient/model/MocksFactory.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -11,6 +11,8 @@ package com.openshift.restclient.model; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; import static org.mockito.Mockito.when; import java.lang.reflect.Field; @@ -19,8 +21,11 @@ import com.openshift.internal.restclient.OpenShiftAPIVersion; import com.openshift.internal.restclient.ResourceFactory; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IApiTypeMapper.IVersionedType; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; +import com.openshift.restclient.ResourceKind; import com.openshift.restclient.utils.Samples; public class MocksFactory { @@ -35,6 +40,30 @@ public MocksFactory() { public MocksFactory(IClient client) { this.client = client; this.factory = new ResourceFactory(client); + IApiTypeMapper mapper = Mockito.mock(IApiTypeMapper.class); + when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + when(mapper.getType(anyString(), eq(ResourceKind.BUILD_CONFIG))).thenReturn(new IVersionedType() { + + @Override + public String getVersion() { + return "v1"; + } + + @Override + public String getPrefix() { + return null; + } + + @Override + public String getKind() { + return ResourceKind.BUILD_CONFIG; + } + + @Override + public String getApiGroupName() { + return null; + } + }); } public IClient getClient() { From 7ca4c199df19f846e03f35a6592f8fa3fc9ea1a2 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Mon, 17 Jun 2019 12:54:46 +0200 Subject: [PATCH 173/258] Fix checkstyle issue Signed-off-by: Jeff MAURY --- src/main/java/com/openshift/restclient/ClientBuilder.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 46330a8f..b3b0a519 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -263,8 +263,6 @@ public Response intercept(Chain chain) throws IOException { if (proxySelector != null) { builder.proxySelector(proxySelector); - } else { - builder.proxySelector(ProxySelector.getDefault()); } if (proxyAuthenticator != null) { From 2087005b311d22b2abc8ea7a580cfbcea97675c2 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 21 Jun 2019 08:36:10 +0200 Subject: [PATCH 174/258] Code refactoring, fixing Sonar issues Signed-off-by: Jeff MAURY --- .../internal/restclient/ApiTypeMapper.java | 86 ++++++++++++------- .../internal/restclient/ResourceFactory.java | 2 +- 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index 555d54c3..325dc3e8 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -94,16 +94,21 @@ public IVersionedApiResource getEndpointFor(String apiVersion, String kind) { return apiresource; } + private boolean isResourceCompatible(String kind, String[] apiGroupNameAndVersion, + VersionedApiResource versionedResource) { + return versionedResource.getName().equals(ResourceKind.pluralize(kind, true, true)) + && (apiGroupNameAndVersion.length == 0 || versionedResource.getVersion().equals(apiGroupNameAndVersion[apiGroupNameAndVersion.length - 1])) + && (apiGroupNameAndVersion.length < 2 || versionedResource.getApiGroupName().equals(apiGroupNameAndVersion[0])); + } + private IVersionedApiResource endpointFor(String version, String kind) { String[] split = StringUtils.isBlank(version) ? new String[] {} : version.split(FWD_SLASH); Optional result = null; if (split.length <= 1) { - result = resourceEndpoints.stream().filter(e -> { - return e.getName().equals(ResourceKind.pluralize(kind, true, true)) - && (split.length == 0 || e.getVersion().equals(split[split.length - 1])) - && (split.length < 2 || e.getApiGroupName().equals(split[0])); + result = resourceEndpoints.stream().filter(e -> + isResourceCompatible(kind, split, e) - }).findFirst(); + ).findFirst(); } else { result = Optional.of(formatEndpointFor(API_GROUPS_API, version, kind)); } @@ -163,34 +168,49 @@ private synchronized void init() { private void addEndpoints(List endpoints, List types, final String prefix, final String apiGroupName, final String version, final Collection nodes) { for (ModelNode node : nodes) { - String name = node.get(NAME).asString(); - String capability = null; - if (name.contains(FWD_SLASH)) { - int first = name.indexOf(FWD_SLASH); - capability = name.substring(first + 1); - name = name.substring(0, first); - } - String kind = node.get(KIND).asString(); - String typeApiGroupName = node.has(GROUP) ? node.get(GROUP).asString() : null; - String typeVersion = node.has(VERSION) ? node.get(VERSION).asString() : null; - boolean namespaced = node.get("namespaced").asBoolean(); - VersionedApiResource resource = new VersionedApiResource(prefix, apiGroupName, version, name, kind, - namespaced); - VersionedType type = new VersionedType(prefix, typeApiGroupName != null ? typeApiGroupName : apiGroupName, - typeVersion != null ? typeVersion : version, kind); - if (capability == null && node.has(VERBS) && !node.get(VERBS).asList().isEmpty()) { - if (!endpoints.contains(resource)) { - endpoints.add(resource); - } - } - if (!types.contains(type)) { - types.add(type); - } - if (capability != null) { - int index = endpoints.indexOf(resource); - if (index != (-1)) { - endpoints.get(index).addCapability(capability); - } + addEndpoint(endpoints, types, prefix, apiGroupName, version, node); + } + } + + private void addEndpoint(List endpoints, List types, final String prefix, + final String apiGroupName, final String version, ModelNode node) { + String[] nameAndCapability = getNameAndCapability(node); + String name = nameAndCapability[0]; + String capability = nameAndCapability[1]; + String kind = node.get(KIND).asString(); + String typeApiGroupName = node.has(GROUP) ? node.get(GROUP).asString() : null; + String typeVersion = node.has(VERSION) ? node.get(VERSION).asString() : null; + boolean namespaced = node.get("namespaced").asBoolean(); + VersionedApiResource resource = new VersionedApiResource(prefix, apiGroupName, version, name, kind, namespaced); + VersionedType type = new VersionedType(prefix, typeApiGroupName != null ? typeApiGroupName : apiGroupName, + typeVersion != null ? typeVersion : version, kind); + if (capability == null && node.has(VERBS) && !node.get(VERBS).asList().isEmpty() + && !endpoints.contains(resource)) { + endpoints.add(resource); + } + if (!types.contains(type)) { + types.add(type); + } + addEndpointCapability(endpoints, capability, resource); + } + + public String[] getNameAndCapability(ModelNode node) { + String name = node.get(NAME).asString(); + String capability = null; + if (name.contains(FWD_SLASH)) { + int first = name.indexOf(FWD_SLASH); + capability = name.substring(first + 1); + name = name.substring(0, first); + } + return new String[] { name, capability }; + } + + private void addEndpointCapability(List endpoints, String capability, + VersionedApiResource resource) { + if (capability != null) { + int index = endpoints.indexOf(resource); + if (index != -1) { + endpoints.get(index).addCapability(capability); } } } diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index 60f3ff44..e3f4e78a 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -169,7 +169,7 @@ public T stub(String kind, String name, String namespace) String[] elements = ResourceKind.parse(kind); IVersionedType type = client.adapt(IApiTypeMapper.class).getType(elements[0], elements[1]); if (type != null) { - KubernetesResource resource = (KubernetesResource) create(type.getApiGroupNameAndVersion(), elements[1]); + KubernetesResource resource = create(type.getApiGroupNameAndVersion(), elements[1]); resource.setName(name); resource.setNamespace(namespace); if (StringUtils.isNotEmpty(namespace)) { From fd1f4945ab48410f8da1793aca7eee8ab8f5d788 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 21 Jun 2019 12:04:25 +0200 Subject: [PATCH 175/258] bumping to 8.0.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2814731e..9121ef3b 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.0.0-SNAPSHOT + 8.0.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From 010b84eaa9fee024074412cca54ffc1a2a3cc2a3 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 25 Jun 2019 13:55:58 +0200 Subject: [PATCH 176/258] bumped to 8.0.1-SNAPSHOT after releasing 8.0.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9121ef3b..13366cee 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.0.0.Final + 8.0.1-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 6202ef308074d5ac0e73bbaebc902377bb1a31f2 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 29 Aug 2019 20:47:15 +0200 Subject: [PATCH 177/258] use "dist: trusty" in .travis.yml to fix oraclejdk8 buil (#396) Signed-off-by: Andre Dietisheim --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 403bd877..c2190743 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +dist: trusty + language: java jdk: From 43de23d3f4e5a71c6f1808c36769916e64ff8d24 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 29 Aug 2019 15:49:24 +0200 Subject: [PATCH 178/258] close responses, avoid leaking connections (#394) Signed-off-by: Andre Dietisheim --- .../internal/restclient/ApiTypeMapper.java | 15 +++- .../internal/restclient/DefaultClient.java | 39 ++++++---- ...erRegistryImageStreamImportCapability.java | 78 +++++++++++-------- .../okhttp/OpenShiftAuthenticator.java | 51 +++++++----- .../okhttp/ResponseCodeInterceptor.java | 13 +++- .../openshift/restclient/ClientBuilder.java | 15 +++- 6 files changed, 132 insertions(+), 79 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index 325dc3e8..ae2b9f65 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -39,6 +39,7 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; +import okhttp3.ResponseBody; /** * Typemapper to determine the endpoints for various openshift resources @@ -253,14 +254,19 @@ private String readEndpoint(final String endpoint) { try { final URL url = new URL(new URL(this.baseUrl), endpoint); LOGGER.debug(url.toString()); - Request request = new Request.Builder().url(url).build(); - Response response = client.newCall(request).execute(); - return response.body().string(); + return request(url); } catch (IOException e) { throw new OpenShiftException(e, "Unable to read endpoint %s/%s", this.baseUrl, endpoint); } } + private String request(final URL url) throws IOException { + Request request = new Request.Builder().url(url).build(); + try (Response response = client.newCall(request).execute()) { + return response.body().string(); + } + } + static class ApiGroup implements IApiGroup { private final ModelNode node; private final String prefix; @@ -322,7 +328,8 @@ public String getName() { @Override public Collection getVersions() { return JBossDmrExtentions.get(getNode(), new HashMap<>(), "versions").asList().stream() - .map(n -> n.asString()).collect(Collectors.toList()); + .map(ModelNode::asString) + .collect(Collectors.toList()); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index f80fa719..364d0424 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -290,23 +290,34 @@ private T execute(ITypeFactory factory, String method, String kind, String v throw new UnsupportedOperationException("Generic create operation not supported for resource type 'List'"); } - final URL endpoint = new URLBuilder(this.baseUrl, typeMapper).apiVersion(version).kind(kind).name(name) - .namespace(namespace).subresource(subresource).subContext(subContext).addParameters(params).build(); - + final URL endpoint = new URLBuilder(this.baseUrl, typeMapper) + .apiVersion(version) + .kind(kind) + .name(name) + .namespace(namespace) + .subresource(subresource) + .subContext(subContext) + .addParameters(params) + .build(); + Request request = newRequestBuilderTo(endpoint.toString()) + .method(method, requestBody) + .build(); + LOGGER.debug("About to make {} request: {}", request.method(), request); try { - Request request = newRequestBuilderTo(endpoint.toString()) - .method(method, requestBody) - .build(); - LOGGER.debug("About to make {} request: {}", request.method(), request); - try (Response result = client.newCall(request).execute()) { - String response = result.body().string(); - LOGGER.debug("Response: {}", response); - return (T) factory.createInstanceFrom(response); - } + String body = request(request); + return (T) factory.createInstanceFrom(body); } catch (IOException e) { throw new OpenShiftException(e, "Unable to execute request to %s", endpoint); } } + + private String request(Request request) throws IOException { + try (Response response = client.newCall(request).execute()) { + String body = response.body().string() ; + LOGGER.debug("Response: {}", body); + return body; + } + } private String getApiVersion(JSONSerializeable payload) { String apiVersion = null; @@ -358,9 +369,7 @@ public String getServerReadyStatus() { .url(new URL(this.baseUrl, URL_HEALTH_CHECK)) .header(PROPERTY_ACCEPT, "*/*") .build(); - try (Response response = client.newCall(request).execute()) { - return response.body().string(); - } + return request(request); } catch (IOException e) { throw new OpenShiftException(e, "Exception while trying to determine the health/ready response of the server"); diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java index fd46998f..2182c6fe 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java @@ -11,6 +11,7 @@ package com.openshift.internal.restclient.capability.resources; +import java.io.IOException; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -41,6 +42,7 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; +import okhttp3.ResponseBody; /** * Retrieve metadata directly from docker. @@ -81,11 +83,12 @@ public String getName() { private boolean registryExists(OkHttpClient client) throws Exception { Request req = new Request.Builder().url(DEFAULT_DOCKER_REGISTRY) .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true").build(); - Response response = client.newCall(req).execute(); - if (response == null) { - return false; + try (Response response = client.newCall(req).execute()) { + if (response == null) { + return false; + } + return (response.code() == STATUS_UNAUTHORIZED || response.code() == STATUS_OK); } - return (response.code() == STATUS_UNAUTHORIZED || response.code() == STATUS_OK); } /** @@ -96,26 +99,34 @@ private String retrieveAuthToken(OkHttpClient client, String details) throws Exc Map auth = parseAuthDetails(details); if (auth.containsKey(REALM)) { Request request = createAuthRequest(auth); - Response response = client.newCall(request).execute(); - LOG.debug("Auth response: " + response.toString()); - if (response.code() == STATUS_OK - && MEDIATYPE_APPLICATION_JSON.equals(response.headers().get(PROPERTY_CONTENT_TYPE))) { - ModelNode tokenNode = ModelNode.fromJSONString(response.body().string()); - if (tokenNode.hasDefined(TOKEN)) { - return tokenNode.get(TOKEN).asString(); - } else { - LOG.debug("No auth token was found on auth response: " + tokenNode.toJSONString(false)); - } + return retrieveAuthToken(client, request); + } else { + LOG.info("Unable to retrieve authentication token - 'realm' was not found in the authenticate header: {}", + auth.toString()); + } + } + return null; + } + + private String retrieveAuthToken(OkHttpClient client, Request request) throws IOException { + String token = null; + try (Response response = client.newCall(request).execute(); + ResponseBody responseBody = response.body()) { + LOG.debug("Auth response: {}", responseBody.string()); + if (response.code() == STATUS_OK + && MEDIATYPE_APPLICATION_JSON.equals(response.headers().get(PROPERTY_CONTENT_TYPE))) { + ModelNode tokenNode = ModelNode.fromJSONString(responseBody.string()); + if (tokenNode.hasDefined(TOKEN)) { + token = tokenNode.get(TOKEN).asString(); } else { - LOG.info( - "Unable to retrieve authentication token as response was not OK and/or unexpected content type"); + LOG.debug("No auth token was found on auth response: {}", tokenNode.toJSONString(false)); } } else { - LOG.info("Unable to retrieve authentication token - 'realm' was not found in the authenticate header: " - + auth.toString()); + LOG.info( + "Unable to retrieve authentication token as response was not OK and/or unexpected content type"); } } - return null; + return token; } private Request createAuthRequest(Map authParams) { @@ -127,12 +138,12 @@ private Request createAuthRequest(Map authParams) { } Request request = new Request.Builder().url(builder.build()) .header(ResponseCodeInterceptor.X_OPENSHIFT_IGNORE_RCI, "true").build(); - LOG.debug("Auth request uri: " + request.url()); + LOG.debug("Auth request uri: {}", request.url()); return request; } private Map parseAuthDetails(String auth) { - LOG.debug("Auth details header: " + auth); + LOG.debug("Auth details header: {}", auth); Map map = new HashMap<>(); String[] authAndValues = auth.split(" "); if (authAndValues.length == 2 && AUTHORIZATION_BEARER.equals(authAndValues[0])) { @@ -156,18 +167,21 @@ private DockerResponse retrieveMetaData(OkHttpClient client, String token, Docke builder.header(PROPERTY_AUTHORIZATION, String.format("%s %s", AUTHORIZATION_BEARER, token)); } - LOG.debug("retrieveMetaData uri: " + regUri); - Response response = client.newCall(builder.build()).execute(); - LOG.debug("retrieveMetaData response: " + response.toString()); - switch (response.code()) { - case STATUS_OK: - return new DockerResponse(DockerResponse.DATA, response.body().string()); - case STATUS_UNAUTHORIZED: - return new DockerResponse(DockerResponse.AUTH, - response.headers().get(IHttpConstants.PROPERTY_WWW_AUTHENTICATE)); + LOG.debug("retrieveMetaData uri: {}", regUri); + try (Response response = client.newCall(builder.build()).execute(); + ResponseBody responseBody = response.body()) { + LOG.debug("retrieveMetaData response: {}", responseBody.string()); + switch (response.code()) { + case STATUS_OK: + return new DockerResponse(DockerResponse.DATA, responseBody.string()); + case STATUS_UNAUTHORIZED: + return new DockerResponse(DockerResponse.AUTH, + response.headers().get(IHttpConstants.PROPERTY_WWW_AUTHENTICATE)); + default: + LOG.info("Unable to retrieve docker meta data: {}", responseBody.string()); + return null; + } } - LOG.info("Unable to retrieve docker meta data: " + response.toString()); - return null; } private static class DockerResponse { diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java index e0ac4c6e..be58d564 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java @@ -55,13 +55,17 @@ public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { public Request authenticate(Route route, Response response) throws IOException { if (unauthorizedForCluster(response)) { String requestUrl = response.request().url().toString(); - Request authRequest = new Request.Builder().addHeader(CSRF_TOKEN, "1").url(new URL(client.getAuthorizationEndpoint().toExternalForm() - + "?response_type=token&client_id=openshift-challenging-client").toString()).build(); + Request authRequest = new Request.Builder() + .addHeader(CSRF_TOKEN, "1") + .url(new URL(client.getAuthorizationEndpoint().toExternalForm() + + "?response_type=token&client_id=openshift-challenging-client").toString()).build(); try (Response authResponse = tryAuth(authRequest)) { if (authResponse.isSuccessful()) { String token = extractAndSetAuthContextToken(authResponse); - return response.request().newBuilder().header(IHttpConstants.PROPERTY_AUTHORIZATION, - String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)).build(); + return response.request().newBuilder() + .header(IHttpConstants.PROPERTY_AUTHORIZATION, + String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)) + .build(); } } throw new UnauthorizedException(captureAuthDetails(requestUrl), @@ -78,24 +82,31 @@ private boolean unauthorizedForCluster(Response response) { } private Response tryAuth(Request authRequest) throws IOException { - return okClient.newBuilder().authenticator(new Authenticator() { - - @Override - public Request authenticate(Route route, Response response) throws IOException { - if (StringUtils.isNotBlank(response.request().header(AUTH_ATTEMPTS))) { - return null; - } - if (StringUtils.isNotBlank(response.header(IHttpConstants.PROPERTY_WWW_AUTHENTICATE))) { - for (IChallangeHandler challangeHandler : challangeHandlers) { - if (!challangeHandler.canHandle(response.headers())) { - Builder requestBuilder = response.request().newBuilder().header(AUTH_ATTEMPTS, "1"); - return challangeHandler.handleChallange(requestBuilder).build(); + return okClient.newBuilder() + .authenticator(new Authenticator() { + + @Override + public Request authenticate(Route route, Response response) throws IOException { + if (StringUtils.isNotBlank(response.request().header(AUTH_ATTEMPTS))) { + return null; + } + if (StringUtils.isNotBlank(response.header(IHttpConstants.PROPERTY_WWW_AUTHENTICATE))) { + for (IChallangeHandler challangeHandler : challangeHandlers) { + if (!challangeHandler.canHandle(response.headers())) { + Builder requestBuilder = response.request().newBuilder() + .header(AUTH_ATTEMPTS, "1"); + response.close(); + return challangeHandler.handleChallange(requestBuilder).build(); + } + } } + return null; } - } - return null; - } - }).followRedirects(false).followRedirects(false).build().newCall(authRequest).execute(); + }) + .followRedirects(false) + .build() + .newCall(authRequest) + .execute(); } private IAuthorizationDetails captureAuthDetails(String url) { diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index a1d25ef5..0a9a141c 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -62,7 +62,7 @@ public Response intercept(Chain chain) throws IOException { response = makeSuccessIfAuthorized(response); break; default: - if (response.request().tag() instanceof Ignore == false) { + if (!(response.request().tag() instanceof Ignore)) { throw createOpenShiftException(client, response, null); } } @@ -70,14 +70,19 @@ public Response intercept(Chain chain) throws IOException { return response; } - private Response makeSuccessIfAuthorized(Response response) { + private Response makeSuccessIfAuthorized(final Response response) { + Response returnedResponse = response; String location = response.header(PROPERTY_LOCATION); if (StringUtils.isNotBlank(location) && URIUtils.splitFragment(location).containsKey(OpenShiftAuthenticator.ACCESS_TOKEN)) { - response = response.newBuilder().request(response.request()).code(STATUS_OK).headers(response.headers()) + returnedResponse = response.newBuilder() + .request(response.request()) + .code(STATUS_OK) + .headers(response.headers()) .build(); + response.close(); } - return response; + return returnedResponse; } public void setClient(DefaultClient client) { diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index b3b0a519..6d29d7c3 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -241,15 +241,22 @@ public IClient build() { String[] pieces = { this.userAgentPrefix, "openshift-restclient-java", Version.userAgent() }; String userAgent = StringUtils.join(pieces, "/"); - OkHttpClient.Builder builder = new OkHttpClient.Builder().addInterceptor(responseCodeInterceptor) + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .addInterceptor(responseCodeInterceptor) .addNetworkInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { - Request agent = chain.request().newBuilder().header("User-Agent", userAgent).build(); + Request agent = chain.request().newBuilder() + .header("User-Agent", userAgent) + .build(); return chain.proceed(agent); } - }).authenticator(authenticator).dispatcher(dispatcher).readTimeout(readTimeout, readTimeoutUnit) - .writeTimeout(writeTimeout, writeTimeoutUnit).connectTimeout(connectTimeout, connectTimeoutUnit) + }) + .authenticator(authenticator) + .dispatcher(dispatcher) + .readTimeout(readTimeout, readTimeoutUnit) + .writeTimeout(writeTimeout, writeTimeoutUnit) + .connectTimeout(connectTimeout, connectTimeoutUnit) .pingInterval(pingInterval, pingIntervalUnit) .sslSocketFactory(sslContext.getSocketFactory(), trustManager); From acdf6421da8dfa80a691a2f0bd9cf4d684899b65 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 6 Sep 2019 13:01:29 +0200 Subject: [PATCH 179/258] use okHttp 4.11 (was: 3.14.2) Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- src/main/java/com/openshift/restclient/ClientBuilder.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 13366cee..a15cb16e 100755 --- a/pom.xml +++ b/pom.xml @@ -161,7 +161,7 @@ com.squareup.okhttp3 okhttp - 3.14.2 + 4.1.1 org.yaml diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 6d29d7c3..7b1bb6a9 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -238,7 +238,7 @@ public IClient build() { // if we need to really expose them. dispatcher.setMaxRequests(maxRequests); dispatcher.setMaxRequestsPerHost(maxRequestsPerHost); - String[] pieces = { this.userAgentPrefix, "openshift-restclient-java", Version.userAgent() }; + String[] pieces = { this.userAgentPrefix, "openshift-restclient-java", Version.userAgent }; String userAgent = StringUtils.join(pieces, "/"); OkHttpClient.Builder builder = new OkHttpClient.Builder() From a6dceeae148473c0f37ee46f46e124aad0206d10 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 18 Sep 2019 19:35:55 +0200 Subject: [PATCH 180/258] upgrade to mockito 3.0.0 (#398) Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- .../restclient/ApiTypeMapperTest.java | 2 +- .../restclient/DefaultClientTest.java | 2 +- .../restclient/TypeMapperFixture.java | 15 ++++++++----- .../internal/restclient/URLBuilderTest.java | 5 +++-- .../api/capabilities/PodExecTest.java | 2 +- .../resources/AnnotationCapabilityTest.java | 2 +- .../resources/DeployCapabilityTest.java | 2 +- .../DeploymentConfigTraceabilityTest.java | 2 +- .../resources/DeploymentTraceabilityTest.java | 2 +- .../ImageStreamImportCapabilityTest.java | 2 +- .../resources/PodLogRetrievalAsyncTest.java | 11 +++------- .../ProjectTemplateProcessingTest.java | 2 +- .../resources/TagCapabilityTest.java | 2 +- .../resources/TemplateTraceabilityTest.java | 7 +++--- .../resources/UpdateableCapabilityTest.java | 9 ++++---- .../restclient/model/ProjectTest.java | 2 +- .../restclient/model/ServiceTest.java | 10 ++++----- .../model/build/BuildConfigBuilderTest.java | 2 +- .../restclient/model/v1/EndpointsTest.java | 2 +- .../restclient/model/v1/EventTest.java | 2 +- .../okhttp/BasicChallangeHandlerTest.java | 2 +- .../restclient/model/MocksFactory.java | 22 +++++++++---------- 23 files changed, 56 insertions(+), 55 deletions(-) diff --git a/pom.xml b/pom.xml index a15cb16e..002ee662 100755 --- a/pom.xml +++ b/pom.xml @@ -192,7 +192,7 @@ org.mockito mockito-core - 1.9.0-rc1 + 3.0.0 test diff --git a/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java b/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java index 612c9b34..a9a6d897 100644 --- a/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java +++ b/src/test/java/com/openshift/internal/restclient/ApiTypeMapperTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.IApiTypeMapper.IVersionedApiResource; import com.openshift.restclient.ResourceKind; diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 6a8edd72..1392e494 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -33,7 +33,7 @@ import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.invocation.InvocationOnMock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import com.openshift.internal.restclient.DefaultClient.HttpMethod; diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index c3a9c25a..4d0d70e3 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -11,9 +11,10 @@ package com.openshift.internal.restclient; -import static org.mockito.Matchers.argThat; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -25,6 +26,8 @@ import org.junit.Before; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; +import org.mockito.Mockito; +import org.mockito.quality.Strictness; import org.mockito.stubbing.OngoingStubbing; import com.openshift.restclient.IApiTypeMapper; @@ -90,10 +93,10 @@ OngoingStubbing whenRequestTo(String url) throws IOException { void mockAsyncRequest(String url, Supplier response) throws IOException { Call call = mock(Call.class); - doReturn(call).when(this).newCall(requestTo(url)); + lenient().doReturn(call).when(this).newCall(requestTo(url)); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(Callback.class); - doAnswer(invocation -> { + lenient().doAnswer(invocation -> { Callback callback = argumentCaptor.getValue(); callback.onResponse(call, response.get()); return null; @@ -119,7 +122,7 @@ protected static Response responseOf(int statusCode, String response) { .build(); } - static class RequestMatcher extends ArgumentMatcher { + static class RequestMatcher implements ArgumentMatcher { private final String url; @@ -128,11 +131,11 @@ public RequestMatcher(String url) { } @Override - public boolean matches(Object argument) { + public boolean matches(Request argument) { if (ANY_URL.equals(this.url)) { return true; } - if (argument == null || !(argument instanceof Request)) { + if (argument == null) { return false; } return ((Request) argument).url().toString().equals(url); diff --git a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java index 16a66972..0ed152eb 100644 --- a/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/URLBuilderTest.java @@ -12,6 +12,7 @@ package com.openshift.internal.restclient; import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -23,7 +24,7 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.IResource; @@ -104,7 +105,7 @@ private String whenBuildingTheURLFor(IResource resource, String namespace) { private IResource givenAResource(String kind, KubernetesAPIVersion version, String namespace) { IResource resource = mock(IResource.class); - when(resource.getApiVersion()).thenReturn(version.toString()); + lenient().when(resource.getApiVersion()).thenReturn(version.toString()); when(resource.getKind()).thenReturn(kind); when(resource.getNamespaceName()).thenReturn(namespace); return resource; diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java index a1adc56f..4d83d240 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java @@ -21,7 +21,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.TypeMapperFixture; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java index 90533658..fd988cb5 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java @@ -18,7 +18,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.model.IResource; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java index 2c453a87..6134029d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java @@ -26,7 +26,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.IClient; import com.openshift.restclient.NotFoundException; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java index f184d614..3fad06a9 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java index 5145aa9e..bff0dc50 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java index 2d61a760..c8f074e4 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java @@ -23,7 +23,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java index eb7882e5..b974882c 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java @@ -13,10 +13,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doThrow; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -25,7 +23,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.TypeMapperFixture; @@ -36,8 +34,6 @@ import com.openshift.restclient.model.IPod; import com.openshift.restclient.model.MocksFactory; -import okhttp3.MediaType; -import okhttp3.ResponseBody; import okhttp3.WebSocket; @RunWith(MockitoJUnitRunner.class) @@ -101,7 +97,6 @@ public void testStopWhenConnected() throws Exception { @Test public void testStopSwallowsException() throws Exception { WebSocket socket = mock(WebSocket.class); - doThrow(Exception.class).when(socket).close(anyInt(), anyString()); adapter.onOpen(socket, null); adapter.stop(); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java index 02b750f5..892659c8 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java @@ -25,7 +25,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.internal.restclient.ResourceFactory; import com.openshift.restclient.IApiTypeMapper; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/TagCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/TagCapabilityTest.java index e3d3bb48..c8923901 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/TagCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/TagCapabilityTest.java @@ -16,7 +16,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.model.IResource; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java index 55078a3a..50df1710 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/TemplateTraceabilityTest.java @@ -12,13 +12,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.IClient; import com.openshift.restclient.ResourceKind; @@ -36,8 +37,8 @@ public class TemplateTraceabilityTest { @Before public void setUp() { capability = new TemplateTraceability(resource); - when(resource.getNamespaceName()).thenReturn("mynamespace"); - when(resource.getKind()).thenReturn(ResourceKind.TEMPLATE); + lenient().when(resource.getNamespaceName()).thenReturn("mynamespace"); + lenient().when(resource.getKind()).thenReturn(ResourceKind.TEMPLATE); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java index d4601d8c..10a7a761 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/UpdateableCapabilityTest.java @@ -11,15 +11,16 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.when; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.internal.restclient.IntegrationTestHelper; import com.openshift.internal.restclient.ResourceFactory; @@ -44,7 +45,7 @@ public class UpdateableCapabilityTest { @Before public void setup() { - when(client.getOpenShiftAPIVersion()).thenReturn("v1"); + lenient().when(client.getOpenShiftAPIVersion()).thenReturn("v1"); when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); when(mapper.getType(anyString(), eq(ResourceKind.SERVICE))).thenReturn(new IVersionedType() { diff --git a/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java b/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java index 69780e56..13617ccb 100644 --- a/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java @@ -23,7 +23,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.internal.restclient.OpenShiftAPIVersion; import com.openshift.internal.restclient.ResourceFactory; diff --git a/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java index 2c1a74bf..c2589948 100644 --- a/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java @@ -10,9 +10,9 @@ package com.openshift.internal.restclient.model; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyMap; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @@ -32,7 +32,7 @@ import com.openshift.restclient.IClient; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceKind; -import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.IService; import com.openshift.restclient.model.IServicePort; @@ -91,7 +91,7 @@ public void testSetPorts() { @Test public void testGetPods() { // setup - when(client.list(anyString(), anyString(), anyMap())).thenReturn(new ArrayList()); + when(client.list(anyString(), anyString(), anyMap())).thenReturn(new ArrayList()); service.addLabel("bar", "foo"); service.setSelector("foo", "bar"); diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java index 6ea8e00e..fc0e93eb 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java @@ -27,7 +27,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.internal.restclient.model.BuildConfig; import com.openshift.restclient.IClient; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java index d7e4f8d4..4ff164d6 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java @@ -19,7 +19,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.internal.restclient.TypeMapperFixture; import com.openshift.restclient.IResourceFactory; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java index 6b11b5bd..0a47937e 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EventTest.java @@ -21,7 +21,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.internal.restclient.model.KubernetesEvent; import com.openshift.restclient.IClient; diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java index eeb683f3..19746123 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java @@ -20,7 +20,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.authorization.IAuthorizationContext; diff --git a/src/test/java/com/openshift/restclient/model/MocksFactory.java b/src/test/java/com/openshift/restclient/model/MocksFactory.java index e5fd3d71..aefadafc 100644 --- a/src/test/java/com/openshift/restclient/model/MocksFactory.java +++ b/src/test/java/com/openshift/restclient/model/MocksFactory.java @@ -11,9 +11,9 @@ package com.openshift.restclient.model; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.lenient; import java.lang.reflect.Field; @@ -41,8 +41,8 @@ public MocksFactory(IClient client) { this.client = client; this.factory = new ResourceFactory(client); IApiTypeMapper mapper = Mockito.mock(IApiTypeMapper.class); - when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); - when(mapper.getType(anyString(), eq(ResourceKind.BUILD_CONFIG))).thenReturn(new IVersionedType() { + lenient().when(client.adapt(IApiTypeMapper.class)).thenReturn(mapper); + lenient().when(mapper.getType(anyString(), eq(ResourceKind.BUILD_CONFIG))).thenReturn(new IVersionedType() { @Override public String getVersion() { @@ -72,8 +72,8 @@ public IClient getClient() { public T mock(Class klass, String namespace, String name) { T mock = mock(klass); - when(mock.getNamespaceName()).thenReturn(namespace); - when(mock.getName()).thenReturn(name); + lenient().when(mock.getNamespaceName()).thenReturn(namespace); + lenient().when(mock.getName()).thenReturn(name); return mock; } @@ -85,10 +85,10 @@ public T mock(Class klass, String namespace, String nam public T mock(Class klass) { final String version = OpenShiftAPIVersion.v1.toString(); T mock = Mockito.mock(klass); - when(mock.getName()).thenReturn("a" + klass.getSimpleName()); - when(mock.getApiVersion()).thenReturn(version); - when(mock.getNamespaceName()).thenReturn("aNamespace"); - when(mock.getKind()).thenReturn(klass.getSimpleName().substring(1)); + lenient().when(mock.getName()).thenReturn("a" + klass.getSimpleName()); + lenient().when(mock.getApiVersion()).thenReturn(version); + lenient().when(mock.getNamespaceName()).thenReturn("aNamespace"); + lenient().when(mock.getKind()).thenReturn(klass.getSimpleName().substring(1)); return mock; } From c66018cfe2a3b56715818071b192e8d6f84dac7b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 26 Sep 2019 14:57:09 +0200 Subject: [PATCH 181/258] addressed sonar complaints Signed-off-by: Andre Dietisheim --- .../internal/restclient/ApiTypeMapper.java | 10 ++++----- .../internal/restclient/DefaultClient.java | 6 +++--- .../capability/CapabilityInitializer.java | 3 +++ .../AbstractOpenShiftBinaryCapability.java | 4 ++-- .../capability/resources/BuildTrigger.java | 6 +++--- .../resources/DeploymentTrigger.java | 2 +- ...erRegistryImageStreamImportCapability.java | 2 +- .../restclient/model/BuildConfig.java | 2 +- .../restclient/model/DeploymentConfig.java | 6 +++--- .../model/volume/PersistentVolume.java | 6 +++--- .../AbstractPersistentVolumeProperties.java | 11 ---------- .../property/HostPathVolumeProperties.java | 2 +- .../ISettablePersistentVolumeProperties.java | 21 +++++++++++++++++++ .../volume/property/NfsVolumeProperties.java | 2 +- .../com/openshift/internal/util/Assert.java | 5 ++++- .../restclient/model/Annotatable.java | 1 + .../openshift/restclient/utils/BeanUtils.java | 6 ++++-- 17 files changed, 57 insertions(+), 38 deletions(-) delete mode 100644 src/main/java/com/openshift/internal/restclient/model/volume/property/AbstractPersistentVolumeProperties.java create mode 100644 src/main/java/com/openshift/internal/restclient/model/volume/property/ISettablePersistentVolumeProperties.java diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index ae2b9f65..b301edff 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -39,7 +39,6 @@ import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import okhttp3.ResponseBody; /** * Typemapper to determine the endpoints for various openshift resources @@ -139,11 +138,12 @@ public IVersionedType getType(String apiVersion, String kind) { private IVersionedType typeFor(String version, String kind) { String[] split = StringUtils.isBlank(version) ? new String[] {} : version.split(FWD_SLASH); Optional result = null; - result = types.stream().filter(e -> { - return e.getKind().equals(kind) && (split.length == 0 || split[split.length - 1].equals(e.getVersion())) - && (split.length < 2 || split[0].equals(e.getApiGroupName())); + result = types.stream().filter(e -> + e.getKind().equals(kind) + && (split.length == 0 || split[split.length - 1].equals(e.getVersion())) + && (split.length < 2 || split[0].equals(e.getApiGroupName())) - }).findFirst(); + ).findFirst(); return result.orElse(null); } diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 364d0424..b6c21e0e 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -487,7 +487,7 @@ public VersionCallback(String description, Consumer versionSetter) { @Override public void onFailure(Call call, IOException e) { versionSetter.accept(""); - LOGGER.warn("Exception while trying to determine " + description + " master version", e); + LOGGER.warn("Exception while trying to determine {} master version", description, e); } @Override @@ -497,7 +497,7 @@ public void onResponse(Call call, Response response) throws IOException { versionSetter.accept(ModelNode.fromJSONString(response.body().string()).get("gitVersion").asString()); } else { versionSetter.accept(""); - LOGGER.warn("Failed to determine " + description + " master version: got " + response.code()); + LOGGER.warn("Failed to determine {} master version: got {}", description, response.code()); } } finally { response.close(); @@ -527,7 +527,7 @@ public void onResponse(Call call, Response response) throws IOException { DefaultClient.this.tokenEndpoint.complete(new URL(node.get("token_endpoint").asString())); } else { setDefaults(); - LOGGER.warn("Failed to determine authorization endpoint: got " + response.code()); + LOGGER.warn("Failed to determine authorization endpoint: got {}", response.code()); } } finally { response.close(); diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index 3927fe6d..8fb9dbdf 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -76,6 +76,9 @@ */ public class CapabilityInitializer { + private CapabilityInitializer() { + } + /** * Registers the capability if it is supported * diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 79c7ea7f..25712c54 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -158,7 +158,7 @@ protected Process getProcess() { } private void addShutdownHook() { - Runtime.getRuntime().addShutdownHook(new Thread(() -> stop())); + Runtime.getRuntime().addShutdownHook(new Thread(this::stop)); } /** @@ -239,7 +239,7 @@ public final synchronized void stop() { LOG.debug("OpenShiftBinaryCapability process exit code {}", exitValue); if (exitValue != 0) { try { - LOG.debug("OpenShiftBinaryCapability process error stream", + LOG.debug("OpenShiftBinaryCapability process error stream: {}", IOUtils.toString(process.getErrorStream())); } catch (IOException e) { LOG.debug("IOException trying to debug the process error stream", e); diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java index e2ad3be1..6b4a43d1 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/BuildTrigger.java @@ -35,7 +35,7 @@ public class BuildTrigger implements IBuildTriggerable { private final String subresource; private String commitId; private List causes; - private HashMap envVars = new HashMap(); + private HashMap envVars = new HashMap<>(); public BuildTrigger(IBuildConfig buildConfig, IClient client) { this.resource = buildConfig; @@ -77,8 +77,8 @@ public IBuild trigger() { if (StringUtils.isNotEmpty(commitId)) { request.setCommitId(commitId); } - causes.forEach(c -> request.addBuildCause(c)); - envVars.forEach((name, value) -> request.setEnvironmentVariable(name, value)); + causes.forEach(request::addBuildCause); + envVars.forEach(request::setEnvironmentVariable); return client.create(resource.getKind(), resource.getNamespaceName(), resource.getName(), subresource, request); } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java index 893ff791..2a12091f 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeploymentTrigger.java @@ -65,7 +65,7 @@ public IDeploymentConfig trigger() { request.setForce(force); request.setLatest(latest); request.setName(resourceName); - return (IDeploymentConfig) client.execute(client.getResourceFactory(), IHttpConstants.POST, + return client.execute(client.getResourceFactory(), IHttpConstants.POST, config.getKind(), config.getNamespaceName(), config.getName(), DEPLOYMENT_ENDPOINT, null, request, Collections.emptyMap()); } else { diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java index 2182c6fe..91d19528 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DockerRegistryImageStreamImportCapability.java @@ -256,7 +256,7 @@ private IImageStreamImport buildResponse(String meta, DockerImageURI uri) { } private ImageStreamImport buildImageStreamImport(DockerImageURI uri, ModelNode node) { - ImageStreamImport isImport = (ImageStreamImport) factory.stub(ResourceKind.IMAGE_STREAM_IMPORT, uri.getName(), + ImageStreamImport isImport = factory.stub(ResourceKind.IMAGE_STREAM_IMPORT, uri.getName(), this.project.getName()); ModelNode root = isImport.getNode(); ModelNode images = JBossDmrExtentions.get(root, null, ImageStreamImport.STATUS_IMAGES); diff --git a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java index 9e41a7fa..961f51a0 100644 --- a/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/BuildConfig.java @@ -79,7 +79,7 @@ public IObjectReference getBuildOutputReference() { @Override public List getBuildTriggers() { - List triggers = new ArrayList(); + List triggers = new ArrayList<>(); if (has(BUILDCONFIG_TRIGGERS)) { List list = get(BUILDCONFIG_TRIGGERS).asList(); final String url = getClient() != null && StringUtils.isNotEmpty(getNamespaceName()) diff --git a/src/main/java/com/openshift/internal/restclient/model/DeploymentConfig.java b/src/main/java/com/openshift/internal/restclient/model/DeploymentConfig.java index 5067e166..4232f187 100644 --- a/src/main/java/com/openshift/internal/restclient/model/DeploymentConfig.java +++ b/src/main/java/com/openshift/internal/restclient/model/DeploymentConfig.java @@ -59,7 +59,7 @@ public DeploymentConfig(ModelNode node, IClient client, Map pr @Override public Collection getTriggerTypes() { - List types = new ArrayList(); + List types = new ArrayList<>(); ModelNode triggers = get(DEPLOYMENTCONFIG_TRIGGERS); for (ModelNode node : triggers.asList()) { types.add(asString(node, TYPE)); @@ -87,7 +87,7 @@ public Collection getTriggers() { // FIXME public List getImageNames() { - List names = new ArrayList(); + List names = new ArrayList<>(); List containers = get(DEPLOYMENTCONFIG_CONTAINERS).asList(); for (ModelNode container : containers) { names.add(container.get("image").asString()); @@ -130,7 +130,7 @@ public boolean haveTriggersFired() { if (causes.getType() == ModelType.UNDEFINED || causes.getType() != ModelType.LIST) { return false; } - return causes.asList().size() > 0; + return !causes.asList().isEmpty(); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java index d350fd4e..8ae99d82 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java @@ -20,7 +20,7 @@ import org.jboss.dmr.ModelType; import com.openshift.internal.restclient.model.KubernetesResource; -import com.openshift.internal.restclient.model.volume.property.AbstractPersistentVolumeProperties; +import com.openshift.internal.restclient.model.volume.property.ISettablePersistentVolumeProperties; import com.openshift.internal.restclient.model.volume.property.HostPathVolumeProperties; import com.openshift.internal.restclient.model.volume.property.NfsVolumeProperties; import com.openshift.restclient.IClient; @@ -177,8 +177,8 @@ public IPersistentVolumeProperties getPersistentVolumeProperties() { */ @Override public void setPersistentVolumeProperties(IPersistentVolumeProperties properties) { - if (properties instanceof AbstractPersistentVolumeProperties) { - ((AbstractPersistentVolumeProperties) properties).setProperties(getNode()); + if (properties instanceof ISettablePersistentVolumeProperties) { + ((ISettablePersistentVolumeProperties) properties).setProperties(getNode()); } } diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/property/AbstractPersistentVolumeProperties.java b/src/main/java/com/openshift/internal/restclient/model/volume/property/AbstractPersistentVolumeProperties.java deleted file mode 100644 index 43f7e07c..00000000 --- a/src/main/java/com/openshift/internal/restclient/model/volume/property/AbstractPersistentVolumeProperties.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.openshift.internal.restclient.model.volume.property; - -import org.jboss.dmr.ModelNode; - -import com.openshift.restclient.model.volume.property.IPersistentVolumeProperties; - -public abstract class AbstractPersistentVolumeProperties implements IPersistentVolumeProperties { - - public abstract void setProperties(ModelNode node); - -} diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/property/HostPathVolumeProperties.java b/src/main/java/com/openshift/internal/restclient/model/volume/property/HostPathVolumeProperties.java index 7236ba12..e29a925a 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/property/HostPathVolumeProperties.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/property/HostPathVolumeProperties.java @@ -17,7 +17,7 @@ import com.openshift.restclient.model.volume.property.IHostPathVolumeProperties; -public class HostPathVolumeProperties extends AbstractPersistentVolumeProperties implements IHostPathVolumeProperties { +public class HostPathVolumeProperties implements ISettablePersistentVolumeProperties, IHostPathVolumeProperties { private static final String PV_SPEC = "spec"; private static final String PV_HOST_PATH = "hostPath"; diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/property/ISettablePersistentVolumeProperties.java b/src/main/java/com/openshift/internal/restclient/model/volume/property/ISettablePersistentVolumeProperties.java new file mode 100644 index 00000000..d5238ca8 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/model/volume/property/ISettablePersistentVolumeProperties.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2015-2019 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.volume.property; + +import org.jboss.dmr.ModelNode; + +import com.openshift.restclient.model.volume.property.IPersistentVolumeProperties; + +public interface ISettablePersistentVolumeProperties extends IPersistentVolumeProperties { + + void setProperties(ModelNode node); + +} diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/property/NfsVolumeProperties.java b/src/main/java/com/openshift/internal/restclient/model/volume/property/NfsVolumeProperties.java index 4e478c8c..36cab962 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/property/NfsVolumeProperties.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/property/NfsVolumeProperties.java @@ -17,7 +17,7 @@ import com.openshift.restclient.model.volume.property.INfsVolumeProperties; -public class NfsVolumeProperties extends AbstractPersistentVolumeProperties implements INfsVolumeProperties { +public class NfsVolumeProperties implements ISettablePersistentVolumeProperties, INfsVolumeProperties { private static final String PV_SPEC = "spec"; private static final String PV_NFS = "nfs"; diff --git a/src/main/java/com/openshift/internal/util/Assert.java b/src/main/java/com/openshift/internal/util/Assert.java index 626eb356..b2f53186 100644 --- a/src/main/java/com/openshift/internal/util/Assert.java +++ b/src/main/java/com/openshift/internal/util/Assert.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011 Red Hat, Inc. + * Copyright (c) 2011-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -26,6 +26,9 @@ public AssertionFailedException() { } + private Assert() { + } + public static V notNull(V value) { if (value == null) { throw new AssertionFailedException(); diff --git a/src/main/java/com/openshift/restclient/model/Annotatable.java b/src/main/java/com/openshift/restclient/model/Annotatable.java index 2b3a996c..f0a9a41f 100644 --- a/src/main/java/com/openshift/restclient/model/Annotatable.java +++ b/src/main/java/com/openshift/restclient/model/Annotatable.java @@ -20,5 +20,6 @@ * @deprecated * {@link IAnnotatable} */ +@Deprecated public interface Annotatable extends IAnnotatable{ } diff --git a/src/main/java/com/openshift/restclient/utils/BeanUtils.java b/src/main/java/com/openshift/restclient/utils/BeanUtils.java index af12579f..1753793e 100644 --- a/src/main/java/com/openshift/restclient/utils/BeanUtils.java +++ b/src/main/java/com/openshift/restclient/utils/BeanUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -33,7 +33,9 @@ private BeanUtils() { */ public static String toCamelCase(String name, String delimiter) { String[] parts = name.split("-"); - List capitalized = Stream.of(parts).map(p -> StringUtils.capitalize(p)).collect(Collectors.toList()); + List capitalized = Stream.of(parts) + .map(StringUtils::capitalize) + .collect(Collectors.toList()); return StringUtils.uncapitalize(StringUtils.join(capitalized, "")); } } From f8044ee9786c7e103267ac48990b39097e89cd19 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 26 Sep 2019 14:57:09 +0200 Subject: [PATCH 182/258] addressed sonar complaints Signed-off-by: Andre Dietisheim --- .../java/com/openshift/internal/restclient/ApiTypeMapper.java | 2 +- .../internal/restclient/model/volume/PersistentVolume.java | 2 +- .../volume/property/ISettablePersistentVolumeProperties.java | 1 + src/main/java/com/openshift/restclient/utils/BeanUtils.java | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index b301edff..c0a649e8 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -140,7 +140,7 @@ private IVersionedType typeFor(String version, String kind) { Optional result = null; result = types.stream().filter(e -> e.getKind().equals(kind) - && (split.length == 0 || split[split.length - 1].equals(e.getVersion())) + && (split.length == 0 || split[split.length - 1].equals(e.getVersion())) && (split.length < 2 || split[0].equals(e.getApiGroupName())) ).findFirst(); diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java index 8ae99d82..cf0034dd 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolume.java @@ -20,8 +20,8 @@ import org.jboss.dmr.ModelType; import com.openshift.internal.restclient.model.KubernetesResource; -import com.openshift.internal.restclient.model.volume.property.ISettablePersistentVolumeProperties; import com.openshift.internal.restclient.model.volume.property.HostPathVolumeProperties; +import com.openshift.internal.restclient.model.volume.property.ISettablePersistentVolumeProperties; import com.openshift.internal.restclient.model.volume.property.NfsVolumeProperties; import com.openshift.restclient.IClient; import com.openshift.restclient.model.volume.IPersistentVolume; diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/property/ISettablePersistentVolumeProperties.java b/src/main/java/com/openshift/internal/restclient/model/volume/property/ISettablePersistentVolumeProperties.java index d5238ca8..879367ab 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/property/ISettablePersistentVolumeProperties.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/property/ISettablePersistentVolumeProperties.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.volume.property; import org.jboss.dmr.ModelNode; diff --git a/src/main/java/com/openshift/restclient/utils/BeanUtils.java b/src/main/java/com/openshift/restclient/utils/BeanUtils.java index 1753793e..65922a70 100644 --- a/src/main/java/com/openshift/restclient/utils/BeanUtils.java +++ b/src/main/java/com/openshift/restclient/utils/BeanUtils.java @@ -34,8 +34,8 @@ private BeanUtils() { public static String toCamelCase(String name, String delimiter) { String[] parts = name.split("-"); List capitalized = Stream.of(parts) - .map(StringUtils::capitalize) - .collect(Collectors.toList()); + .map(StringUtils::capitalize) + .collect(Collectors.toList()); return StringUtils.uncapitalize(StringUtils.join(capitalized, "")); } } From 313a1d9cf85a652f5878934edde2782312b3e129 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 3 Oct 2019 18:01:45 +0200 Subject: [PATCH 183/258] Test running ITs on Travis Signed-off-by: Jeff MAURY --- .travis.yml | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c2190743..5d7c13f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,34 @@ jdk: - oraclejdk8 - oraclejdk11 -script: - mvn clean verify +env: + - OCP=3.9.101 + - OCP=3.10.175 + - OCP=3.11.146 + +stages: + - test + - integration-test sudo: false + +jobs: + include: + - stage: test + script: mvn clean verify + - stage: integration-test + script: | + curl https://mirror.openshift.com/pub/openshift-v3/$OCP/linux/oc.tar.gz --location --output oc-client.tgz + tar -xzvf oc-client.tgz + cd openshift-origin-client* + sudo echo '{"insecure-registries": ["172.30.0.0/16"]}' > daemon.json + sudo mv daemon.json /etc/docker + sudo cat /etc/docker/daemon.json + sudo service docker restart + ./oc cluster up + cd .. + mvn verify -Pintegration-tests + cd openshift-origin-client* + ./oc cluster down + cd .. + rm -rf openshift-origin-client* \ No newline at end of file From c668f065360913c3c6c04e0e50a84de8b54a63fe Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 3 Oct 2019 18:12:10 +0200 Subject: [PATCH 184/258] Testing IT phase and matrix Signed-off-by: Jeff MAURY --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5d7c13f7..b86f02b0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,10 @@ jobs: - stage: test script: mvn clean verify - stage: integration-test + env: + - OCP=3.9.101 + - OCP=3.10.175 + - OCP=3.11.146 script: | curl https://mirror.openshift.com/pub/openshift-v3/$OCP/linux/oc.tar.gz --location --output oc-client.tgz tar -xzvf oc-client.tgz From f1a545253859eacc9552aa1c63b66b196bbe9954 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 3 Oct 2019 18:27:02 +0200 Subject: [PATCH 185/258] Use a single stage Signed-off-by: Jeff MAURY --- .travis.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b86f02b0..12837a33 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,21 +13,18 @@ env: stages: - test - - integration-test sudo: false jobs: include: - stage: test - script: mvn clean verify - - stage: integration-test env: - OCP=3.9.101 - OCP=3.10.175 - OCP=3.11.146 script: | - curl https://mirror.openshift.com/pub/openshift-v3/$OCP/linux/oc.tar.gz --location --output oc-client.tgz + curl https://mirror.openshift.com/pub/openshift-v3/${OCP}/linux/oc.tar.gz --location --output oc-client.tgz tar -xzvf oc-client.tgz cd openshift-origin-client* sudo echo '{"insecure-registries": ["172.30.0.0/16"]}' > daemon.json From 66729a899fe2c0b45a17565198c6af3b130adb1a Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 3 Oct 2019 18:31:12 +0200 Subject: [PATCH 186/258] Remove language Signed-off-by: Jeff MAURY --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 12837a33..61f381e6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ dist: trusty -language: java - jdk: - oraclejdk8 - oraclejdk11 @@ -19,10 +17,6 @@ sudo: false jobs: include: - stage: test - env: - - OCP=3.9.101 - - OCP=3.10.175 - - OCP=3.11.146 script: | curl https://mirror.openshift.com/pub/openshift-v3/${OCP}/linux/oc.tar.gz --location --output oc-client.tgz tar -xzvf oc-client.tgz From dc0e6c3f13d6ff63dfbe8e698ef7919292dc5d47 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 3 Oct 2019 18:33:19 +0200 Subject: [PATCH 187/258] Restore language Signed-off-by: Jeff MAURY --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 61f381e6..6f0e9dbb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ dist: trusty +language: java + jdk: - oraclejdk8 - oraclejdk11 From 0a73e9849815919519ddc7561edc88530f6fea47 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 4 Oct 2019 07:33:04 +0200 Subject: [PATCH 188/258] Loop in script Signed-off-by: Jeff MAURY --- .travis.yml | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6f0e9dbb..0935a708 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,31 +6,26 @@ jdk: - oraclejdk8 - oraclejdk11 -env: - - OCP=3.9.101 - - OCP=3.10.175 - - OCP=3.11.146 - stages: - test + - integration-test sudo: false jobs: include: - - stage: test + - stage: integration-test script: | - curl https://mirror.openshift.com/pub/openshift-v3/${OCP}/linux/oc.tar.gz --location --output oc-client.tgz - tar -xzvf oc-client.tgz - cd openshift-origin-client* + for OCP in 3.9.101 3.10.175 3.11.146; + do + curl https://mirror.openshift.com/pub/openshift-v3/${OCP}/linux/oc.tar.gz --location --output oc.tar.gz + gunzip oc.tar.gz + tar -xvf oc.tar sudo echo '{"insecure-registries": ["172.30.0.0/16"]}' > daemon.json sudo mv daemon.json /etc/docker sudo cat /etc/docker/daemon.json sudo service docker restart ./oc cluster up - cd .. mvn verify -Pintegration-tests - cd openshift-origin-client* ./oc cluster down - cd .. - rm -rf openshift-origin-client* \ No newline at end of file + done \ No newline at end of file From 20e5213adb91e01fdafcf79711d366e03b62639e Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Fri, 4 Oct 2019 13:36:40 +0200 Subject: [PATCH 189/258] Add traces Signed-off-by: Jeff MAURY --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0935a708..4f552b75 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,8 @@ jobs: script: | for OCP in 3.9.101 3.10.175 3.11.146; do - curl https://mirror.openshift.com/pub/openshift-v3/${OCP}/linux/oc.tar.gz --location --output oc.tar.gz + echo $OCP + curl https://mirror.openshift.com/pub/openshift-v3/$OCP/linux/oc.tar.gz --location --output oc.tar.gz gunzip oc.tar.gz tar -xvf oc.tar sudo echo '{"insecure-registries": ["172.30.0.0/16"]}' > daemon.json From ee58b0f09311cf376a8e74f9c33ddedcb63d6a80 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 4 Oct 2019 19:09:47 +0200 Subject: [PATCH 190/258] fixed DefaultClientIntegrationTest for use with OCP4 Signed-off-by: Andre Dietisheim --- .../internal/restclient/IntegrationTestHelper.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index daac68a8..4cb88971 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -41,6 +41,7 @@ import com.openshift.restclient.IWatcher; import com.openshift.restclient.NotFoundException; import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.authorization.ResourceForbiddenException; import com.openshift.restclient.capability.IBinaryCapability; import com.openshift.restclient.images.DockerImageURI; import com.openshift.restclient.model.IBuildConfig; @@ -125,8 +126,10 @@ public IProject getOrCreateProject(String name, IClient client) { IProject project = null; try { project = client.get(ResourceKind.PROJECT, name, ""); - } catch (NotFoundException e ) { - project = createProject(name, client); + } catch (NotFoundException | ResourceForbiddenException e) { + // OS3: NotFoundException + // OS4: ResourceForbiddenException + project = createProject(name, client); } return project; } From e5d04673d862c4f99d3984d2a7bf4113a2f77c74 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 1 Oct 2019 18:14:05 +0200 Subject: [PATCH 191/258] impl'd capability to retrieve console url (#400) Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- .../internal/restclient/DefaultClient.java | 9 + .../restclient/KubernetesVersion.java | 85 ++++++++ .../restclient/OpenShiftMajorVersion.java | 52 +++++ .../capability/CapabilityInitializer.java | 3 + .../restclient/capability/server/Console.java | 189 ++++++++++++++++++ .../model/volume/PersistentVolumeClaim.java | 6 + .../com/openshift/restclient/IClient.java | 11 +- .../capability/server/IConsole.java | 33 +++ .../DefaultClientIntegrationTest.java | 42 +++- .../restclient/IntegrationTestHelper.java | 49 ++++- .../restclient/KubernetesVersionTest.java | 98 +++++++++ .../restclient/OpenShiftVersionTest.java | 91 +++++++++ .../server/ConsoleIntegrationTest.java | 51 +++++ .../capability/server/DataPair.java | 30 +++ .../server/OpenShift3ConsoleTest.java | 131 ++++++++++++ .../server/OpenShift4ConsoleTest.java | 178 +++++++++++++++++ .../openshift/restclient/utils/Samples.java | 3 +- .../v1_config_map_console_public.json | 18 ++ 19 files changed, 1075 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/KubernetesVersion.java create mode 100644 src/main/java/com/openshift/internal/restclient/OpenShiftMajorVersion.java create mode 100644 src/main/java/com/openshift/internal/restclient/capability/server/Console.java create mode 100644 src/main/java/com/openshift/restclient/capability/server/IConsole.java create mode 100644 src/test/java/com/openshift/internal/restclient/KubernetesVersionTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/OpenShiftVersionTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/server/ConsoleIntegrationTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/server/DataPair.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/server/OpenShift3ConsoleTest.java create mode 100644 src/test/java/com/openshift/internal/restclient/capability/server/OpenShift4ConsoleTest.java create mode 100644 src/test/resources/samples/openshift3/v1_config_map_console_public.json diff --git a/pom.xml b/pom.xml index 002ee662..a06f1448 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.0.1-SNAPSHOT + 8.1.0-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index b6c21e0e..1782888d 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -91,6 +91,7 @@ public class DefaultClient implements IClient, IHttpConstants { private String kubernetesVersion; private AuthorizationContext authContext; private IApiTypeMapper typeMapper; + private OpenShiftMajorVersion openShiftMajorVersion; public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, IApiTypeMapper typeMapper, AuthorizationContext authContext) { @@ -597,6 +598,14 @@ public String getToken() { return getAuthorizationContext().getToken(); } + @Override + public int getOpenShiftMajorVersion() { + if (openShiftMajorVersion == null) { + this.openShiftMajorVersion = new OpenShiftMajorVersion(getOpenShiftAPIVersion(), getKubernetesMasterVersion()); + } + return openShiftMajorVersion.get(); + } + @Override public int hashCode() { final int prime = 31; diff --git a/src/main/java/com/openshift/internal/restclient/KubernetesVersion.java b/src/main/java/com/openshift/internal/restclient/KubernetesVersion.java new file mode 100644 index 00000000..7bd2b07e --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/KubernetesVersion.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; + +public class KubernetesVersion { + + public static final int NO_VERSION = -1; + private static final Pattern REGEX_KUBERVERSION = Pattern.compile("v(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})(\\+(\\p{ASCII}+)){0,1}"); + + private boolean detected = false; + private int major = NO_VERSION; + private int minor = NO_VERSION; + private int patch = NO_VERSION; + private String git; + + public KubernetesVersion(String kubernetesVersion) { + parse(kubernetesVersion); + } + + private void parse(String kubernetesVersion) { + reset(); + if (StringUtils.isEmpty(kubernetesVersion)) { + return; + } + Matcher matcher = REGEX_KUBERVERSION.matcher(kubernetesVersion); + if (!matcher.matches() + || matcher.groupCount() < 5) { + return; + } + try { + detected = true; + this.major = parseGroup(matcher.group(1)); + this.minor = parseGroup(matcher.group(2)); + this.patch = parseGroup(matcher.group(3)); + this.git = matcher.group(5); + } catch(NumberFormatException e) { + // stop when error encoutered + } + + } + + private int parseGroup(String version) { + return Integer.parseInt(version); + } + + private void reset() { + this.detected = false; + this.major = NO_VERSION; + this.minor = NO_VERSION; + this.patch = NO_VERSION; + this.git = null; + } + + public boolean isDetected() { + return detected; + } + + public int getMajor() { + return major; + } + + public int getMinor() { + return minor; + } + + public int getPatch() { + return patch; + } + + public String getGit() { + return git; + } +} diff --git a/src/main/java/com/openshift/internal/restclient/OpenShiftMajorVersion.java b/src/main/java/com/openshift/internal/restclient/OpenShiftMajorVersion.java new file mode 100644 index 00000000..5cc22bf2 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/OpenShiftMajorVersion.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient; + +public class OpenShiftMajorVersion { + + private KubernetesVersion openshiftVersion; + private KubernetesVersion kubernetesVersion; + + public OpenShiftMajorVersion(String openshiftAPIVersion, String kubernetesMasterVersion) { + this.openshiftVersion = new KubernetesVersion(openshiftAPIVersion); + this.kubernetesVersion = new KubernetesVersion(kubernetesMasterVersion); + } + + public boolean isDetected() { + return openshiftVersion.isDetected() + || kubernetesVersion.isDetected(); + } + + public int get() { + if (openshiftVersion.isDetected()) { + return openshiftVersion.getMajor(); + } + + if (!kubernetesVersion.isDetected()) { + return KubernetesVersion.NO_VERSION; + } + + return mapKubernetesToOpenShift(kubernetesVersion); + } + + private int mapKubernetesToOpenShift(KubernetesVersion kubernetesVersion) { + if (kubernetesVersion.getMajor() < 1) { + return 3; + } + + if (kubernetesVersion.getMajor() == 1 + && kubernetesVersion.getMinor() <= 11) { + return 3; + } + + return 4; + } + +} diff --git a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java index 8fb9dbdf..0b7fd498 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java +++ b/src/main/java/com/openshift/internal/restclient/capability/CapabilityInitializer.java @@ -33,6 +33,7 @@ import com.openshift.internal.restclient.capability.resources.TagCapability; import com.openshift.internal.restclient.capability.resources.TemplateTraceability; import com.openshift.internal.restclient.capability.resources.UpdateableCapability; +import com.openshift.internal.restclient.capability.server.Console; import com.openshift.internal.restclient.capability.server.ServerTemplateProcessing; import com.openshift.internal.restclient.model.Service; import com.openshift.internal.restclient.model.build.BuildConfigBuilder; @@ -59,6 +60,7 @@ import com.openshift.restclient.capability.resources.ITags; import com.openshift.restclient.capability.resources.ITemplateTraceability; import com.openshift.restclient.capability.resources.IUpdatable; +import com.openshift.restclient.capability.server.IConsole; import com.openshift.restclient.capability.server.ITemplateProcessing; import com.openshift.restclient.model.IBuild; import com.openshift.restclient.model.IBuildConfig; @@ -169,5 +171,6 @@ public static void initializeClientCapabilities(Map IClient client) { initializeCapability(capabilities, ITemplateProcessing.class, new ServerTemplateProcessing(client)); initializeCapability(capabilities, IBuildConfigBuilder.class, new BuildConfigBuilder(client)); + initializeCapability(capabilities, IConsole.class, new Console(client)); } } diff --git a/src/main/java/com/openshift/internal/restclient/capability/server/Console.java b/src/main/java/com/openshift/internal/restclient/capability/server/Console.java new file mode 100644 index 00000000..b00fc6ac --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/capability/server/Console.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient.capability.server; + +import java.util.Arrays; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Stream; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.server.IConsole; +import com.openshift.restclient.model.IConfigMap; +import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.IResource; + +public class Console implements IConsole { + + public static final String CONFIGMAP_DATA_CONSOLE_URL = "consoleURL"; + public static final String NAMESPACE_OPENSHIFT_CONFIG_MANAGED = "openshift-config-managed"; + public static final String CONFIGMAP_CONSOLE_PUBLIC = "console-public"; + + private IClient client; + + public Console(IClient client) { + this.client = client; + } + + @Override + public boolean isSupported() { + return true; + } + + @Override + public String getName() { + return this.getClass().getSimpleName(); + } + + @Override + public String getConsoleUrl() { + switch (client.getOpenShiftMajorVersion()) { + case 3: + return getOpenShift3ConsoleUrl(); + case 4: + return getOpenShift4ConsoleUrl(); + default: + return null; + } + } + + @Override + public String getConsoleUrl(R resource) { + switch (client.getOpenShiftMajorVersion()) { + case 3: + return getOpenShift3ConsoleUrl(resource); + case 4: + return getOpenShift4ConsoleUrl(resource); + default: + return null; + } + } + + private String getOpenShift3ConsoleUrl() { + return client.getBaseURL() + "/console"; + } + + private String getOpenShift3ConsoleUrl(R resource) { + StringBuilder builder = new StringBuilder(getOpenShift3ConsoleUrl()); + String projectName = resource == null ? null : resource.getNamespaceName(); + if (projectName != null) { + builder.append("/project/").append(projectName); + } + if (resource != null + && !(resource instanceof IProject)) { + String consoleResourceUrl = getOpenShiftResourceURL(resource, + Arrays.stream(OpenShiftConsoleResourceUrls.values()) + .filter(resourceUrl -> resourceUrl.getVersion() == 3)); + if (consoleResourceUrl != null) { + builder.append(consoleResourceUrl); + } + } + return builder.toString(); + } + + private String getOpenShift4ConsoleUrl() { + IConfigMap configMap = client.get( + ResourceKind.CONFIG_MAP, CONFIGMAP_CONSOLE_PUBLIC, NAMESPACE_OPENSHIFT_CONFIG_MANAGED); + if (configMap == null) { + return null; + } + Map data = configMap.getData(); + if (data == null + || data.isEmpty()) { + return null; + } + return data.get(CONFIGMAP_DATA_CONSOLE_URL); + } + + private String getOpenShift4ConsoleUrl(R resource) { + StringBuilder builder = new StringBuilder(getOpenShift4ConsoleUrl()); + if (resource == null) { + return builder.toString(); + } + String projectName = resource.getNamespaceName(); + if (resource.getKind().equals(ResourceKind.PROJECT)) { + builder.append("/overview/ns/").append(projectName); + } else { + String consoleResourceUrl = getOpenShiftResourceURL(resource, + Arrays.stream(OpenShiftConsoleResourceUrls.values()) + .filter(resourceUrl -> resourceUrl.getVersion() == 4)); + if (consoleResourceUrl != null) { + builder.append("/k8s/ns/").append(projectName).append(consoleResourceUrl); + } else { + // show project overview + builder.append("/overview/ns/").append(projectName); + } + } + return builder.toString(); + } + + protected String getOpenShiftResourceURL(IResource resource, Stream resourceUrls) { + return resourceUrls + .filter(resUrl -> resUrl.getResType().equals(resource.getKind())) + .findAny() + .map(resUrl -> resUrl.getUrlPart() + resUrl.getEndUrlFunc().apply(resource)) + .orElse(null); + } + + protected enum OpenShiftConsoleResourceUrls { + // OS3 + V3_BUILD(3, ResourceKind.BUILD, "/browse/builds/", r -> String.join("/", r.getLabels().get("buildconfig"), r.getName())), + V3_BUILDCONFIG(3, ResourceKind.BUILD_CONFIG, "/browse/builds/", IResource::getName), + V3_DEPLOYMENT(3, ResourceKind.REPLICATION_CONTROLLER, "/browse/rc/", IResource::getName), + V3_DEPLOYMENTCONFIG(3, ResourceKind.DEPLOYMENT_CONFIG, "/browse/deployments/", IResource::getName), + V3_EVENT(3, ResourceKind.EVENT, "/browse/events/", r -> org.apache.commons.lang.StringUtils.EMPTY), + V3_IMAGESTREAM(3, ResourceKind.IMAGE_STREAM, "/browse/images/", IResource::getName), + V3_PERSISTENTVOLUMECLAIM(3, ResourceKind.PVC, "/browse/persistentvolumeclaims/", IResource::getName), + V3_POD(3, ResourceKind.POD, "/browse/pods/", IResource::getName), + V3_ROUTES(3, ResourceKind.ROUTE, "/browse/routes/", IResource::getName), + V3_SERVICE(3, ResourceKind.SERVICE, "/browse/services/", IResource::getName), + // OS4 + V4_BUILDCONFIG(4, ResourceKind.BUILD_CONFIG, "/buildconfigs/", IResource::getName), + V4_BUILD(4, ResourceKind.BUILD, "/builds/", IResource::getName), + V4_DEPLOYMENT(4, ResourceKind.REPLICATION_CONTROLLER, "/replicationcontrollers/", IResource::getName), + V4_DEPLOYMENTCONFIG(4, ResourceKind.DEPLOYMENT_CONFIG, "/deploymentconfigs/", IResource::getName), + V4_EVENT(4, ResourceKind.EVENT, "/events/", r -> org.apache.commons.lang.StringUtils.EMPTY), + V4_IMAGESTREAM(4, ResourceKind.IMAGE_STREAM, "/imagestreams/", IResource::getName), + V4_PERSISTENTVOLUMECLAIM(4, ResourceKind.PVC, "/persistentvolumeclaims/", IResource::getName), + V4_POD(4, ResourceKind.POD, "/pods/", IResource::getName), + V4_ROUTES(4, ResourceKind.ROUTE, "/routes/", IResource::getName), + V4_SERVICE(4, ResourceKind.SERVICE, "/services/", IResource::getName); + + private int openShiftVersion; + private final String resourceKind; + private final String urlPart; + private final Function endUrlFunc; + + private OpenShiftConsoleResourceUrls(int version, String resourceKind, String urlPart, + Function endUrlFunc) { + this.openShiftVersion = version; + this.resourceKind = resourceKind; + this.urlPart = urlPart; + this.endUrlFunc = endUrlFunc; + } + + public int getVersion() { + return openShiftVersion; + } + + public String getResType() { + return resourceKind; + } + + public String getUrlPart() { + return urlPart; + } + + public Function getEndUrlFunc() { + return endUrlFunc; + } + } +} diff --git a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java index 8f55493b..b0568540 100644 --- a/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java +++ b/src/main/java/com/openshift/internal/restclient/model/volume/PersistentVolumeClaim.java @@ -20,6 +20,7 @@ import com.openshift.internal.restclient.model.KubernetesResource; import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; import com.openshift.restclient.model.volume.IPersistentVolumeClaim; public class PersistentVolumeClaim extends KubernetesResource implements IPersistentVolumeClaim { @@ -63,6 +64,11 @@ public void setRequestedStorage(String requestedStorage) { set(PVC_REQUESTED_STORAGE, requestedStorage); } + @Override + public String getKind() { + return ResourceKind.PVC; + } + @Override public String getStatus() { return asString(STATUS_PHASE); diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index f75f2389..2d5954b2 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -15,6 +15,8 @@ import java.util.List; import java.util.Map; +import com.openshift.internal.restclient.KubernetesVersion; +import com.openshift.internal.restclient.OpenShiftMajorVersion; import com.openshift.restclient.api.ITypeFactory; import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.capability.ICapable; @@ -379,5 +381,12 @@ default T adapt(Class klass) { String getKubernetesMasterVersion(); IClient clone(); - + + /** + * Returns the major version for OpenShift or + * {@link KubernetesVersion#NO_VERSION} if it could not be detected. + * + * @return the major version of openshift that this client talks to. + */ + int getOpenShiftMajorVersion(); } diff --git a/src/main/java/com/openshift/restclient/capability/server/IConsole.java b/src/main/java/com/openshift/restclient/capability/server/IConsole.java new file mode 100644 index 00000000..ba59989b --- /dev/null +++ b/src/main/java/com/openshift/restclient/capability/server/IConsole.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.restclient.capability.server; + +import com.openshift.restclient.capability.ICapability; +import com.openshift.restclient.model.IResource; + +/** + * Identifies an OpenShift server as capable of hosting a (web) console + */ +public interface IConsole extends ICapability { + + /** + * Returns the console url + * + * @return the console url (e.g. https://console-openshift-console.apps.com) + */ + String getConsoleUrl(); + + /** + * Returns the url in the console for the given resource + * + * @return the console url (e.g. https://console-openshift-console.apps.com) + */ + String getConsoleUrl(R resource); +} diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index 115df3db..ed325711 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -10,13 +10,16 @@ package com.openshift.internal.restclient; import static com.openshift.internal.restclient.IntegrationTestHelper.MILLISECONDS_PER_SECOND; +import static org.fest.assertions.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; import java.util.Collections; import java.util.List; +import org.apache.commons.lang.StringUtils; import org.junit.Before; import org.junit.Test; import org.slf4j.Logger; @@ -35,7 +38,6 @@ public class DefaultClientIntegrationTest { - private static final String VERSION = "v1"; private static final Logger LOG = LoggerFactory.getLogger(DefaultClientIntegrationTest.class); private IntegrationTestHelper helper = new IntegrationTestHelper(); @@ -157,5 +159,43 @@ private void assertServiceEquals(IService stub, IService service) { assertEquals(stub.getSelector(), service.getSelector()); assertEquals(stub.getPort(), service.getPort()); } + + @Test + public void shouldHaveOpenShiftMasterVersion() { + // given + // when + int osMajorVersion = client.getOpenShiftMajorVersion(); + // then + assertThat(osMajorVersion).isNotEqualTo(KubernetesVersion.NO_VERSION); + } + + @Test + public void shouldDetectCorrectOpenShiftMasterVersion() { + // given + String osVersion = client.getOpenshiftMasterVersion(); + String k8Version = client.getKubernetesMasterVersion(); + // when + int osMajorVersion = client.getOpenShiftMajorVersion(); + // then + assertOpenShiftVersion(osMajorVersion, osVersion, k8Version); + } + + private void assertOpenShiftVersion(int osMajorVersion, String osVersion, String k8Version) { + if (StringUtils.length(osVersion) > 1) { + int guessedOSMajorVersion = Integer.parseInt(osVersion.charAt(1) + ""); + assertThat(osMajorVersion).isEqualTo(guessedOSMajorVersion); + } else if (!StringUtils.isEmpty(k8Version)) { + int guessedOSMajorVersion = KubernetesVersion.NO_VERSION; + int guessedK8MinorVersion = Integer.parseInt(k8Version.split("\\.")[1]); + if (guessedK8MinorVersion <= 11) { + guessedOSMajorVersion = 3; + } else { + guessedOSMajorVersion = 4; + } + assertThat(osMajorVersion).isEqualTo(guessedOSMajorVersion); + } else { + fail("Could not guess OpenShift version, neither /version/openshift nor /version are available."); + } + } } diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index 4cb88971..25c1f438 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -12,6 +12,8 @@ import static org.junit.Assert.fail; import java.io.IOException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -24,6 +26,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; @@ -39,6 +46,7 @@ import com.openshift.restclient.ClientBuilder; import com.openshift.restclient.IClient; import com.openshift.restclient.IWatcher; +import com.openshift.restclient.NoopSSLCertificateCallback; import com.openshift.restclient.NotFoundException; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.authorization.ResourceForbiddenException; @@ -53,6 +61,8 @@ import com.openshift.restclient.model.IService; import com.openshift.restclient.model.deploy.DeploymentTriggerType; +import okhttp3.OkHttpClient; + public class IntegrationTestHelper implements ResourcePropertyKeys { public static final long TEST_TIMEOUT = 6 * 1000; @@ -128,8 +138,8 @@ public IProject getOrCreateProject(String name, IClient client) { project = client.get(ResourceKind.PROJECT, name, ""); } catch (NotFoundException | ResourceForbiddenException e) { // OS3: NotFoundException - // OS4: ResourceForbiddenException - project = createProject(name, client); + // OS4: ResourceForbiddenException + project = createProject(name, client); } return project; } @@ -438,4 +448,39 @@ public void stopWatcher(IWatcher watcher) { public boolean isDeployPod(IPod pod) { return pod.getName().endsWith(POD_NAME_DEPLOY); } + + public OkHttpClient createTrustAllOkHttpClient() { + try { + TrustManager trustAllManager = new TrustAllTrustManager(); + final TrustManager[] trustAllCerts = new TrustManager[] { trustAllManager }; + final SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); + + return new OkHttpClient.Builder() + .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllManager) + .hostnameVerifier(new NoopSSLCertificateCallback()) + .build(); + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private static class TrustAllTrustManager implements X509TrustManager { + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) + throws CertificateException { + } + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) + throws CertificateException { + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + } } diff --git a/src/test/java/com/openshift/internal/restclient/KubernetesVersionTest.java b/src/test/java/com/openshift/internal/restclient/KubernetesVersionTest.java new file mode 100644 index 00000000..1b10a00b --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/KubernetesVersionTest.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient; + +import static org.fest.assertions.Assertions.assertThat; + +import org.junit.Test; + +public class KubernetesVersionTest { + + @Test + public void shouldReturnNotDetectedIfNullVersionString() { + // given + KubernetesVersion version = new KubernetesVersion(null); + // when + boolean isDetected = version.isDetected(); + // then + assertThat(isDetected).isFalse(); + } + + @Test + public void shouldReturnNotDetectedIfEmptyVersionString() { + // given + KubernetesVersion version = new KubernetesVersion(""); + // when + boolean isDetected = version.isDetected(); + // then + assertThat(isDetected).isFalse(); + } + + @Test + public void shouldReturnNotDetectedIfDoesntStartWithV() { + // given + KubernetesVersion version = new KubernetesVersion("3"); + // when + boolean isDetected = version.isDetected(); + // then + assertThat(isDetected).isFalse(); + } + + @Test + public void shouldNotParseIfOnlyMajorPresent() { + // given + KubernetesVersion version = new KubernetesVersion("v3"); + // when + // then + assertThat(version.isDetected()).isFalse(); + assertVersions(KubernetesVersion.NO_VERSION, KubernetesVersion.NO_VERSION, KubernetesVersion.NO_VERSION, null, + version); + } + + @Test + public void shouldNotParseIfOnlyMajorAndMinorVersion() { + // given + KubernetesVersion version = new KubernetesVersion("v3.2"); + // when + // then + assertThat(version.isDetected()).isFalse(); + assertVersions(KubernetesVersion.NO_VERSION, KubernetesVersion.NO_VERSION, KubernetesVersion.NO_VERSION, null, + version); + } + + @Test + public void shouldParseIfNoPatchVersion() { + // given + KubernetesVersion version = new KubernetesVersion("v3.2.1"); + // when + // then + assertThat(version.isDetected()).isTrue(); + assertVersions(3,2,1, null, + version); + } + + @Test + public void shouldMajorAndMinorAndPatchAndGitVersion() { + // given + KubernetesVersion version = new KubernetesVersion("v3.2.1+d42"); + // when + // then + assertThat(version.isDetected()).isTrue(); + assertVersions(3, 2, 1, "d42", version); + } + + private void assertVersions(int major, int minor, int patch, String git, KubernetesVersion version) { + assertThat(version.getMajor()).isEqualTo(major); + assertThat(version.getMinor()).isEqualTo(minor); + assertThat(version.getPatch()).isEqualTo(patch); + assertThat(version.getGit()).isEqualTo(git); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/OpenShiftVersionTest.java b/src/test/java/com/openshift/internal/restclient/OpenShiftVersionTest.java new file mode 100644 index 00000000..40ff6b5d --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/OpenShiftVersionTest.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient; + +import static org.fest.assertions.Assertions.assertThat; + +import org.junit.Test; + +public class OpenShiftVersionTest { + + @Test + public void shouldNotDetectedIfNullVersionStrings() { + // given + OpenShiftMajorVersion version = new OpenShiftMajorVersion(null, null); + // when + boolean isDetected = version.isDetected(); + int majorVersion = version.get(); + // then + assertThat(isDetected).isFalse(); + assertThat(majorVersion).isEqualTo(KubernetesVersion.NO_VERSION); + } + + @Test + public void shouldNotDetectedIfEmptyVersionStrings() { + // given + OpenShiftMajorVersion version = new OpenShiftMajorVersion("", ""); + // when + boolean isDetected = version.isDetected(); + int majorVersion = version.get(); + // then + assertThat(isDetected).isFalse(); + assertThat(majorVersion).isEqualTo(KubernetesVersion.NO_VERSION); + } + + @Test + public void shouldReturnVersionDetectedInOpenShiftString() { + // given + OpenShiftMajorVersion version = new OpenShiftMajorVersion("v3.11.43", "v1.11.0+d4cacc0"); + // when + int majorVersion = version.get(); + // then + assertThat(majorVersion).isEqualTo(3); + } + + @Test + public void shouldReturnVersion3ForKubernetes1_11() { + // given + OpenShiftMajorVersion version = new OpenShiftMajorVersion(null, "v1.11.0+d4cacc0"); + // when + int majorVersion = version.get(); + // then + assertThat(majorVersion).isEqualTo(3); + } + + @Test + public void shouldReturnVersion4ForKubernetes1_13() { + // given + OpenShiftMajorVersion version = new OpenShiftMajorVersion(null, "v1.13.4+f61b934"); + // when + int majorVersion = version.get(); + // then + assertThat(majorVersion).isEqualTo(4); + } + + @Test + public void shouldReturnVersion3IndependentlyOfKubernetesVersion() { + // given + OpenShiftMajorVersion version = new OpenShiftMajorVersion("v3.11.43", "v1.13.4+f61b934"); + // when + int majorVersion = version.get(); + // then + assertThat(majorVersion).isEqualTo(3); + } + + @Test + public void shouldReturnVersion4ByKubernetesIfOpenShiftVersionIsNotDetected() { + // given + OpenShiftMajorVersion version = new OpenShiftMajorVersion("smurf_version", "v1.13.4+f61b934"); + // when + int majorVersion = version.get(); + // then + assertThat(majorVersion).isEqualTo(4); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/ConsoleIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/ConsoleIntegrationTest.java new file mode 100644 index 00000000..36af4527 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/server/ConsoleIntegrationTest.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient.capability.server; + +import static org.fest.assertions.Assertions.assertThat; + +import java.net.MalformedURLException; + +import org.junit.Before; +import org.junit.Test; + +import com.openshift.internal.restclient.IntegrationTestHelper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.capability.server.IConsole; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class ConsoleIntegrationTest { + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IClient client; + private IConsole console; + private OkHttpClient httpClient; + + @Before + public void before() throws MalformedURLException { + this.client = helper.createClientForBasicAuth(); + this.console = client.adapt(IConsole.class); + this.httpClient = helper.createTrustAllOkHttpClient(); + } + + @Test + public void shouldRetrieveValidConsoleUrl() throws Exception { + // given + // when + String consoleUrl = console.getConsoleUrl(); + // then + assertThat(consoleUrl).isNotNull(); + Request request = new Request.Builder().url(consoleUrl).build(); + Response response = httpClient.newCall(request).execute(); + assertThat(response.isSuccessful()).isTrue(); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/DataPair.java b/src/test/java/com/openshift/internal/restclient/capability/server/DataPair.java new file mode 100644 index 00000000..489d288f --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/server/DataPair.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient.capability.server; + +import com.openshift.restclient.model.IResource; + +public class DataPair { + private IResource input; + private String expected; + + public DataPair(IResource input, String expected) { + this.input = input; + this.expected = expected; + } + + public IResource getResource() { + return input; + } + + public String getExpected() { + return expected; + } +} \ No newline at end of file diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift3ConsoleTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift3ConsoleTest.java new file mode 100644 index 00000000..174b16e1 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift3ConsoleTest.java @@ -0,0 +1,131 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient.capability.server; + +import static org.fest.assertions.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.server.IConsole; +import com.openshift.restclient.model.IBuild; +import com.openshift.restclient.model.IBuildConfig; +import com.openshift.restclient.model.IDeploymentConfig; +import com.openshift.restclient.model.IEvent; +import com.openshift.restclient.model.IImageStream; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.IReplicationController; +import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.IService; +import com.openshift.restclient.model.route.IRoute; +import com.openshift.restclient.model.volume.IPersistentVolumeClaim; + +@RunWith(Theories.class) +public class OpenShift3ConsoleTest { + + private static final String NAMESPACE = "namespace"; + + private static final String RESOURCE_NAME = "qwerty"; + + private static final String HOST = "http://openshifthost.testing"; + + @DataPoints + public static DataPair[] dataPoints = new DataPair[] { + new DataPair(mockResource(IBuild.class, ResourceKind.BUILD), + HOST + "/console/project/" + NAMESPACE + "/browse/builds/label/" + RESOURCE_NAME), + new DataPair(mockResource(IBuildConfig.class, ResourceKind.BUILD_CONFIG), + HOST + "/console/project/" + NAMESPACE + "/browse/builds/" + RESOURCE_NAME), + new DataPair(mockResource(IDeploymentConfig.class, ResourceKind.DEPLOYMENT_CONFIG), + HOST + "/console/project/" + NAMESPACE + "/browse/deployments/" + RESOURCE_NAME), + new DataPair(mockResource(IEvent.class, ResourceKind.EVENT), + HOST + "/console/project/" + NAMESPACE + "/browse/events/"), + new DataPair(mockResource(IImageStream.class, ResourceKind.IMAGE_STREAM), + HOST + "/console/project/" + NAMESPACE + "/browse/images/" + RESOURCE_NAME), + new DataPair(mockResource(IPod.class, ResourceKind.POD), + HOST + "/console/project/" + NAMESPACE + "/browse/pods/" + RESOURCE_NAME), + new DataPair(mockResource(IProject.class, ResourceKind.PROJECT), + HOST + "/console/project/" + NAMESPACE), + new DataPair(mockResource(IPersistentVolumeClaim.class, ResourceKind.PVC), + HOST + "/console/project/" + NAMESPACE + "/browse/persistentvolumeclaims/" + RESOURCE_NAME), + new DataPair(mockResource(IReplicationController.class, ResourceKind.REPLICATION_CONTROLLER), + HOST + "/console/project/" + NAMESPACE + "/browse/rc/" + RESOURCE_NAME), + new DataPair(mockResource(IRoute.class, ResourceKind.ROUTE), + HOST + "/console/project/" + NAMESPACE + "/browse/routes/" + RESOURCE_NAME), + new DataPair(mockResource(IService.class, ResourceKind.SERVICE), + HOST + "/console/project/" + NAMESPACE + "/browse/services/" + RESOURCE_NAME), + new DataPair(null, + HOST + "/console"), + // inexistant resource -> show project + new DataPair(mockResource(IResource.class, "INEXISTANT_RESOURCE_TYPE"), + HOST + "/console/project/" + NAMESPACE) + }; + + private IClient client; + private IConsole console; + + @Before + public void setup() throws MalformedURLException { + this.client = mockClient(HOST); + this.console = new Console(client); + } + + private static R mockResource(Class resourceClass, String kind) { + R resource = mock(resourceClass); + when(resource.getNamespaceName()).thenReturn(NAMESPACE); + when(resource.getName()).thenReturn(RESOURCE_NAME); + when(resource.getLabels()).thenReturn(new HashMap() { + { + put("buildconfig", "label"); + } + }); + doReturn(kind).when(resource).getKind(); + return resource; + } + + private IClient mockClient(String host) throws MalformedURLException { + IClient client = mock(IClient.class); + doReturn(3).when(client).getOpenShiftMajorVersion(); + doReturn(new URL(host)).when(client).getBaseURL(); + return client; + } + + @Test + public void shouldBeSupportedForOpenShift3() { + assertTrue("Exp. Console capability should be supported for OpenShift 3 server", console.isSupported()); + } + + @Test + public void shouldReturnConsoleUrlForOpenShift3() { + assertThat(console.getConsoleUrl()).isEqualTo(HOST + "/console"); + } + + @Theory + public void shouldReturnConsoleUrlForOpenShift3ForResource(DataPair dataPair) { + IResource resourceMock = dataPair.getResource(); + String consoleUrl = console.getConsoleUrl(resourceMock); + assertEquals(dataPair.getExpected(), consoleUrl); + } +} diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift4ConsoleTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift4ConsoleTest.java new file mode 100644 index 00000000..c92c6273 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift4ConsoleTest.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient.capability.server; + +import static org.fest.assertions.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +import com.openshift.internal.restclient.model.ConfigMap; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.capability.server.IConsole; +import com.openshift.restclient.model.IBuild; +import com.openshift.restclient.model.IBuildConfig; +import com.openshift.restclient.model.IConfigMap; +import com.openshift.restclient.model.IDeploymentConfig; +import com.openshift.restclient.model.IEvent; +import com.openshift.restclient.model.IImageStream; +import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IProject; +import com.openshift.restclient.model.IReplicationController; +import com.openshift.restclient.model.IResource; +import com.openshift.restclient.model.IService; +import com.openshift.restclient.model.route.IRoute; +import com.openshift.restclient.model.volume.IPersistentVolumeClaim; +import com.openshift.restclient.utils.Samples; + +@RunWith(Theories.class) +public class OpenShift4ConsoleTest { + + private static final String HOST = "http://openshifthost.testing"; + private static final String NAMESPACE = "grumpy"; + private static final String RESOURCE_NAME = "eap-app"; + + @DataPoints + public static DataPair[] dataPoints = new DataPair[] { + new DataPair(mockResource(IBuild.class, ResourceKind.BUILD), + HOST + "/k8s/ns/" + NAMESPACE + "/builds/" + RESOURCE_NAME), + new DataPair(mockResource(IBuildConfig.class, ResourceKind.BUILD_CONFIG), + HOST + "/k8s/ns/" + NAMESPACE + "/buildconfigs/" + RESOURCE_NAME), + new DataPair(mockResource(IDeploymentConfig.class, ResourceKind.DEPLOYMENT_CONFIG), + HOST + "/k8s/ns/" + NAMESPACE + "/deploymentconfigs/" + RESOURCE_NAME), + new DataPair(mockResource(IEvent.class, ResourceKind.EVENT), + HOST + "/k8s/ns/" + NAMESPACE + "/events/"), + new DataPair(mockResource(IImageStream.class, ResourceKind.IMAGE_STREAM), + HOST + "/k8s/ns/" + NAMESPACE + "/imagestreams/" + RESOURCE_NAME), + new DataPair(mockResource(IPod.class, ResourceKind.POD), + HOST + "/k8s/ns/" + NAMESPACE + "/pods/" + RESOURCE_NAME), + new DataPair(mockResource(IProject.class, ResourceKind.PROJECT), + HOST + "/overview/ns/" + NAMESPACE), + new DataPair(mockResource(IPersistentVolumeClaim.class, ResourceKind.PVC), + HOST + "/k8s/ns/" + NAMESPACE + "/persistentvolumeclaims/" + RESOURCE_NAME), + new DataPair(mockResource(IReplicationController.class, ResourceKind.REPLICATION_CONTROLLER), + HOST + "/k8s/ns/" + NAMESPACE + "/replicationcontrollers/" + RESOURCE_NAME), + new DataPair(mockResource(IRoute.class, ResourceKind.ROUTE), + HOST + "/k8s/ns/" + NAMESPACE + "/routes/" + RESOURCE_NAME), + new DataPair(mockResource(IService.class, ResourceKind.SERVICE), + HOST + "/k8s/ns/" + NAMESPACE + "/services/" + RESOURCE_NAME), + new DataPair(null, + HOST), + // inexistant resource -> show project + new DataPair(mockResource(IResource.class, "INEXISTANT_RESOURCE_TYPE"), + HOST + "/overview/ns/" + NAMESPACE) + }; + + private IClient client; + private IConsole console; + + private static R mockResource(Class resourceClass, String kind) { + R resource = mock(resourceClass); + when(resource.getNamespaceName()).thenReturn(NAMESPACE); + when(resource.getName()).thenReturn(RESOURCE_NAME); + doReturn(kind).when(resource).getKind(); + return resource; + } + + @Before + public void setup() throws MalformedURLException { + this.client = mockClient(HOST); + this.console = new Console(client); + } + + private IClient mockClient(String host) throws MalformedURLException { + IClient client = mock(IClient.class); + doReturn(4).when(client).getOpenShiftMajorVersion(); + doReturn(new URL(host)).when(client).getBaseURL(); + + ConfigMap map = mock(ConfigMap.class); + Map data = new HashMap(); + data.put(Console.CONFIGMAP_DATA_CONSOLE_URL, HOST); + doReturn(data).when(map).getData(); + doReturn(map).when(client).get(eq(ResourceKind.CONFIG_MAP), eq(Console.CONFIGMAP_CONSOLE_PUBLIC), eq(Console.NAMESPACE_OPENSHIFT_CONFIG_MANAGED)); + + return client; + } + + @Test + public void shouldBeSupportedForOpenShift4() { + assertTrue("Exp. Console endpoint should be supported for OpenShift 4 server", console.isSupported()); + } + + @Test + public void shouldReturnNullIfOpenShift4HasNoConfigmap() { + // given + doReturn(null).when(client).get(eq(ResourceKind.CONFIG_MAP), eq(Console.CONFIGMAP_CONSOLE_PUBLIC), eq(Console.NAMESPACE_OPENSHIFT_CONFIG_MANAGED)); + // when + String consoleUrl = console.getConsoleUrl(); + assertThat(consoleUrl).isNull(); + } + + @Test + public void shouldReturnNullIfOpenShift4HasNoConfigmapData() { + // given + ConfigMap map = mock(ConfigMap.class); + doReturn(null).when(map).getData(); + doReturn(map).when(client).get(eq(ResourceKind.CONFIG_MAP), eq(Console.CONFIGMAP_CONSOLE_PUBLIC), eq(Console.NAMESPACE_OPENSHIFT_CONFIG_MANAGED)); + // when + String consoleUrl = console.getConsoleUrl(); + // then + assertThat(consoleUrl).isNull(); + } + + @Test + public void shouldReturnNullIfOpenShift4EmptyConfigmapData() { + // given + IConfigMap map = mock(IConfigMap.class); + doReturn(new HashMap<>()).when(map).getData(); + doReturn(map).when(client).get(eq(ResourceKind.CONFIG_MAP), eq(Console.CONFIGMAP_CONSOLE_PUBLIC), eq(Console.NAMESPACE_OPENSHIFT_CONFIG_MANAGED)); + // when + String consoleUrl = console.getConsoleUrl(); + // then + assertThat(consoleUrl).isNull(); + } + + @Test + public void shouldReturnConsoleUrlForForOpenShift4ConfigMap() { + // given + ModelNode node = ModelNode.fromJSONString(Samples.V1_CONFIGMAP_CONSOLE_PUBLIC.getContentAsString()); + ConfigMap map = new ConfigMap(node, client, null); + doReturn(map).when(client).get(eq(ResourceKind.CONFIG_MAP), anyString(), anyString()); + // when + String consoleUrl = console.getConsoleUrl(); + // then + assertThat(consoleUrl).isEqualTo("https://console-openshift-console.apps.crw.codereadyqe.com"); + } + + @Theory + public void shouldReturnConsoleUrlForForOpenShift4ForResource(DataPair dataPair) { + IResource resourceMock = dataPair.getResource(); + String consoleUrl = console.getConsoleUrl(resourceMock); + assertEquals(dataPair.getExpected(), consoleUrl); + } +} diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index d5d54bee..4d520c57 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -73,7 +73,8 @@ public enum Samples { V1_PVC_VOLUME_SOURCE("openshift3/v1_pvc_volume_source.json"), V1_LIFECYCLE("openshift3/v1_lifecycle.json"), V1_DOCKER_IMAGE_MANIFEST("dockerregistry/v1_image_manifest.json"), - V1_BUILDCONFIG_PIPELINE("openshift3/v1_buildconfig_pipeline.json"); + V1_BUILDCONFIG_PIPELINE("openshift3/v1_buildconfig_pipeline.json"), + V1_CONFIGMAP_CONSOLE_PUBLIC("openshift3/v1_config_map_console_public.json"); private static final String SAMPLES_FOLDER = "/samples/"; diff --git a/src/test/resources/samples/openshift3/v1_config_map_console_public.json b/src/test/resources/samples/openshift3/v1_config_map_console_public.json new file mode 100644 index 00000000..7511b64e --- /dev/null +++ b/src/test/resources/samples/openshift3/v1_config_map_console_public.json @@ -0,0 +1,18 @@ +{ + "apiVersion": "v1", + "data": { + "consoleURL": "https://console-openshift-console.apps.crw.codereadyqe.com" + }, + "kind": "ConfigMap", + "metadata": { + "annotations": { + "release.openshift.io/create-only": "true" + }, + "creationTimestamp": "2019-09-24T11:13:17Z", + "name": "console-public", + "namespace": "openshift-config-managed", + "resourceVersion": "13313", + "selfLink": "/api/v1/namespaces/openshift-config-managed/configmaps/console-public", + "uid": "4f16131e-debc-11e9-a5c3-02ae3992b00c" + } +} \ No newline at end of file From c694d47d1adea318d8e67481ea889b306250c76c Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Sat, 5 Oct 2019 10:51:24 +0200 Subject: [PATCH 192/258] Use external script from Travis Signed-off-by: Jeff MAURY --- .travis.yml | 15 +++++++-------- startOCP.sh | 4 ++++ 2 files changed, 11 insertions(+), 8 deletions(-) create mode 100755 startOCP.sh diff --git a/.travis.yml b/.travis.yml index 4f552b75..fc62528a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,17 +16,16 @@ jobs: include: - stage: integration-test script: | - for OCP in 3.9.101 3.10.175 3.11.146; - do - echo $OCP - curl https://mirror.openshift.com/pub/openshift-v3/$OCP/linux/oc.tar.gz --location --output oc.tar.gz - gunzip oc.tar.gz - tar -xvf oc.tar sudo echo '{"insecure-registries": ["172.30.0.0/16"]}' > daemon.json sudo mv daemon.json /etc/docker sudo cat /etc/docker/daemon.json sudo service docker restart - ./oc cluster up + ./startOCP.sh 3.9.101 + mvn verify -Pintegration-tests + ./oc cluster down + ./startOCP.sh 3.10.175 + mvn verify -Pintegration-tests + ./oc cluster down + ./startOCP 3.11.146 mvn verify -Pintegration-tests ./oc cluster down - done \ No newline at end of file diff --git a/startOCP.sh b/startOCP.sh new file mode 100755 index 00000000..333c34e7 --- /dev/null +++ b/startOCP.sh @@ -0,0 +1,4 @@ +curl https://mirror.openshift.com/pub/openshift-v3/$1/linux/oc.tar.gz --location --output oc.tar.gz +gunzip oc.tar.gz +tar -xvf oc.tar +./oc cluster up From 5cff8632fdbd3b829dba05d7ac970a83c74a6fb4 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Sat, 5 Oct 2019 10:58:53 +0200 Subject: [PATCH 193/258] Fix download URL Signed-off-by: Jeff MAURY --- startOCP.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/startOCP.sh b/startOCP.sh index 333c34e7..65a8cc33 100755 --- a/startOCP.sh +++ b/startOCP.sh @@ -1,4 +1,4 @@ -curl https://mirror.openshift.com/pub/openshift-v3/$1/linux/oc.tar.gz --location --output oc.tar.gz +curl https://mirror.openshift.com/pub/openshift-v3/clients/$1/linux/oc.tar.gz --location --output oc.tar.gz gunzip oc.tar.gz tar -xvf oc.tar ./oc cluster up From 1df479a8b8e4006b549a63d247ee65b8b0207064 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Mon, 7 Oct 2019 10:27:40 +0200 Subject: [PATCH 194/258] Use GitHub to download oc Signed-off-by: Jeff MAURY --- .travis.yml | 6 +++--- startOCP.sh | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index fc62528a..2d33d807 100644 --- a/.travis.yml +++ b/.travis.yml @@ -20,12 +20,12 @@ jobs: sudo mv daemon.json /etc/docker sudo cat /etc/docker/daemon.json sudo service docker restart - ./startOCP.sh 3.9.101 + ./startOCP.sh v3.9.0 mvn verify -Pintegration-tests ./oc cluster down - ./startOCP.sh 3.10.175 + ./startOCP.sh v3.10.0 mvn verify -Pintegration-tests ./oc cluster down - ./startOCP 3.11.146 + ./startOCP v3.11.0 mvn verify -Pintegration-tests ./oc cluster down diff --git a/startOCP.sh b/startOCP.sh index 65a8cc33..add9c9f6 100755 --- a/startOCP.sh +++ b/startOCP.sh @@ -1,4 +1,5 @@ -curl https://mirror.openshift.com/pub/openshift-v3/clients/$1/linux/oc.tar.gz --location --output oc.tar.gz -gunzip oc.tar.gz -tar -xvf oc.tar +curl https://github.com/openshift/origin/releases/download/$1/openshift-origin-client-tools-v3.10.0-dd10d17-linux-64bit.tar.gz --location --output oc-client.tgz +tar -xzvf oc-client.tgz +mv openshift-origin-client*/oc . +rm -rf openshift-origin-client* ./oc cluster up From 54bd0aab3b7963e66baac39d8e769065086c56d6 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Mon, 7 Oct 2019 10:45:53 +0200 Subject: [PATCH 195/258] Overrides cluster coordinates Signed-off-by: Jeff MAURY --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d33d807..ea3df80f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,11 +21,11 @@ jobs: sudo cat /etc/docker/daemon.json sudo service docker restart ./startOCP.sh v3.9.0 - mvn verify -Pintegration-tests + mvn verify -Pintegration-tests -DserverURL=https://127.0.0.1:8443 -Ddefault.clusteradmin.user=admin -Ddefault.clusteradmin.password=admin -Docbinary.location=./oc ./oc cluster down ./startOCP.sh v3.10.0 - mvn verify -Pintegration-tests + mvn verify -Pintegration-tests -DserverURL=https://127.0.0.1:8443 -Ddefault.clusteradmin.user=admin -Ddefault.clusteradmin.password=admin -Docbinary.location=./oc ./oc cluster down ./startOCP v3.11.0 - mvn verify -Pintegration-tests + mvn verify -Pintegration-tests -DserverURL=https://127.0.0.1:8443 -Ddefault.clusteradmin.user=admin -Ddefault.clusteradmin.password=admin -Docbinary.location=./oc ./oc cluster down From 7020b7dd22694891334cd167595508f3f26339ad Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 14 Oct 2019 21:20:01 +0200 Subject: [PATCH 196/258] fixing travis build by switching to openjdk (#405) Signed-off-by: Andre Dietisheim --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ea3df80f..6de75e4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,10 @@ -dist: trusty +dist: xenial language: java jdk: - - oraclejdk8 - - oraclejdk11 + - openjdk8 + - openjdk11 stages: - test From 129ba3b47edcde5cca36a9633576f6def635024a Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 10 Oct 2019 16:36:59 +0200 Subject: [PATCH 197/258] Allow connecting to OpenShift 4.2 (#403) Signed-off-by: Andre Dietisheim --- .../internal/restclient/ApiTypeMapper.java | 12 +- .../internal/restclient/DefaultClient.java | 17 ++- .../restclient/api/capabilities/PodExec.java | 11 +- .../resources/PodLogRetrievalAsync.java | 9 +- .../okhttp/BasicChallangeHandler.java | 16 +-- .../restclient/okhttp/IChallangeHandler.java | 2 +- .../okhttp/OpenShiftAuthenticator.java | 83 ++++++++------ .../okhttp/OpenShiftRequestBuilder.java | 101 ++++++++++++++++ .../okhttp/ResponseCodeInterceptor.java | 28 +++-- .../restclient/okhttp/WatchClient.java | 10 +- .../openshift/restclient/ClientBuilder.java | 108 ++++++++++-------- .../authorization/UnauthorizedException.java | 6 +- .../DefaultClientIntegrationTest.java | 2 +- .../restclient/TypeMapperFixture.java | 2 +- .../okhttp/BasicChallangeHandlerTest.java | 4 +- .../openshiftv3IntegrationTest.properties | 19 ++- 16 files changed, 298 insertions(+), 132 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index c0a649e8..c824dd8d 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -29,11 +29,13 @@ import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.model.properties.ResourcePropertyKeys; +import com.openshift.internal.restclient.okhttp.OpenShiftRequestBuilder; import com.openshift.internal.util.JBossDmrExtentions; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.UnsupportedEndpointException; +import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.model.IResource; import okhttp3.OkHttpClient; @@ -51,14 +53,16 @@ public class ApiTypeMapper implements IApiTypeMapper, ResourcePropertyKeys { private static final Logger LOGGER = LoggerFactory.getLogger(ApiTypeMapper.class); private final String baseUrl; private final OkHttpClient client; + private IAuthorizationContext authorizationContext; private List resourceEndpoints; private List types; private final Map preferedVersion = new HashMap<>(2); private boolean initialized = false; - public ApiTypeMapper(String baseUrl, OkHttpClient client) { + public ApiTypeMapper(String baseUrl, OkHttpClient client, IAuthorizationContext authorizationContext) { this.baseUrl = baseUrl; this.client = client; + this.authorizationContext = authorizationContext; preferedVersion.put(KUBE_API, KubernetesAPIVersion.v1.toString()); preferedVersion.put(OS_API, OpenShiftAPIVersion.v1.toString()); } @@ -261,6 +265,12 @@ private String readEndpoint(final String endpoint) { } private String request(final URL url) throws IOException { +// Request request = new OpenShiftRequestBuilder() +// .acceptJson() +// .authorization(authorizationContext) +// .builder() +// .url(url) +// .build(); Request request = new Request.Builder().url(url).build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 1782888d..2d9bc930 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -34,6 +34,7 @@ import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.authorization.AuthorizationContext; +import com.openshift.internal.restclient.okhttp.OpenShiftRequestBuilder; import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; import com.openshift.internal.restclient.okhttp.WatchClient; import com.openshift.restclient.IApiTypeMapper; @@ -104,7 +105,7 @@ public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, initMasterVersion("version/openshift", new VersionCallback("OpenShift", version -> this.openShiftVersion = version)); initMasterVersion("version", new VersionCallback("Kubernetes", version -> this.kubernetesVersion = version)); initMasterVersion(".well-known/oauth-authorization-server", new AuthorizationCallback()); - this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client); + this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client, authContext); this.authContext = authContext; } @@ -300,9 +301,13 @@ private T execute(ITypeFactory factory, String method, String kind, String v .subContext(subContext) .addParameters(params) .build(); - Request request = newRequestBuilderTo(endpoint.toString()) - .method(method, requestBody) - .build(); + Request request = new OpenShiftRequestBuilder() + .acceptJson() + .authorization(authContext) + .builder() + .method(method, requestBody) + .url(endpoint) + .build(); LOGGER.debug("About to make {} request: {}", request.method(), request); try { String body = request(request); @@ -681,5 +686,9 @@ public T adapt(Class klass) { } return null; } + + public OpenShiftRequestBuilder newRequestBuilder() { + return new OpenShiftRequestBuilder(); + } } diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java index deb19f54..92e35f96 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java @@ -20,6 +20,7 @@ import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.URLBuilder; import com.openshift.internal.restclient.capability.AbstractCapability; +import com.openshift.internal.restclient.okhttp.OpenShiftRequestBuilder; import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; @@ -95,12 +96,16 @@ public IStoppable start(IPodExecOutputListener listener, Options options, String final String endpoint = urlBuilder.websocket(); - Request request = client.newRequestBuilderTo(endpoint, IHttpConstants.MEDIATYPE_ANY).method("GET", null) + Request request = new OpenShiftRequestBuilder() + .url(endpoint) + .method("GET", null) + .accept(IHttpConstants.MEDIATYPE_ANY) + .authorization(client.getAuthorizationContext()) .addHeader(K8S_PROTOCOL_HEADER, K8S_PROTOCOL) // Unless we mark this as ignored, exceptions triggered by interceptor would be // lost in dispatcher thread - .tag(new ResponseCodeInterceptor.Ignore() { - }).build(); + .tag(new ResponseCodeInterceptor.Ignore() {}) + .build(); ExecOutputListenerAdapter adapter = new ExecOutputListenerAdapter(listener); okClient.newWebSocket(request, adapter); diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java index 04c802f3..d4785acb 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsync.java @@ -20,6 +20,7 @@ import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.URLBuilder; +import com.openshift.internal.restclient.okhttp.OpenShiftRequestBuilder; import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; @@ -85,8 +86,12 @@ public IStoppable start(IPodLogListener listener, Options options) { final String endpoint = new URLBuilder(client.getBaseURL(), mapper).kind(pod.getKind()) .namespace(pod.getNamespaceName()).name(pod.getName()).subresource(CAPABILITY).addParameters(parameters) .websocket(); - Request request = client.newRequestBuilderTo(endpoint).tag(new ResponseCodeInterceptor.Ignore() { - }).build(); + Request request = new OpenShiftRequestBuilder() + .url(endpoint) + .acceptJson() + .authorization(client.getAuthorizationContext()) + .tag(new ResponseCodeInterceptor.Ignore() {}) + .build(); okClient.newWebSocket(request, adapter); return adapter; } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java index 189ee6bc..022c6f43 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java @@ -14,9 +14,8 @@ import org.apache.commons.lang.StringUtils; import com.openshift.restclient.authorization.IAuthorizationContext; -import com.openshift.restclient.http.IHttpConstants; -import com.openshift.restclient.utils.Base64Coder; +import okhttp3.Credentials; import okhttp3.Headers; import okhttp3.Request.Builder; @@ -35,16 +34,11 @@ public boolean canHandle(Headers headers) { } @Override - public Builder handleChallange(Builder builder) { - StringBuilder value = new StringBuilder(); - if (StringUtils.isNotBlank(context.getUserName())) { - value.append(context.getUserName()).append(":"); - } - if (StringUtils.isNotBlank(context.getPassword())) { - value.append(context.getPassword()); - } + public Builder handleChallenge(Builder builder) { return builder.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION, - IHttpConstants.AUTHORIZATION_BASIC + " " + Base64Coder.encode(value.toString())); + Credentials.basic( + StringUtils.defaultIfBlank(context.getUserName(), ""), + StringUtils.defaultIfBlank(context.getPassword(), ""))); } } \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java index 8e9a7ee8..9be1979d 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java @@ -35,5 +35,5 @@ interface IChallangeHandler { * @param builder * @return */ - Request.Builder handleChallange(Builder builder); + Request.Builder handleChallenge(Builder builder); } \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java index be58d564..8ae0e588 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java @@ -19,10 +19,10 @@ import org.apache.commons.lang.StringUtils; -import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.authorization.AuthorizationDetails; import com.openshift.internal.util.URIUtils; import com.openshift.restclient.IClient; +import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.authorization.IAuthorizationDetails; import com.openshift.restclient.authorization.UnauthorizedException; @@ -36,8 +36,7 @@ import okhttp3.Route; /** - * OkHttp Authenticator implementations for OpenShift 3 - * + * Adds authentication means to okhttp requests for use in OpenShift */ public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { @@ -48,40 +47,53 @@ public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { private static final String ERROR_DETAILS = "error_details"; private Collection challangeHandlers = new ArrayList<>(); - private OkHttpClient okClient; private IClient client; @Override public Request authenticate(Route route, Response response) throws IOException { - if (unauthorizedForCluster(response)) { - String requestUrl = response.request().url().toString(); - Request authRequest = new Request.Builder() - .addHeader(CSRF_TOKEN, "1") - .url(new URL(client.getAuthorizationEndpoint().toExternalForm() - + "?response_type=token&client_id=openshift-challenging-client").toString()).build(); - try (Response authResponse = tryAuth(authRequest)) { - if (authResponse.isSuccessful()) { - String token = extractAndSetAuthContextToken(authResponse); - return response.request().newBuilder() - .header(IHttpConstants.PROPERTY_AUTHORIZATION, - String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)) - .build(); - } + Request request = response.request(); + if (!unauthorizedForCluster(response, request)) { + return null; + } + String requestUrl = request.url().toString(); + try (Response authResponse = tryAuth()) { + if (authResponse == null + || !authResponse.isSuccessful()) { + throw new UnauthorizedException(getAuthDetails(requestUrl), + ResponseCodeInterceptor.getStatus(response.body().string())); } - throw new UnauthorizedException(captureAuthDetails(requestUrl), + String token = getToken(authResponse); + setToken(token, client.getAuthorizationContext()); + return new OpenShiftRequestBuilder(request.newBuilder()) + .authorization(token) + .build(); + } catch(OpenShiftException e) { + throw new UnauthorizedException(getAuthDetails(requestUrl), ResponseCodeInterceptor.getStatus(response.body().string())); } - - return null; } - private boolean unauthorizedForCluster(Response response) { - String requestHost = response.request().url().host(); - return response.code() == IHttpConstants.STATUS_UNAUTHORIZED - && client.getBaseURL().getHost().equals(requestHost); + private boolean unauthorizedForCluster(Response response, Request request) { + String requestHost = request.url().host(); + switch (response.code()) { + case IHttpConstants.STATUS_UNAUTHORIZED: + case IHttpConstants.STATUS_FORBIDDEN: + return client.getBaseURL().getHost().equals(requestHost); + default: + return false; + } } - private Response tryAuth(Request authRequest) throws IOException { + private Response tryAuth() throws IOException { + OkHttpClient okClient = client.adapt(OkHttpClient.class); + if (okClient == null) { + return null; + } + Request authRequest = new Request.Builder() + .addHeader(CSRF_TOKEN, "1") + .url(new URL(client.getAuthorizationEndpoint().toExternalForm() + + "?response_type=token&client_id=openshift-challenging-client").toString()) + .build(); return okClient.newBuilder() .authenticator(new Authenticator() { @@ -96,7 +108,7 @@ public Request authenticate(Route route, Response response) throws IOException { Builder requestBuilder = response.request().newBuilder() .header(AUTH_ATTEMPTS, "1"); response.close(); - return challangeHandler.handleChallange(requestBuilder).build(); + return challangeHandler.handleChallenge(requestBuilder).build(); } } } @@ -109,7 +121,7 @@ public Request authenticate(Route route, Response response) throws IOException { .execute(); } - private IAuthorizationDetails captureAuthDetails(String url) { + private IAuthorizationDetails getAuthDetails(String url) { IAuthorizationDetails details = null; Map pairs = URIUtils.splitFragment(url); if (pairs.containsKey(ERROR)) { @@ -118,27 +130,24 @@ private IAuthorizationDetails captureAuthDetails(String url) { return details; } - private String extractAndSetAuthContextToken(Response response) { + private String getToken(Response response) { String token = null; Map pairs = URIUtils.splitFragment(response.header(PROPERTY_LOCATION)); if (pairs.containsKey(ACCESS_TOKEN)) { token = pairs.get(ACCESS_TOKEN); - IAuthorizationContext authContext = client.getAuthorizationContext(); - if (authContext != null) { - authContext.setToken(token); - } } return token; } - public void setOkClient(OkHttpClient okClient) { - this.okClient = okClient; + private void setToken(String token, IAuthorizationContext authorizationContext) { + if (authorizationContext != null) { + authorizationContext.setToken(token); + } } - public void setClient(DefaultClient client) { + public void setClient(IClient client) { this.client = client; challangeHandlers.clear(); challangeHandlers.add(new BasicChallangeHandler(client.getAuthorizationContext())); } - } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java new file mode 100644 index 00000000..92dec52a --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java @@ -0,0 +1,101 @@ +/******************************************************************************* + * Copyright (c) 2015-2018 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + +package com.openshift.internal.restclient.okhttp; + +import static com.openshift.restclient.http.IHttpConstants.MEDIATYPE_APPLICATION_JSON; +import static com.openshift.restclient.http.IHttpConstants.PROPERTY_ACCEPT; + +import java.net.URL; + +import org.apache.commons.lang.StringUtils; + +import com.openshift.restclient.authorization.IAuthorizationContext; +import com.openshift.restclient.http.IHttpConstants; + +import okhttp3.Request; +import okhttp3.Request.Builder; +import okhttp3.RequestBody; + +public class OpenShiftRequestBuilder { + + private Builder builder; + + public OpenShiftRequestBuilder() { + this(new Builder()); + } + + public OpenShiftRequestBuilder(Builder builder) { + this.builder = builder; + } + + public OpenShiftRequestBuilder accept(String mediaType) { + builder.header(PROPERTY_ACCEPT, mediaType); + return this; + } + + public OpenShiftRequestBuilder acceptJson() { + builder.header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON); + return this; + } + + public OpenShiftRequestBuilder authorization(IAuthorizationContext authorizationContext) { + String token = null; + if (authorizationContext != null + && StringUtils.isNotBlank(authorizationContext.getToken())) { + token = authorizationContext.getToken(); + } + return authorization(token); + } + + public OpenShiftRequestBuilder authorization(String token) { + builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, IHttpConstants.AUTHORIZATION_BEARER + " " + token); + return this; + } + + public OpenShiftRequestBuilder url(URL url) { + this.builder.url(url); + return this; + } + + public OpenShiftRequestBuilder url(String url) { + this.builder.url(url); + return this; + } + + public OpenShiftRequestBuilder method(String method, RequestBody body) { + this.builder.method(method, body); + return this; + } + + public OpenShiftRequestBuilder addHeader(String key, String value) { + this.builder.addHeader(key, value); + return this; + } + + public OpenShiftRequestBuilder header(String key, String value) { + this.builder.header(key, value); + return this; + } + + public OpenShiftRequestBuilder tag(Object tag) { + this.builder.tag(tag); + return this; + } + + public Builder builder() { + return builder; + } + + public Request build() { + return builder.build(); + } +} diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index 0a9a141c..55c71078 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -25,6 +25,7 @@ import com.openshift.restclient.NotFoundException; import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.authorization.ResourceForbiddenException; +import com.openshift.restclient.authorization.UnauthorizedException; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IStatus; @@ -37,12 +38,12 @@ */ public class ResponseCodeInterceptor implements Interceptor, IHttpConstants { - public static final String X_OPENSHIFT_IGNORE_RCI = "X-OPENSHIFT-IGNORE-RCI"; - private static final Logger LOGGER = Logger.getLogger(ResponseCodeInterceptor.class); - private IClient client; + public static final String X_OPENSHIFT_IGNORE_RCI = "X-OPENSHIFT-IGNORE-RCI"; + private IClient client; + /** * If a request tag() implements this interface, HTTP errors will not throw * OpenShift exceptions. @@ -53,7 +54,8 @@ public interface Ignore { @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); - if (!response.isSuccessful() && StringUtils.isBlank(response.request().header(X_OPENSHIFT_IGNORE_RCI))) { + if (!response.isSuccessful() + && StringUtils.isBlank(response.request().header(X_OPENSHIFT_IGNORE_RCI))) { switch (response.code()) { case STATUS_UPGRADE_PROTOCOL: case STATUS_MOVED_PERMANENTLY: @@ -62,7 +64,7 @@ public Response intercept(Chain chain) throws IOException { response = makeSuccessIfAuthorized(response); break; default: - if (!(response.request().tag() instanceof Ignore)) { + if (!isIgnoreTagged(response)) { throw createOpenShiftException(client, response, null); } } @@ -70,6 +72,10 @@ public Response intercept(Chain chain) throws IOException { return response; } + private boolean isIgnoreTagged(Response response) { + return response.request().tag() instanceof Ignore; + } + private Response makeSuccessIfAuthorized(final Response response) { Response returnedResponse = response; String location = response.header(PROPERTY_LOCATION); @@ -96,7 +102,7 @@ public static IStatus getStatus(String response) { return null; } - public static OpenShiftException createOpenShiftException(IClient client, Response response, Throwable e) + private static OpenShiftException createOpenShiftException(IClient client, Response response, Throwable e) throws IOException { LOGGER.debug(response, e); IStatus status = getStatus(response.body().string()); @@ -108,12 +114,12 @@ public static OpenShiftException createOpenShiftException(IClient client, Respon case STATUS_BAD_REQUEST: return new BadRequestException(e, status, response.request().url().toString()); case STATUS_FORBIDDEN: - return new ResourceForbiddenException(status != null ? status.getMessage() : "Resource Forbidden", status, - e); + return new ResourceForbiddenException(status != null ? + status.getMessage() : "Resource Forbidden", status, e); case STATUS_UNAUTHORIZED: String link = String.format("%s/oauth/token/request", client.getBaseURL()); AuthorizationDetails details = new AuthorizationDetails(response.headers(), link); - return new com.openshift.restclient.authorization.UnauthorizedException(details, status); + return new UnauthorizedException(details, status); case IHttpConstants.STATUS_NOT_FOUND: return new NotFoundException(e, status, status == null ? "Not Found" : status.getMessage()); default: @@ -123,7 +129,7 @@ public static OpenShiftException createOpenShiftException(IClient client, Respon } public static OpenShiftException createOpenShiftException(IClient client, int responseCode, String message, - String response, Throwable e) throws IOException { + String response, Throwable e) { LOGGER.debug(response, e); IStatus status = getStatus(response); if (status != null && status.getCode() != 0) { @@ -136,7 +142,7 @@ public static OpenShiftException createOpenShiftException(IClient client, int re return new ResourceForbiddenException(status != null ? status.getMessage() : "Resource Forbidden", status, e); case STATUS_UNAUTHORIZED: - return new com.openshift.restclient.authorization.UnauthorizedException( + return new UnauthorizedException( client.getAuthorizationContext().getAuthorizationDetails(), status); case IHttpConstants.STATUS_NOT_FOUND: return new NotFoundException(status == null ? "Not Found" : status.getMessage()); diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index c94f2e28..50aeb423 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -34,7 +34,6 @@ import com.openshift.restclient.IOpenShiftWatchListener; import com.openshift.restclient.IOpenShiftWatchListener.ChangeType; import com.openshift.restclient.IWatcher; -import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.model.IList; import com.openshift.restclient.model.IResource; @@ -85,7 +84,10 @@ public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatc final String endpoint = new URLBuilder(client.getBaseURL(), this.typeMappings).kind(kind) .namespace(namespace).watch() .addParmeter(ResourcePropertyKeys.RESOURCE_VERSION, resourceVersion).websocket(); - Request request = client.newRequestBuilderTo(endpoint) + Request request = new OpenShiftRequestBuilder() + .url(endpoint) + .acceptJson() + .authorization(client.getAuthorizationContext()) .header(PROPERTY_ORIGIN, client.getBaseURL().toString()) .header(PROPERTY_USER_AGENT, "openshift-restclient-java").build(); okClient.newWebSocket(request, socket); @@ -95,13 +97,9 @@ public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatc } catch (Exception e) { endpointMap.clear(); status.set(Status.Stopped); - try { throw ResponseCodeInterceptor.createOpenShiftException(client, 0, String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), null, e); - } catch (IOException e1) { - throw new OpenShiftException(e1, "IOException trying to create an OpenShift specific exception"); - } } } return this; diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 7b1bb6a9..d7ff17d6 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -232,51 +232,10 @@ public IClient build() { ResponseCodeInterceptor responseCodeInterceptor = new ResponseCodeInterceptor(); OpenShiftAuthenticator authenticator = new OpenShiftAuthenticator(); - Dispatcher dispatcher = new Dispatcher(); - - // hiding these for now to since not certain - // if we need to really expose them. - dispatcher.setMaxRequests(maxRequests); - dispatcher.setMaxRequestsPerHost(maxRequestsPerHost); - String[] pieces = { this.userAgentPrefix, "openshift-restclient-java", Version.userAgent }; - String userAgent = StringUtils.join(pieces, "/"); - - OkHttpClient.Builder builder = new OkHttpClient.Builder() - .addInterceptor(responseCodeInterceptor) - .addNetworkInterceptor(new Interceptor() { - @Override - public Response intercept(Chain chain) throws IOException { - Request agent = chain.request().newBuilder() - .header("User-Agent", userAgent) - .build(); - return chain.proceed(agent); - } - }) - .authenticator(authenticator) - .dispatcher(dispatcher) - .readTimeout(readTimeout, readTimeoutUnit) - .writeTimeout(writeTimeout, writeTimeoutUnit) - .connectTimeout(connectTimeout, connectTimeoutUnit) - .pingInterval(pingInterval, pingIntervalUnit) - .sslSocketFactory(sslContext.getSocketFactory(), trustManager); - - if (!this.sslCertCallbackWithDefaultHostnameVerifier) { - builder.hostnameVerifier(sslCertificateCallback); - } - - if (proxy != null) { - builder.proxy(proxy); - } - - if (proxySelector != null) { - builder.proxySelector(proxySelector); - } - - if (proxyAuthenticator != null) { - builder.proxyAuthenticator(proxyAuthenticator); - } + Dispatcher dispatcher = createDispatcher(); - OkHttpClient okClient = builder.build(); + OkHttpClient okClient = createOkHttpClient(trustManager, sslContext, responseCodeInterceptor, + authenticator, dispatcher); IResourceFactory factory = defaultIfNull(resourceFactory, new ResourceFactory(null)); AuthorizationContext authContext = new AuthorizationContext(token, userName, password); @@ -285,7 +244,6 @@ public Response intercept(Chain chain) throws IOException { authContext.setClient(client); responseCodeInterceptor.setClient(client); authenticator.setClient(client); - authenticator.setOkClient(okClient); factory.setClient(client); return client; } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException @@ -294,6 +252,49 @@ public Response intercept(Chain chain) throws IOException { } } + private Dispatcher createDispatcher() { + Dispatcher dispatcher = new Dispatcher(); + + // hiding these for now to since not certain + // if we need to really expose them. + dispatcher.setMaxRequests(maxRequests); + dispatcher.setMaxRequestsPerHost(maxRequestsPerHost); + return dispatcher; + } + + private OkHttpClient createOkHttpClient(X509TrustManager trustManager, SSLContext sslContext, + ResponseCodeInterceptor responseCodeInterceptor, OpenShiftAuthenticator authenticator, + Dispatcher dispatcher) { + OkHttpClient.Builder builder = new OkHttpClient.Builder() + .addNetworkInterceptor(new UserAgentInterceptor(userAgentPrefix)) + .addInterceptor(responseCodeInterceptor) + .authenticator(authenticator) + .dispatcher(dispatcher) + .readTimeout(readTimeout, readTimeoutUnit) + .writeTimeout(writeTimeout, writeTimeoutUnit) + .connectTimeout(connectTimeout, connectTimeoutUnit) + .pingInterval(pingInterval, pingIntervalUnit) + .sslSocketFactory(sslContext.getSocketFactory(), trustManager); + + if (!this.sslCertCallbackWithDefaultHostnameVerifier) { + builder.hostnameVerifier(sslCertificateCallback); + } + + if (proxy != null) { + builder.proxy(proxy); + } + + if (proxySelector != null) { + builder.proxySelector(proxySelector); + } + + if (proxyAuthenticator != null) { + builder.proxyAuthenticator(proxyAuthenticator); + } + + return builder.build(); + } + private T defaultIfNull(T value, T theDefault) { if (value != null) { return value; @@ -381,4 +382,21 @@ public void checkClientTrusted(X509Certificate[] chain, String authType) throws } } + private static class UserAgentInterceptor implements Interceptor { + + private final String userAgent; + + public UserAgentInterceptor(String userAgentPrefix) { + this.userAgent = StringUtils.join( + new String[]{ userAgentPrefix, "openshift-restclient-java", Version.userAgent }, "/"); + } + + + @Override + public Response intercept(Chain chain) throws IOException { + Request agent = chain.request().newBuilder().header("User-Agent", userAgent).build(); + return chain.proceed(agent); + } + } + } diff --git a/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java b/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java index 91989d8b..9693cac0 100644 --- a/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java +++ b/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java @@ -18,9 +18,9 @@ public class UnauthorizedException extends OpenShiftException { private static final long serialVersionUID = -3999801367045252906L; private static final String MSG_BASE = "Unauthorized to access resource."; - private String message; - private IStatus status; - private IAuthorizationDetails details; + private final String message; + private final IStatus status; + private final IAuthorizationDetails details; public UnauthorizedException(IAuthorizationDetails details) { this(details, null); diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index ed325711..b043c9ef 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -57,7 +57,7 @@ public void testAuthContextIsAuthorizedWithValidUserNameAndPassword() { client = helper.createClient(); client.getAuthorizationContext().setUserName(helper.getDefaultClusterAdminUser()); client.getAuthorizationContext().setPassword(helper.getDefaultClusterAdminPassword()); - client.getAuthorizationContext().isAuthorized(); + assertThat(client.getAuthorizationContext().isAuthorized()).isTrue(); } @Test(expected = UnauthorizedException.class) diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 4d0d70e3..780cf162 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -80,7 +80,7 @@ public void setUp() throws Exception { () -> responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); client.mockAsyncRequest(base + "/version/openshift", () -> responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); - mapper = new ApiTypeMapper(base, client); + mapper = new ApiTypeMapper(base, client, null); } static class TestOkHttpClient extends OkHttpClient { diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java index 19746123..433d9965 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java @@ -55,7 +55,7 @@ public void testCanHandle() { @Test public void testHandleChallange() { Builder builder = new Request.Builder().url("http://foo"); - Request request = handler.handleChallange(builder).build(); + Request request = handler.handleChallenge(builder).build(); String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); @@ -65,7 +65,7 @@ public void testHandleChallange() { public void testHandleChallangeWhenUsernameIsNull() { when(context.getUserName()).thenReturn(null); Builder builder = new Request.Builder().url("http://foo"); - Request request = handler.handleChallange(builder).build(); + Request request = handler.handleChallenge(builder).build(); String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); diff --git a/src/test/resources/openshiftv3IntegrationTest.properties b/src/test/resources/openshiftv3IntegrationTest.properties index 7e9d4c5c..91c88221 100644 --- a/src/test/resources/openshiftv3IntegrationTest.properties +++ b/src/test/resources/openshiftv3IntegrationTest.properties @@ -1,9 +1,20 @@ -serverURL=https://192.168.64.69:8443 +# cdk +serverURL=https://192.168.64.91:8443 +default.clusteradmin.user=developer +default.clusteradmin.password=developer +# OS 4.1 +#serverURL= +#default.clusteradmin.user= +#default.clusteradmin.password= +# OS 3.11 #serverURL=https://console.rh-us-east-1.openshift.com - -default.clusteradmin.user=admin -default.clusteradmin.password=system +#default.clusteradmin.user= +#default.clusteradmin.password= +# OS 4.2 +#serverURL= +#default.clusteradmin.user= +#default.clusteradmin.password= integrationtest.project=int-test ocbinary.location=/usr/local/bin/oc From ba870db660f5abdb7a8ddbdd3c1d3c6497e9cced Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 11 Oct 2019 12:50:07 +0200 Subject: [PATCH 198/258] Added auth to ApiTypeMapper requests Signed-off-by: Andre Dietisheim --- .../internal/restclient/ApiTypeMapper.java | 12 +++++------- .../internal/restclient/DefaultClient.java | 3 ++- .../okhttp/OpenShiftAuthenticator.java | 6 +++--- .../okhttp/OpenShiftRequestBuilder.java | 18 ++++++++++-------- .../openshift/restclient/ClientBuilder.java | 10 ++-------- .../model/build/BuildConfigBuilderTest.java | 4 ++-- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index c824dd8d..07a9e4e2 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -265,13 +265,11 @@ private String readEndpoint(final String endpoint) { } private String request(final URL url) throws IOException { -// Request request = new OpenShiftRequestBuilder() -// .acceptJson() -// .authorization(authorizationContext) -// .builder() -// .url(url) -// .build(); - Request request = new Request.Builder().url(url).build(); + Request request = new OpenShiftRequestBuilder() + .url(url) + .acceptJson() + .authorization(authorizationContext) + .build(); try (Response response = client.newCall(request).execute()) { return response.body().string(); } diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 2d9bc930..b25bd905 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; @@ -662,7 +663,7 @@ public boolean equals(Object obj) { if (other.authContext == null) { return false; } - return ObjectUtils.equals(authContext.getUserName(), other.authContext.getUserName()); + return Objects.equals(authContext.getUserName(), other.authContext.getUserName()); } } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java index 8ae0e588..a1df0947 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java @@ -59,7 +59,7 @@ public Request authenticate(Route route, Response response) throws IOException { try (Response authResponse = tryAuth()) { if (authResponse == null || !authResponse.isSuccessful()) { - throw new UnauthorizedException(getAuthDetails(requestUrl), + throw new UnauthorizedException(getAuthorizationDetails(requestUrl), ResponseCodeInterceptor.getStatus(response.body().string())); } String token = getToken(authResponse); @@ -68,7 +68,7 @@ public Request authenticate(Route route, Response response) throws IOException { .authorization(token) .build(); } catch(OpenShiftException e) { - throw new UnauthorizedException(getAuthDetails(requestUrl), + throw new UnauthorizedException(getAuthorizationDetails(requestUrl), ResponseCodeInterceptor.getStatus(response.body().string())); } } @@ -121,7 +121,7 @@ public Request authenticate(Route route, Response response) throws IOException { .execute(); } - private IAuthorizationDetails getAuthDetails(String url) { + private IAuthorizationDetails getAuthorizationDetails(String url) { IAuthorizationDetails details = null; Map pairs = URIUtils.splitFragment(url); if (pairs.containsKey(ERROR)) { diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java index 92dec52a..e113c50a 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015-2018 Red Hat, Inc. + * Copyright (c) 2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -57,44 +57,46 @@ public OpenShiftRequestBuilder authorization(IAuthorizationContext authorization } public OpenShiftRequestBuilder authorization(String token) { + // Authenticator only gets triggered with a 401. + // We thus always use the token even if it's null so that we get a 401 instead of 403 in OS 4.2 builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, IHttpConstants.AUTHORIZATION_BEARER + " " + token); return this; } public OpenShiftRequestBuilder url(URL url) { - this.builder.url(url); + builder.url(url); return this; } public OpenShiftRequestBuilder url(String url) { - this.builder.url(url); + builder.url(url); return this; } public OpenShiftRequestBuilder method(String method, RequestBody body) { - this.builder.method(method, body); + builder.method(method, body); return this; } public OpenShiftRequestBuilder addHeader(String key, String value) { - this.builder.addHeader(key, value); + builder.addHeader(key, value); return this; } public OpenShiftRequestBuilder header(String key, String value) { - this.builder.header(key, value); + builder.header(key, value); return this; } public OpenShiftRequestBuilder tag(Object tag) { - this.builder.tag(tag); + builder.tag(tag); return this; } public Builder builder() { return builder; } - + public Request build() { return builder.build(); } diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index d7ff17d6..928f1656 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -29,6 +29,7 @@ import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; +import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import com.openshift.internal.restclient.DefaultClient; @@ -237,7 +238,7 @@ public IClient build() { OkHttpClient okClient = createOkHttpClient(trustManager, sslContext, responseCodeInterceptor, authenticator, dispatcher); - IResourceFactory factory = defaultIfNull(resourceFactory, new ResourceFactory(null)); + IResourceFactory factory = (IResourceFactory) ObjectUtils.defaultIfNull(resourceFactory, new ResourceFactory(null)); AuthorizationContext authContext = new AuthorizationContext(token, userName, password); DefaultClient client = new DefaultClient(new URL(this.baseUrl), okClient, factory, null, authContext); @@ -295,13 +296,6 @@ private OkHttpClient createOkHttpClient(X509TrustManager trustManager, SSLContex return builder.build(); } - private T defaultIfNull(T value, T theDefault) { - if (value != null) { - return value; - } - return theDefault; - } - private X509TrustManager getCurrentTrustManager(TrustManagerFactory trustManagerFactory) throws NoSuchAlgorithmException, KeyStoreException { for (TrustManager trustManager : trustManagerFactory.getTrustManagers()) { diff --git a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java index fc0e93eb..ea5f8a4f 100644 --- a/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/build/BuildConfigBuilderTest.java @@ -13,8 +13,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import java.util.Arrays; From a28e46cccd1a5bb691a60834196f2abd5bf00ad6 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 10 Oct 2019 22:35:47 +0200 Subject: [PATCH 199/258] fixed tests Signed-off-by: Andre Dietisheim --- .../internal/restclient/DefaultClient.java | 35 ++++--------------- .../okhttp/OpenShiftRequestBuilder.java | 2 +- .../okhttp/ResponseCodeInterceptor.java | 4 +-- .../restclient/okhttp/WatchClient.java | 15 ++++---- .../restclient/DefaultClientTest.java | 30 +++++----------- 5 files changed, 27 insertions(+), 59 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index b25bd905..92945bda 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -28,7 +28,6 @@ import java.util.concurrent.ExecutionException; import java.util.function.Consumer; -import org.apache.commons.lang.ObjectUtils; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.slf4j.Logger; @@ -302,12 +301,11 @@ private T execute(ITypeFactory factory, String method, String kind, String v .subContext(subContext) .addParameters(params) .build(); - Request request = new OpenShiftRequestBuilder() + Request request = newRequestBuilder() + .url(endpoint) + .method(method, requestBody) .acceptJson() .authorization(authContext) - .builder() - .method(method, requestBody) - .url(endpoint) .build(); LOGGER.debug("About to make {} request: {}", request.method(), request); try { @@ -383,25 +381,9 @@ public String getServerReadyStatus() { } } - public Builder newRequestBuilderTo(String endpoint) { - return newRequestBuilderTo(endpoint, MEDIATYPE_APPLICATION_JSON); - } - - public Builder newRequestBuilderTo(String endpoint, String acceptMediaType) { - Builder builder = new Builder() - .url(endpoint) - .header(PROPERTY_ACCEPT, acceptMediaType); - addAuthorizationHeader(builder); - return builder; - } - - private void addAuthorizationHeader(Builder builder) { - String token = null; - if (this.authContext != null && StringUtils.isNotBlank(this.authContext.getToken())) { - token = this.authContext.getToken(); - } - builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, - String.format("%s %s", IHttpConstants.AUTHORIZATION_BEARER, token)); + /* for debugging purposes */ + protected OpenShiftRequestBuilder newRequestBuilder() { + return new OpenShiftRequestBuilder(); } @Override @@ -687,9 +669,4 @@ public T adapt(Class klass) { } return null; } - - public OpenShiftRequestBuilder newRequestBuilder() { - return new OpenShiftRequestBuilder(); - } - } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java index e113c50a..baba4ba4 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java @@ -57,7 +57,7 @@ public OpenShiftRequestBuilder authorization(IAuthorizationContext authorization } public OpenShiftRequestBuilder authorization(String token) { - // Authenticator only gets triggered with a 401. + // Authenticator only gets triggered with a 401. // We thus always use the token even if it's null so that we get a 401 instead of 403 in OS 4.2 builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, IHttpConstants.AUTHORIZATION_BEARER + " " + token); return this; diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index 55c71078..2907f263 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -114,8 +114,8 @@ private static OpenShiftException createOpenShiftException(IClient client, Respo case STATUS_BAD_REQUEST: return new BadRequestException(e, status, response.request().url().toString()); case STATUS_FORBIDDEN: - return new ResourceForbiddenException(status != null ? - status.getMessage() : "Resource Forbidden", status, e); + return new ResourceForbiddenException( + status != null ? status.getMessage() : "Resource Forbidden", status, e); case STATUS_UNAUTHORIZED: String link = String.format("%s/oauth/token/request", client.getBaseURL()); AuthorizationDetails details = new AuthorizationDetails(response.headers(), link); diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java index 50aeb423..8ab9721d 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/WatchClient.java @@ -81,15 +81,18 @@ public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatc WatchEndpoint socket = new WatchEndpoint(client, listener, kind); final String resourceVersion = getResourceVersion(kind, namespace, socket); - final String endpoint = new URLBuilder(client.getBaseURL(), this.typeMappings).kind(kind) - .namespace(namespace).watch() + final String endpoint = new URLBuilder(client.getBaseURL(), this.typeMappings) + .kind(kind) + .namespace(namespace) + .watch() .addParmeter(ResourcePropertyKeys.RESOURCE_VERSION, resourceVersion).websocket(); Request request = new OpenShiftRequestBuilder() .url(endpoint) .acceptJson() .authorization(client.getAuthorizationContext()) .header(PROPERTY_ORIGIN, client.getBaseURL().toString()) - .header(PROPERTY_USER_AGENT, "openshift-restclient-java").build(); + .header(PROPERTY_USER_AGENT, "openshift-restclient-java") + .build(); okClient.newWebSocket(request, socket); endpointMap.put(kind, socket); } @@ -97,9 +100,9 @@ public IWatcher watch(Collection kinds, String namespace, IOpenShiftWatc } catch (Exception e) { endpointMap.clear(); status.set(Status.Stopped); - throw ResponseCodeInterceptor.createOpenShiftException(client, 0, - String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), - null, e); + throw ResponseCodeInterceptor.createOpenShiftException(client, 0, + String.format("Could not watch resources in namespace %s: %s", namespace, e.getMessage()), null, + e); } } return this; diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 1392e494..347d81fd 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2014-2018 Red Hat, Inc. + * Copyright (c) 2014-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -12,9 +12,9 @@ package com.openshift.internal.restclient; import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doAnswer; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -32,13 +32,12 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; import com.openshift.internal.restclient.DefaultClient.HttpMethod; import com.openshift.internal.restclient.authorization.AuthorizationContext; import com.openshift.internal.restclient.model.Pod; +import com.openshift.internal.restclient.okhttp.OpenShiftRequestBuilder; import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.ResourceKind; import com.openshift.restclient.api.ITypeFactory; @@ -269,7 +268,7 @@ public void should_not_send_resource_payload_when_deleting() throws IOException verify(builder).method(anyString(), bodyCaptor.capture()); assertThat(bodyCaptor.getValue().contentLength()).isEqualTo(0); } - + private String getPayload(Builder builder, ArgumentCaptor builderCaptor) throws IOException { verify(builder).method(anyString(), builderCaptor.capture()); RequestBody requestBody = builderCaptor.getValue(); @@ -282,20 +281,9 @@ private String getPayload(Builder builder, ArgumentCaptor builderCa } private Builder givenRequestBuilder(DefaultClient client) { - final Builder builder = spy(new Builder()); - doAnswer(new Answer() { - - @Override - public Builder answer(InvocationOnMock invocation) throws Throwable { - assertThat(invocation.getArguments()).isNotNull().hasSize(2); - - // set builder url that was given as parameter - String endpoint = (String) invocation.getArguments()[0]; - builder.url(endpoint); - return builder; - } - }) - .when(client).newRequestBuilderTo(anyString(), anyString()); + Builder builder = spy(new Builder()); + final OpenShiftRequestBuilder osBuilder = spy(new OpenShiftRequestBuilder(builder)); + doReturn(osBuilder).when(client).newRequestBuilder(); return builder; } From 3ec0790ee317331c99e72d2332a008b951156814 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 11 Oct 2019 15:38:42 +0200 Subject: [PATCH 200/258] Addressed sonar complaints Signed-off-by: Andre Dietisheim --- .../openshift/internal/restclient/ResourceFactory.java | 9 +++------ .../com/openshift/internal/restclient/model/Secret.java | 2 +- .../restclient/okhttp/OpenShiftRequestBuilder.java | 2 +- .../restclient/authorization/UnauthorizedException.java | 7 +++---- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java index e3f4e78a..04ed5a01 100644 --- a/src/main/java/com/openshift/internal/restclient/ResourceFactory.java +++ b/src/main/java/com/openshift/internal/restclient/ResourceFactory.java @@ -12,7 +12,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -58,7 +57,7 @@ public static Map> getImplMap() { public List createList(String json, String kind) { ModelNode data = ModelNode.fromJSONString(json); final String dataKind = data.get(KIND).asString(); - if (!(kind.toString() + "List").equals(dataKind)) { + if (!(kind + "List").equals(dataKind)) { throw new RuntimeException( String.format("Unexpected container type '%s' for desired kind: %s", dataKind, kind)); } @@ -71,9 +70,7 @@ public List createList(String json, String kind) { } } - private List buildList(final String version, List items, String kind) - throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, - IllegalArgumentException, InvocationTargetException { + private List buildList(final String version, List items, String kind) { List resources = new ArrayList(items.size()); for (ModelNode item : items) { resources.add(create(item, version, kind)); @@ -125,7 +122,7 @@ public T create(String version, String kind, String name) private IResource create(ModelNode node, String version, String kind) { try { node.get(APIVERSION).set(version); - node.get(KIND).set(kind.toString()); + node.get(KIND).set(kind); Map properyKeyMap = ResourcePropertiesRegistry.getInstance().get(version, kind); if (kind.endsWith("List")) { return new com.openshift.internal.restclient.model.List(node, client, properyKeyMap); diff --git a/src/main/java/com/openshift/internal/restclient/model/Secret.java b/src/main/java/com/openshift/internal/restclient/model/Secret.java index 3a176562..29f7c850 100644 --- a/src/main/java/com/openshift/internal/restclient/model/Secret.java +++ b/src/main/java/com/openshift/internal/restclient/model/Secret.java @@ -57,7 +57,7 @@ public byte[] getData(final String key) { @Override public void setType(final String type) { - get(SECRET_TYPE).set(type.toString()); + get(SECRET_TYPE).set(type); } @Override diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java index baba4ba4..e113c50a 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java @@ -57,7 +57,7 @@ public OpenShiftRequestBuilder authorization(IAuthorizationContext authorization } public OpenShiftRequestBuilder authorization(String token) { - // Authenticator only gets triggered with a 401. + // Authenticator only gets triggered with a 401. // We thus always use the token even if it's null so that we get a 401 instead of 403 in OS 4.2 builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, IHttpConstants.AUTHORIZATION_BEARER + " " + token); return this; diff --git a/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java b/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java index 9693cac0..49e165e2 100644 --- a/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java +++ b/src/main/java/com/openshift/restclient/authorization/UnauthorizedException.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -27,9 +27,8 @@ public UnauthorizedException(IAuthorizationDetails details) { } public UnauthorizedException(IAuthorizationDetails details, IStatus status) { - super(String.format( - "%s See the authorization details for additional information or contact your system administrator.", - MSG_BASE)); + super(MSG_BASE + + " See the authorization details for additional information or contact your system administrator."); this.status = status; this.details = details; if (details != null) { From 33b66b96fb6b397756f81f6eb8d19bb240d91e9d Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 14 Oct 2019 11:50:27 +0200 Subject: [PATCH 201/258] Using interceptor for authentication Signed-off-by: Andre Dietisheim --- .../internal/restclient/DefaultClient.java | 10 +- ...tor.java => AuthenticatorInterceptor.java} | 123 ++++++++++-------- ...andler.java => BasicChallengeHandler.java} | 11 +- .../okhttp/ResponseCodeInterceptor.java | 2 +- .../openshift/restclient/ClientBuilder.java | 15 +-- .../restclient/http/IHttpConstants.java | 3 + .../okhttp/BasicChallangeHandlerTest.java | 21 +-- .../openshiftv3IntegrationTest.properties | 6 +- 8 files changed, 106 insertions(+), 85 deletions(-) rename src/main/java/com/openshift/internal/restclient/okhttp/{OpenShiftAuthenticator.java => AuthenticatorInterceptor.java} (50%) rename src/main/java/com/openshift/internal/restclient/okhttp/{BasicChallangeHandler.java => BasicChallengeHandler.java} (75%) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 92945bda..52621590 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -71,6 +71,10 @@ */ public class DefaultClient implements IClient, IHttpConstants { + public static final String PATH_OAUTH_AUTHORIZATION_SERVER = ".well-known/oauth-authorization-server"; + public static final String PATH_KUBERNETES_VERSION = "version"; + public static final String PATH_OPENSHIFT_VERSION = "version/openshift"; + public static final String SYSTEM_PROP_K8E_API_VERSION = "osjc.k8e.apiversion"; public static final String SYSTEM_PROP_OPENSHIFT_API_VERSION = "osjc.openshift.apiversion"; @@ -102,9 +106,9 @@ public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, if (this.factory != null) { this.factory.setClient(this); } - initMasterVersion("version/openshift", new VersionCallback("OpenShift", version -> this.openShiftVersion = version)); - initMasterVersion("version", new VersionCallback("Kubernetes", version -> this.kubernetesVersion = version)); - initMasterVersion(".well-known/oauth-authorization-server", new AuthorizationCallback()); + initMasterVersion(PATH_OPENSHIFT_VERSION, new VersionCallback("OpenShift", version -> this.openShiftVersion = version)); + initMasterVersion(PATH_KUBERNETES_VERSION, new VersionCallback("Kubernetes", version -> this.kubernetesVersion = version)); + initMasterVersion(PATH_OAUTH_AUTHORIZATION_SERVER, new AuthorizationCallback()); this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client, authContext); this.authContext = authContext; } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java similarity index 50% rename from src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java rename to src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java index a1df0947..b6c10f7c 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftAuthenticator.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2019 Red Hat, Inc. + * Copyright (c) 2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -18,17 +18,19 @@ import java.util.Map; import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.authorization.AuthorizationDetails; import com.openshift.internal.util.URIUtils; import com.openshift.restclient.IClient; -import com.openshift.restclient.OpenShiftException; import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.authorization.IAuthorizationDetails; import com.openshift.restclient.authorization.UnauthorizedException; import com.openshift.restclient.http.IHttpConstants; import okhttp3.Authenticator; +import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Request.Builder; @@ -36,9 +38,12 @@ import okhttp3.Route; /** - * Adds authentication means to okhttp requests for use in OpenShift + * Adds authorization means to every request. Authorizes and retrieves the token + * if it's not present yet. */ -public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { +public class AuthenticatorInterceptor implements Interceptor, IHttpConstants { + + private static final Logger LOGGER = Logger.getLogger(AuthenticatorInterceptor.class); public static final String ACCESS_TOKEN = "access_token"; private static final String AUTH_ATTEMPTS = "X-OPENSHIFT-AUTH-ATTEMPTS"; @@ -46,45 +51,43 @@ public class OpenShiftAuthenticator implements Authenticator, IHttpConstants { private static final String ERROR = "error"; private static final String ERROR_DETAILS = "error_details"; - private Collection challangeHandlers = new ArrayList<>(); private IClient client; - + private Collection challangeHandlers = new ArrayList<>(); + @Override - public Request authenticate(Route route, Response response) throws IOException { - Request request = response.request(); - if (!unauthorizedForCluster(response, request)) { - return null; + public Response intercept(Chain chain) throws IOException { + Request request = chain.request(); + String url = request.url().toString(); + if (isUrlWithoutAuthorization(request, url)) { + return chain.proceed(request); } - String requestUrl = request.url().toString(); - try (Response authResponse = tryAuth()) { - if (authResponse == null - || !authResponse.isSuccessful()) { - throw new UnauthorizedException(getAuthorizationDetails(requestUrl), - ResponseCodeInterceptor.getStatus(response.body().string())); + IAuthorizationContext authorizationContext = client.getAuthorizationContext(); + if (StringUtils.isBlank(authorizationContext.getToken())) { + try (Response authResponse = authenticate()) { + if (authResponse == null + || !authResponse.isSuccessful()) { + throw new UnauthorizedException(getAuthorizationDetails(url), + authResponse == null ? null : ResponseCodeInterceptor.getStatus(authResponse.body().string())); + } + String token = getToken(authResponse); + setToken(token, client.getAuthorizationContext()); + request = new OpenShiftRequestBuilder(request.newBuilder()) + .acceptJson() + .authorization(authorizationContext) + .build(); } - String token = getToken(authResponse); - setToken(token, client.getAuthorizationContext()); - return new OpenShiftRequestBuilder(request.newBuilder()) - .authorization(token) - .build(); - } catch(OpenShiftException e) { - throw new UnauthorizedException(getAuthorizationDetails(requestUrl), - ResponseCodeInterceptor.getStatus(response.body().string())); } + return chain.proceed(request); } - private boolean unauthorizedForCluster(Response response, Request request) { - String requestHost = request.url().host(); - switch (response.code()) { - case IHttpConstants.STATUS_UNAUTHORIZED: - case IHttpConstants.STATUS_FORBIDDEN: - return client.getBaseURL().getHost().equals(requestHost); - default: - return false; - } + private boolean isUrlWithoutAuthorization(Request request, String url) { + return url.endsWith(DefaultClient.PATH_OPENSHIFT_VERSION) + || url.endsWith(DefaultClient.PATH_KUBERNETES_VERSION) + || url.endsWith(DefaultClient.PATH_OAUTH_AUTHORIZATION_SERVER) + || request.url().toString().startsWith(client.getAuthorizationEndpoint().toString()); } - private Response tryAuth() throws IOException { + private Response authenticate() throws IOException { OkHttpClient okClient = client.adapt(OkHttpClient.class); if (okClient == null) { return null; @@ -95,26 +98,7 @@ private Response tryAuth() throws IOException { + "?response_type=token&client_id=openshift-challenging-client").toString()) .build(); return okClient.newBuilder() - .authenticator(new Authenticator() { - - @Override - public Request authenticate(Route route, Response response) throws IOException { - if (StringUtils.isNotBlank(response.request().header(AUTH_ATTEMPTS))) { - return null; - } - if (StringUtils.isNotBlank(response.header(IHttpConstants.PROPERTY_WWW_AUTHENTICATE))) { - for (IChallangeHandler challangeHandler : challangeHandlers) { - if (!challangeHandler.canHandle(response.headers())) { - Builder requestBuilder = response.request().newBuilder() - .header(AUTH_ATTEMPTS, "1"); - response.close(); - return challangeHandler.handleChallenge(requestBuilder).build(); - } - } - } - return null; - } - }) + .authenticator(new OpenShiftAuthenticator()) .followRedirects(false) .build() .newCall(authRequest) @@ -147,7 +131,36 @@ private void setToken(String token, IAuthorizationContext authorizationContext) public void setClient(IClient client) { this.client = client; + initChallengeHandlers(client.getAuthorizationContext()); + } + + private void initChallengeHandlers(IAuthorizationContext context) { challangeHandlers.clear(); - challangeHandlers.add(new BasicChallangeHandler(client.getAuthorizationContext())); + challangeHandlers.add(new BasicChallengeHandler(context)); + } + + private final class OpenShiftAuthenticator implements Authenticator { + @Override + public Request authenticate(Route route, Response response) throws IOException { + if (StringUtils.isNotBlank(response.request().header(AUTH_ATTEMPTS))) { + return null; + } + if (StringUtils.isNotBlank(response.header(IHttpConstants.PROPERTY_WWW_AUTHENTICATE))) { + Request authenticationRequest = createAuthenticationRequest(response); + response.close(); + return authenticationRequest; + } + return null; + } + + private Request createAuthenticationRequest(Response response) { + for (IChallangeHandler challangeHandler : challangeHandlers) { + if (!challangeHandler.canHandle(response.headers())) { + Builder requestBuilder = response.request().newBuilder().header(AUTH_ATTEMPTS, "1"); + return challangeHandler.handleChallenge(requestBuilder).build(); + } + } + return null; + } } } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java similarity index 75% rename from src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java rename to src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java index 022c6f43..e1741adf 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java @@ -14,28 +14,29 @@ import org.apache.commons.lang.StringUtils; import com.openshift.restclient.authorization.IAuthorizationContext; +import com.openshift.restclient.http.IHttpConstants; import okhttp3.Credentials; import okhttp3.Headers; import okhttp3.Request.Builder; -public class BasicChallangeHandler implements IChallangeHandler { +public class BasicChallengeHandler implements IChallangeHandler { private IAuthorizationContext context; - public BasicChallangeHandler(IAuthorizationContext context) { + public BasicChallengeHandler(IAuthorizationContext context) { this.context = context; } @Override public boolean canHandle(Headers headers) { - return OpenShiftAuthenticator.AUTHORIZATION_BASIC - .equalsIgnoreCase(headers.get(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE)); + return IHttpConstants.AUTHORIZATION_BASIC + .equalsIgnoreCase(headers.get(IHttpConstants.PROPERTY_WWW_AUTHENTICATE)); } @Override public Builder handleChallenge(Builder builder) { - return builder.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION, + return builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, Credentials.basic( StringUtils.defaultIfBlank(context.getUserName(), ""), StringUtils.defaultIfBlank(context.getPassword(), ""))); diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index 2907f263..3c8b35d3 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -80,7 +80,7 @@ private Response makeSuccessIfAuthorized(final Response response) { Response returnedResponse = response; String location = response.header(PROPERTY_LOCATION); if (StringUtils.isNotBlank(location) - && URIUtils.splitFragment(location).containsKey(OpenShiftAuthenticator.ACCESS_TOKEN)) { + && URIUtils.splitFragment(location).containsKey(IHttpConstants.PROPERTY_ACCESS_TOKEN)) { returnedResponse = response.newBuilder() .request(response.request()) .code(STATUS_OK) diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 928f1656..b3f04cd5 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -35,7 +35,7 @@ import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.ResourceFactory; import com.openshift.internal.restclient.authorization.AuthorizationContext; -import com.openshift.internal.restclient.okhttp.OpenShiftAuthenticator; +import com.openshift.internal.restclient.okhttp.AuthenticatorInterceptor; import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; import com.openshift.restclient.http.IHttpConstants; import com.openshift.restclient.utils.SSLUtils; @@ -231,20 +231,20 @@ public IClient build() { X509TrustManager trustManager = getCurrentTrustManager(trustManagerFactory); SSLContext sslContext = SSLUtils.getSSLContext(trustManager); + AuthenticatorInterceptor authenticatorInterceptor = new AuthenticatorInterceptor(); ResponseCodeInterceptor responseCodeInterceptor = new ResponseCodeInterceptor(); - OpenShiftAuthenticator authenticator = new OpenShiftAuthenticator(); Dispatcher dispatcher = createDispatcher(); - OkHttpClient okClient = createOkHttpClient(trustManager, sslContext, responseCodeInterceptor, - authenticator, dispatcher); + OkHttpClient okClient = + createOkHttpClient(trustManager, sslContext, authenticatorInterceptor, responseCodeInterceptor, dispatcher); IResourceFactory factory = (IResourceFactory) ObjectUtils.defaultIfNull(resourceFactory, new ResourceFactory(null)); AuthorizationContext authContext = new AuthorizationContext(token, userName, password); DefaultClient client = new DefaultClient(new URL(this.baseUrl), okClient, factory, null, authContext); authContext.setClient(client); + authenticatorInterceptor.setClient(client); responseCodeInterceptor.setClient(client); - authenticator.setClient(client); factory.setClient(client); return client; } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException @@ -264,12 +264,11 @@ private Dispatcher createDispatcher() { } private OkHttpClient createOkHttpClient(X509TrustManager trustManager, SSLContext sslContext, - ResponseCodeInterceptor responseCodeInterceptor, OpenShiftAuthenticator authenticator, - Dispatcher dispatcher) { + AuthenticatorInterceptor authenticatorInterceptor, ResponseCodeInterceptor responseCodeInterceptor, Dispatcher dispatcher) { OkHttpClient.Builder builder = new OkHttpClient.Builder() .addNetworkInterceptor(new UserAgentInterceptor(userAgentPrefix)) .addInterceptor(responseCodeInterceptor) - .authenticator(authenticator) + .addInterceptor(authenticatorInterceptor) .dispatcher(dispatcher) .readTimeout(readTimeout, readTimeoutUnit) .writeTimeout(writeTimeout, writeTimeoutUnit) diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index 755efa62..8ac7d3bc 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -18,6 +18,7 @@ */ public interface IHttpConstants { + public static final int STATUS_UPGRADE_PROTOCOL = 101; public static final int STATUS_OK = 200; public static final int STATUS_MOVED_PERMANENTLY = 301; @@ -40,6 +41,7 @@ public interface IHttpConstants { public static final String PROPERTY_AUTHKEY = "broker_auth_key"; public static final String PROPERTY_AUTHIV = "broker_auth_iv"; + static final String PROPERTY_ACCESS_TOKEN = "access_token"; public static final String MEDIATYPE_ANY = "*/*"; public static final String MEDIATYPE_APPLICATION_JSON = "application/json"; @@ -66,4 +68,5 @@ public interface IHttpConstants { static final String PUT = "PUT"; static final String POST = "POST"; + } diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java index 433d9965..7539ad78 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java @@ -23,6 +23,7 @@ import org.mockito.junit.MockitoJUnitRunner; import com.openshift.restclient.authorization.IAuthorizationContext; +import com.openshift.restclient.http.IHttpConstants; import okhttp3.Headers; import okhttp3.Request; @@ -33,11 +34,11 @@ public class BasicChallangeHandlerTest { @Mock private IAuthorizationContext context; - private BasicChallangeHandler handler; + private BasicChallengeHandler handler; @Before public void setUp() throws Exception { - this.handler = new BasicChallangeHandler(context); + this.handler = new BasicChallengeHandler(context); when(context.getUserName()).thenReturn("username"); when(context.getPassword()).thenReturn("password"); @@ -45,10 +46,10 @@ public void setUp() throws Exception { @Test public void testCanHandle() { - assertTrue(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "basic"))); - assertTrue(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "bAsIC"))); - assertFalse(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, "foobar"))); - assertFalse(handler.canHandle(givenHeader(OpenShiftAuthenticator.PROPERTY_WWW_AUTHENTICATE, ""))); + assertTrue(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, "basic"))); + assertTrue(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, "bAsIC"))); + assertFalse(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, "foobar"))); + assertFalse(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, ""))); assertFalse(handler.canHandle(givenHeader("key", "value"))); } @@ -56,9 +57,9 @@ public void testCanHandle() { public void testHandleChallange() { Builder builder = new Request.Builder().url("http://foo"); Request request = handler.handleChallenge(builder).build(); - String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); + String authorization = request.header(IHttpConstants.PROPERTY_AUTHORIZATION); assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); - assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); + assertTrue("Exp. auth to be basic", authorization.startsWith(IHttpConstants.AUTHORIZATION_BASIC)); } @Test @@ -66,9 +67,9 @@ public void testHandleChallangeWhenUsernameIsNull() { when(context.getUserName()).thenReturn(null); Builder builder = new Request.Builder().url("http://foo"); Request request = handler.handleChallenge(builder).build(); - String authorization = request.header(OpenShiftAuthenticator.PROPERTY_AUTHORIZATION); + String authorization = request.header(IHttpConstants.PROPERTY_AUTHORIZATION); assertTrue("Exp. auth to not be blank", StringUtils.isNotBlank(authorization)); - assertTrue("Exp. auth to be basic", authorization.startsWith(OpenShiftAuthenticator.AUTHORIZATION_BASIC)); + assertTrue("Exp. auth to be basic", authorization.startsWith(IHttpConstants.AUTHORIZATION_BASIC)); } private Headers givenHeader(String name, String value) { diff --git a/src/test/resources/openshiftv3IntegrationTest.properties b/src/test/resources/openshiftv3IntegrationTest.properties index 91c88221..b7cef753 100644 --- a/src/test/resources/openshiftv3IntegrationTest.properties +++ b/src/test/resources/openshiftv3IntegrationTest.properties @@ -4,9 +4,9 @@ serverURL=https://192.168.64.91:8443 default.clusteradmin.user=developer default.clusteradmin.password=developer # OS 4.1 -#serverURL= -#default.clusteradmin.user= -#default.clusteradmin.password= +serverURL=https://api.crw.codereadyqe.com:6443 +default.clusteradmin.user=andre +default.clusteradmin.password=andre # OS 3.11 #serverURL=https://console.rh-us-east-1.openshift.com #default.clusteradmin.user= From 6258d33d4b737b176903f5b82f3fe7a1dd4e3583 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 15 Oct 2019 17:13:02 +0200 Subject: [PATCH 202/258] renamed IChallangeHandler -> IChallengeHandler Signed-off-by: Andre Dietisheim --- .../restclient/okhttp/AuthenticatorInterceptor.java | 4 ++-- .../internal/restclient/okhttp/BasicChallengeHandler.java | 2 +- .../{IChallangeHandler.java => IChallengeHandler.java} | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/main/java/com/openshift/internal/restclient/okhttp/{IChallangeHandler.java => IChallengeHandler.java} (89%) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java index b6c10f7c..03d83cd9 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java @@ -52,7 +52,7 @@ public class AuthenticatorInterceptor implements Interceptor, IHttpConstants { private static final String ERROR_DETAILS = "error_details"; private IClient client; - private Collection challangeHandlers = new ArrayList<>(); + private Collection challangeHandlers = new ArrayList<>(); @Override public Response intercept(Chain chain) throws IOException { @@ -154,7 +154,7 @@ public Request authenticate(Route route, Response response) throws IOException { } private Request createAuthenticationRequest(Response response) { - for (IChallangeHandler challangeHandler : challangeHandlers) { + for (IChallengeHandler challangeHandler : challangeHandlers) { if (!challangeHandler.canHandle(response.headers())) { Builder requestBuilder = response.request().newBuilder().header(AUTH_ATTEMPTS, "1"); return challangeHandler.handleChallenge(requestBuilder).build(); diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java index e1741adf..3e78e849 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java @@ -20,7 +20,7 @@ import okhttp3.Headers; import okhttp3.Request.Builder; -public class BasicChallengeHandler implements IChallangeHandler { +public class BasicChallengeHandler implements IChallengeHandler { private IAuthorizationContext context; diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/IChallengeHandler.java similarity index 89% rename from src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java rename to src/main/java/com/openshift/internal/restclient/okhttp/IChallengeHandler.java index 9be1979d..eddda45f 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/IChallangeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/IChallengeHandler.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -16,10 +16,10 @@ import okhttp3.Request.Builder; /** - * A challange handler that can retrieve a token + * A challenge handler that can retrieve a token * */ -interface IChallangeHandler { +interface IChallengeHandler { /** * Is able to handle a challange given the auth mechanism provided in the header From cc15a8a02bcb895786b084eecb27bb44a85f6fd2 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 16 Oct 2019 10:40:46 +0200 Subject: [PATCH 203/258] Allowed ITs to run against OS 3/4 online variants (#407) Signed-off-by: Andre Dietisheim --- pom.xml | 8 +- .../com/openshift/restclient/IClient.java | 1 - .../openshift/restclient/model/IEvent.java | 2 - .../restclient/model/ILimitRange.java | 2 - .../model/IReplicationController.java | 1 - .../restclient/model/IResourceQuota.java | 2 - .../DefaultClientConstructionTest.java | 14 +++- .../DefaultClientFilterIntegrationTest.java | 15 +--- .../DefaultClientIntegrationTest.java | 2 +- .../restclient/DefaultClientTest.java | 2 +- .../restclient/IntegrationTestHelper.java | 82 +++++++++++++++---- .../restclient/KubernetesVersionTest.java | 3 +- .../restclient/OpenShiftVersionTest.java | 3 +- .../restclient/ResourceFactoryTest.java | 4 +- .../restclient/TypeMapperFixture.java | 3 - .../capabilities/PodExecIntegrationTest.java | 15 +++- .../api/capabilities/PodExecTest.java | 1 - .../AuthorizationKindsIntegrationTest.java | 3 +- .../resources/AnnotationCapabilityTest.java | 2 +- .../BuildCapabilitiesIntegrationTest.java | 70 ++++++++++------ .../resources/DeployCapabilityTest.java | 2 +- .../DeploymentConfigTraceabilityTest.java | 2 +- .../resources/DeploymentTraceabilityTest.java | 2 +- .../ImageStreamImportCapabilityTest.java | 4 +- ...tBinaryPortForwardingIntegrationTest2.java | 2 +- .../OpenShiftBinaryPortForwardingTest.java | 4 +- .../resources/OpenShiftBinaryRSyncTest.java | 4 +- ...BinaryPodLogRetrievalIntegrationTest2.java | 2 +- ...ftBinaryRSyncRetrievalIntegrationTest.java | 15 +++- .../PodLogRetrievalAsyncIntegrationTest.java | 9 +- .../ProjectTemplateProcessingTest.java | 6 +- .../server/ConsoleIntegrationTest.java | 3 +- .../server/OpenShift3ConsoleTest.java | 2 +- .../server/OpenShift4ConsoleTest.java | 2 +- .../model/KubernetesResourceTest.java | 2 +- .../restclient/model/ProjectTest.java | 4 +- .../model/template/ParameterTest.java | 2 +- .../restclient/model/v1/BuildConfigTest.java | 4 +- .../restclient/model/v1/ConfigMapTest.java | 4 +- .../model/v1/DeploymentConfigTest.java | 2 +- .../restclient/model/v1/EndpointsTest.java | 3 +- .../model/v1/EnvironmentVariableTest.java | 2 +- .../internal/restclient/model/v1/PVCTest.java | 4 +- .../model/v1/PipelineBuildConfigTest.java | 6 +- .../internal/restclient/model/v1/PodTest.java | 2 +- .../model/v1/ReplicationControllerTest.java | 10 ++- .../restclient/model/v1/SecretTest.java | 2 - .../restclient/okhttp/WatchClientTest.java | 2 +- .../WatchClientIntegrationTest.java | 2 +- 49 files changed, 218 insertions(+), 127 deletions(-) diff --git a/pom.xml b/pom.xml index a06f1448..1211e24e 100755 --- a/pom.xml +++ b/pom.xml @@ -195,10 +195,10 @@ 3.0.0 test - - org.easytesting - fest-assert - 1.4 + + org.assertj + assertj-core + 3.13.2 test diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index 2d5954b2..cf69305b 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -16,7 +16,6 @@ import java.util.Map; import com.openshift.internal.restclient.KubernetesVersion; -import com.openshift.internal.restclient.OpenShiftMajorVersion; import com.openshift.restclient.api.ITypeFactory; import com.openshift.restclient.authorization.IAuthorizationContext; import com.openshift.restclient.capability.ICapable; diff --git a/src/main/java/com/openshift/restclient/model/IEvent.java b/src/main/java/com/openshift/restclient/model/IEvent.java index b6dc805e..c03b0340 100644 --- a/src/main/java/com/openshift/restclient/model/IEvent.java +++ b/src/main/java/com/openshift/restclient/model/IEvent.java @@ -11,8 +11,6 @@ package com.openshift.restclient.model; -import com.openshift.restclient.model.IResource; - public interface IEvent extends IResource { /** diff --git a/src/main/java/com/openshift/restclient/model/ILimitRange.java b/src/main/java/com/openshift/restclient/model/ILimitRange.java index 5fbac77d..8f9b8be4 100644 --- a/src/main/java/com/openshift/restclient/model/ILimitRange.java +++ b/src/main/java/com/openshift/restclient/model/ILimitRange.java @@ -11,8 +11,6 @@ package com.openshift.restclient.model; -import com.openshift.restclient.model.IResource; - public interface ILimitRange extends IResource { } diff --git a/src/main/java/com/openshift/restclient/model/IReplicationController.java b/src/main/java/com/openshift/restclient/model/IReplicationController.java index 019ab852..84aa6e04 100644 --- a/src/main/java/com/openshift/restclient/model/IReplicationController.java +++ b/src/main/java/com/openshift/restclient/model/IReplicationController.java @@ -15,7 +15,6 @@ import java.util.Set; import com.openshift.restclient.images.DockerImageURI; -import com.openshift.restclient.model.probe.IProbe; import com.openshift.restclient.model.volume.IVolumeSource; public interface IReplicationController extends IResource { diff --git a/src/main/java/com/openshift/restclient/model/IResourceQuota.java b/src/main/java/com/openshift/restclient/model/IResourceQuota.java index d8b28bde..c0ce547d 100644 --- a/src/main/java/com/openshift/restclient/model/IResourceQuota.java +++ b/src/main/java/com/openshift/restclient/model/IResourceQuota.java @@ -11,8 +11,6 @@ package com.openshift.restclient.model; -import com.openshift.restclient.model.IResource; - public interface IResourceQuota extends IResource { } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java index 78458190..72bb6647 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java @@ -1,6 +1,18 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ****************************************************************************** + */ + package com.openshift.internal.restclient; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java index 49d16162..f328be6d 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientFilterIntegrationTest.java @@ -10,6 +10,7 @@ package com.openshift.internal.restclient; import static com.openshift.restclient.ResourceKind.BUILD_CONFIG; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -112,11 +113,7 @@ public void testFilteringWithLabelNotExist() { Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); - assertEquals(3, list.size()); - assertTrue("Should contain build2", names.contains("build2")); - assertTrue("Should contain build3", names.contains("build3")); - assertTrue("Should contain build4", names.contains("build4")); - + assertThat(names).contains("build2", "build3", "build4").doesNotContain("build1"); } @Test @@ -125,17 +122,13 @@ public void testFilteringWithLabelNotEqualTo() { Set names = list.stream().map(IResource::getName).collect(Collectors.toSet()); - assertEquals(2, list.size()); - assertTrue("Should contain build2", names.contains("build2")); - assertTrue("Should contain build4", names.contains("build4")); + assertThat(names).contains("build2", "build4").doesNotContain("build1", "build3"); } @Test public void testFilteringWithLabelCombinedLabelQuery() { List list = client.list(BUILD_CONFIG, project.getNamespaceName(), "foo,bar=no"); - assertEquals(1, list.size()); - IBuildConfig bc = list.get(0); - assertEquals("build1", bc.getName()); + assertThat(list).allMatch(bc -> "build1".equals(bc.getName())); } } diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java index b043c9ef..b2d340a8 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientIntegrationTest.java @@ -10,7 +10,7 @@ package com.openshift.internal.restclient; import static com.openshift.internal.restclient.IntegrationTestHelper.MILLISECONDS_PER_SECOND; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 347d81fd..7af38f52 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -11,7 +11,7 @@ package com.openshift.internal.restclient; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.doReturn; diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index 25c1f438..733f8ce2 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -23,6 +23,13 @@ import java.util.Optional; import java.util.Properties; import java.util.Random; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -65,6 +72,11 @@ public class IntegrationTestHelper implements ResourcePropertyKeys { + public static final String IMAGE_HELLO_OPENSHIFT_ALPINE = "adietish/hello-openshift-alpine:0.3"; + public static final String IMAGE_HELLO_OPENSHIFT = "openshift/hello-openshift"; + + public static final String POD_NAME_DEFAULT = "test-pod"; + public static final long TEST_TIMEOUT = 6 * 1000; public static final long TEST_LONG_TIMEOUT = 3 * 60 * 1000; @@ -133,15 +145,21 @@ public IProject getOrCreateIntegrationTestProject(IClient client) { * @return the existing/new project */ public IProject getOrCreateProject(String name, IClient client) { - IProject project = null; + return getOrCreateResource( + () -> client.get(ResourceKind.PROJECT, name, ""), + () -> createProject(name, client)); + } + + private R getOrCreateResource(Supplier supplier, Supplier factory) { + R resource = null; try { - project = client.get(ResourceKind.PROJECT, name, ""); + resource = supplier.get(); } catch (NotFoundException | ResourceForbiddenException e) { // OS3: NotFoundException // OS4: ResourceForbiddenException - project = createProject(name, client); + resource = factory.get(); } - return project; + return resource; } public static String appendRandom(String string) { @@ -154,10 +172,14 @@ public static boolean isDockerRegistry(IPod pod, String podPrefix) { } private Optional getDockerRegistryPod(IClient client, String project, String podPrefix) { - List pods = client.list(ResourceKind.POD, project); - return pods.stream() - .filter(p -> isDockerRegistry(p, podPrefix)) - .findFirst(); + try { + List pods = client.list(ResourceKind.POD, project); + return pods.stream() + .filter(p -> isDockerRegistry(p, podPrefix)) + .findFirst(); + } catch (ResourceForbiddenException e) { + return Optional.empty(); + } } public IPod getDockerRegistryPod(IClient client) { @@ -168,7 +190,6 @@ public IPod getDockerRegistryPod(IClient client) { return pod.orElse(null); } - public Collection createResources(IClient client, R... resources) { if (ArrayUtils.isEmpty(resources)) { return Collections.emptyList(); @@ -186,8 +207,41 @@ public R createResource(IClient client, R resource) { return client.create(resource); } - public IPod createPod(IClient client, String namespace, String name) { - return client.create(stubPod(client, namespace, name)); + public IPod getPod(IClient client, String namespace, String name) { + return client.get(ResourceKind.POD, name, namespace); + } + + public IPod createPod(IClient client, String namespace, String name, String image) { + return client.create(stubPod(client, namespace, name, image)); + } + + public IPod getOrCreatePod(IClient client, String namespace, String image) { + return getOrCreatePod(client, namespace, POD_NAME_DEFAULT, image); + } + + public IPod getOrCreatePod(IClient client, String namespace, String name, String image) { + return getOrCreateResource( + () -> getPod(client, namespace, name), + () -> createPod(client, namespace, name, image)); + } + + public boolean waitForPodReady(IClient client, String namespace, String name, int timeout) throws InterruptedException, ExecutionException, TimeoutException { + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future podReady = executor.submit(() -> { + IPod pod = null; + try { + while (pod == null + || !pod.isReady()) { + pod = getPod(client, namespace, name); + Thread.sleep(2 * 1000); + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return pod.isReady(); + }); + return podReady.get(timeout, TimeUnit.SECONDS); } /** @@ -200,13 +254,13 @@ public IPod createPod(IClient client, String namespace, String name) { * * @return a pod definition that needs to be further created using the client */ - public IPod stubPod(IClient client, String namespace, String name) { + private IPod stubPod(IClient client, String namespace, String name, String image) { ModelNode builder = new ModelNodeBuilder().set(ResourcePropertyKeys.KIND, ResourceKind.POD) .set(ResourcePropertyKeys.METADATA_NAME, name) .set(ResourcePropertyKeys.METADATA_NAMESPACE, namespace) .add("spec.containers", - new ModelNodeBuilder().set(ResourcePropertyKeys.NAME, "hello-openshift") - .set("image", "openshift/hello-openshift") + new ModelNodeBuilder().set(ResourcePropertyKeys.NAME, name) + .set("image", image) .add("ports", new ModelNodeBuilder().set("containerPort", 8080).set("protocol", "TCP"))) .build(); return new Pod(builder, client, new HashMap<>()); diff --git a/src/test/java/com/openshift/internal/restclient/KubernetesVersionTest.java b/src/test/java/com/openshift/internal/restclient/KubernetesVersionTest.java index 1b10a00b..dbbb26b9 100644 --- a/src/test/java/com/openshift/internal/restclient/KubernetesVersionTest.java +++ b/src/test/java/com/openshift/internal/restclient/KubernetesVersionTest.java @@ -9,7 +9,8 @@ package com.openshift.internal.restclient; -import static org.fest.assertions.Assertions.assertThat; + +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; diff --git a/src/test/java/com/openshift/internal/restclient/OpenShiftVersionTest.java b/src/test/java/com/openshift/internal/restclient/OpenShiftVersionTest.java index 40ff6b5d..d61ee189 100644 --- a/src/test/java/com/openshift/internal/restclient/OpenShiftVersionTest.java +++ b/src/test/java/com/openshift/internal/restclient/OpenShiftVersionTest.java @@ -9,7 +9,8 @@ package com.openshift.internal.restclient; -import static org.fest.assertions.Assertions.assertThat; + +import static org.assertj.core.api.Assertions.assertThat; import org.junit.Test; diff --git a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java index 0e0f4dad..ac0e0cce 100644 --- a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java +++ b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java @@ -12,8 +12,8 @@ package com.openshift.internal.restclient; import static junit.framework.Assert.assertEquals; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 780cf162..65c237d1 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -12,7 +12,6 @@ package com.openshift.internal.restclient; import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; @@ -26,8 +25,6 @@ import org.junit.Before; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; -import org.mockito.Mockito; -import org.mockito.quality.Strictness; import org.mockito.stubbing.OngoingStubbing; import com.openshift.restclient.IApiTypeMapper; diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java index 5e2cf096..023edb1f 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecIntegrationTest.java @@ -33,11 +33,16 @@ import com.openshift.restclient.capability.CapabilityVisitor; import com.openshift.restclient.capability.IStoppable; import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IProject; public class PodExecIntegrationTest { + private static final int TIMEOUT_POD_READY = 30; + private IntegrationTestHelper helper = new IntegrationTestHelper(); + private IProject project; private IPod pod; + private IClient client; public static class TestExecListener implements IPodExec.IPodExecOutputListener { @@ -100,9 +105,13 @@ public void onFailure(Throwable t) { @Before public void setUp() throws Exception { - IClient client = helper.createClientForBasicAuth(); - this.pod = helper.getDockerRegistryPod(client); - assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); + this.client = helper.createClientForBasicAuth(); + this.project = helper.getOrCreateIntegrationTestProject(client); + this.pod = helper.getOrCreatePod(client, + project.getNamespaceName(), + IntegrationTestHelper.IMAGE_HELLO_OPENSHIFT_ALPINE); + assertNotNull("Could not create a pod to test against.", pod); + helper.waitForPodReady(client, pod.getNamespaceName(), pod.getName(), TIMEOUT_POD_READY); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java index 4d83d240..34d11569 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java @@ -25,7 +25,6 @@ import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.TypeMapperFixture; -import com.openshift.internal.restclient.api.capabilities.PodExec.ExecOutputListenerAdapter; import com.openshift.internal.restclient.capability.resources.PodLogRetrievalAsync; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.api.capabilities.IPodExec; diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java index 52b3ec35..8581a1e6 100644 --- a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationKindsIntegrationTest.java @@ -9,7 +9,8 @@ package com.openshift.internal.restclient.authorization; -import static org.fest.assertions.Assertions.assertThat; + +import static org.assertj.core.api.Assertions.assertThat; import java.util.List; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java index fd988cb5..fb28cb55 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/AnnotationCapabilityTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; import org.junit.Before; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java index 8a260e2f..fd9da3a9 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/BuildCapabilitiesIntegrationTest.java @@ -68,45 +68,53 @@ public void setUp() throws Exception { assertNotNull(bc); } + @After + public void tearDown() { + helper.cleanUpResources(client, bc, is); + } + @Test - public void testBuildActions() { - // trigger the build - LOG.debug("Triggering build from the buildconfig..."); - IBuild build = bc.accept(new CapabilityVisitor() { - @Override - public IBuild visit(IBuildTriggerable capability) { - return capability.trigger(); - } - }, null); - assertNotNull("Exp. to be able to trigger a build from a buildconfig", build); - LOG.debug("Triggered build {}", build); + public void shouldTriggerBuild() { + IBuild build = triggerBuild(bc); + assertNotNull("Exp. to be able to trigger a build from a buildconfig", build); + } - LOG.debug("Canceling the build..."); - // cancel the build - build = build.accept(new CapabilityVisitor() { + @Test + public void shouldCancelBuild() { + // given + final IBuild build = triggerBuild(bc); + // when + IBuild cancelledBuild = build.accept(new CapabilityVisitor() { @Override public IBuild visit(IBuildCancelable cap) { - return cap.cancel(); + // bug in 4.1? build needs to be refreshed + IBuild refreshedBuild = refresh(build); + refreshedBuild.cancel(); + return refreshedBuild; } }, null); - assertNotNull("Exp. to be able to cancel a build", build); - LOG.debug("Canceled build {}", build); + assertNotNull("Exp. to be able to cancel a build", cancelledBuild); + } - // trigger the build from a build - LOG.debug("Triggering build from a build..."); + @Test + public void shouldTriggerBuildFromBuild() { + // given + IBuild build = triggerBuild(bc); + // when build = build.accept(new CapabilityVisitor() { @Override public IBuild visit(IBuildTriggerable capability) { return capability.trigger(); } }, null); + // when assertNotNull("Exp. to be able to trigger a build from a build", build); - LOG.debug("Triggered build {}", build); + } - // add a build cause - LOG.debug("Triggering build with build cause..."); - build = build.accept(new CapabilityVisitor() { + @Test + public void shouldTriggerBuildWithCause() { + IBuild build = bc.accept(new CapabilityVisitor() { @Override public IBuild visit(IBuildTriggerable capability) { capability.addBuildCause("test cause"); @@ -114,12 +122,20 @@ public IBuild visit(IBuildTriggerable capability) { } }, null); assertNotNull("Exp. to be able to add a build cause for a build", build); - LOG.debug("Triggered build {}", build); } - @After - public void tearDown() { - helper.cleanUpResources(client, bc, is); + private IBuild refresh(IBuild build) { + return client.get(ResourceKind.BUILD, build.getName(), build.getNamespaceName()); + } + + private IBuild triggerBuild(IBuildConfig bc) { + IBuild build = bc.accept(new CapabilityVisitor() { + @Override + public IBuild visit(IBuildTriggerable capability) { + return capability.trigger(); + } + }, null); + return build; } } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java index 6134029d..d73de3d9 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java @@ -16,7 +16,7 @@ import static com.openshift.restclient.utils.ResourceTestHelper.thenResourceShouldBeUpdated; import static com.openshift.restclient.utils.ResourceTestHelper.thenResourceShouldNotBeUpdated; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java index 3fad06a9..600e7187 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentConfigTraceabilityTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java index bff0dc50..ec5cd0d6 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeploymentTraceabilityTest.java @@ -11,7 +11,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java index c8f074e4..68310d76 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityTest.java @@ -12,8 +12,8 @@ package com.openshift.internal.restclient.capability.resources; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java index 4011c0a0..6c32c538 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java @@ -48,7 +48,7 @@ public void setUp() throws Exception { System.setProperty(IBinaryCapability.OPENSHIFT_BINARY_LOCATION, helper.getOpenShiftLocation()); this.client = helper.createClientForBasicAuth(); this.project = helper.getOrCreateIntegrationTestProject(client); - IPod pod = helper.createPod(client, project.getNamespaceName(), IntegrationTestHelper.appendRandom("test-pod")); + IPod pod = helper.getOrCreatePod(client, project.getNamespaceName(), IntegrationTestHelper.IMAGE_HELLO_OPENSHIFT); this.pod = helper.waitForResource( client, pod, diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java index eaaee470..a1afcceb 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingTest.java @@ -19,8 +19,8 @@ import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockClient; import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockPod; import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockPortPair; -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.any; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java index 85106a0d..7b633017 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSyncTest.java @@ -18,8 +18,8 @@ import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.TOKEN; import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockClient; import static com.openshift.internal.restclient.capability.resources.testutils.BinaryCapabilityTestMocks.mockPod; -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.any; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest2.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest2.java index f45cd5c3..2ea67a5f 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest2.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryPodLogRetrievalIntegrationTest2.java @@ -42,7 +42,7 @@ public void before() { helper.setOpenShiftBinarySystemProperty(); this.client = helper.createClientForBasicAuth(); this.project = helper.getOrCreateIntegrationTestProject(client); - IPod pod = helper.createPod(client, project.getNamespaceName(), IntegrationTestHelper.appendRandom("test-pod")); + IPod pod = helper.getOrCreatePod(client, project.getNamespaceName(), IntegrationTestHelper.IMAGE_HELLO_OPENSHIFT); this.pod = helper.waitForResource( client, pod, diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java index e39f4085..91e725a5 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenshiftBinaryRSyncRetrievalIntegrationTest.java @@ -11,7 +11,7 @@ package com.openshift.internal.restclient.capability.resources; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -44,6 +44,7 @@ import com.openshift.restclient.capability.resources.IRSyncable.Peer; import com.openshift.restclient.capability.resources.IRSyncable.PodPeer; import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IProject; /** * @@ -51,6 +52,8 @@ * */ public class OpenshiftBinaryRSyncRetrievalIntegrationTest { + private static final int TIMEOUT_POD_READY = 30; + // rsync now reports special characters as octal UTF-8: 'é' -> octal utf8: \\0303\\0251, hex utf8: \u00e9 private static final String TARGET_FOLDER_WITH_SPECIAL_CHARS = "/tmp/OpenshiftBinaryRSyncRetrievalIntegrationTest/with sp@ce/"; private static final String FILE_NAME_SPECIAL_CHARS = "test with speci@l characters and spaces"; @@ -68,6 +71,7 @@ public class OpenshiftBinaryRSyncRetrievalIntegrationTest { @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); + private IProject project; private IPod pod; private String podFolderToClean; @@ -76,8 +80,13 @@ public void setUp() throws Exception { // given this.helper.setOpenShiftBinarySystemProperty(); this.client = helper.createClientForBasicAuth(); - this.pod = helper.getDockerRegistryPod(client); - assertNotNull("Did not find the registry pod to which to rsync", pod); + this.project = helper.getOrCreateIntegrationTestProject(client); + this.pod = helper.getOrCreatePod(client, + project.getNamespaceName(), + getClass().getSimpleName().toLowerCase() + "-pod", + IntegrationTestHelper.IMAGE_HELLO_OPENSHIFT_ALPINE); + assertNotNull("Could not create a pod to test against.", pod); + helper.waitForPodReady(client, pod.getNamespaceName(), pod.getName(), TIMEOUT_POD_READY); } @After diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java index 1d981539..2b5db24d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncIntegrationTest.java @@ -29,6 +29,7 @@ import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.IPodLogListener; import com.openshift.restclient.capability.resources.IPodLogRetrievalAsync.Options; import com.openshift.restclient.model.IPod; +import com.openshift.restclient.model.IProject; public class PodLogRetrievalAsyncIntegrationTest { @@ -41,8 +42,12 @@ public class PodLogRetrievalAsyncIntegrationTest { public void testAsyncLogRetrieval() throws Exception { latch = new CountDownLatch(2); DefaultClient client = (DefaultClient) helper.createClientForBasicAuth(); - IPod pod = helper.getDockerRegistryPod(client); - assertNotNull("Need a pod to continue the test. Expected to find the registry", pod); + IProject project = helper.getOrCreateIntegrationTestProject(client); + IPod pod = helper.getOrCreatePod(client, + project.getNamespaceName(), + getClass().getSimpleName().toLowerCase() + "-pod", + IntegrationTestHelper.IMAGE_HELLO_OPENSHIFT_ALPINE); + assertNotNull("Could not create a pod to test against.", pod); final String container = pod.getContainers().iterator().next().getName(); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java index 892659c8..ee93a431 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ProjectTemplateProcessingTest.java @@ -12,9 +12,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/ConsoleIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/ConsoleIntegrationTest.java index 36af4527..35a34864 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/ConsoleIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/ConsoleIntegrationTest.java @@ -9,7 +9,8 @@ package com.openshift.internal.restclient.capability.server; -import static org.fest.assertions.Assertions.assertThat; + +import static org.assertj.core.api.Assertions.assertThat; import java.net.MalformedURLException; diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift3ConsoleTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift3ConsoleTest.java index 174b16e1..3ce0cdf7 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift3ConsoleTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift3ConsoleTest.java @@ -9,7 +9,7 @@ package com.openshift.internal.restclient.capability.server; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doReturn; diff --git a/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift4ConsoleTest.java b/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift4ConsoleTest.java index c92c6273..5395aef1 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift4ConsoleTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/server/OpenShift4ConsoleTest.java @@ -9,7 +9,7 @@ package com.openshift.internal.restclient.capability.server; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; diff --git a/src/test/java/com/openshift/internal/restclient/model/KubernetesResourceTest.java b/src/test/java/com/openshift/internal/restclient/model/KubernetesResourceTest.java index 5b63ce3e..b163136a 100644 --- a/src/test/java/com/openshift/internal/restclient/model/KubernetesResourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/KubernetesResourceTest.java @@ -10,7 +10,7 @@ package com.openshift.internal.restclient.model; import static com.openshift.internal.util.JBossDmrExtentions.getPath; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; diff --git a/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java b/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java index 13617ccb..1e2c89e6 100644 --- a/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/ProjectTest.java @@ -10,8 +10,8 @@ package com.openshift.internal.restclient.model; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/model/template/ParameterTest.java b/src/test/java/com/openshift/internal/restclient/model/template/ParameterTest.java index 18a0c033..f39f331b 100644 --- a/src/test/java/com/openshift/internal/restclient/model/template/ParameterTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/template/ParameterTest.java @@ -4,7 +4,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import org.fest.assertions.Assertions; +import org.assertj.core.api.Assertions; import org.jboss.dmr.ModelNode; import org.junit.Test; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java index ebce4e6b..fbcebc74 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/BuildConfigTest.java @@ -12,8 +12,8 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java index 4e7c8c02..7df2d7e1 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ConfigMapTest.java @@ -10,8 +10,8 @@ package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java index 546eaf7c..b8f77e4d 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/DeploymentConfigTest.java @@ -10,7 +10,7 @@ package com.openshift.internal.restclient.model.v1; import static com.openshift.internal.util.JBossDmrExtentions.getPath; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java index 4ff164d6..4d2a27b7 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EndpointsTest.java @@ -11,7 +11,8 @@ package com.openshift.internal.restclient.model.v1; -import static org.fest.assertions.Assertions.assertThat; + +import static org.assertj.core.api.Assertions.assertThat; import java.util.List; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java index 33e69d0c..89e6b088 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EnvironmentVariableTest.java @@ -9,7 +9,7 @@ package com.openshift.internal.restclient.model.v1; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import java.util.ArrayList; import java.util.Collection; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java index 70b148b9..3551ba85 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PVCTest.java @@ -11,8 +11,8 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java index fc6a3c79..b973213d 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PipelineBuildConfigTest.java @@ -9,9 +9,9 @@ package com.openshift.internal.restclient.model.v1; -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java index 81ae8acb..f0e85cc7 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PodTest.java @@ -9,7 +9,7 @@ package com.openshift.internal.restclient.model.v1; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java index d098f7ab..9f24cbfc 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java @@ -10,8 +10,8 @@ package com.openshift.internal.restclient.model.v1; import static com.openshift.internal.util.JBossDmrExtentions.getPath; -import static org.fest.assertions.Assertions.assertThat; -import static org.fest.assertions.MapAssert.entry; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -307,8 +307,10 @@ public void testAddContainerAllowsContainerToBeFurtherManipulated() throws JSONE @Test public void shouldReturnTemplateLabels() { Map labels = rc.getTemplateLabels(); - assertThat(labels).hasSize(3).includes(entry("deployment", "database-1")) - .includes(entry("deploymentconfig", "database")).includes(entry("name", "database")); + assertThat(labels).hasSize(3) + .contains(entry("deployment", "database-1")) + .contains(entry("deploymentconfig", "database")) + .contains(entry("name", "database")); } @Test diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java index 77a16a80..26191fce 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/SecretTest.java @@ -10,12 +10,10 @@ package com.openshift.internal.restclient.model.v1; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import java.io.ByteArrayInputStream; -import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java index 534a5f0d..b3686784 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java @@ -14,7 +14,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; diff --git a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java index c1e148af..9b84b482 100644 --- a/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java +++ b/src/test/java/com/openshift/restclient/WatchClientIntegrationTest.java @@ -11,7 +11,7 @@ package com.openshift.restclient; -import static org.fest.assertions.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; From ff60454e6555d75b0b62a82f6ac6baf5839b1cb8 Mon Sep 17 00:00:00 2001 From: Jonas Berlin Date: Mon, 21 Oct 2019 10:27:19 +0300 Subject: [PATCH 204/258] Update IClient.java Some javadoc fixes --- src/main/java/com/openshift/restclient/IClient.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index cf69305b..9af142c8 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -31,7 +31,7 @@ public interface IClient extends ICapable, Cloneable { /* - * Watch for changes + * Watch for changes scoped to a specific namespace * * @param namespace The namespace to watch for changes in * @@ -43,10 +43,8 @@ public interface IClient extends ICapable, Cloneable { IWatcher watch(String namespace, IOpenShiftWatchListener listener, String... kinds); /* - * Watch for changes + * Watch for changes in the default namespace * - * @param namespace The namespace to watch for changes in - * * @param listener The listener to be notified on events * * @param kids The kinds to watch for @@ -62,7 +60,7 @@ public interface IClient extends ICapable, Cloneable { List list(String kind); /** - * Lists the given given resource kind scoping it to a specific namespace + * Lists the given given resource kind in the default namespace * * @param kind * @param labels From 29ec88d12458fde1fa0c91c13d56fecddac03234 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 23 Oct 2019 15:32:19 +0200 Subject: [PATCH 205/258] bumped to 8.1.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1211e24e..081b23a4 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.1.0-SNAPSHOT + 8.1.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From 1a66d549c511d0ad689cca0ddf8fcc915bfaad46 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 23 Oct 2019 21:16:58 +0200 Subject: [PATCH 206/258] bumped to 8.1.1-SNAPSHOT after release of 8.1.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 081b23a4..216260a5 100755 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.1.0.Final + 8.1.1-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 1779b0d6b7849e6f61f229ab40cd044ee8af5c31 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 29 Oct 2019 19:40:05 +0100 Subject: [PATCH 207/258] /healthz shold not trigger authentication Signed-off-by: Andre Dietisheim --- .../com/openshift/internal/restclient/DefaultClient.java | 6 ++---- .../restclient/okhttp/AuthenticatorInterceptor.java | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 52621590..d08cb232 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -74,12 +74,12 @@ public class DefaultClient implements IClient, IHttpConstants { public static final String PATH_OAUTH_AUTHORIZATION_SERVER = ".well-known/oauth-authorization-server"; public static final String PATH_KUBERNETES_VERSION = "version"; public static final String PATH_OPENSHIFT_VERSION = "version/openshift"; + public static final String URL_HEALTH_CHECK = "healthz"; + private static final String OS_API_ENDPOINT = "oapi"; public static final String SYSTEM_PROP_K8E_API_VERSION = "osjc.k8e.apiversion"; public static final String SYSTEM_PROP_OPENSHIFT_API_VERSION = "osjc.openshift.apiversion"; - private static final String URL_HEALTH_CHECK = "healthz"; - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); private URL baseUrl; private CompletableFuture authorizationEndpoint = new CompletableFuture<>(); @@ -90,8 +90,6 @@ public class DefaultClient implements IClient, IHttpConstants { private Map, ICapability> capabilities = new HashMap<>(); private boolean capabilitiesInitialized = false; - private static final String OS_API_ENDPOINT = "oapi"; - private String openShiftVersion; private String kubernetesVersion; private AuthorizationContext authContext; diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java index 03d83cd9..b1567239 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java @@ -84,7 +84,8 @@ private boolean isUrlWithoutAuthorization(Request request, String url) { return url.endsWith(DefaultClient.PATH_OPENSHIFT_VERSION) || url.endsWith(DefaultClient.PATH_KUBERNETES_VERSION) || url.endsWith(DefaultClient.PATH_OAUTH_AUTHORIZATION_SERVER) - || request.url().toString().startsWith(client.getAuthorizationEndpoint().toString()); + || request.url().toString().startsWith(client.getAuthorizationEndpoint().toString()) + || url.endsWith(DefaultClient.URL_HEALTH_CHECK); } private Response authenticate() throws IOException { From dfac31b84a28f295a248e447f5b5f0409dd06582 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 25 Oct 2019 16:26:12 +0200 Subject: [PATCH 208/258] lazily requesting k8-,os-version & auth-,token-endpoint Signed-off-by: Andre Dietisheim --- .../internal/restclient/DefaultClient.java | 251 ++++++++++-------- .../okhttp/AuthenticatorInterceptor.java | 2 +- .../AuthorizationEndpointsTest.java | 65 +++++ ...tionTest.java => ClusterVersionsTest.java} | 41 +-- .../restclient/TypeMapperFixture.java | 8 +- .../api/capabilities/PodExecTest.java | 6 +- .../resources/PodLogRetrievalAsyncTest.java | 4 +- .../openshift/restclient/utils/Samples.java | 3 +- ...well_known_oauth_authorization_server.json | 24 ++ 9 files changed, 265 insertions(+), 139 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/AuthorizationEndpointsTest.java rename src/test/java/com/openshift/internal/restclient/{DefaultClientConstructionTest.java => ClusterVersionsTest.java} (55%) create mode 100644 src/test/resources/samples/openshift3/api_well_known_oauth_authorization_server.json diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index d08cb232..dc0ac6e5 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -24,9 +24,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; @@ -54,8 +53,6 @@ import com.openshift.restclient.model.IResource; import com.openshift.restclient.model.JSONSerializeable; -import okhttp3.Call; -import okhttp3.Callback; import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -71,29 +68,29 @@ */ public class DefaultClient implements IClient, IHttpConstants { + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); + public static final String PATH_OAUTH_AUTHORIZATION_SERVER = ".well-known/oauth-authorization-server"; public static final String PATH_KUBERNETES_VERSION = "version"; public static final String PATH_OPENSHIFT_VERSION = "version/openshift"; - public static final String URL_HEALTH_CHECK = "healthz"; - private static final String OS_API_ENDPOINT = "oapi"; + public static final String PATH_HEALTH_CHECK = "healthz"; public static final String SYSTEM_PROP_K8E_API_VERSION = "osjc.k8e.apiversion"; public static final String SYSTEM_PROP_OPENSHIFT_API_VERSION = "osjc.openshift.apiversion"; - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); + private static final String OS_API_ENDPOINT = "oapi"; + private URL baseUrl; - private CompletableFuture authorizationEndpoint = new CompletableFuture<>(); - private CompletableFuture tokenEndpoint = new CompletableFuture<>(); - private OkHttpClient client; private IResourceFactory factory; private Map, ICapability> capabilities = new HashMap<>(); private boolean capabilitiesInitialized = false; - private String openShiftVersion; - private String kubernetesVersion; - private AuthorizationContext authContext; - private IApiTypeMapper typeMapper; + private final AuthorizationContext authContext; + private final IApiTypeMapper typeMapper; + private final ClusterVersion kubernetesVersion; + private final ClusterVersion openShiftVersion; + private final AuthorizationEndpoints authorizationEndpoints; private OpenShiftMajorVersion openShiftMajorVersion; public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, IApiTypeMapper typeMapper, @@ -104,11 +101,11 @@ public DefaultClient(URL baseUrl, OkHttpClient client, IResourceFactory factory, if (this.factory != null) { this.factory.setClient(this); } - initMasterVersion(PATH_OPENSHIFT_VERSION, new VersionCallback("OpenShift", version -> this.openShiftVersion = version)); - initMasterVersion(PATH_KUBERNETES_VERSION, new VersionCallback("Kubernetes", version -> this.kubernetesVersion = version)); - initMasterVersion(PATH_OAUTH_AUTHORIZATION_SERVER, new AuthorizationCallback()); this.typeMapper = typeMapper != null ? typeMapper : new ApiTypeMapper(baseUrl.toString(), client, authContext); this.authContext = authContext; + this.kubernetesVersion = new ClusterVersion(baseUrl.toExternalForm() + "/" + PATH_KUBERNETES_VERSION, "Kubernetes Version", client); + this.openShiftVersion = new ClusterVersion(baseUrl.toExternalForm() + "/" + PATH_OPENSHIFT_VERSION, "OpenShift Version", client); + this.authorizationEndpoints = new AuthorizationEndpoints(baseUrl.toExternalForm(), client); } @Override @@ -373,7 +370,7 @@ private boolean isPayloadlessMethod(String method) { public String getServerReadyStatus() { try { Request request = new Request.Builder() - .url(new URL(this.baseUrl, URL_HEALTH_CHECK)) + .url(new URL(this.baseUrl, PATH_HEALTH_CHECK)) .header(PROPERTY_ACCEPT, "*/*") .build(); return request(request); @@ -454,86 +451,14 @@ public String getOpenShiftAPIVersion() { return typeMapper.getPreferedVersionFor(OS_API_ENDPOINT); } - private void initMasterVersion(String versionInfoType, Callback callback) { - try { - Request request = new Builder().url(new URL(this.baseUrl, versionInfoType)) - .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON) - .tag(new ResponseCodeInterceptor.Ignore() {}) - .build(); - client.newCall(request).enqueue(callback); - } catch (IOException e) { - LOGGER.warn("Exception while trying to determine master version of openshift and kubernetes", e); - } - } - - private class VersionCallback implements Callback { - String description; - Consumer versionSetter; - - public VersionCallback(String description, Consumer versionSetter) { - this.description = description; - this.versionSetter = versionSetter; - } - - @Override - public void onFailure(Call call, IOException e) { - versionSetter.accept(""); - LOGGER.warn("Exception while trying to determine {} master version", description, e); - } - - @Override - public void onResponse(Call call, Response response) throws IOException { - try { - if (response.isSuccessful()) { - versionSetter.accept(ModelNode.fromJSONString(response.body().string()).get("gitVersion").asString()); - } else { - versionSetter.accept(""); - LOGGER.warn("Failed to determine {} master version: got {}", description, response.code()); - } - } finally { - response.close(); - } - } - } - - private class AuthorizationCallback implements Callback { - - private void setDefaults() { - DefaultClient.this.authorizationEndpoint.complete(DefaultClient.this.getDefaultAuthorizationEndpoint()); - DefaultClient.this.tokenEndpoint.complete(DefaultClient.this.getDefaultTokenEndpoint()); - } - - @Override - public void onFailure(Call call, IOException e) { - setDefaults(); - LOGGER.warn("Exception while trying to get authorization endpoint", e); - } - - @Override - public void onResponse(Call call, Response response) throws IOException { - try { - if (response.isSuccessful()) { - ModelNode node = ModelNode.fromJSONString(response.body().string()); - DefaultClient.this.authorizationEndpoint.complete(new URL(node.get("authorization_endpoint").asString())); - DefaultClient.this.tokenEndpoint.complete(new URL(node.get("token_endpoint").asString())); - } else { - setDefaults(); - LOGGER.warn("Failed to determine authorization endpoint: got {}", response.code()); - } - } finally { - response.close(); - } - } - } - @Override public String getOpenshiftMasterVersion() { - return this.openShiftVersion; + return openShiftVersion.get(); } @Override public String getKubernetesMasterVersion() { - return this.kubernetesVersion; + return kubernetesVersion.get(); } @Override @@ -543,11 +468,7 @@ public URL getBaseURL() { @Override public URL getAuthorizationEndpoint() { - try { - return authorizationEndpoint.get(); - } catch (InterruptedException | ExecutionException e) { - throw new OpenShiftException(e, e.getLocalizedMessage()); - } + return authorizationEndpoints.getAuthorizationEndpoint(); } protected URL getDefaultAuthorizationEndpoint() { @@ -560,11 +481,7 @@ protected URL getDefaultAuthorizationEndpoint() { @Override public URL getTokenEndpoint() { - try { - return tokenEndpoint.get(); - } catch (InterruptedException | ExecutionException e) { - throw new OpenShiftException(e, e.getLocalizedMessage()); - } + return authorizationEndpoints.getTokenEndpoint(); } protected URL getDefaultTokenEndpoint() { @@ -627,20 +544,6 @@ public boolean equals(Object obj) { } else if (!baseUrl.toString().equals(other.baseUrl.toString())) { return false; } - if (kubernetesVersion == null) { - if (other.kubernetesVersion != null) { - return false; - } - } else if (!kubernetesVersion.equals(other.kubernetesVersion)) { - return false; - } - if (openShiftVersion == null) { - if (other.openShiftVersion != null) { - return false; - } - } else if (!openShiftVersion.equals(other.openShiftVersion)) { - return false; - } if (authContext == null) { return other.authContext == null; } else { @@ -671,4 +574,118 @@ public T adapt(Class klass) { } return null; } + + private abstract static class RequestingSupplier implements Supplier { + + private String url; + protected String description; + private OkHttpClient client; + + private boolean requested = false; + private T value; + + protected RequestingSupplier(String url, String description, OkHttpClient client) { + this.url = url; + this.description = description; + this.client = client; + this.value = getDefaultValue(); + } + + @Override + public T get() { + return requestIfRequired(); + } + + private T requestIfRequired() { + if (!requested) { + this.value = request(url); + } + return value; + } + + protected T request(String url) { + Request request = new Builder() + .url(url) + .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON) + .tag(new ResponseCodeInterceptor.Ignore() {}) + .build(); + try (Response response = client.newCall(request).execute()) { + this.requested = true; + if (response != null + && response.isSuccessful()) { + this.value = extractValue(response.body().string()); + } else { + LOGGER.error("Failed to determine {}: got {}", description, + response == null ? "null" : response.code()); + } + } catch (IOException | IllegalArgumentException e) { + LOGGER.error("Failed to determine {}.", description, e); + } + return this.value; + } + + protected abstract T getDefaultValue(); + + protected abstract T extractValue(String response) throws IOException; + } + + private class ClusterVersion extends RequestingSupplier { + + protected ClusterVersion(String url, String description, OkHttpClient client) { + super(url, description, client); + } + + @Override + protected String extractValue(String response) { + return ModelNode.fromJSONString(response).get("gitVersion").asString(); + } + + @Override + protected String getDefaultValue() { + return ""; + } + } + + private class AuthorizationEndpoints { + + private RequestingSupplier endpointsSupplier; + + protected AuthorizationEndpoints(String baseUrl, OkHttpClient client) { + + this.endpointsSupplier = new RequestingSupplier(baseUrl + "/" + PATH_OAUTH_AUTHORIZATION_SERVER, "authorization- & token-endpoint", client) { + @Override + protected ModelNode extractValue(String response) throws IOException { + return ModelNode.fromJSONString(response); + } + + @Override + protected ModelNode getDefaultValue() { + return null; + } + }; + } + + public URL getAuthorizationEndpoint() { + return getEndpoint(node -> node.get("authorization_endpoint").asString(), "token_endpoint"); + } + + public URL getTokenEndpoint() { + return getEndpoint(node -> node.get("token_endpoint").asString(), "token-endpoint"); + } + + private URL getEndpoint(Function extractor, String description) { + URL authorizationEndpoint = null; + ModelNode node = endpointsSupplier.get(); + if (node != null) { + try { + authorizationEndpoint = new URL(extractor.apply(node)); + } catch (MalformedURLException e) { + LOGGER.error("Failed to determine {}.", description, e); + } + } + return authorizationEndpoint; + + } + } + } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java index b1567239..1eaa6e91 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java @@ -85,7 +85,7 @@ private boolean isUrlWithoutAuthorization(Request request, String url) { || url.endsWith(DefaultClient.PATH_KUBERNETES_VERSION) || url.endsWith(DefaultClient.PATH_OAUTH_AUTHORIZATION_SERVER) || request.url().toString().startsWith(client.getAuthorizationEndpoint().toString()) - || url.endsWith(DefaultClient.URL_HEALTH_CHECK); + || url.endsWith(DefaultClient.PATH_HEALTH_CHECK); } private Response authenticate() throws IOException { diff --git a/src/test/java/com/openshift/internal/restclient/AuthorizationEndpointsTest.java b/src/test/java/com/openshift/internal/restclient/AuthorizationEndpointsTest.java new file mode 100644 index 00000000..6708ac15 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/AuthorizationEndpointsTest.java @@ -0,0 +1,65 @@ +/******************************************************************************* + * Copyright (c) 2019 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ****************************************************************************** + */ + +package com.openshift.internal.restclient; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URL; + +import org.junit.Test; + +import com.openshift.restclient.utils.Samples; + +public class AuthorizationEndpointsTest extends TypeMapperFixture { + + @Test + public void shouldRetrieveAuthorizationEndpoint() throws Exception { + getHttpClient().whenRequestTo(base + "/.well-known/oauth-authorization-server", + responseOf(Samples.WELL_KNOW_OAUTH_AUTHORIZATION_SERVER.getContentAsString())); + + URL authorizationEndpoint = getIClient().getAuthorizationEndpoint(); + assertThat(authorizationEndpoint).isNotNull(); + assertThat(authorizationEndpoint.toExternalForm()).isEqualTo( + "https://api.rh-us-east-1.openshift.com/oauth/authorize"); + } + + @Test + public void shouldRetrieveTokenEndpoint() throws Exception { + getHttpClient().whenRequestTo(base + "/.well-known/oauth-authorization-server", + responseOf(Samples.WELL_KNOW_OAUTH_AUTHORIZATION_SERVER.getContentAsString())); + + URL tokenEndpoint = getIClient().getTokenEndpoint(); + assertThat(tokenEndpoint).isNotNull(); + assertThat(tokenEndpoint.toExternalForm()).isEqualTo( + "https://api.rh-us-east-1.openshift.com/oauth/token"); + } + + @Test + public void shouldReturnNullifAuthorizationEndpoint404() throws Exception { + getHttpClient().whenRequestTo(base + "/.well-known/oauth-authorization-server", + responseOf(404, "something wrong")); + + assertThat(getIClient().getAuthorizationEndpoint()).isEqualTo(null); + assertThat(getIClient().getTokenEndpoint()).isEqualTo(null); + } + + @Test + public void shouldReturnNullifAuthorizationEndpointInvalidJson() throws Exception { + getHttpClient().whenRequestTo(base + "/.well-known/oauth-authorization-server", + responseOf("{bogus")); + + assertThat(getIClient().getAuthorizationEndpoint()).isEqualTo(null); + assertThat(getIClient().getTokenEndpoint()).isEqualTo(null); + } + +} diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java b/src/test/java/com/openshift/internal/restclient/ClusterVersionsTest.java similarity index 55% rename from src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java rename to src/test/java/com/openshift/internal/restclient/ClusterVersionsTest.java index 72bb6647..f0444c32 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientConstructionTest.java +++ b/src/test/java/com/openshift/internal/restclient/ClusterVersionsTest.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2019 Red Hat, Inc. - * Distributed under license by Red Hat, Inc. All rights reserved. - * This program is 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 + * Copyright (c) 2019 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: - * Red Hat, Inc. - initial API and implementation + * Contributors: + * Red Hat, Inc. - initial API and implementation ****************************************************************************** */ @@ -18,36 +18,45 @@ import com.openshift.restclient.utils.Samples; -public class DefaultClientConstructionTest extends TypeMapperFixture { +public class ClusterVersionsTest extends TypeMapperFixture { @Test public void testKubernetesMasterVersionOk() throws Exception { - getHttpClient().mockAsyncRequest(base + "/version", - () -> responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); + getHttpClient().whenRequestTo(base + "/version", + responseOf(Samples.KUBERNETES_VERSION.getContentAsString())); assertThat(getIClient().getKubernetesMasterVersion()).isEqualTo("v1.6.1+5115d708d7"); } @Test public void testKubernetesMasterVersion404() throws Exception { - getHttpClient().mockAsyncRequest(base + "/version", - () -> responseOf(404, "something wrong")); + getHttpClient().whenRequestTo(base + "/version", + responseOf(404, "something wrong")); assertThat(getIClient().getKubernetesMasterVersion()).isEqualTo(""); } @Test public void testOpenShiftMasterVersionOk() throws Exception { - getHttpClient().mockAsyncRequest(base + "/version/openshift", - () -> responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); + getHttpClient().whenRequestTo(base + "/version/openshift", + responseOf(Samples.OPENSHIFT_VERSION.getContentAsString())); assertThat(getIClient().getOpenshiftMasterVersion()).isEqualTo("v3.6.0-alpha.2+3c221d5"); } @Test public void testOpenShiftMasterVersion404() throws Exception { - getHttpClient().mockAsyncRequest(base + "/version/openshift", - () -> responseOf(404, "something wrong")); + getHttpClient().whenRequestTo(base + "/version/openshift", + responseOf(404, "something wrong")); assertThat(getIClient().getOpenshiftMasterVersion()).isEqualTo(""); } + + @Test + public void testOpenShiftMasterVersionIllegalJson() throws Exception { + getHttpClient().whenRequestTo(base + "/version/openshift", + responseOf("{bogus")); + + assertThat(getIClient().getOpenshiftMasterVersion()).isEqualTo(""); + } + } diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 65c237d1..15a25f52 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2018 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -82,6 +82,12 @@ public void setUp() throws Exception { static class TestOkHttpClient extends OkHttpClient { + void whenRequestTo(String url, Response response) throws IOException { + Call call = mock(Call.class); + doReturn(response).when(call).execute(); + doReturn(call).when(this).newCall(requestTo(url)); + } + OngoingStubbing whenRequestTo(String url) throws IOException { Call call = mock(Call.class); doReturn(call).when(this).newCall(requestTo(url)); diff --git a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java index 34d11569..6c972c22 100644 --- a/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java +++ b/src/test/java/com/openshift/internal/restclient/api/capabilities/PodExecTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016-2018 Red Hat, Inc. + * Copyright (c) 2016-2019 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -17,6 +17,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.net.URL; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -47,7 +49,7 @@ public class PodExecTest extends TypeMapperFixture { @Before public void setUp() throws Exception { super.setUp(); - client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); + client = new DefaultClient(new URL("https://localhost"), getHttpClient(), null, getApiTypeMapper(), null); pod = new MocksFactory().mock(IPod.class); capability = new PodLogRetrievalAsync(pod, client); adapter = new PodExec.ExecOutputListenerAdapter(listener); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java index b974882c..0c15c98d 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/PodLogRetrievalAsyncTest.java @@ -19,6 +19,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.net.URL; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -52,7 +54,7 @@ public class PodLogRetrievalAsyncTest extends TypeMapperFixture { @Before public void setUp() throws Exception { super.setUp(); - client = new DefaultClient(null, getHttpClient(), null, getApiTypeMapper(), null); + client = new DefaultClient(new URL("http://localhost"), getHttpClient(), null, getApiTypeMapper(), null); pod = new MocksFactory().mock(IPod.class); capability = new PodLogRetrievalAsync(pod, client); diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 4d520c57..7392b3eb 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -22,7 +22,8 @@ public enum Samples { OPENSHIFT_VERSION("openshift3/api_openshift_version.json"), KUBERNETES_VERSION("openshift3/api_kubernetes_version.json"), - + WELL_KNOW_OAUTH_AUTHORIZATION_SERVER("openshift3/api_well_known_oauth_authorization_server.json"), + GROUP_ENDPONT_API_V1("openshift3/api_v1_endpoint.json"), GROUP_ENDPONT_OAPI_V1("openshift3/oapi_v1_endpoint.json"), GROUP_ENDPONT_APIS("openshift3/apis_endpoint.json"), diff --git a/src/test/resources/samples/openshift3/api_well_known_oauth_authorization_server.json b/src/test/resources/samples/openshift3/api_well_known_oauth_authorization_server.json new file mode 100644 index 00000000..dbe01bab --- /dev/null +++ b/src/test/resources/samples/openshift3/api_well_known_oauth_authorization_server.json @@ -0,0 +1,24 @@ +{ + "issuer": "https://api.rh-us-east-1.openshift.com", + "authorization_endpoint": "https://api.rh-us-east-1.openshift.com/oauth/authorize", + "token_endpoint": "https://api.rh-us-east-1.openshift.com/oauth/token", + "scopes_supported": [ + "user:check-access", + "user:full", + "user:info", + "user:list-projects", + "user:list-scoped-projects" + ], + "response_types_supported": [ + "code", + "token" + ], + "grant_types_supported": [ + "authorization_code", + "implicit" + ], + "code_challenge_methods_supported": [ + "plain", + "S256" + ] +} \ No newline at end of file From c8f514ecb2005826e249b6fa4fbe5b481bd97b8b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 25 Oct 2019 12:16:12 +0200 Subject: [PATCH 209/258] authorize by direct request to auth-endpoint (was: using invalid bearer & authenticator indirection) Signed-off-by: Andre Dietisheim --- .../okhttp/AuthenticatorInterceptor.java | 48 ++++--------------- .../okhttp/OpenShiftRequestBuilder.java | 6 +-- 2 files changed, 12 insertions(+), 42 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java index b1567239..c7c14aa5 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java @@ -13,8 +13,6 @@ import java.io.IOException; import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; import java.util.Map; import org.apache.commons.lang.StringUtils; @@ -29,13 +27,11 @@ import com.openshift.restclient.authorization.UnauthorizedException; import com.openshift.restclient.http.IHttpConstants; -import okhttp3.Authenticator; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Request.Builder; import okhttp3.Response; -import okhttp3.Route; /** * Adds authorization means to every request. Authorizes and retrieves the token @@ -52,7 +48,6 @@ public class AuthenticatorInterceptor implements Interceptor, IHttpConstants { private static final String ERROR_DETAILS = "error_details"; private IClient client; - private Collection challangeHandlers = new ArrayList<>(); @Override public Response intercept(Chain chain) throws IOException { @@ -93,13 +88,13 @@ private Response authenticate() throws IOException { if (okClient == null) { return null; } - Request authRequest = new Request.Builder() - .addHeader(CSRF_TOKEN, "1") - .url(new URL(client.getAuthorizationEndpoint().toExternalForm() - + "?response_type=token&client_id=openshift-challenging-client").toString()) - .build(); + Request authRequest = appendAuthorization( + client.getAuthorizationContext(), + new Request.Builder() + .addHeader(CSRF_TOKEN, "1") + .url(new URL(client.getAuthorizationEndpoint().toExternalForm() + + "?response_type=token&client_id=openshift-challenging-client").toString())); return okClient.newBuilder() - .authenticator(new OpenShiftAuthenticator()) .followRedirects(false) .build() .newCall(authRequest) @@ -132,36 +127,11 @@ private void setToken(String token, IAuthorizationContext authorizationContext) public void setClient(IClient client) { this.client = client; - initChallengeHandlers(client.getAuthorizationContext()); } - private void initChallengeHandlers(IAuthorizationContext context) { - challangeHandlers.clear(); - challangeHandlers.add(new BasicChallengeHandler(context)); + private Request appendAuthorization(IAuthorizationContext context, Builder builder) { + builder.header(AUTH_ATTEMPTS, "1"); + return new BasicChallengeHandler(context).handleChallenge(builder).build(); } - private final class OpenShiftAuthenticator implements Authenticator { - @Override - public Request authenticate(Route route, Response response) throws IOException { - if (StringUtils.isNotBlank(response.request().header(AUTH_ATTEMPTS))) { - return null; - } - if (StringUtils.isNotBlank(response.header(IHttpConstants.PROPERTY_WWW_AUTHENTICATE))) { - Request authenticationRequest = createAuthenticationRequest(response); - response.close(); - return authenticationRequest; - } - return null; - } - - private Request createAuthenticationRequest(Response response) { - for (IChallengeHandler challangeHandler : challangeHandlers) { - if (!challangeHandler.canHandle(response.headers())) { - Builder requestBuilder = response.request().newBuilder().header(AUTH_ATTEMPTS, "1"); - return challangeHandler.handleChallenge(requestBuilder).build(); - } - } - return null; - } - } } diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java index e113c50a..4765eb80 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/OpenShiftRequestBuilder.java @@ -57,9 +57,9 @@ public OpenShiftRequestBuilder authorization(IAuthorizationContext authorization } public OpenShiftRequestBuilder authorization(String token) { - // Authenticator only gets triggered with a 401. - // We thus always use the token even if it's null so that we get a 401 instead of 403 in OS 4.2 - builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, IHttpConstants.AUTHORIZATION_BEARER + " " + token); + if (!StringUtils.isBlank(token)) { + builder.header(IHttpConstants.PROPERTY_AUTHORIZATION, IHttpConstants.AUTHORIZATION_BEARER + " " + token); + } return this; } From 8865880fbe7c0f716867fccc05f29e75388a99c7 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 13 Jan 2020 13:18:27 +0100 Subject: [PATCH 210/258] upgrade log4j, sl4j to latest versions Signed-off-by: Andre Dietisheim --- pom.xml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 216260a5..d27946cc 100755 --- a/pom.xml +++ b/pom.xml @@ -211,16 +211,17 @@ slf4j-api 1.6.4 - - org.slf4j - slf4j-log4j12 - 1.6.4 - - - log4j - log4j - 1.2.16 - + + org.slf4j + slf4j-log4j12 + 2.0.0-alpha1 + + + org.apache.logging.log4j + log4j + 2.13.0 + pom + commons-codec commons-codec From 40f1f36e103782422f330c9ede801ca978976eb7 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Tue, 14 Jan 2020 13:29:44 +0100 Subject: [PATCH 211/258] Fix OCP startup script Fixes #421 Signed-off-by: Jeff MAURY --- startOCP.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/startOCP.sh b/startOCP.sh index add9c9f6..972c6b47 100755 --- a/startOCP.sh +++ b/startOCP.sh @@ -1,4 +1,10 @@ -curl https://github.com/openshift/origin/releases/download/$1/openshift-origin-client-tools-v3.10.0-dd10d17-linux-64bit.tar.gz --location --output oc-client.tgz +if [ "$1" = "v3.9.0" ] +then curl https://github.com/openshift/origin/releases/download/v3.9.0/openshift-origin-client-tools-v3.9.0-191fece-linux-64bit.tar.gz --location --output oc-client.tgz +elif [ "$1" = "v3.10.0" ] +then curl https://github.com/openshift/origin/releases/download/v3.10.0/openshift-origin-client-tools-v3.10.0-dd10d17-linux-64bit.tar.gz --location --output oc-client.tgz +elif [ "$1" = "v3.11.0" ] +then curl https://github.com/openshift/origin/releases/download/v3.11.0/openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit.tar.gz --location --output oc-client.tgz +fi tar -xzvf oc-client.tgz mv openshift-origin-client*/oc . rm -rf openshift-origin-client* From f24e2bbe2ad6e1ef039c4a9f4c596205a584713e Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Tue, 14 Jan 2020 14:05:10 +0100 Subject: [PATCH 212/258] Fix typo in travis.yml Signed-off-by: Jeff MAURY --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6de75e4d..b8cc26da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,6 @@ jobs: ./startOCP.sh v3.10.0 mvn verify -Pintegration-tests -DserverURL=https://127.0.0.1:8443 -Ddefault.clusteradmin.user=admin -Ddefault.clusteradmin.password=admin -Docbinary.location=./oc ./oc cluster down - ./startOCP v3.11.0 + ./startOCP.sh v3.11.0 mvn verify -Pintegration-tests -DserverURL=https://127.0.0.1:8443 -Ddefault.clusteradmin.user=admin -Ddefault.clusteradmin.password=admin -Docbinary.location=./oc ./oc cluster down From d0b0c791817308fd56b8bd89d7423242220cbebe Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 15 Jan 2020 17:36:47 +0100 Subject: [PATCH 213/258] fix NPE when using unreachable server (#424) Signed-off-by: Andre Dietisheim --- .../restclient/AuthorizationEndpoints.java | 73 ++++++++++++ .../internal/restclient/DefaultClient.java | 111 ++---------------- .../restclient/RequestingSupplier.java | 74 ++++++++++++ .../okhttp/AuthenticatorInterceptor.java | 46 +++++--- .../com/openshift/restclient/IClient.java | 2 + .../restclient/ClusterVersionsTest.java | 7 +- 6 files changed, 190 insertions(+), 123 deletions(-) create mode 100644 src/main/java/com/openshift/internal/restclient/AuthorizationEndpoints.java create mode 100644 src/main/java/com/openshift/internal/restclient/RequestingSupplier.java diff --git a/src/main/java/com/openshift/internal/restclient/AuthorizationEndpoints.java b/src/main/java/com/openshift/internal/restclient/AuthorizationEndpoints.java new file mode 100644 index 00000000..dea935c6 --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/AuthorizationEndpoints.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2019-2020 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * All rights reserved. This program is 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: Red Hat, Inc. + ******************************************************************************/ + +package com.openshift.internal.restclient; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.function.Function; + +import org.jboss.dmr.ModelNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import okhttp3.OkHttpClient; + +public class AuthorizationEndpoints { + + public static final String PATH_OAUTH_AUTHORIZATION_SERVER = ".well-known/oauth-authorization-server"; + + private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationEndpoints.class); + + private RequestingSupplier endpointsSupplier; + + protected AuthorizationEndpoints(String baseUrl, OkHttpClient client) { + this.endpointsSupplier = new RequestingSupplier( + baseUrl + "/" + PATH_OAUTH_AUTHORIZATION_SERVER, + "authorization- & token-endpoint", + client) { + + @Override + protected ModelNode extractValue(String response) { + return ModelNode.fromJSONString(response); + } + + @Override + protected ModelNode getDefaultValue() { + return null; + } + }; + } + + public URL getAuthorizationEndpoint() { + return getEndpoint(node -> node.get("authorization_endpoint").asString(), "authorization-endpoint"); + } + + public URL getTokenEndpoint() { + return getEndpoint(node -> node.get("token_endpoint").asString(), "token_endpoint"); + } + + private URL getEndpoint(Function extractor, String description) { + URL authorizationEndpoint = null; + try { + ModelNode node = endpointsSupplier.get(); + if (node != null) { + try { + authorizationEndpoint = new URL(extractor.apply(node)); + } catch (MalformedURLException e) { + LOGGER.error("Failed to determine {}.", description, e); + } + } + } catch (IllegalArgumentException e) { + LOGGER.error("Could not determine {} endpoint: invalid JSON.", description); + } + return authorizationEndpoint; + + } +} \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index dc0ac6e5..16afc90e 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2015-2019 Red Hat, Inc. Distributed under license by Red Hat, Inc. + * Copyright (c) 2015-2020 Red Hat, Inc. Distributed under license by Red Hat, Inc. * All rights reserved. This program is 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 @@ -24,8 +24,6 @@ import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.function.Function; -import java.util.function.Supplier; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; @@ -34,7 +32,6 @@ import com.openshift.internal.restclient.authorization.AuthorizationContext; import com.openshift.internal.restclient.okhttp.OpenShiftRequestBuilder; -import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; import com.openshift.internal.restclient.okhttp.WatchClient; import com.openshift.restclient.IApiTypeMapper; import com.openshift.restclient.IClient; @@ -56,7 +53,6 @@ import okhttp3.MediaType; import okhttp3.OkHttpClient; import okhttp3.Request; -import okhttp3.Request.Builder; import okhttp3.RequestBody; import okhttp3.Response; import okio.BufferedSink; @@ -70,7 +66,6 @@ public class DefaultClient implements IClient, IHttpConstants { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); - public static final String PATH_OAUTH_AUTHORIZATION_SERVER = ".well-known/oauth-authorization-server"; public static final String PATH_KUBERNETES_VERSION = "version"; public static final String PATH_OPENSHIFT_VERSION = "version/openshift"; public static final String PATH_HEALTH_CHECK = "healthz"; @@ -575,60 +570,6 @@ public T adapt(Class klass) { return null; } - private abstract static class RequestingSupplier implements Supplier { - - private String url; - protected String description; - private OkHttpClient client; - - private boolean requested = false; - private T value; - - protected RequestingSupplier(String url, String description, OkHttpClient client) { - this.url = url; - this.description = description; - this.client = client; - this.value = getDefaultValue(); - } - - @Override - public T get() { - return requestIfRequired(); - } - - private T requestIfRequired() { - if (!requested) { - this.value = request(url); - } - return value; - } - - protected T request(String url) { - Request request = new Builder() - .url(url) - .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON) - .tag(new ResponseCodeInterceptor.Ignore() {}) - .build(); - try (Response response = client.newCall(request).execute()) { - this.requested = true; - if (response != null - && response.isSuccessful()) { - this.value = extractValue(response.body().string()); - } else { - LOGGER.error("Failed to determine {}: got {}", description, - response == null ? "null" : response.code()); - } - } catch (IOException | IllegalArgumentException e) { - LOGGER.error("Failed to determine {}.", description, e); - } - return this.value; - } - - protected abstract T getDefaultValue(); - - protected abstract T extractValue(String response) throws IOException; - } - private class ClusterVersion extends RequestingSupplier { protected ClusterVersion(String url, String description, OkHttpClient client) { @@ -637,7 +578,12 @@ protected ClusterVersion(String url, String description, OkHttpClient client) { @Override protected String extractValue(String response) { - return ModelNode.fromJSONString(response).get("gitVersion").asString(); + try { + return ModelNode.fromJSONString(response).get("gitVersion").asString(); + } catch (IllegalArgumentException e) { + LOGGER.error("Could not retrieve {}: Invalid JSON.", description); + return null; + } } @Override @@ -645,47 +591,4 @@ protected String getDefaultValue() { return ""; } } - - private class AuthorizationEndpoints { - - private RequestingSupplier endpointsSupplier; - - protected AuthorizationEndpoints(String baseUrl, OkHttpClient client) { - - this.endpointsSupplier = new RequestingSupplier(baseUrl + "/" + PATH_OAUTH_AUTHORIZATION_SERVER, "authorization- & token-endpoint", client) { - @Override - protected ModelNode extractValue(String response) throws IOException { - return ModelNode.fromJSONString(response); - } - - @Override - protected ModelNode getDefaultValue() { - return null; - } - }; - } - - public URL getAuthorizationEndpoint() { - return getEndpoint(node -> node.get("authorization_endpoint").asString(), "token_endpoint"); - } - - public URL getTokenEndpoint() { - return getEndpoint(node -> node.get("token_endpoint").asString(), "token-endpoint"); - } - - private URL getEndpoint(Function extractor, String description) { - URL authorizationEndpoint = null; - ModelNode node = endpointsSupplier.get(); - if (node != null) { - try { - authorizationEndpoint = new URL(extractor.apply(node)); - } catch (MalformedURLException e) { - LOGGER.error("Failed to determine {}.", description, e); - } - } - return authorizationEndpoint; - - } - } - } diff --git a/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java b/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java new file mode 100644 index 00000000..9c40b6da --- /dev/null +++ b/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java @@ -0,0 +1,74 @@ +package com.openshift.internal.restclient; + +import static com.openshift.restclient.http.IHttpConstants.MEDIATYPE_APPLICATION_JSON; +import static com.openshift.restclient.http.IHttpConstants.PROPERTY_ACCEPT; + +import java.io.IOException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.openshift.internal.restclient.okhttp.ResponseCodeInterceptor; +import com.openshift.restclient.OpenShiftException; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Request.Builder; +import okhttp3.Response; + +abstract class RequestingSupplier { + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); + + private String url; + protected String description; + private OkHttpClient client; + + private boolean requested = false; + private T value; + + protected RequestingSupplier(String url, String description, OkHttpClient client) { + this.url = url; + this.description = description; + this.client = client; + this.value = getDefaultValue(); + } + + public T get() { + return requestIfRequired(); + } + + private T requestIfRequired() { + try { + if (!requested) { + this.value = request(url); + } + return value; + } catch (IOException e) { + throw new OpenShiftException(e, "Unable to execute request to request url %s", url); + } + } + + protected T request(String url) throws IOException { + Request request = new Builder() + .url(url) + .header(PROPERTY_ACCEPT, MEDIATYPE_APPLICATION_JSON) + .tag(new ResponseCodeInterceptor.Ignore() {}) + .build(); + try (Response response = client.newCall(request).execute()) { + this.requested = true; + if (response != null + && response.isSuccessful()) { + this.value = extractValue(response.body().string()); + } else { + LOGGER.error("Failed to determine {}: got {}", description, + response == null ? "null" : response.code()); + } + } + return this.value; + } + + protected abstract T getDefaultValue(); + + protected abstract T extractValue(String response); +} \ No newline at end of file diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java index e4bfb656..e54643c5 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 Red Hat, Inc. + * Copyright (c) 2019-2020 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -16,8 +16,8 @@ import java.util.Map; import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; +import com.openshift.internal.restclient.AuthorizationEndpoints; import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.authorization.AuthorizationDetails; import com.openshift.internal.util.URIUtils; @@ -27,6 +27,7 @@ import com.openshift.restclient.authorization.UnauthorizedException; import com.openshift.restclient.http.IHttpConstants; +import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -39,8 +40,6 @@ */ public class AuthenticatorInterceptor implements Interceptor, IHttpConstants { - private static final Logger LOGGER = Logger.getLogger(AuthenticatorInterceptor.class); - public static final String ACCESS_TOKEN = "access_token"; private static final String AUTH_ATTEMPTS = "X-OPENSHIFT-AUTH-ATTEMPTS"; private static final String CSRF_TOKEN = "X-CSRF-Token"; @@ -58,29 +57,39 @@ public Response intercept(Chain chain) throws IOException { } IAuthorizationContext authorizationContext = client.getAuthorizationContext(); if (StringUtils.isBlank(authorizationContext.getToken())) { - try (Response authResponse = authenticate()) { - if (authResponse == null - || !authResponse.isSuccessful()) { + request = createAuthorizationRequest(request, url, authorizationContext); + } + return chain.proceed(request); + } + + private Request createAuthorizationRequest(Request request, String url, IAuthorizationContext authorizationContext) throws IOException { + try (Response authResponse = authenticate()) { + if (authResponse != null) { + if (!authResponse.isSuccessful()) { throw new UnauthorizedException(getAuthorizationDetails(url), - authResponse == null ? null : ResponseCodeInterceptor.getStatus(authResponse.body().string())); + ResponseCodeInterceptor.getStatus(authResponse.body().string())); } String token = getToken(authResponse); setToken(token, client.getAuthorizationContext()); - request = new OpenShiftRequestBuilder(request.newBuilder()) - .acceptJson() + request = new OpenShiftRequestBuilder(request.newBuilder()).acceptJson() .authorization(authorizationContext) .build(); } + return request; } - return chain.proceed(request); } private boolean isUrlWithoutAuthorization(Request request, String url) { return url.endsWith(DefaultClient.PATH_OPENSHIFT_VERSION) || url.endsWith(DefaultClient.PATH_KUBERNETES_VERSION) - || url.endsWith(DefaultClient.PATH_OAUTH_AUTHORIZATION_SERVER) - || request.url().toString().startsWith(client.getAuthorizationEndpoint().toString()) - || url.endsWith(DefaultClient.PATH_HEALTH_CHECK); + || url.endsWith(DefaultClient.PATH_HEALTH_CHECK) + || url.endsWith(AuthorizationEndpoints.PATH_OAUTH_AUTHORIZATION_SERVER) + || isAuthorizationEndpoint(request.url(), client.getAuthorizationEndpoint()); + } + + private boolean isAuthorizationEndpoint(HttpUrl request, URL authEndpoint) { + return authEndpoint != null + && request.toString().startsWith(authEndpoint.toString()); } private Response authenticate() throws IOException { @@ -88,11 +97,15 @@ private Response authenticate() throws IOException { if (okClient == null) { return null; } + URL endpoint = client.getAuthorizationEndpoint(); + if (endpoint == null) { + return null; + } Request authRequest = appendAuthorization( client.getAuthorizationContext(), new Request.Builder() .addHeader(CSRF_TOKEN, "1") - .url(new URL(client.getAuthorizationEndpoint().toExternalForm() + .url(new URL(endpoint.toExternalForm() + "?response_type=token&client_id=openshift-challenging-client").toString())); return okClient.newBuilder() .followRedirects(false) @@ -111,6 +124,9 @@ private IAuthorizationDetails getAuthorizationDetails(String url) { } private String getToken(Response response) { + if (response == null) { + return null; + } String token = null; Map pairs = URIUtils.splitFragment(response.header(PROPERTY_LOCATION)); if (pairs.containsKey(ACCESS_TOKEN)) { diff --git a/src/main/java/com/openshift/restclient/IClient.java b/src/main/java/com/openshift/restclient/IClient.java index 9af142c8..6346b3b5 100644 --- a/src/main/java/com/openshift/restclient/IClient.java +++ b/src/main/java/com/openshift/restclient/IClient.java @@ -314,11 +314,13 @@ T execute(ITypeFactory factory, String httpMethod, String kin /** * @return the authentication endpoint to be used when login + * @throws OpenShiftException if endpoint retrieval fails */ URL getAuthorizationEndpoint(); /** * @return the token endpoint to be used when login + * @throws OpenShiftException if endpoint retrieval fails */ URL getTokenEndpoint(); diff --git a/src/test/java/com/openshift/internal/restclient/ClusterVersionsTest.java b/src/test/java/com/openshift/internal/restclient/ClusterVersionsTest.java index f0444c32..65ab4b5c 100644 --- a/src/test/java/com/openshift/internal/restclient/ClusterVersionsTest.java +++ b/src/test/java/com/openshift/internal/restclient/ClusterVersionsTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 Red Hat, Inc. + * Copyright (c) 2019-2020 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -7,8 +7,7 @@ * * Contributors: * Red Hat, Inc. - initial API and implementation - ****************************************************************************** - */ + ******************************************************************************/ package com.openshift.internal.restclient; @@ -56,7 +55,7 @@ public void testOpenShiftMasterVersionIllegalJson() throws Exception { getHttpClient().whenRequestTo(base + "/version/openshift", responseOf("{bogus")); - assertThat(getIClient().getOpenshiftMasterVersion()).isEqualTo(""); + assertThat(getIClient().getOpenshiftMasterVersion()).isEqualTo(null); } } From 152a9f966c98b65b119159896ef804375f31415b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 28 Jan 2020 14:15:22 +0100 Subject: [PATCH 214/258] removed unnecessary param request when testing if url needs auth Signed-off-by: Andre Dietisheim --- .../restclient/okhttp/AuthenticatorInterceptor.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java index e54643c5..f2052825 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java @@ -27,7 +27,6 @@ import com.openshift.restclient.authorization.UnauthorizedException; import com.openshift.restclient.http.IHttpConstants; -import okhttp3.HttpUrl; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -52,7 +51,7 @@ public class AuthenticatorInterceptor implements Interceptor, IHttpConstants { public Response intercept(Chain chain) throws IOException { Request request = chain.request(); String url = request.url().toString(); - if (isUrlWithoutAuthorization(request, url)) { + if (isUrlWithoutAuthorization(url)) { return chain.proceed(request); } IAuthorizationContext authorizationContext = client.getAuthorizationContext(); @@ -79,17 +78,17 @@ private Request createAuthorizationRequest(Request request, String url, IAuthori } } - private boolean isUrlWithoutAuthorization(Request request, String url) { + private boolean isUrlWithoutAuthorization(String url) { return url.endsWith(DefaultClient.PATH_OPENSHIFT_VERSION) || url.endsWith(DefaultClient.PATH_KUBERNETES_VERSION) || url.endsWith(DefaultClient.PATH_HEALTH_CHECK) || url.endsWith(AuthorizationEndpoints.PATH_OAUTH_AUTHORIZATION_SERVER) - || isAuthorizationEndpoint(request.url(), client.getAuthorizationEndpoint()); + || isAuthorizationEndpoint(url, client.getAuthorizationEndpoint()); } - private boolean isAuthorizationEndpoint(HttpUrl request, URL authEndpoint) { + private boolean isAuthorizationEndpoint(String url, URL authEndpoint) { return authEndpoint != null - && request.toString().startsWith(authEndpoint.toString()); + && url.startsWith(authEndpoint.toString()); } private Response authenticate() throws IOException { From d2ed25b505a6bef9b626c7a1b31be458f54a8dcd Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 28 Jan 2020 16:02:44 +0100 Subject: [PATCH 215/258] dont re-authorize an authorization request (#423) Signed-off-by: Andre Dietisheim --- .../okhttp/AuthenticatorInterceptor.java | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java index f2052825..c88b3916 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/AuthenticatorInterceptor.java @@ -27,6 +27,7 @@ import com.openshift.restclient.authorization.UnauthorizedException; import com.openshift.restclient.http.IHttpConstants; +import okhttp3.Headers; import okhttp3.Interceptor; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -40,7 +41,6 @@ public class AuthenticatorInterceptor implements Interceptor, IHttpConstants { public static final String ACCESS_TOKEN = "access_token"; - private static final String AUTH_ATTEMPTS = "X-OPENSHIFT-AUTH-ATTEMPTS"; private static final String CSRF_TOKEN = "X-CSRF-Token"; private static final String ERROR = "error"; private static final String ERROR_DETAILS = "error_details"; @@ -51,7 +51,8 @@ public class AuthenticatorInterceptor implements Interceptor, IHttpConstants { public Response intercept(Chain chain) throws IOException { Request request = chain.request(); String url = request.url().toString(); - if (isUrlWithoutAuthorization(url)) { + if (AuthAttempHeader.isContainedIn(request.headers()) + || isUrlWithoutAuthorization(url)) { return chain.proceed(request); } IAuthorizationContext authorizationContext = client.getAuthorizationContext(); @@ -145,8 +146,21 @@ public void setClient(IClient client) { } private Request appendAuthorization(IAuthorizationContext context, Builder builder) { - builder.header(AUTH_ATTEMPTS, "1"); + AuthAttempHeader.add(builder); return new BasicChallengeHandler(context).handleChallenge(builder).build(); } + private static class AuthAttempHeader { + + private static final String AUTH_ATTEMPTS = "X-OPENSHIFT-AUTH-ATTEMPTS"; + + public static void add(Builder builder) { + builder.header(AUTH_ATTEMPTS, "1"); + } + + public static boolean isContainedIn(Headers headers) { + return headers != null + && headers.get(AUTH_ATTEMPTS) != null; + } + } } From 0a668f39b921ad9704121a73a72d7b875e299ec7 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 30 Jan 2020 14:52:05 +0100 Subject: [PATCH 216/258] correctly handle challenge headers with 'realm=' (#430) See https://tools.ietf.org/html/rfc7235#section-4.1 kudos to Akram Ben Aissi @akram who found out about this bug Signed-off-by: Andre Dietisheim --- .../internal/restclient/okhttp/BasicChallengeHandler.java | 5 +++-- .../java/com/openshift/restclient/http/IHttpConstants.java | 2 +- .../restclient/okhttp/BasicChallangeHandlerTest.java | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java index 3e78e849..6dbaa3bc 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/BasicChallengeHandler.java @@ -30,8 +30,9 @@ public BasicChallengeHandler(IAuthorizationContext context) { @Override public boolean canHandle(Headers headers) { - return IHttpConstants.AUTHORIZATION_BASIC - .equalsIgnoreCase(headers.get(IHttpConstants.PROPERTY_WWW_AUTHENTICATE)); + String header = headers.get(IHttpConstants.PROPERTY_WWW_AUTHENTICATE); + return StringUtils.isNotEmpty(header) + && header.toLowerCase().startsWith(IHttpConstants.AUTHORIZATION_BASIC.toLowerCase()); } @Override diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index 8ac7d3bc..2c923d2b 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -37,7 +37,7 @@ public interface IHttpConstants { public static final String PROPERTY_ORIGIN = "Origin"; public static final String PROPERTY_LOCATION = "Location"; public static final String PROPERTY_USER_AGENT = "User-Agent"; - public static final String PROPERTY_WWW_AUTHENTICATE = "Www-Authenticate"; + public static final String PROPERTY_WWW_AUTHENTICATE = "WWW-Authenticate"; public static final String PROPERTY_AUTHKEY = "broker_auth_key"; public static final String PROPERTY_AUTHIV = "broker_auth_iv"; diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java index 7539ad78..d7f2aeee 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/BasicChallangeHandlerTest.java @@ -48,6 +48,7 @@ public void setUp() throws Exception { public void testCanHandle() { assertTrue(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, "basic"))); assertTrue(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, "bAsIC"))); + assertTrue(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, "Basic realm=\"WallyWorld\""))); assertFalse(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, "foobar"))); assertFalse(handler.canHandle(givenHeader(IHttpConstants.PROPERTY_WWW_AUTHENTICATE, ""))); assertFalse(handler.canHandle(givenHeader("key", "value"))); From c93794475c33b403a8bc8311f17cc4e62d5be9e3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Feb 2020 19:31:08 +0000 Subject: [PATCH 217/258] Bump checkstyle from 6.19 to 8.29 Bumps [checkstyle](https://github.com/checkstyle/checkstyle) from 6.19 to 8.29. - [Release notes](https://github.com/checkstyle/checkstyle/releases) - [Commits](https://github.com/checkstyle/checkstyle/compare/checkstyle-6.19...checkstyle-8.29) Signed-off-by: dependabot[bot] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 pom.xml diff --git a/pom.xml b/pom.xml old mode 100755 new mode 100644 index d27946cc..bccedc85 --- a/pom.xml +++ b/pom.xml @@ -78,7 +78,7 @@ com.puppycrawl.tools checkstyle - 6.19 + 8.29 From ca83275439ee9037ba942e4b09af609ba0cef4dc Mon Sep 17 00:00:00 2001 From: Josef Kopriva Date: Thu, 6 Feb 2020 10:29:48 +0100 Subject: [PATCH 218/258] Issue-418 Update log4j configuration for 2.13.0 Signed-off-by: Josef Kopriva --- src/test/resources/log4j.xml | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/test/resources/log4j.xml b/src/test/resources/log4j.xml index dde9ab0a..83881435 100644 --- a/src/test/resources/log4j.xml +++ b/src/test/resources/log4j.xml @@ -1,20 +1,14 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file From 6446f3f3bb0f14fcf6cb5a306e9219d3a2403c10 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 7 Feb 2020 13:31:58 +0100 Subject: [PATCH 219/258] upgraded maven-checkstyle-plugin to 3.1.0 Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bccedc85..36368bb2 100644 --- a/pom.xml +++ b/pom.xml @@ -73,7 +73,7 @@ org.apache.maven.plugins maven-checkstyle-plugin - 2.16 + 3.1.0 com.puppycrawl.tools From 693beb6d67c4ae8a871c36f74e485fce529c2bae Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 7 Feb 2020 13:33:02 +0100 Subject: [PATCH 220/258] fixed checkstyle config to 3.1.0 compliance Signed-off-by: Andre Dietisheim --- checkstyle.xml | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/checkstyle.xml b/checkstyle.xml index 5da71ec9..332c1e69 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -41,10 +41,13 @@ - - - - + + + + + + + @@ -58,10 +61,6 @@ - - - - @@ -70,9 +69,7 @@ - - - + @@ -257,4 +254,4 @@ - \ No newline at end of file + From b794cb12c8399c69198dd980de812eca00fc7550 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 7 Feb 2020 15:21:26 +0100 Subject: [PATCH 221/258] fixed custom import order violations Signed-off-by: Andre Dietisheim --- checkstyle-suppressions.xml | 9 +++++++++ checkstyle.xml | 4 ++++ .../java/com/openshift/restclient/ClientBuilder.java | 1 - .../openshift/restclient/ISSLCertificateCallback.java | 1 - .../openshift/restclient/NoopSSLCertificateCallback.java | 1 - .../java/com/openshift/restclient/utils/SSLUtils.java | 1 - .../internal/restclient/IntegrationTestHelper.java | 1 - .../com/openshift/restclient/server/HttpsServerFake.java | 1 - 8 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 checkstyle-suppressions.xml diff --git a/checkstyle-suppressions.xml b/checkstyle-suppressions.xml new file mode 100644 index 00000000..5859ee5c --- /dev/null +++ b/checkstyle-suppressions.xml @@ -0,0 +1,9 @@ + + + + + + + diff --git a/checkstyle.xml b/checkstyle.xml index 332c1e69..ef0dd3ab 100644 --- a/checkstyle.xml +++ b/checkstyle.xml @@ -44,6 +44,10 @@ + + + + diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index b3f04cd5..59ec033e 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -23,7 +23,6 @@ import java.security.cert.X509Certificate; import java.util.Collection; import java.util.concurrent.TimeUnit; - import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; diff --git a/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java b/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java index 6855ebbb..dd63767e 100644 --- a/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java +++ b/src/main/java/com/openshift/restclient/ISSLCertificateCallback.java @@ -10,7 +10,6 @@ package com.openshift.restclient; import java.security.cert.X509Certificate; - import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; diff --git a/src/main/java/com/openshift/restclient/NoopSSLCertificateCallback.java b/src/main/java/com/openshift/restclient/NoopSSLCertificateCallback.java index d2b44b86..f432b77d 100644 --- a/src/main/java/com/openshift/restclient/NoopSSLCertificateCallback.java +++ b/src/main/java/com/openshift/restclient/NoopSSLCertificateCallback.java @@ -12,7 +12,6 @@ package com.openshift.restclient; import java.security.cert.X509Certificate; - import javax.net.ssl.SSLSession; /** diff --git a/src/main/java/com/openshift/restclient/utils/SSLUtils.java b/src/main/java/com/openshift/restclient/utils/SSLUtils.java index 247f11ee..79a2e93b 100644 --- a/src/main/java/com/openshift/restclient/utils/SSLUtils.java +++ b/src/main/java/com/openshift/restclient/utils/SSLUtils.java @@ -17,7 +17,6 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; - import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; diff --git a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java index 733f8ce2..7af793ae 100644 --- a/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java +++ b/src/test/java/com/openshift/internal/restclient/IntegrationTestHelper.java @@ -32,7 +32,6 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; - import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; diff --git a/src/test/java/com/openshift/restclient/server/HttpsServerFake.java b/src/test/java/com/openshift/restclient/server/HttpsServerFake.java index 76a99d65..c665b9f5 100644 --- a/src/test/java/com/openshift/restclient/server/HttpsServerFake.java +++ b/src/test/java/com/openshift/restclient/server/HttpsServerFake.java @@ -17,7 +17,6 @@ import java.net.URL; import java.security.KeyStore; import java.text.MessageFormat; - import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; From 4af84eb02cf2eb7b8fcdfe0ef5e83787514af9c3 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 7 Feb 2020 15:46:15 +0100 Subject: [PATCH 222/258] bumped version of sl4j-api to 2.0.0-alpha1 Signed-off-by: Andre Dietisheim --- pom.xml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 36368bb2..acdd3131 100644 --- a/pom.xml +++ b/pom.xml @@ -209,19 +209,19 @@ org.slf4j slf4j-api - 1.6.4 + 2.0.0-alpha1 + + + org.slf4j + slf4j-log4j12 + 2.0.0-alpha1 + + + org.apache.logging.log4j + log4j + 2.13.0 + pom - - org.slf4j - slf4j-log4j12 - 2.0.0-alpha1 - - - org.apache.logging.log4j - log4j - 2.13.0 - pom - commons-codec commons-codec From cf63429f1580007c2b80ec714e16abacb670f9db Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 17 Feb 2020 18:18:58 +0100 Subject: [PATCH 223/258] corrected IRSyncable#Peer#toString (#437) Signed-off-by: Andre Dietisheim --- .../restclient/capability/resources/IRSyncable.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java b/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java index 56620313..4557ba32 100644 --- a/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java +++ b/src/main/java/com/openshift/restclient/capability/resources/IRSyncable.java @@ -164,6 +164,11 @@ protected String getLocation() { public void append(StringBuilder commandLine) { commandLine.append(" ").append(getParameter()); } + + @Override + public String toString() { + return getParameter(); + } } /** From 457110c957fc9ac2cb3c3f4ea646d6a062e0a214 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Thu, 13 Feb 2020 12:23:38 +0100 Subject: [PATCH 224/258] only log to slf4j (use log4j2 only in tests, integration-tests) Signed-off-by: Andre Dietisheim --- pom.xml | 72 ++++++++++--------- .../restclient/RequestingSupplier.java | 13 +++- .../restclient/api/capabilities/PodExec.java | 2 +- .../resources/DeployCapability.java | 2 +- .../okhttp/ResponseCodeInterceptor.java | 7 +- .../com/openshift/internal/util/URIUtils.java | 5 +- src/test/resources/log4j.xml | 14 ---- src/test/resources/log4j2.xml | 18 +++++ 8 files changed, 79 insertions(+), 54 deletions(-) delete mode 100644 src/test/resources/log4j.xml create mode 100644 src/test/resources/log4j2.xml diff --git a/pom.xml b/pom.xml index acdd3131..786efe07 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,8 @@ 1.0.0-beta-6 1.0.0-beta-5 1.1.0-beta-1 + 2.0.0-alpha1 + 2.13.0 ${basedir}/src/test/resources/openshiftv3IntegrationTest.properties @@ -183,6 +185,44 @@ commons-compress 1.18 + + commons-io + commons-io + 2.1 + + + org.slf4j + slf4j-api + ${version.slf4j} + + + commons-codec + commons-codec + 1.6 + + + commons-lang + commons-lang + 2.6 + + + org.apache.logging.log4j + log4j-api + ${version.log4j} + test + + + org.apache.logging.log4j + log4j-core + ${version.log4j} + test + + + org.apache.logging.log4j + log4j-slf4j18-impl + ${version.log4j} + test + junit junit @@ -201,37 +241,6 @@ 3.13.2 test - - commons-io - commons-io - 2.1 - - - org.slf4j - slf4j-api - 2.0.0-alpha1 - - - org.slf4j - slf4j-log4j12 - 2.0.0-alpha1 - - - org.apache.logging.log4j - log4j - 2.13.0 - pom - - - commons-codec - commons-codec - 1.6 - - - commons-lang - commons-lang - 2.6 - org.skyscreamer jsonassert @@ -240,7 +249,6 @@ - release diff --git a/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java b/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java index 9c40b6da..5a58f24e 100644 --- a/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java +++ b/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java @@ -1,3 +1,14 @@ +/******************************************************************************* + * Copyright (c) 2020 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is 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: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ + package com.openshift.internal.restclient; import static com.openshift.restclient.http.IHttpConstants.MEDIATYPE_APPLICATION_JSON; @@ -18,7 +29,7 @@ abstract class RequestingSupplier { - private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); + private static final Logger LOGGER = LoggerFactory.getLogger(RequestingSupplier.class); private String url; protected String description; diff --git a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java index 92e35f96..41eff79d 100644 --- a/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java +++ b/src/main/java/com/openshift/internal/restclient/api/capabilities/PodExec.java @@ -38,7 +38,7 @@ public class PodExec extends AbstractCapability implements IPodExec { - private static final Logger LOG = LoggerFactory.getLogger(IPodExec.class); + private static final Logger LOG = LoggerFactory.getLogger(PodExec.class); private static final String CAPABILITY = "exec"; private static final String COMMAND = "command"; diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java index 29c57bd3..b8be851a 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/DeployCapability.java @@ -28,7 +28,7 @@ public class DeployCapability implements IDeployCapability { private static final List COMPLETED_STATES = Arrays.asList("Complete", "Failed"); - private static final Logger LOG = LoggerFactory.getLogger(IDeployCapability.class); + private static final Logger LOG = LoggerFactory.getLogger(DeployCapability.class); private final IClient client; private final IDeploymentConfig config; diff --git a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java index 3c8b35d3..0c151e14 100644 --- a/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java +++ b/src/main/java/com/openshift/internal/restclient/okhttp/ResponseCodeInterceptor.java @@ -14,7 +14,8 @@ import java.io.IOException; import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import com.openshift.internal.restclient.DefaultClient; import com.openshift.internal.restclient.authorization.AuthorizationDetails; @@ -38,7 +39,7 @@ */ public class ResponseCodeInterceptor implements Interceptor, IHttpConstants { - private static final Logger LOGGER = Logger.getLogger(ResponseCodeInterceptor.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ResponseCodeInterceptor.class); public static final String X_OPENSHIFT_IGNORE_RCI = "X-OPENSHIFT-IGNORE-RCI"; @@ -104,7 +105,7 @@ public static IStatus getStatus(String response) { private static OpenShiftException createOpenShiftException(IClient client, Response response, Throwable e) throws IOException { - LOGGER.debug(response, e); + LOGGER.debug(response.toString(), e); IStatus status = getStatus(response.body().string()); int responseCode = response.code(); if (status != null && status.getCode() != 0) { diff --git a/src/main/java/com/openshift/internal/util/URIUtils.java b/src/main/java/com/openshift/internal/util/URIUtils.java index 3b498e2c..b238e3a9 100644 --- a/src/main/java/com/openshift/internal/util/URIUtils.java +++ b/src/main/java/com/openshift/internal/util/URIUtils.java @@ -19,14 +19,15 @@ import java.util.Map; import org.apache.commons.lang.StringUtils; -import org.apache.log4j.Logger; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Helper methods for manipulating URIs * */ public class URIUtils { - private static final Logger LOG = Logger.getLogger(URIUtils.class); + private static final Logger LOG = LoggerFactory.getLogger(URIUtils.class); private URIUtils() { } diff --git a/src/test/resources/log4j.xml b/src/test/resources/log4j.xml deleted file mode 100644 index 83881435..00000000 --- a/src/test/resources/log4j.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/log4j2.xml b/src/test/resources/log4j2.xml new file mode 100644 index 00000000..27b353e2 --- /dev/null +++ b/src/test/resources/log4j2.xml @@ -0,0 +1,18 @@ + +> + + + + + + + + + + + \ No newline at end of file From efa36d81d6d9163726432f6281b5890888e46581 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Fri, 7 Feb 2020 17:48:27 +0100 Subject: [PATCH 225/258] bumped to 8.1.1.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 786efe07..29f00790 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.1.1-SNAPSHOT + 8.1.1.Final jar OpenShift Java REST Client http://openshift.redhat.com From 5b03c0d1afae9f390738fec2f40523630df863c1 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 18 Feb 2020 17:09:08 +0100 Subject: [PATCH 226/258] bumped to 8.1.2-SNAPSHOT after release Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 29f00790..6b315ba5 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.1.1.Final + 8.1.2-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From e07c7c8d54215cb688255049e3a8989f6496380f Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 14 Apr 2020 15:54:11 +0200 Subject: [PATCH 227/258] use default auth endpoint if discovering fails (#439) Signed-off-by: Andre Dietisheim --- .../internal/restclient/DefaultClient.java | 23 +++- .../AuthorizationEndpointsTest.java | 100 +++++++++++++++--- 2 files changed, 105 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index 16afc90e..c51ceb21 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -64,11 +64,14 @@ */ public class DefaultClient implements IClient, IHttpConstants { + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultClient.class); public static final String PATH_KUBERNETES_VERSION = "version"; public static final String PATH_OPENSHIFT_VERSION = "version/openshift"; public static final String PATH_HEALTH_CHECK = "healthz"; + public static final String PATH_DEFAULT_OAUTH_TOKEN = "oauth/token"; + public static final String PATH_DEFAULT_OAUTH_AUTHORIZE = "oauth/authorize"; public static final String SYSTEM_PROP_K8E_API_VERSION = "osjc.k8e.apiversion"; public static final String SYSTEM_PROP_OPENSHIFT_API_VERSION = "osjc.openshift.apiversion"; @@ -272,6 +275,7 @@ public T execute(ITypeFactory factory, String method, String kind, String na getPayload(payload, method), params); } + @SuppressWarnings("unchecked") private T execute(ITypeFactory factory, String method, String kind, String version, String namespace, String name, String subresource, String subContext, RequestBody requestBody, Map params) { if (factory == null) { @@ -332,7 +336,7 @@ private RequestBody getPayload(JSONSerializeable payload, String method) { } String json = payload == null ? "" : payload.toJson(true); LOGGER.debug("About to send payload: {}", json); - return RequestBody.create(MediaType.parse(MEDIATYPE_APPLICATION_JSON), json); + return RequestBody.create(json, MediaType.parse(MEDIATYPE_APPLICATION_JSON)); } @@ -463,12 +467,17 @@ public URL getBaseURL() { @Override public URL getAuthorizationEndpoint() { - return authorizationEndpoints.getAuthorizationEndpoint(); + URL url = authorizationEndpoints.getAuthorizationEndpoint(); + if (url != null) { + return url; + } + return getDefaultAuthorizationEndpoint(); + } protected URL getDefaultAuthorizationEndpoint() { try { - return new URL(getBaseURL(), "oauth/authorize"); + return new URL(getBaseURL(), PATH_DEFAULT_OAUTH_AUTHORIZE); } catch (MalformedURLException e) { throw new OpenShiftException(e, e.getLocalizedMessage()); } @@ -476,12 +485,16 @@ protected URL getDefaultAuthorizationEndpoint() { @Override public URL getTokenEndpoint() { - return authorizationEndpoints.getTokenEndpoint(); + URL url = authorizationEndpoints.getTokenEndpoint(); + if (url != null) { + return url; + } + return getDefaultTokenEndpoint(); } protected URL getDefaultTokenEndpoint() { try { - return new URL(getBaseURL(), "oauth/token"); + return new URL(getBaseURL(), PATH_DEFAULT_OAUTH_TOKEN); } catch (MalformedURLException e) { throw new OpenShiftException(e, e.getLocalizedMessage()); } diff --git a/src/test/java/com/openshift/internal/restclient/AuthorizationEndpointsTest.java b/src/test/java/com/openshift/internal/restclient/AuthorizationEndpointsTest.java index 6708ac15..5d98d713 100644 --- a/src/test/java/com/openshift/internal/restclient/AuthorizationEndpointsTest.java +++ b/src/test/java/com/openshift/internal/restclient/AuthorizationEndpointsTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2019 Red Hat, Inc. + * Copyright (c) 2019-2020 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -7,8 +7,7 @@ * * Contributors: * Red Hat, Inc. - initial API and implementation - ****************************************************************************** - */ + *******************************************************************************/ package com.openshift.internal.restclient; @@ -18,13 +17,19 @@ import org.junit.Test; +import com.openshift.internal.restclient.authorization.AuthorizationContext; +import com.openshift.restclient.IApiTypeMapper; +import com.openshift.restclient.IClient; +import com.openshift.restclient.IResourceFactory; import com.openshift.restclient.utils.Samples; +import okhttp3.OkHttpClient; + public class AuthorizationEndpointsTest extends TypeMapperFixture { @Test public void shouldRetrieveAuthorizationEndpoint() throws Exception { - getHttpClient().whenRequestTo(base + "/.well-known/oauth-authorization-server", + getHttpClient().whenRequestTo(base + '/' + AuthorizationEndpoints.PATH_OAUTH_AUTHORIZATION_SERVER, responseOf(Samples.WELL_KNOW_OAUTH_AUTHORIZATION_SERVER.getContentAsString())); URL authorizationEndpoint = getIClient().getAuthorizationEndpoint(); @@ -35,7 +40,7 @@ public void shouldRetrieveAuthorizationEndpoint() throws Exception { @Test public void shouldRetrieveTokenEndpoint() throws Exception { - getHttpClient().whenRequestTo(base + "/.well-known/oauth-authorization-server", + getHttpClient().whenRequestTo(base + '/' + AuthorizationEndpoints.PATH_OAUTH_AUTHORIZATION_SERVER, responseOf(Samples.WELL_KNOW_OAUTH_AUTHORIZATION_SERVER.getContentAsString())); URL tokenEndpoint = getIClient().getTokenEndpoint(); @@ -45,21 +50,90 @@ public void shouldRetrieveTokenEndpoint() throws Exception { } @Test - public void shouldReturnNullifAuthorizationEndpoint404() throws Exception { - getHttpClient().whenRequestTo(base + "/.well-known/oauth-authorization-server", + public void shouldReturnNullifAuthorizationEndpoint404AndNoDefault() throws Exception { + // given + getHttpClient().whenRequestTo(base + '/' + AuthorizationEndpoints.PATH_OAUTH_AUTHORIZATION_SERVER, responseOf(404, "something wrong")); + DefaultClient client = new DefaultableEndpointsClient(null, null, getIClient()); + // when + URL authEndpoint = client.getAuthorizationEndpoint(); + URL tokenEndpoint = client.getTokenEndpoint(); + // then + assertThat(authEndpoint).isEqualTo(null); + assertThat(tokenEndpoint).isEqualTo(null); + } - assertThat(getIClient().getAuthorizationEndpoint()).isEqualTo(null); - assertThat(getIClient().getTokenEndpoint()).isEqualTo(null); + @Test + public void shouldReturnDefaultsIfAuthorizationEndpoint404() throws Exception { + // given + getHttpClient().whenRequestTo(base + '/' + AuthorizationEndpoints.PATH_OAUTH_AUTHORIZATION_SERVER, + responseOf(404, "something wrong")); + URL defaultAuthEndpoint = new URL("https://www.redhat.com"); + URL defaultTokenEndpoint = new URL("https://www.openshift.com"); + DefaultClient client = new DefaultableEndpointsClient(defaultAuthEndpoint, defaultTokenEndpoint, getIClient()); + // when + URL authEndpoint = client.getAuthorizationEndpoint(); + URL tokenEndpoint = client.getTokenEndpoint(); + // then + assertThat(authEndpoint).isEqualTo(defaultAuthEndpoint); + assertThat(tokenEndpoint).isEqualTo(defaultTokenEndpoint); } @Test - public void shouldReturnNullifAuthorizationEndpointInvalidJson() throws Exception { - getHttpClient().whenRequestTo(base + "/.well-known/oauth-authorization-server", + public void shouldReturnNullifAuthorizationEndpointInvalidJsonAndNoDefault() throws Exception { + // given + getHttpClient().whenRequestTo(base + '/' + AuthorizationEndpoints.PATH_OAUTH_AUTHORIZATION_SERVER, responseOf("{bogus")); + DefaultClient client = new DefaultableEndpointsClient(null, null, getIClient()); + // when + URL authEndpoint = client.getAuthorizationEndpoint(); + URL tokenEndpoint = client.getTokenEndpoint(); + // then + assertThat(authEndpoint).isEqualTo(null); + assertThat(tokenEndpoint).isEqualTo(null); + } + + @Test + public void shouldReturnDefaultsifAuthorizationEndpointInvalidJson() throws Exception { + // given + getHttpClient().whenRequestTo(base + '/' + AuthorizationEndpoints.PATH_OAUTH_AUTHORIZATION_SERVER, + responseOf("{bogus")); + URL defaultAuthEndpoint = new URL("https://www.redhat.com"); + URL defaultTokenEndpoint = new URL("https://www.openshift.com"); + DefaultClient client = new DefaultableEndpointsClient(defaultAuthEndpoint, defaultTokenEndpoint, getIClient()); + // when + URL authEndpoint = client.getAuthorizationEndpoint(); + URL tokenEndpoint = client.getTokenEndpoint(); + // then + assertThat(authEndpoint).isEqualTo(defaultAuthEndpoint); + assertThat(tokenEndpoint).isEqualTo(defaultTokenEndpoint); + } + + private static class DefaultableEndpointsClient extends DefaultClient { + + private URL defaultAuthorizationEndpoint; + private URL defaultTokenEndpoint; + + public DefaultableEndpointsClient(URL defaultAuthorizationEndpoint, URL defaultTokenEndpoint, IClient client) { + super(client.getBaseURL(), + client.adapt(OkHttpClient.class), + client.adapt(IResourceFactory.class), + client.adapt(IApiTypeMapper.class), + (AuthorizationContext) client.getAuthorizationContext()); + this.defaultAuthorizationEndpoint = defaultAuthorizationEndpoint; + this.defaultTokenEndpoint = defaultTokenEndpoint; + } + + @Override + public URL getDefaultAuthorizationEndpoint() { + return defaultAuthorizationEndpoint; + } + + @Override + public URL getDefaultTokenEndpoint() { + return defaultTokenEndpoint; + } - assertThat(getIClient().getAuthorizationEndpoint()).isEqualTo(null); - assertThat(getIClient().getTokenEndpoint()).isEqualTo(null); } } From e8873a2137de02458c4521b676cb4cabf6c8891c Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 14 Apr 2020 19:05:30 +0200 Subject: [PATCH 228/258] bump to 8.1.2.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6b315ba5..08fa374b 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.1.2-SNAPSHOT + 8.1.2.Final jar OpenShift Java REST Client http://openshift.redhat.com From 0e6edb9b40edc8df98a0de9555b604eb7f21e1f8 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 14 Apr 2020 19:56:48 +0200 Subject: [PATCH 229/258] bump to 8.1.3-SNAPSHOT after release of 8.1.2.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 08fa374b..fb47a693 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.1.2.Final + 8.1.3-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 69f2ae018bf0dab7104a5e26cc562a4edcff630a Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 15 Apr 2020 15:38:01 +0200 Subject: [PATCH 230/258] fixed erroneous prop retrieval in EnvVar.getValueFrom() (#444) Signed-off-by: Andre Dietisheim --- .../restclient/model/EnvironmentVariable.java | 98 +++++++++++-------- .../model/IObjectFieldSelector.java | 4 +- .../model/v1/ReplicationControllerTest.java | 55 ++++++----- .../openshift3/v1_replication_controller.json | 24 ++++- 4 files changed, 111 insertions(+), 70 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java b/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java index 060770a2..ea768236 100644 --- a/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java +++ b/src/main/java/com/openshift/internal/restclient/model/EnvironmentVariable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2020 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -25,6 +25,11 @@ public class EnvironmentVariable extends ModelNodeAdapter implements IEnvironmentVariable, ResourcePropertyKeys { + private static final String PROP_VALUE_FROM = "valueFrom"; + private static final String PROP_FIELD_REF = "fieldRef"; + private static final String PROP_CONFIG_MAP_KEY_REF = "configMapKeyRef"; + private static final String PROP_SECRET_KEY_REF = "secretKeyRef"; + public EnvironmentVariable(ModelNode node, Map propertyKeys) { super(node, propertyKeys); } @@ -41,50 +46,61 @@ public String getValue() { @Override public IEnvVarSource getValueFrom() { - if (getNode().hasDefined("fieldRef")) { - return new IObjectFieldSelector() { - @Override - public String getApiVersion() { - return asString(getNode(), getPropertyKeys(), "fieldRef.apiVersion"); - } - - @Override - public String getFieldPath() { - return asString(getNode(), getPropertyKeys(), "fieldRef.fieldPath"); - } - - }; - } else if (getNode().hasDefined("configMapKeyRef")) { - return new IConfigMapKeySelector() { - - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), "configMapKeyRef.name"); - } - - @Override - public String getKey() { - return asString(getNode(), getPropertyKeys(), "configMapKeyRef.key"); - } - }; - - } else if (getNode().hasDefined("secretKeyRef")) { - return new ISecretKeySelector() { - - @Override - public String getName() { - return asString(getNode(), getPropertyKeys(), "secretKeyRef.name"); - } - - @Override - public String getKey() { - return asString(getNode(), getPropertyKeys(), "secretKeyRef.key"); - } - }; + ModelNode valueFrom = getNode().get(PROP_VALUE_FROM); + if (valueFrom == null) { + return null; + } + if (valueFrom.hasDefined(PROP_FIELD_REF)) { + return createObjectFieldSelector(valueFrom); + } else if (valueFrom.hasDefined(PROP_CONFIG_MAP_KEY_REF)) { + return createConfigMapKeySelector(valueFrom); + } else if (valueFrom.hasDefined(PROP_SECRET_KEY_REF)) { + return createSecretKeySelector(valueFrom); } return null; } + private IEnvVarSource createSecretKeySelector(ModelNode valueFrom) { + return new ISecretKeySelector() { + + @Override + public String getName() { + return asString(valueFrom, getPropertyKeys(), PROP_SECRET_KEY_REF + ".name"); + } + + @Override + public String getKey() { + return asString(valueFrom, getPropertyKeys(), PROP_SECRET_KEY_REF + ".key"); + } + }; + } + + private IEnvVarSource createConfigMapKeySelector(ModelNode valueFrom) { + return new IConfigMapKeySelector() { + + @Override + public String getName() { + return asString(valueFrom, getPropertyKeys(), PROP_CONFIG_MAP_KEY_REF + ".name"); + } + + @Override + public String getKey() { + return asString(valueFrom, getPropertyKeys(), PROP_CONFIG_MAP_KEY_REF + ".key"); + } + }; + } + + private IEnvVarSource createObjectFieldSelector(ModelNode valueFrom) { + return new IObjectFieldSelector() { + + @Override + public String getFieldPath() { + return asString(valueFrom, getPropertyKeys(), PROP_FIELD_REF + ".fieldPath"); + } + + }; + } + @Override public boolean equals(Object object) { if (!(object instanceof IEnvironmentVariable)) { diff --git a/src/main/java/com/openshift/restclient/model/IObjectFieldSelector.java b/src/main/java/com/openshift/restclient/model/IObjectFieldSelector.java index fa931d0d..142d6316 100644 --- a/src/main/java/com/openshift/restclient/model/IObjectFieldSelector.java +++ b/src/main/java/com/openshift/restclient/model/IObjectFieldSelector.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Red Hat, Inc. + * Copyright (c) 2016-2020 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, @@ -15,7 +15,5 @@ public interface IObjectFieldSelector extends IEnvVarSource { - String getApiVersion(); - String getFieldPath(); } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java index 9f24cbfc..7a6a3563 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/ReplicationControllerTest.java @@ -72,37 +72,44 @@ public void setup() { ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.REPLICATION_CONTROLLER)); } - public void testGetEnvironmentVariablesWithValueFrom() { - + @Test + public void shouldReturnValueFrom_FieldRef() { Collection envVars = rc.getEnvironmentVariables(); - - // fieldref Optional envVar = envVars.stream() - .filter(e -> "OPENSHIFT_KUBE_PING_NAMESPACE".equals(e.getName())).findFirst(); - assertTrue("Exp. to find env var", envVar.isPresent()); + .filter(e -> "ENV_FIELD_REF".equals(e.getName())) + .findFirst(); + assertThat(envVar.isPresent()).isTrue(); IEnvVarSource from = envVar.get().getValueFrom(); - assertTrue(from instanceof IObjectFieldSelector); + assertThat(from).isInstanceOf(IObjectFieldSelector.class); IObjectFieldSelector selector = (IObjectFieldSelector) from; - assertEquals("v1", selector.getApiVersion()); - assertEquals("metadata.namespace", selector.getFieldPath()); - - // configmapkeyref - envVar = envVars.stream().filter(e -> "OPENSHIFT_CONFIGMAP_KEY_REF".equals(e.getName())).findFirst(); - assertTrue("Exp. to find env var", envVar.isPresent()); - from = envVar.get().getValueFrom(); - assertTrue(from instanceof IConfigMapKeySelector); + assertThat(selector.getFieldPath()).isEqualTo("metadata.namespace"); + } + + @Test + public void shouldReturnValueFrom_ConfigMapKeyRef() { + Collection envVars = rc.getEnvironmentVariables(); + Optional envVar = envVars.stream() + .filter(e -> "ENV_CONFIGMAPKEY_REF".equals(e.getName())) + .findFirst(); + assertThat(envVar.isPresent()).isTrue(); + IEnvVarSource from = envVar.get().getValueFrom(); + assertThat(from).isInstanceOf(IConfigMapKeySelector.class); IConfigMapKeySelector configSelector = (IConfigMapKeySelector) from; - assertEquals("xyz", configSelector.getName()); - assertEquals("abc123", configSelector.getKey()); + assertThat(configSelector.getName()).isEqualTo("env-config", configSelector.getName()); + assertThat(configSelector.getKey()).isEqualTo("log_level"); + } - // secretkeyref - envVar = envVars.stream().filter(e -> "OPENSHIFT_SECRET_KEY_REF".equals(e.getName())).findFirst(); - assertTrue("Exp. to find env var", envVar.isPresent()); - from = envVar.get().getValueFrom(); - assertTrue(from instanceof ISecretKeySelector); + @Test + public void shouldReturnValueFrom_SecretKeyRef() { + Collection envVars = rc.getEnvironmentVariables(); + + Optional envVar = envVars.stream().filter(e -> "ENV_SECRETKEY_REF".equals(e.getName())).findFirst(); + assertThat(envVar.isPresent()).isTrue(); + IEnvVarSource from = envVar.get().getValueFrom(); + assertThat(from).isInstanceOf(ISecretKeySelector.class); ISecretKeySelector secretKeySelector = (ISecretKeySelector) from; - assertEquals("bar", secretKeySelector.getName()); - assertEquals("foo", secretKeySelector.getKey()); + assertThat(secretKeySelector.getName()).isEqualTo("nodejs-mongo-persistent"); + assertThat(secretKeySelector.getKey()).isEqualTo("database-user"); } @Test diff --git a/src/test/resources/samples/openshift3/v1_replication_controller.json b/src/test/resources/samples/openshift3/v1_replication_controller.json index ca23a6db..6373d646 100644 --- a/src/test/resources/samples/openshift3/v1_replication_controller.json +++ b/src/test/resources/samples/openshift3/v1_replication_controller.json @@ -65,8 +65,28 @@ { "name": "MYSQL_DATABASE", "value": "root" - } - ], + }, + { + "name": "ENV_FIELD_REF", + "valueFrom": { "fieldRef": { + "fieldPath": "metadata.namespace" + }} + }, + { + "name": "ENV_CONFIGMAPKEY_REF", + "valueFrom": { "configMapKeyRef": { + "name": "env-config", + "key": "log_level" + }} + }, + { + "name" : "ENV_SECRETKEY_REF", + "valueFrom" : { "secretKeyRef" : { + "name" : "nodejs-mongo-persistent", + "key" : "database-user" + }} + } + ], "resources": {}, "terminationMessagePath": "/dev/termination-log", "imagePullPolicy": "Always", From 107d02c60f0fed16a9d46caba42db292bcc90c31 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 15 Apr 2020 15:55:15 +0200 Subject: [PATCH 231/258] bumping to 9.0.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb47a693..05572762 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 8.1.3-SNAPSHOT + 9.0.0.Final jar OpenShift Java REST Client http://openshift.redhat.com From 1c3bbcfdbda38ac7fb4cc84a711e2eeeff2e8420 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 11 May 2020 11:01:25 +0200 Subject: [PATCH 232/258] bump to 9.0.1-SNAPSHOT after release of 9.0.0.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 05572762..cf7fb23c 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.0.Final + 9.0.1-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From cf0cc58252e07bcd185963848c51ad215734654e Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 18 Jun 2020 12:48:52 +0200 Subject: [PATCH 233/258] ClassCastException when fetching RoleBindings on OCP4 Fixes #451 Signed-off-by: Jeff MAURY --- src/main/resources/k8stypes.properties | 2 +- .../restclient/TypeMapperFixture.java | 4 +- .../model/authorization/RoleBindingTest.java | 60 ++++++++ .../openshift/restclient/utils/Samples.java | 5 +- .../v1/rolebindings.json | 139 +++++++++++++++++ .../v1/rolebindings.json | 140 ++++++++++++++++++ 6 files changed, 346 insertions(+), 4 deletions(-) create mode 100644 src/test/java/com/openshift/internal/restclient/model/authorization/RoleBindingTest.java create mode 100644 src/test/resources/samples/k8s/rbac.authorization.k8s.io/v1/rolebindings.json create mode 100644 src/test/resources/samples/openshift3/authorization.openshift.io/v1/rolebindings.json diff --git a/src/main/resources/k8stypes.properties b/src/main/resources/k8stypes.properties index b864e2ca..7e909ed1 100644 --- a/src/main/resources/k8stypes.properties +++ b/src/main/resources/k8stypes.properties @@ -37,7 +37,7 @@ com.openshift.internal.restclient.model.project.OpenshiftProjectRequest=v1.Proje com.openshift.internal.restclient.model.authorization.OpenshiftRole=v1.Role,authorization.openshift.io/v1.Role com.openshift.internal.restclient.model.user.OpenShiftUser=v1.User,user.openshift.io/v1.User com.openshift.internal.restclient.model.Project=v1.Project,project.openshift.io/v1.Project -com.openshift.internal.restclient.model.authorization.RoleBinding=v1.RoleBinding,authorization.openshift.io/v1.RoleBinding +com.openshift.internal.restclient.model.authorization.RoleBinding=v1.RoleBinding,authorization.openshift.io/v1.RoleBinding,rbac.authorization.k8s.io/v1.RoleBinding com.openshift.internal.restclient.model.Route=v1.Route,route.openshift.io/v1.Route com.openshift.internal.restclient.model.template.Template=v1.Template,template.openshift.io/v1.Template com.openshift.internal.restclient.model.deploy.DeploymentRequest=v1.DeploymentRequest,apps.openshift.io/v1.DeploymentRequest diff --git a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java index 15a25f52..d4e12ffe 100644 --- a/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java +++ b/src/test/java/com/openshift/internal/restclient/TypeMapperFixture.java @@ -80,9 +80,9 @@ public void setUp() throws Exception { mapper = new ApiTypeMapper(base, client, null); } - static class TestOkHttpClient extends OkHttpClient { + protected static class TestOkHttpClient extends OkHttpClient { - void whenRequestTo(String url, Response response) throws IOException { + public void whenRequestTo(String url, Response response) throws IOException { Call call = mock(Call.class); doReturn(response).when(call).execute(); doReturn(call).when(this).newCall(requestTo(url)); diff --git a/src/test/java/com/openshift/internal/restclient/model/authorization/RoleBindingTest.java b/src/test/java/com/openshift/internal/restclient/model/authorization/RoleBindingTest.java new file mode 100644 index 00000000..109e9e1f --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/model/authorization/RoleBindingTest.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * Copyright (c) 2020 Red Hat, Inc. + * Distributed under license by Red Hat, Inc. All rights reserved. + * This program is made available under the terms of the + * Eclipse Public License v2.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v20.html + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + ******************************************************************************/ +package com.openshift.internal.restclient.model.authorization; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.List; + +import org.junit.Test; + +import com.openshift.internal.restclient.TypeMapperFixture; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.utils.Samples; + +/** + * @author Red Hat Developers + * + */ +public class RoleBindingTest extends TypeMapperFixture { + + private static final String RBAC_OCP4_GROUP = "{\"kind\":\"APIGroupList\",\"apiVersion\":\"v1\",\"groups\":[{\"name\":\"rbac.authorization.k8s.io\",\"versions\":[{\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"version\":\"v1\"},{\"groupVersion\":\"rbac.authorization.k8s.io/v1beta1\",\"version\":\"v1beta1\"}],\"preferredVersion\":{\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"version\":\"v1\"}}]}"; + + private static final String RBAC_OCP4_RESOURCE = "{\"kind\":\"APIResourceList\",\"apiVersion\":\"v1\",\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"resources\":[{\"name\":\"clusterrolebindings\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRoleBinding\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"48tpQ8gZHFc=\"},{\"name\":\"clusterroles\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRole\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"bYE5ZWDrJ44=\"},{\"name\":\"rolebindings\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBinding\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"eGsCzGH6b1g=\"},{\"name\":\"roles\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"Role\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"7FuwZcIIItM=\"}]}"; + + private static final String RBAC_OCP3_GROUP = "{\"kind\":\"APIGroupList\",\"apiVersion\":\"v1\",\"groups\":[{\"name\":\"authorization.openshift.io\",\"versions\":[{\"groupVersion\":\"authorization.openshift.io/v1\",\"version\":\"v1\"}],\"preferredVersion\":{\"groupVersion\":\"authorization.openshift.io/v1\",\"version\":\"v1\"}}]}"; + + private static final String RBAC_OCP3_RESOURCE = "{\"kind\":\"APIResourceList\",\"apiVersion\":\"v1\",\"groupVersion\":\"authorization.openshift.io/v1\",\"resources\":[{\"name\":\"clusterrolebindings\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRoleBinding\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"clusterroles\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRole\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"localresourceaccessreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"LocalResourceAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"localsubjectaccessreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"LocalSubjectAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"resourceaccessreviews\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ResourceAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"rolebindingrestrictions\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBindingRestriction\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"]},{\"name\":\"rolebindings\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBinding\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"roles\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"Role\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"selfsubjectrulesreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"SelfSubjectRulesReview\",\"verbs\":[\"create\"]},{\"name\":\"subjectaccessreviews\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"SubjectAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"subjectrulesreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"SubjectRulesReview\",\"verbs\":[\"create\"]}]}"; + + @Test + public void checkRoleBindingListOCP4() throws Exception { + getHttpClient().whenRequestTo(base + "/oapi", responseOf("")); + getHttpClient().whenRequestTo(base + "/apis", responseOf(RBAC_OCP4_GROUP)); + getHttpClient().whenRequestTo(base + "/apis/rbac.authorization.k8s.io/v1", responseOf(RBAC_OCP4_RESOURCE)); + getHttpClient().whenRequestTo(base + "/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings", responseOf(Samples.RBAC_AUTHORIZATION_K8S_IO_ROLEBINDINGS.getContentAsString())); + List roleBindings = getIClient().list(ResourceKind.ROLE_BINDING, "default"); + assertFalse(roleBindings.isEmpty()); + assertEquals(RoleBinding.class, roleBindings.get(0).getClass()); + } + + @Test + public void checkRoleBindingListOCP3() throws Exception { + getHttpClient().whenRequestTo(base + "/oapi", responseOf("")); + getHttpClient().whenRequestTo(base + "/apis", responseOf(RBAC_OCP3_GROUP)); + getHttpClient().whenRequestTo(base + "/apis/authorization.openshift.io/v1", responseOf(RBAC_OCP3_RESOURCE)); + getHttpClient().whenRequestTo(base + "/apis/authorization.openshift.io/v1/namespaces/default/rolebindings", responseOf(Samples.AUTHORIZATION_OPENSHIFT_IO_ROLEBINDINGS.getContentAsString())); + List roleBindings = getIClient().list(ResourceKind.ROLE_BINDING, "default"); + assertFalse(roleBindings.isEmpty()); + assertEquals(RoleBinding.class, roleBindings.get(0).getClass()); + } + +} diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 7392b3eb..3b360f21 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -75,7 +75,10 @@ public enum Samples { V1_LIFECYCLE("openshift3/v1_lifecycle.json"), V1_DOCKER_IMAGE_MANIFEST("dockerregistry/v1_image_manifest.json"), V1_BUILDCONFIG_PIPELINE("openshift3/v1_buildconfig_pipeline.json"), - V1_CONFIGMAP_CONSOLE_PUBLIC("openshift3/v1_config_map_console_public.json"); + V1_CONFIGMAP_CONSOLE_PUBLIC("openshift3/v1_config_map_console_public.json"), + + RBAC_AUTHORIZATION_K8S_IO_ROLEBINDINGS("k8s/rbac.authorization.k8s.io/v1/rolebindings.json"), + AUTHORIZATION_OPENSHIFT_IO_ROLEBINDINGS("openshift3/authorization.openshift.io/v1/rolebindings.json"); private static final String SAMPLES_FOLDER = "/samples/"; diff --git a/src/test/resources/samples/k8s/rbac.authorization.k8s.io/v1/rolebindings.json b/src/test/resources/samples/k8s/rbac.authorization.k8s.io/v1/rolebindings.json new file mode 100644 index 00000000..0f54f9a0 --- /dev/null +++ b/src/test/resources/samples/k8s/rbac.authorization.k8s.io/v1/rolebindings.json @@ -0,0 +1,139 @@ +{ + "apiVersion": "v1", + "items": [ + { + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "RoleBinding", + "metadata": { + "creationTimestamp": "2020-04-16T14:37:03Z", + "name": "machine-config-daemon-events", + "namespace": "default", + "resourceVersion": "2388", + "selfLink": "/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings/machine-config-daemon-events", + "uid": "ffc653d7-9cb1-4af9-89d4-1aa95512b1fd" + }, + "roleRef": { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "ClusterRole", + "name": "machine-config-daemon-events" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "machine-config-daemon", + "namespace": "openshift-machine-config-operator" + } + ] + }, + { + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "RoleBinding", + "metadata": { + "creationTimestamp": "2020-04-16T15:05:23Z", + "name": "prometheus-k8s", + "namespace": "default", + "resourceVersion": "15971", + "selfLink": "/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings/prometheus-k8s", + "uid": "016e7037-7081-45ef-bf3c-3f75773b0ef9" + }, + "roleRef": { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "Role", + "name": "prometheus-k8s" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "prometheus-k8s", + "namespace": "openshift-monitoring" + } + ] + }, + { + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "RoleBinding", + "metadata": { + "annotations": { + "openshift.io/description": "Allows deploymentconfigs in this namespace to rollout pods in this namespace. It is auto-managed by a controller; remove subjects to disable." + }, + "creationTimestamp": "2020-04-16T14:42:27Z", + "name": "system:deployers", + "namespace": "default", + "resourceVersion": "6343", + "selfLink": "/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings/system:deployers", + "uid": "686aef1c-9b44-4b14-b618-7b795dce8afb" + }, + "roleRef": { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "ClusterRole", + "name": "system:deployer" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "deployer", + "namespace": "default" + } + ] + }, + { + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "RoleBinding", + "metadata": { + "annotations": { + "openshift.io/description": "Allows builds in this namespace to push images to this namespace. It is auto-managed by a controller; remove subjects to disable." + }, + "creationTimestamp": "2020-04-16T14:42:27Z", + "name": "system:image-builders", + "namespace": "default", + "resourceVersion": "6309", + "selfLink": "/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings/system:image-builders", + "uid": "168be431-6fb1-4ff2-b31d-69f25425da20" + }, + "roleRef": { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "ClusterRole", + "name": "system:image-builder" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "builder", + "namespace": "default" + } + ] + }, + { + "apiVersion": "rbac.authorization.k8s.io/v1", + "kind": "RoleBinding", + "metadata": { + "annotations": { + "openshift.io/description": "Allows all pods in this namespace to pull images from this namespace. It is auto-managed by a controller; remove subjects to disable." + }, + "creationTimestamp": "2020-04-16T14:42:26Z", + "name": "system:image-pullers", + "namespace": "default", + "resourceVersion": "6276", + "selfLink": "/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings/system:image-pullers", + "uid": "0ce48cfa-80c0-4ec0-a6ba-e7f10aa8ed9c" + }, + "roleRef": { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "ClusterRole", + "name": "system:image-puller" + }, + "subjects": [ + { + "apiGroup": "rbac.authorization.k8s.io", + "kind": "Group", + "name": "system:serviceaccounts:default" + } + ] + } + ], + "kind": "List", + "metadata": { + "resourceVersion": "", + "selfLink": "" + } +} diff --git a/src/test/resources/samples/openshift3/authorization.openshift.io/v1/rolebindings.json b/src/test/resources/samples/openshift3/authorization.openshift.io/v1/rolebindings.json new file mode 100644 index 00000000..2d1a29c6 --- /dev/null +++ b/src/test/resources/samples/openshift3/authorization.openshift.io/v1/rolebindings.json @@ -0,0 +1,140 @@ +{ + "apiVersion": "v1", + "items": [ + { + "apiVersion": "authorization.openshift.io/v1", + "groupNames": null, + "kind": "RoleBinding", + "metadata": { + "creationTimestamp": "2019-03-06T15:28:13Z", + "name": "admin", + "namespace": "jbosstools", + "resourceVersion": "231467480", + "selfLink": "/apis/authorization.openshift.io/v1/namespaces/jbosstools/rolebindings/admin", + "uid": "74f6f212-4024-11e9-98a4-02e0bae989b4" + }, + "roleRef": { + "name": "admin" + }, + "subjects": [ + { + "kind": "User", + "name": "105985317302514941658" + } + ], + "userNames": [ + "105985317302514941658" + ] + }, + { + "apiVersion": "authorization.openshift.io/v1", + "groupNames": null, + "kind": "RoleBinding", + "metadata": { + "creationTimestamp": "2019-03-06T15:28:13Z", + "name": "project-owner", + "namespace": "jbosstools", + "resourceVersion": "231467483", + "selfLink": "/apis/authorization.openshift.io/v1/namespaces/jbosstools/rolebindings/project-owner", + "uid": "74f7fe60-4024-11e9-98a4-02e0bae989b4" + }, + "roleRef": { + "name": "project-owner" + }, + "subjects": [ + { + "kind": "User", + "name": "105985317302514941658" + } + ], + "userNames": [ + "105985317302514941658" + ] + }, + { + "apiVersion": "authorization.openshift.io/v1", + "groupNames": null, + "kind": "RoleBinding", + "metadata": { + "creationTimestamp": "2019-03-06T15:28:13Z", + "name": "system:deployers", + "namespace": "jbosstools", + "resourceVersion": "231467487", + "selfLink": "/apis/authorization.openshift.io/v1/namespaces/jbosstools/rolebindings/system%3Adeployers", + "uid": "74fb1262-4024-11e9-98a4-02e0bae989b4" + }, + "roleRef": { + "name": "system:deployer" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "deployer", + "namespace": "jbosstools" + } + ], + "userNames": [ + "system:serviceaccount:jbosstools:deployer" + ] + }, + { + "apiVersion": "authorization.openshift.io/v1", + "groupNames": null, + "kind": "RoleBinding", + "metadata": { + "creationTimestamp": "2019-03-06T15:28:13Z", + "name": "system:image-builders", + "namespace": "jbosstools", + "resourceVersion": "231467485", + "selfLink": "/apis/authorization.openshift.io/v1/namespaces/jbosstools/rolebindings/system%3Aimage-builders", + "uid": "74fa4045-4024-11e9-98a4-02e0bae989b4" + }, + "roleRef": { + "name": "system:image-builder" + }, + "subjects": [ + { + "kind": "ServiceAccount", + "name": "builder", + "namespace": "jbosstools" + } + ], + "userNames": [ + "system:serviceaccount:jbosstools:builder" + ] + }, + { + "apiVersion": "authorization.openshift.io/v1", + "groupNames": [ + "system:serviceaccounts:jbosstools" + ], + "kind": "RoleBinding", + "metadata": { + "annotations": { + "openshift.io/description": "Allows all pods in this namespace to pull images from this namespace. It is auto-managed by a controller; remove subjects to disable." + }, + "creationTimestamp": "2019-03-06T15:28:13Z", + "name": "system:image-pullers", + "namespace": "jbosstools", + "resourceVersion": "231467475", + "selfLink": "/apis/authorization.openshift.io/v1/namespaces/jbosstools/rolebindings/system%3Aimage-pullers", + "uid": "74f0bf3f-4024-11e9-8234-02fe3a6cfaba" + }, + "roleRef": { + "name": "system:image-puller" + }, + "subjects": [ + { + "kind": "SystemGroup", + "name": "system:serviceaccounts:jbosstools" + } + ], + "userNames": null + } + ], + "kind": "List", + "metadata": { + "resourceVersion": "", + "selfLink": "" + } +} From b4f8d2545948bad28ecefc9974cee235ebc5b1d1 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Thu, 18 Jun 2020 16:56:57 +0200 Subject: [PATCH 234/258] Fix checkstyle issues Signed-off-by: Jeff MAURY --- .../model/authorization/RoleBindingTest.java | 77 ++++++++++++------- 1 file changed, 51 insertions(+), 26 deletions(-) diff --git a/src/test/java/com/openshift/internal/restclient/model/authorization/RoleBindingTest.java b/src/test/java/com/openshift/internal/restclient/model/authorization/RoleBindingTest.java index 109e9e1f..8ae22562 100644 --- a/src/test/java/com/openshift/internal/restclient/model/authorization/RoleBindingTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/authorization/RoleBindingTest.java @@ -8,6 +8,7 @@ * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ + package com.openshift.internal.restclient.model.authorization; import static org.junit.Assert.assertEquals; @@ -27,34 +28,58 @@ */ public class RoleBindingTest extends TypeMapperFixture { - private static final String RBAC_OCP4_GROUP = "{\"kind\":\"APIGroupList\",\"apiVersion\":\"v1\",\"groups\":[{\"name\":\"rbac.authorization.k8s.io\",\"versions\":[{\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"version\":\"v1\"},{\"groupVersion\":\"rbac.authorization.k8s.io/v1beta1\",\"version\":\"v1beta1\"}],\"preferredVersion\":{\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"version\":\"v1\"}}]}"; + private static final String RBAC_OCP4_GROUP = "{\"kind\":\"APIGroupList\",\"apiVersion\":\"v1\",\"groups\":[{\"name\":\"rbac.authorization.k8s.io\",\"versions\":" + + "[{\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"version\":\"v1\"},{\"groupVersion\":\"rbac.authorization.k8s.io/v1beta1\",\"version\":\"v1beta1\"}]," + + "\"preferredVersion\":{\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"version\":\"v1\"}}]}"; - private static final String RBAC_OCP4_RESOURCE = "{\"kind\":\"APIResourceList\",\"apiVersion\":\"v1\",\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"resources\":[{\"name\":\"clusterrolebindings\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRoleBinding\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"48tpQ8gZHFc=\"},{\"name\":\"clusterroles\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRole\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"bYE5ZWDrJ44=\"},{\"name\":\"rolebindings\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBinding\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"eGsCzGH6b1g=\"},{\"name\":\"roles\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"Role\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"7FuwZcIIItM=\"}]}"; + private static final String RBAC_OCP4_RESOURCE = "{\"kind\":\"APIResourceList\",\"apiVersion\":\"v1\",\"groupVersion\":\"rbac.authorization.k8s.io/v1\",\"resources\"" + + ":[{\"name\":\"clusterrolebindings\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRoleBinding\",\"verbs\":[\"create\",\"delete\"," + + "\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"48tpQ8gZHFc=\"},{\"name\":\"clusterroles\",\"singularName\":" + + "\"\",\"namespaced\":false,\"kind\":\"ClusterRole\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"]," + + "\"storageVersionHash\":\"bYE5ZWDrJ44=\"},{\"name\":\"rolebindings\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBinding\",\"verbs\":[\"create\"," + + "\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"],\"storageVersionHash\":\"eGsCzGH6b1g=\"},{\"name\":\"roles\",\"singularName\":" + + "\"\",\"namespaced\":true,\"kind\":\"Role\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"]," + + "\"storageVersionHash\":\"7FuwZcIIItM=\"}]}"; - private static final String RBAC_OCP3_GROUP = "{\"kind\":\"APIGroupList\",\"apiVersion\":\"v1\",\"groups\":[{\"name\":\"authorization.openshift.io\",\"versions\":[{\"groupVersion\":\"authorization.openshift.io/v1\",\"version\":\"v1\"}],\"preferredVersion\":{\"groupVersion\":\"authorization.openshift.io/v1\",\"version\":\"v1\"}}]}"; + private static final String RBAC_OCP3_GROUP = "{\"kind\":\"APIGroupList\",\"apiVersion\":\"v1\",\"groups\":[{\"name\":\"authorization.openshift.io\",\"versions\":" + + "[{\"groupVersion\":\"authorization.openshift.io/v1\",\"version\":\"v1\"}],\"preferredVersion\":{\"groupVersion\":\"authorization.openshift.io/v1\"," + + "\"version\":\"v1\"}}]}"; - private static final String RBAC_OCP3_RESOURCE = "{\"kind\":\"APIResourceList\",\"apiVersion\":\"v1\",\"groupVersion\":\"authorization.openshift.io/v1\",\"resources\":[{\"name\":\"clusterrolebindings\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRoleBinding\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"clusterroles\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRole\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"localresourceaccessreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"LocalResourceAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"localsubjectaccessreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"LocalSubjectAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"resourceaccessreviews\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ResourceAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"rolebindingrestrictions\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBindingRestriction\",\"verbs\":[\"create\",\"delete\",\"deletecollection\",\"get\",\"list\",\"patch\",\"update\",\"watch\"]},{\"name\":\"rolebindings\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBinding\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"roles\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"Role\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"selfsubjectrulesreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"SelfSubjectRulesReview\",\"verbs\":[\"create\"]},{\"name\":\"subjectaccessreviews\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"SubjectAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"subjectrulesreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"SubjectRulesReview\",\"verbs\":[\"create\"]}]}"; - - @Test - public void checkRoleBindingListOCP4() throws Exception { - getHttpClient().whenRequestTo(base + "/oapi", responseOf("")); - getHttpClient().whenRequestTo(base + "/apis", responseOf(RBAC_OCP4_GROUP)); - getHttpClient().whenRequestTo(base + "/apis/rbac.authorization.k8s.io/v1", responseOf(RBAC_OCP4_RESOURCE)); - getHttpClient().whenRequestTo(base + "/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings", responseOf(Samples.RBAC_AUTHORIZATION_K8S_IO_ROLEBINDINGS.getContentAsString())); - List roleBindings = getIClient().list(ResourceKind.ROLE_BINDING, "default"); - assertFalse(roleBindings.isEmpty()); - assertEquals(RoleBinding.class, roleBindings.get(0).getClass()); - } - - @Test - public void checkRoleBindingListOCP3() throws Exception { - getHttpClient().whenRequestTo(base + "/oapi", responseOf("")); - getHttpClient().whenRequestTo(base + "/apis", responseOf(RBAC_OCP3_GROUP)); - getHttpClient().whenRequestTo(base + "/apis/authorization.openshift.io/v1", responseOf(RBAC_OCP3_RESOURCE)); - getHttpClient().whenRequestTo(base + "/apis/authorization.openshift.io/v1/namespaces/default/rolebindings", responseOf(Samples.AUTHORIZATION_OPENSHIFT_IO_ROLEBINDINGS.getContentAsString())); - List roleBindings = getIClient().list(ResourceKind.ROLE_BINDING, "default"); - assertFalse(roleBindings.isEmpty()); - assertEquals(RoleBinding.class, roleBindings.get(0).getClass()); - } + private static final String RBAC_OCP3_RESOURCE = "{\"kind\":\"APIResourceList\",\"apiVersion\":\"v1\",\"groupVersion\":\"authorization.openshift.io/v1\",\"resources\":" + + "[{\"name\":\"clusterrolebindings\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRoleBinding\",\"verbs\":[\"create\",\"delete\",\"get\",\"list\"," + + "\"patch\",\"update\"]},{\"name\":\"clusterroles\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ClusterRole\",\"verbs\":[\"create\",\"delete\",\"get\"," + + "\"list\",\"patch\",\"update\"]},{\"name\":\"localresourceaccessreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"LocalResourceAccessReview\"," + + "\"verbs\":[\"create\"]},{\"name\":\"localsubjectaccessreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"LocalSubjectAccessReview\",\"verbs\":" + + "[\"create\"]},{\"name\":\"resourceaccessreviews\",\"singularName\":\"\",\"namespaced\":false,\"kind\":\"ResourceAccessReview\",\"verbs\":[\"create\"]},{\"name\":" + + "\"rolebindingrestrictions\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBindingRestriction\",\"verbs\":[\"create\",\"delete\",\"deletecollection\"," + + "\"get\",\"list\",\"patch\",\"update\",\"watch\"]},{\"name\":\"rolebindings\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"RoleBinding\",\"verbs\":" + + "[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"roles\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"Role\",\"verbs\":" + + "[\"create\",\"delete\",\"get\",\"list\",\"patch\",\"update\"]},{\"name\":\"selfsubjectrulesreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":" + + "\"SelfSubjectRulesReview\",\"verbs\":[\"create\"]},{\"name\":\"subjectaccessreviews\",\"singularName\":\"\",\"namespaced\":false,\"kind\":" + + "\"SubjectAccessReview\",\"verbs\":[\"create\"]},{\"name\":\"subjectrulesreviews\",\"singularName\":\"\",\"namespaced\":true,\"kind\":\"SubjectRulesReview\"," + + "\"verbs\":[\"create\"]}]}"; + + @Test + public void checkRoleBindingListOCP4() throws Exception { + getHttpClient().whenRequestTo(base + "/oapi", responseOf("")); + getHttpClient().whenRequestTo(base + "/apis", responseOf(RBAC_OCP4_GROUP)); + getHttpClient().whenRequestTo(base + "/apis/rbac.authorization.k8s.io/v1", responseOf(RBAC_OCP4_RESOURCE)); + getHttpClient().whenRequestTo(base + "/apis/rbac.authorization.k8s.io/v1/namespaces/default/rolebindings", + responseOf(Samples.RBAC_AUTHORIZATION_K8S_IO_ROLEBINDINGS.getContentAsString())); + List roleBindings = getIClient().list(ResourceKind.ROLE_BINDING, "default"); + assertFalse(roleBindings.isEmpty()); + assertEquals(RoleBinding.class, roleBindings.get(0).getClass()); + } + @Test + public void checkRoleBindingListOCP3() throws Exception { + getHttpClient().whenRequestTo(base + "/oapi", responseOf("")); + getHttpClient().whenRequestTo(base + "/apis", responseOf(RBAC_OCP3_GROUP)); + getHttpClient().whenRequestTo(base + "/apis/authorization.openshift.io/v1", responseOf(RBAC_OCP3_RESOURCE)); + getHttpClient().whenRequestTo(base + "/apis/authorization.openshift.io/v1/namespaces/default/rolebindings", + responseOf(Samples.AUTHORIZATION_OPENSHIFT_IO_ROLEBINDINGS.getContentAsString())); + List roleBindings = getIClient().list(ResourceKind.ROLE_BINDING, "default"); + assertFalse(roleBindings.isEmpty()); + assertEquals(RoleBinding.class, roleBindings.get(0).getClass()); + } } From 09e412a72d3dd3e5003e6fd3544cae6b9d9f308c Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 21 Jul 2020 18:42:41 +0200 Subject: [PATCH 235/258] added warning about maintenance mode Signed-off-by: Andre Dietisheim --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 590ced05..4f52894e 100755 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ OpenShift Java REST Client [![Travis](https://travis-ci.org/openshift/openshift-restclient-java.svg?branch=master)](https://travis-ci.org/openshift/openshift-restclient-java) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.openshift/openshift-restclient-java/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.openshift/openshift-restclient-java) +**The project is now in the maintenance mode. Only critical bugs will be fixed, and there won’t be any more feature development. Please consider moving to the OpenShift client library that's developed by the great team at [fabric8](https://github.com/fabric8io/kubernetes-client/).** + This is the Java REST client for the version 3 architecture of [OpenShift](https://github.com/openshift/origin) based on Kubernetes. The implementation is a work in progress to provide similar functionality and features of the command-line interface and is used by JBoss Tools for OpenShift. For compatibility with OpenShift 2.x see https://github.com/openshift/openshift-java-client/. From fb60df1166f3626b6bd8c4092ba4ec7fa3f82208 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 21 Jul 2020 23:36:12 +0200 Subject: [PATCH 236/258] lowered logging level for non harmful request failures (#450) Signed-off-by: Andre Dietisheim --- .../openshift/internal/restclient/AuthorizationEndpoints.java | 2 +- .../com/openshift/internal/restclient/RequestingSupplier.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/AuthorizationEndpoints.java b/src/main/java/com/openshift/internal/restclient/AuthorizationEndpoints.java index dea935c6..5e159e2b 100644 --- a/src/main/java/com/openshift/internal/restclient/AuthorizationEndpoints.java +++ b/src/main/java/com/openshift/internal/restclient/AuthorizationEndpoints.java @@ -61,7 +61,7 @@ private URL getEndpoint(Function extractor, String descriptio try { authorizationEndpoint = new URL(extractor.apply(node)); } catch (MalformedURLException e) { - LOGGER.error("Failed to determine {}.", description, e); + LOGGER.info("Failed to determine {}.", description, e); } } } catch (IllegalArgumentException e) { diff --git a/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java b/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java index 5a58f24e..e7406ddb 100644 --- a/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java +++ b/src/main/java/com/openshift/internal/restclient/RequestingSupplier.java @@ -72,7 +72,7 @@ protected T request(String url) throws IOException { && response.isSuccessful()) { this.value = extractValue(response.body().string()); } else { - LOGGER.error("Failed to determine {}: got {}", description, + LOGGER.info("Failed to determine {}: got {}", description, response == null ? "null" : response.code()); } } From 394f68504ce5a20d0aab2ba23714d909c6ca0b53 Mon Sep 17 00:00:00 2001 From: linyx002 <85302543@qq.com> Date: Wed, 22 Jul 2020 21:28:11 +0800 Subject: [PATCH 237/258] Fix (#456) --- src/main/java/com/openshift/restclient/http/IHttpConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/openshift/restclient/http/IHttpConstants.java b/src/main/java/com/openshift/restclient/http/IHttpConstants.java index 2c923d2b..4a9cfee1 100644 --- a/src/main/java/com/openshift/restclient/http/IHttpConstants.java +++ b/src/main/java/com/openshift/restclient/http/IHttpConstants.java @@ -44,7 +44,7 @@ public interface IHttpConstants { static final String PROPERTY_ACCESS_TOKEN = "access_token"; public static final String MEDIATYPE_ANY = "*/*"; - public static final String MEDIATYPE_APPLICATION_JSON = "application/json"; + public static final String MEDIATYPE_APPLICATION_JSON = "application/json;charset=utf-8"; public static final String MEDIATYPE_APPLICATION_XML = "application/xml"; public static final String MEDIATYPE_APPLICATION_FORMURLENCODED = "application/x-www-form-urlencoded"; public static final String MEDIATYPE_APPLICATION_OCTET_STREAM = "application/octet-stream"; From 9f1458209b41c5f471c42749e0da44217e6650ff Mon Sep 17 00:00:00 2001 From: alfonzjanfrithz Date: Mon, 27 Jul 2020 12:18:55 +0800 Subject: [PATCH 238/258] Add test to ensure null payload is transformed into empty string --- .../restclient/DefaultClientTest.java | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java index 7af38f52..a6ca35cf 100644 --- a/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/DefaultClientTest.java @@ -46,6 +46,9 @@ import okhttp3.Request.Builder; import okhttp3.RequestBody; import okio.Buffer; +import okio.BufferedSink; +import okio.Okio; +import okio.Source; /** * @author Jeff Cantrill @@ -158,7 +161,7 @@ public void client_should_not_equal_client_with_different_username() throws Exce } @Test - public void should_use_paylod_in_delete_request() throws IOException { + public void should_use_payload_in_delete_request() throws IOException { // given DefaultClient client = spy(this.client); @@ -177,7 +180,7 @@ public void should_use_paylod_in_delete_request() throws IOException { } @Test - public void should_use_paylod_in_post_request() throws IOException { + public void should_use_payload_in_post_request() throws IOException { // given DefaultClient client = spy(this.client); @@ -196,7 +199,7 @@ public void should_use_paylod_in_post_request() throws IOException { } @Test - public void should_use_paylod_in_put_request() throws IOException { + public void should_use_payload_in_put_request() throws IOException { // given DefaultClient client = spy(this.client); @@ -215,7 +218,7 @@ public void should_use_paylod_in_put_request() throws IOException { } @Test - public void should_not_use_paylod_in_get_request() throws IOException { + public void should_not_use_payload_in_get_request() throws IOException { // given DefaultClient client = spy(this.client); @@ -233,7 +236,7 @@ public void should_not_use_paylod_in_get_request() throws IOException { } @Test - public void should_not_use_paylod_in_head_request() throws IOException { + public void should_not_use_payload_in_head_request() throws IOException { // given DefaultClient client = spy(this.client); @@ -269,6 +272,25 @@ public void should_not_send_resource_payload_when_deleting() throws IOException assertThat(bodyCaptor.getValue().contentLength()).isEqualTo(0); } + @Test + public void should_transform_input_to_empty_string_when_payload_is_null() throws IOException { + // given + DefaultClient client = spy(this.client); + RequestBody payload = client.getPayload(null, HttpMethod.DELETE.name()); + + BufferedSink bufferedSink = mock(BufferedSink.class); + ArgumentCaptor bodyCaptor = ArgumentCaptor.forClass(Source.class); + + // when + payload.writeTo(bufferedSink); + + // then + verify(bufferedSink).writeAll(bodyCaptor.capture()); + String actualPayload = Okio.buffer(bodyCaptor.getValue()).readUtf8(); + + assertThat(actualPayload).isEqualTo(""); + } + private String getPayload(Builder builder, ArgumentCaptor builderCaptor) throws IOException { verify(builder).method(anyString(), builderCaptor.capture()); RequestBody requestBody = builderCaptor.getValue(); From 9d5a7dc777ba2c24c793afd72db59330ae0e41c5 Mon Sep 17 00:00:00 2001 From: alfonzjanfrithz Date: Mon, 27 Jul 2020 12:20:03 +0800 Subject: [PATCH 239/258] Transform the input stream to empty string when null is found --- .../com/openshift/internal/restclient/DefaultClient.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index c51ceb21..bf3165d3 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Objects; +import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.jboss.dmr.ModelNode; import org.slf4j.Logger; @@ -339,19 +340,19 @@ private RequestBody getPayload(JSONSerializeable payload, String method) { return RequestBody.create(json, MediaType.parse(MEDIATYPE_APPLICATION_JSON)); } - - private RequestBody getPayload(InputStream payload, String method) { + RequestBody getPayload(InputStream payload, String method) { if(isPayloadlessMethod(method)) { return null; } + InputStream input = payload == null ? IOUtils.toInputStream("") : payload; LOGGER.debug("About to send binary payload"); return new RequestBody() { @Override public void writeTo(BufferedSink sink) throws IOException { - Source source = Okio.source(payload); + Source source = Okio.source(input); sink.writeAll(source); } - + @Override public MediaType contentType() { return MediaType.parse(MEDIATYPE_APPLICATION_OCTET_STREAM); From 5f0cb0a550b5de8af52cb298f33869f97e6dd50f Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 4 Aug 2020 12:43:27 +0200 Subject: [PATCH 240/258] impl'd AuthorizationContext#invalidate (#455) (#461) Signed-off-by: Andre Dietisheim --- .../authorization/AuthorizationContext.java | 8 +++ .../authorization/IAuthorizationContext.java | 6 ++ .../AuthorizationContextTest.java | 66 +++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 src/test/java/com/openshift/internal/restclient/authorization/AuthorizationContextTest.java diff --git a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java index ca3df0db..a503c35a 100644 --- a/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java +++ b/src/main/java/com/openshift/internal/restclient/authorization/AuthorizationContext.java @@ -120,4 +120,12 @@ public String getPassword() { return this.password; } + @Override + public void invalidate() { + this.user = null; + this.token = null; + } + + + } diff --git a/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java b/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java index c0be3a4f..a73dd2a2 100644 --- a/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java +++ b/src/main/java/com/openshift/restclient/authorization/IAuthorizationContext.java @@ -87,4 +87,10 @@ public interface IAuthorizationContext { * */ IAuthorizationDetails getAuthorizationDetails(); + + /** + * Invalidates this context which forces re-authentication. The context gets unauthenticated, + * User and token are cleared. + */ + void invalidate(); } diff --git a/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationContextTest.java b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationContextTest.java new file mode 100644 index 00000000..590349c0 --- /dev/null +++ b/src/test/java/com/openshift/internal/restclient/authorization/AuthorizationContextTest.java @@ -0,0 +1,66 @@ +/******************************************************************************* +* Copyright (c) 2020 Red Hat, Inc. Distributed under license by Red Hat, Inc. +* All rights reserved. This program is 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: Red Hat, Inc. +******************************************************************************/ + +package com.openshift.internal.restclient.authorization; + + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import org.jboss.dmr.ModelNode; +import org.junit.Before; +import org.junit.Test; + +import com.openshift.internal.restclient.model.properties.ResourcePropertiesRegistry; +import com.openshift.internal.restclient.model.user.OpenShiftUser; +import com.openshift.restclient.IClient; +import com.openshift.restclient.ResourceKind; +import com.openshift.restclient.model.user.IUser; +import com.openshift.restclient.utils.Samples; + +public class AuthorizationContextTest { + + private static final String VERSION = "v1"; + private static String TOKEN = "42"; + private static String EXPIRES = "84"; + private static String SCHEME = "Scheme"; + private AuthorizationContext context; + private IClient client; + + @Before + public void setup() throws Exception { + IUser user = mock(IUser.class); + this.context = new AuthorizationContext(TOKEN, EXPIRES, user, SCHEME); + this.client = createClient(); + context.setClient(client); + } + + private IClient createClient() { + IClient client = mock(IClient.class); + ModelNode node = ModelNode.fromJSONString(Samples.V1_USER.getContentAsString()); + IUser user = new OpenShiftUser(node, client, + ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.USER)); + doReturn(user).when(client).get(ResourceKind.USER, "~", ""); + return client; + } + + @Test + public void invalidateShouldForceNewUserRequestWhenEventualIsAuthorized() { + // given + assertThat(context.isAuthorized()).isTrue(); + context.invalidate(); + // when + context.isAuthorized(); + // then + verify(client, times(1)).get(ResourceKind.USER, "~", ""); + } +} From 16329fb1c45883dc0dfeba1ee3dde2db10bccd27 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 10 Aug 2020 14:50:23 +0200 Subject: [PATCH 241/258] corrected logging for inaccessible legacy apis to info (#462) Signed-off-by: Andre Dietisheim --- .../com/openshift/internal/restclient/ApiTypeMapper.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java index 07a9e4e2..f1863c85 100644 --- a/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java +++ b/src/main/java/com/openshift/internal/restclient/ApiTypeMapper.java @@ -242,13 +242,13 @@ private Collection getResources(IApiGroup group, String version) { private Collection getLegacyGroups() { Collection groups = new ArrayList<>(); - for (String e : Arrays.asList(KUBE_API, OS_API)) { + for (String endpoint : Arrays.asList(KUBE_API, OS_API)) { try { - String json = readEndpoint(e); + String json = readEndpoint(endpoint); ModelNode n = ModelNode.fromJSONString(json); - groups.add(new LegacyApiGroup(e, n)); + groups.add(new LegacyApiGroup(endpoint, n)); } catch (Exception ex) { - LOGGER.error("Can't access legacy endpoint {}", e); + LOGGER.info("Can't access legacy endpoint {}", endpoint, ex); } } return groups; From 79bbac269adbf40720f0c6667bedf8da6d7d3951 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 22 Sep 2020 12:01:55 +0200 Subject: [PATCH 242/258] bump to 9.0.1.Final (#466) Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cf7fb23c..0a388196 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.1-SNAPSHOT + 9.0.1.Final jar OpenShift Java REST Client http://openshift.redhat.com From 22ce4644a4b257e8b8be9914cb70b575e78f50bb Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 22 Sep 2020 12:06:43 +0200 Subject: [PATCH 243/258] bump to 9.0.2-SNAPSHOT after release Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0a388196..3b4a1881 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.1.Final + 9.0.2-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 48adb95955a89eff53d5243d9a242bafd253d34f Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Wed, 1 Sep 2021 16:21:24 +0200 Subject: [PATCH 244/258] OSJC-288: Fix CVEs from commons-compress and snakeyaml - commons-compress bumped to 1.21 - snakeyaml bumped to 1.19 Signed-off-by: Jeff MAURY --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3b4a1881..24d1465a 100644 --- a/pom.xml +++ b/pom.xml @@ -168,7 +168,7 @@ org.yaml snakeyaml - 1.14 + 1.29 org.jboss @@ -183,7 +183,7 @@ org.apache.commons commons-compress - 1.18 + 1.21 commons-io From aaf4f84f1186b145cb37b6eb1cca7c6da64e0ad8 Mon Sep 17 00:00:00 2001 From: Jeff MAURY Date: Wed, 1 Sep 2021 16:33:23 +0200 Subject: [PATCH 245/258] Fix compilation error Signed-off-by: Jeff MAURY --- .../model/kubeclient/KubeClientConfigSerializer.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/openshift/restclient/model/kubeclient/KubeClientConfigSerializer.java b/src/main/java/com/openshift/restclient/model/kubeclient/KubeClientConfigSerializer.java index 27552f85..5068c2bf 100644 --- a/src/main/java/com/openshift/restclient/model/kubeclient/KubeClientConfigSerializer.java +++ b/src/main/java/com/openshift/restclient/model/kubeclient/KubeClientConfigSerializer.java @@ -11,7 +11,6 @@ package com.openshift.restclient.model.kubeclient; -import java.beans.IntrospectionException; import java.io.Reader; import org.yaml.snakeyaml.Yaml; @@ -34,7 +33,7 @@ public IKubeClientConfig loadKubeClientConfig(Reader reader) { private static class YamlPropertyUtils extends PropertyUtils { @Override - public Property getProperty(Class type, String name) throws IntrospectionException { + public Property getProperty(Class type, String name) { if (name.indexOf('-') > -1) { name = BeanUtils.toCamelCase(name, "-"); } From cccaf86ef789e9fc74e55cc56f879e6fe2ddeb93 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 20 Sep 2021 10:10:21 +0200 Subject: [PATCH 246/258] bump to 9.0.2.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 24d1465a..f3e09282 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.2-SNAPSHOT + 9.0.2.Final jar OpenShift Java REST Client http://openshift.redhat.com From 31d81f8350e08752ea8d2b0e7b57521b30fdf441 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 20 Sep 2021 10:20:12 +0200 Subject: [PATCH 247/258] bump to 9.0.3-SNAPSHOT after release Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f3e09282..654a40f9 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.2.Final + 9.0.3-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From d1d2de711ffa2148c527c13dc9121edcd4614184 Mon Sep 17 00:00:00 2001 From: Ondrej Dockal Date: Thu, 20 Jan 2022 10:59:15 +0100 Subject: [PATCH 248/258] Updage log4j libraries to 2.17.1 to fix CVE-2021-44832 Signed-off-by: Ondrej Dockal --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 654a40f9..6918e87a 100644 --- a/pom.xml +++ b/pom.xml @@ -43,7 +43,7 @@ 1.0.0-beta-5 1.1.0-beta-1 2.0.0-alpha1 - 2.13.0 + 2.17.1 ${basedir}/src/test/resources/openshiftv3IntegrationTest.properties From 36e29a20705fde42962ec4454d56d0446fba08ff Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 16 Feb 2022 11:42:35 +0100 Subject: [PATCH 249/258] bumped to 9.0.3.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6918e87a..d27be141 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.3-SNAPSHOT + 9.0.3.Final jar OpenShift Java REST Client http://openshift.redhat.com From 92d8b77293e9e6beac3813472fd9bdb62a19ff1a Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Wed, 16 Feb 2022 11:59:00 +0100 Subject: [PATCH 250/258] bumped to 9.0.4-SNAPSHOT after release Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d27be141..c1ee6c33 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.3.Final + 9.0.4-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 64714f9f373d5d19d4950863ebdceb3439bd6485 Mon Sep 17 00:00:00 2001 From: Stephane Bouchet Date: Thu, 28 Apr 2022 15:35:35 +0000 Subject: [PATCH 251/258] updqate dependencies to latest and refactored tests Signed-off-by: Stephane Bouchet --- pom.xml | 18 +++++++++--------- .../internal/restclient/DefaultClient.java | 3 ++- .../AbstractOpenShiftBinaryCapability.java | 7 ++++--- .../resources/OpenShiftBinaryRSync.java | 3 ++- .../openshift/restclient/ClientBuilder.java | 4 ++-- .../resources/DeployCapabilityTest.java | 1 - ...ftBinaryPortForwardingIntegrationTest2.java | 3 ++- .../model/v1/PVCVolumeSourceTest.java | 2 +- .../restclient/model/v1/RouteTest.java | 6 ++++-- .../model/v1/SecretVolumeSourceTest.java | 2 +- .../restclient/okhttp/WatchClientTest.java | 2 +- .../internal/util/JBossDmrExtentionsTest.java | 2 +- .../internal/util/StringSplitterTest.java | 2 +- .../openshift/restclient/utils/Samples.java | 9 +++++++++ .../samples/openshift3/v1_build_config.json | 2 +- .../openshift3/v1_config_map_list_empty.json | 2 +- .../samples/openshift3/v1_objectref.json | 2 +- .../samples/openshift3/v1_project_request.json | 2 +- .../openshift3/v1_replication_controller.json | 2 +- .../samples/openshift3/v1_route_wo_tls.json | 2 +- 20 files changed, 45 insertions(+), 31 deletions(-) diff --git a/pom.xml b/pom.xml index c1ee6c33..803b5ad0 100644 --- a/pom.xml +++ b/pom.xml @@ -163,17 +163,17 @@ com.squareup.okhttp3 okhttp - 4.1.1 + 4.9.3 org.yaml snakeyaml - 1.29 + 1.30 org.jboss jboss-dmr - 1.3.0.Final + 1.6.1.Final org.apache.commons @@ -188,7 +188,7 @@ commons-io commons-io - 2.1 + 2.11.0 org.slf4j @@ -198,7 +198,7 @@ commons-codec commons-codec - 1.6 + 1.15 commons-lang @@ -226,25 +226,25 @@ junit junit - 4.8.2 + 4.13.2 test org.mockito mockito-core - 3.0.0 + 3.12.4 test org.assertj assertj-core - 3.13.2 + 3.22.0 test org.skyscreamer jsonassert - 1.2.3 + 1.5.0 test diff --git a/src/main/java/com/openshift/internal/restclient/DefaultClient.java b/src/main/java/com/openshift/internal/restclient/DefaultClient.java index bf3165d3..7f640da5 100644 --- a/src/main/java/com/openshift/internal/restclient/DefaultClient.java +++ b/src/main/java/com/openshift/internal/restclient/DefaultClient.java @@ -16,6 +16,7 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -344,7 +345,7 @@ RequestBody getPayload(InputStream payload, String method) { if(isPayloadlessMethod(method)) { return null; } - InputStream input = payload == null ? IOUtils.toInputStream("") : payload; + InputStream input = payload == null ? IOUtils.toInputStream("", StandardCharsets.UTF_8) : payload; LOGGER.debug("About to send binary payload"); return new RequestBody() { @Override diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java index 25712c54..f39afa56 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/AbstractOpenShiftBinaryCapability.java @@ -13,6 +13,7 @@ import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -216,12 +217,12 @@ private void checkProcessIsAlive() throws IOException { Thread.sleep(1000); if (!process.isAlive() && process.exitValue() != 0) { throw new OpenShiftException("OpenShiftBinaryCapability process exited: %s", - IOUtils.toString(process.getErrorStream())); + IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8)); } } catch (InterruptedException e) { if (!process.isAlive() && process.exitValue() != 0) { throw new OpenShiftException("OpenShiftBinaryCapability process exited: %s", - IOUtils.toString(process.getErrorStream())); + IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8)); } } } @@ -240,7 +241,7 @@ public final synchronized void stop() { if (exitValue != 0) { try { LOG.debug("OpenShiftBinaryCapability process error stream: {}", - IOUtils.toString(process.getErrorStream())); + IOUtils.toString(process.getErrorStream(), StandardCharsets.UTF_8)); } catch (IOException e) { LOG.debug("IOException trying to debug the process error stream", e); } diff --git a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java index 234d3b16..7d01f9c3 100644 --- a/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java +++ b/src/main/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryRSync.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -128,7 +129,7 @@ public void await() throws InterruptedException { private static String getErrorMessage(InputStream errorStream) { try { - return IOUtils.toString(errorStream); + return IOUtils.toString(errorStream, StandardCharsets.UTF_8); } catch (IOException e) { LOG.error("Could not retrieve error message from process", e); return null; diff --git a/src/main/java/com/openshift/restclient/ClientBuilder.java b/src/main/java/com/openshift/restclient/ClientBuilder.java index 59ec033e..62ea8dcf 100644 --- a/src/main/java/com/openshift/restclient/ClientBuilder.java +++ b/src/main/java/com/openshift/restclient/ClientBuilder.java @@ -42,10 +42,10 @@ import okhttp3.Authenticator; import okhttp3.Dispatcher; import okhttp3.Interceptor; +import okhttp3.OkHttp; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; -import okhttp3.internal.Version; /** * Builder to create IClient instances. @@ -380,7 +380,7 @@ private static class UserAgentInterceptor implements Interceptor { public UserAgentInterceptor(String userAgentPrefix) { this.userAgent = StringUtils.join( - new String[]{ userAgentPrefix, "openshift-restclient-java", Version.userAgent }, "/"); + new String[]{ userAgentPrefix, "openshift-restclient-java", "okhttp/" + OkHttp.VERSION }, "/"); } diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java index d73de3d9..bb35f4e2 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/DeployCapabilityTest.java @@ -66,7 +66,6 @@ public void testIsSupported() { assertTrue("Exp. the capability to be supported", cap.isSupported()); } - @SuppressWarnings("unchecked") @Test(expected = OpenShiftException.class) public void testThrowsErrorWhenUnableToFindLatestDeployment() { when(client.get(anyString(), anyString(), anyString())).thenThrow(OpenShiftException.class); diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java index 6c32c538..9f64d9f3 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/OpenShiftBinaryPortForwardingIntegrationTest2.java @@ -15,6 +15,7 @@ import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import org.apache.commons.io.IOUtils; @@ -92,7 +93,7 @@ private void curl() throws Exception { con.setRequestMethod("GET"); con.setDoInput(true); con.connect(); - System.out.println(IOUtils.toString(con.getInputStream())); + System.out.println(IOUtils.toString(con.getInputStream(), StandardCharsets.UTF_8)); con.disconnect(); } } diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/PVCVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/PVCVolumeSourceTest.java index cd6b90c8..52f76773 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/PVCVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/PVCVolumeSourceTest.java @@ -12,7 +12,7 @@ package com.openshift.internal.restclient.model.v1; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import org.jboss.dmr.ModelNode; import org.junit.Before; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java index a130c662..b97c47e9 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java @@ -14,6 +14,8 @@ import static org.junit.Assert.assertNull; import static org.mockito.Mockito.mock; +import java.io.IOException; + import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; @@ -74,8 +76,8 @@ public void getPortWhenUndefined() { } @Test - public void createPortWhenUndefined() { - ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); + public void createPortWhenUndefined() throws IOException { + ModelNode node = ModelNode.fromJSONStream(Samples.V1_ROUTE_WO_TLS.getContent()); route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); ITargetPort port = route.createPort(); assertNotNull(port); diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/SecretVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/SecretVolumeSourceTest.java index 48a5f7ca..a4a07dd0 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/SecretVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/SecretVolumeSourceTest.java @@ -12,7 +12,7 @@ package com.openshift.internal.restclient.model.v1; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import org.jboss.dmr.ModelNode; import org.junit.Before; diff --git a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java index b3686784..0fafc145 100644 --- a/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java +++ b/src/test/java/com/openshift/internal/restclient/okhttp/WatchClientTest.java @@ -13,7 +13,7 @@ import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; diff --git a/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java b/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java index c5dcb705..477f9c71 100644 --- a/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java +++ b/src/test/java/com/openshift/internal/util/JBossDmrExtentionsTest.java @@ -63,7 +63,7 @@ public void testToJson() { node.get("xyz").add(complex); node.get("def").add(new ModelNode()); node.get("abc").set("xyx"); - assertEquals("{\"foo\" : {}, \"xyz\" : [1,3,{\"sub1\" : {}, \"sub1a\" : \"avalue\"}], \"abc\" : \"xyx\"}", + assertEquals("{\"foo\":{},\"xyz\":[1,3,{\"sub1\":{},\"sub1a\":\"avalue\"}],\"abc\":\"xyx\"}", toJsonString(node, true)); } diff --git a/src/test/java/com/openshift/internal/util/StringSplitterTest.java b/src/test/java/com/openshift/internal/util/StringSplitterTest.java index 3ac5e8ad..5fd9e7b6 100644 --- a/src/test/java/com/openshift/internal/util/StringSplitterTest.java +++ b/src/test/java/com/openshift/internal/util/StringSplitterTest.java @@ -10,7 +10,7 @@ package com.openshift.internal.util; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import java.util.Arrays; import java.util.List; diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index 3b360f21..c1eb506c 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -103,4 +103,13 @@ public String getContentAsString() { } return content; } + + public InputStream getContent(){ + try { + return Samples.class.getResourceAsStream(filePath); + } catch (Throwable e) { + e.printStackTrace(); + throw new RuntimeException("Could not read file " + filePath + ": " + e.getMessage()); + } + } } diff --git a/src/test/resources/samples/openshift3/v1_build_config.json b/src/test/resources/samples/openshift3/v1_build_config.json index 6780d6ba..438dd6c3 100644 --- a/src/test/resources/samples/openshift3/v1_build_config.json +++ b/src/test/resources/samples/openshift3/v1_build_config.json @@ -55,7 +55,7 @@ "name" : "foo", "value" : "bar" }] - }, + } }, "output": { "to": { diff --git a/src/test/resources/samples/openshift3/v1_config_map_list_empty.json b/src/test/resources/samples/openshift3/v1_config_map_list_empty.json index a804f099..9dd98e80 100644 --- a/src/test/resources/samples/openshift3/v1_config_map_list_empty.json +++ b/src/test/resources/samples/openshift3/v1_config_map_list_empty.json @@ -3,6 +3,6 @@ "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/namespaces/fooproj/configmaps", - "resourceVersion": "1418", + "resourceVersion": "1418" } } diff --git a/src/test/resources/samples/openshift3/v1_objectref.json b/src/test/resources/samples/openshift3/v1_objectref.json index 607423a5..3bf9b168 100644 --- a/src/test/resources/samples/openshift3/v1_objectref.json +++ b/src/test/resources/samples/openshift3/v1_objectref.json @@ -4,5 +4,5 @@ "name": "builder", "uid": "ce20b132-7986-11e5-b1e5-080027bdffff", "resourceVersion": "33366", - "apiVersion": "v1", + "apiVersion": "v1" } \ No newline at end of file diff --git a/src/test/resources/samples/openshift3/v1_project_request.json b/src/test/resources/samples/openshift3/v1_project_request.json index a4fcb72f..998f7939 100644 --- a/src/test/resources/samples/openshift3/v1_project_request.json +++ b/src/test/resources/samples/openshift3/v1_project_request.json @@ -2,7 +2,7 @@ "kind": "ProjectRequest", "apiVersion": "v1", "metadata": { - "name": "test", + "name": "test" }, "displayName": "the display name", "description": "The project description" diff --git a/src/test/resources/samples/openshift3/v1_replication_controller.json b/src/test/resources/samples/openshift3/v1_replication_controller.json index 6373d646..81358cc0 100644 --- a/src/test/resources/samples/openshift3/v1_replication_controller.json +++ b/src/test/resources/samples/openshift3/v1_replication_controller.json @@ -98,7 +98,7 @@ ], "restartPolicy": "Always", "dnsPolicy": "ClusterFirst", - "serviceAccountName": "dbServiceAccountName", + "serviceAccountName": "dbServiceAccountName" } } }, diff --git a/src/test/resources/samples/openshift3/v1_route_wo_tls.json b/src/test/resources/samples/openshift3/v1_route_wo_tls.json index e67f5d4a..2efacfa9 100644 --- a/src/test/resources/samples/openshift3/v1_route_wo_tls.json +++ b/src/test/resources/samples/openshift3/v1_route_wo_tls.json @@ -22,7 +22,7 @@ "to": { "kind": "Service", "name": "frontend" - }, + } }, "status": {} } \ No newline at end of file From 15cf4b7d152d49d6ec6271a969ece62ced8f0a68 Mon Sep 17 00:00:00 2001 From: Stephane Bouchet Date: Fri, 29 Apr 2022 13:28:04 +0000 Subject: [PATCH 252/258] refactoring Signed-off-by: Stephane Bouchet --- .../model/kubeclient/KubeClientConfigConstructor.java | 6 +++--- .../internal/restclient/ResourceFactoryTest.java | 2 +- .../ImageStreamImportCapabilityIntegrationTest.java | 3 +-- .../openshift/internal/restclient/model/ServiceTest.java | 1 - .../restclient/model/v1/EmptyDirVolumeSourceTest.java | 2 +- .../restclient/model/v1/HostPathVolumeSourceTest.java | 2 +- .../openshift/internal/restclient/model/v1/RouteTest.java | 6 ++---- .../com/openshift/restclient/OpenShiftContextTest.java | 6 +++--- src/test/java/com/openshift/restclient/utils/Samples.java | 8 -------- 9 files changed, 12 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfigConstructor.java b/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfigConstructor.java index cff04166..c02d7b89 100644 --- a/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfigConstructor.java +++ b/src/main/java/com/openshift/internal/restclient/model/kubeclient/KubeClientConfigConstructor.java @@ -25,9 +25,9 @@ public KubeClientConfigConstructor(PropertyUtils propertyUtils) { super(KubeClientConfig.class); TypeDescription configTypeDesc = new TypeDescription(KubeClientConfig.class); - configTypeDesc.putListPropertyType(CONTEXTS, Context.class); - configTypeDesc.putListPropertyType(CLUSTERS, Cluster.class); - configTypeDesc.putListPropertyType(USERS, User.class); + configTypeDesc.addPropertyParameters(CONTEXTS, Context.class); + configTypeDesc.addPropertyParameters(CLUSTERS, Cluster.class); + configTypeDesc.addPropertyParameters(USERS, User.class); addTypeDescription(configTypeDesc); setPropertyUtils(propertyUtils); diff --git a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java index ac0e0cce..3a636c8e 100644 --- a/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java +++ b/src/test/java/com/openshift/internal/restclient/ResourceFactoryTest.java @@ -11,7 +11,7 @@ package com.openshift.internal.restclient; -import static junit.framework.Assert.assertEquals; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; diff --git a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java index 7a010bbe..858e9523 100644 --- a/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java +++ b/src/test/java/com/openshift/internal/restclient/capability/resources/ImageStreamImportCapabilityIntegrationTest.java @@ -16,6 +16,7 @@ import static org.junit.Assert.assertTrue; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -28,8 +29,6 @@ import com.openshift.restclient.model.IStatus; import com.openshift.restclient.model.image.IImageStreamImport; -import junit.framework.Assert; - public class ImageStreamImportCapabilityIntegrationTest { private IImageStreamImportCapability cap; diff --git a/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java b/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java index c2589948..01496e5e 100644 --- a/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/ServiceTest.java @@ -87,7 +87,6 @@ public void testSetPorts() { assertEquals("foo", service.getPorts().get(0).getName()); } - @SuppressWarnings("unchecked") @Test public void testGetPods() { // setup diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java index 0fdea0f7..2cb993fc 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/EmptyDirVolumeSourceTest.java @@ -12,7 +12,7 @@ package com.openshift.internal.restclient.model.v1; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import org.jboss.dmr.ModelNode; import org.junit.Before; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java index af9d4b02..3da01e7f 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/HostPathVolumeSourceTest.java @@ -12,7 +12,7 @@ package com.openshift.internal.restclient.model.v1; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertThat; +import static org.hamcrest.MatcherAssert.assertThat; import org.jboss.dmr.ModelNode; import org.junit.Before; diff --git a/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java b/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java index b97c47e9..a130c662 100644 --- a/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java +++ b/src/test/java/com/openshift/internal/restclient/model/v1/RouteTest.java @@ -14,8 +14,6 @@ import static org.junit.Assert.assertNull; import static org.mockito.Mockito.mock; -import java.io.IOException; - import org.jboss.dmr.ModelNode; import org.junit.Before; import org.junit.Test; @@ -76,8 +74,8 @@ public void getPortWhenUndefined() { } @Test - public void createPortWhenUndefined() throws IOException { - ModelNode node = ModelNode.fromJSONStream(Samples.V1_ROUTE_WO_TLS.getContent()); + public void createPortWhenUndefined() { + ModelNode node = ModelNode.fromJSONString(Samples.V1_ROUTE_WO_TLS.getContentAsString()); route = new Route(node, client, ResourcePropertiesRegistry.getInstance().get(VERSION, ResourceKind.ROUTE)); ITargetPort port = route.createPort(); assertNotNull(port); diff --git a/src/test/java/com/openshift/restclient/OpenShiftContextTest.java b/src/test/java/com/openshift/restclient/OpenShiftContextTest.java index 3d62e19f..db1ab8fa 100644 --- a/src/test/java/com/openshift/restclient/OpenShiftContextTest.java +++ b/src/test/java/com/openshift/restclient/OpenShiftContextTest.java @@ -9,9 +9,9 @@ package com.openshift.restclient; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotSame; -import static junit.framework.Assert.assertNull; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertNull; import org.junit.After; import org.junit.Test; diff --git a/src/test/java/com/openshift/restclient/utils/Samples.java b/src/test/java/com/openshift/restclient/utils/Samples.java index c1eb506c..43cc669a 100644 --- a/src/test/java/com/openshift/restclient/utils/Samples.java +++ b/src/test/java/com/openshift/restclient/utils/Samples.java @@ -104,12 +104,4 @@ public String getContentAsString() { return content; } - public InputStream getContent(){ - try { - return Samples.class.getResourceAsStream(filePath); - } catch (Throwable e) { - e.printStackTrace(); - throw new RuntimeException("Could not read file " + filePath + ": " + e.getMessage()); - } - } } From 7c28db2c2ab1a81094994aa417f75c8565bc0e01 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 2 May 2022 10:47:35 +0200 Subject: [PATCH 253/258] release 9.0.4.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 803b5ad0..cbeced03 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.4-SNAPSHOT + 9.0.4.Final jar OpenShift Java REST Client http://openshift.redhat.com From 2a19540dd4e6d38f77022ec5d5e64c2bf8914b1e Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Tue, 3 May 2022 12:14:19 +0200 Subject: [PATCH 254/258] bump to 9.0.5-SNAPSHOT after release Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index cbeced03..925cb107 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.4.Final + 9.0.5-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 33fe756860ba1e24befe91e1cd1163c32acc712a Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 26 Sep 2022 16:13:49 +0200 Subject: [PATCH 255/258] bumped okhttp, snakeyaml, log4j, slf4j, assertj (#476) Signed-off-by: Andre Dietisheim --- pom.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 925cb107..50f0c6f8 100644 --- a/pom.xml +++ b/pom.xml @@ -42,8 +42,8 @@ 1.0.0-beta-6 1.0.0-beta-5 1.1.0-beta-1 - 2.0.0-alpha1 - 2.17.1 + 2.0.1 + 2.19.0 ${basedir}/src/test/resources/openshiftv3IntegrationTest.properties @@ -163,12 +163,12 @@ com.squareup.okhttp3 okhttp - 4.9.3 + 4.10.0 org.yaml snakeyaml - 1.30 + 1.32 org.jboss @@ -219,7 +219,7 @@ org.apache.logging.log4j - log4j-slf4j18-impl + log4j-slf4j-impl ${version.log4j} test @@ -232,19 +232,19 @@ org.mockito mockito-core - 3.12.4 + 4.8.0 test org.assertj assertj-core - 3.22.0 + 3.23.1 test org.skyscreamer jsonassert - 1.5.0 + 1.5.1 test From 2575f45bc1287d0979a8e270ab480d1fb2143e78 Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 26 Sep 2022 17:15:34 +0200 Subject: [PATCH 256/258] release 9.0.5.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 50f0c6f8..70b26266 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.5-SNAPSHOT + 9.0.5.Final jar OpenShift Java REST Client http://openshift.redhat.com From 5e70e71679e7b710e970f19e6fd87b9b5abf4c0b Mon Sep 17 00:00:00 2001 From: Andre Dietisheim Date: Mon, 26 Sep 2022 17:20:37 +0200 Subject: [PATCH 257/258] bump after release of 9.0.5.Final Signed-off-by: Andre Dietisheim --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 70b26266..d2c2640f 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,7 @@ com.openshift openshift-restclient-java - 9.0.5.Final + 9.0.6-SNAPSHOT jar OpenShift Java REST Client http://openshift.redhat.com From 80990c0239cd396e626681eedb157b3c7046f9a6 Mon Sep 17 00:00:00 2001 From: Corey Daley Date: Tue, 13 Dec 2022 14:50:58 -0500 Subject: [PATCH 258/258] Delete .travis.yml --- .travis.yml | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b8cc26da..00000000 --- a/.travis.yml +++ /dev/null @@ -1,31 +0,0 @@ -dist: xenial - -language: java - -jdk: - - openjdk8 - - openjdk11 - -stages: - - test - - integration-test - -sudo: false - -jobs: - include: - - stage: integration-test - script: | - sudo echo '{"insecure-registries": ["172.30.0.0/16"]}' > daemon.json - sudo mv daemon.json /etc/docker - sudo cat /etc/docker/daemon.json - sudo service docker restart - ./startOCP.sh v3.9.0 - mvn verify -Pintegration-tests -DserverURL=https://127.0.0.1:8443 -Ddefault.clusteradmin.user=admin -Ddefault.clusteradmin.password=admin -Docbinary.location=./oc - ./oc cluster down - ./startOCP.sh v3.10.0 - mvn verify -Pintegration-tests -DserverURL=https://127.0.0.1:8443 -Ddefault.clusteradmin.user=admin -Ddefault.clusteradmin.password=admin -Docbinary.location=./oc - ./oc cluster down - ./startOCP.sh v3.11.0 - mvn verify -Pintegration-tests -DserverURL=https://127.0.0.1:8443 -Ddefault.clusteradmin.user=admin -Ddefault.clusteradmin.password=admin -Docbinary.location=./oc - ./oc cluster down