Skip to content

Commit

Permalink
[JBPM-8549] - Introducing Kogito Kubernetes Client (apache#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardozanini authored and mswiderski committed Jul 18, 2019
1 parent 291b244 commit f245caf
Show file tree
Hide file tree
Showing 37 changed files with 2,088 additions and 161 deletions.
32 changes: 32 additions & 0 deletions kogito-cloud-services/kogito-cloud-kubernetes-client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
bin/
/target
/local

# Eclipse, Netbeans and IntelliJ files
/.*
!.gitignore
/nbproject
/*.ipr
/*.iws
/*.iml

# Repository wide ignore mac DS_Store files
.DS_Store

# Original jbpm ignores
*~

# Test info
/settings*.xml
/lib-jdbc/
*.db
*.tlog

# modules that don't exist in this branch
/jbpm-human-task-war/
/jbpm-bam/
/jbpm-gwt/

# files used for external db testing
jdbc_driver.jar
db-settings.xml
10 changes: 10 additions & 0 deletions kogito-cloud-services/kogito-cloud-kubernetes-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Kogito Cloud Kubernetes Client

This library is designed to be used with Kogito Cloud module, but also as a standalone library as an alternative Kubernetes client on [native images](https://www.graalvm.org/docs/reference-manual/aot-compilation/).

It's a wrapper around the [Fabric8 Kubernetes Client API](https://github.com/fabric8io/kubernetes-client), with some tweaks:

1. Removes the Kube Config file parsing as an alternative to connect to the cluster because of [its reflection usage](https://github.com/fabric8io/kubernetes-client/issues/1591).
2. Parse JSON API responses as simple Maps to avoid using reflection to build domain objects during runtime like Jackson does. As an alternative, uses Yasson to parse JSON responses and a simple utility to walk into the resulted map.

It's meant to be simple to support simple use cases.
56 changes: 56 additions & 0 deletions kogito-cloud-services/kogito-cloud-kubernetes-client/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.kie.kogito</groupId>
<artifactId>kogito-cloud-services</artifactId>
<version>8.0.0-SNAPSHOT</version>
</parent>
<artifactId>kogito-cloud-kubernetes-client</artifactId>
<name>Kogito Cloud Kubernetes Client</name>
<description>Kogito Cloud Kubernetes Client</description>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-server-mock</artifactId>
<version>${version.kubernetes-client}</version>
<scope>test</scope>
</dependency>

<!-- Logging -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.kogito.cloud.kubernetes.client;

import org.kie.kogito.cloud.kubernetes.client.operations.IstioGatewayOperations;
import org.kie.kogito.cloud.kubernetes.client.operations.KNativeServiceOperations;
import org.kie.kogito.cloud.kubernetes.client.operations.ServiceOperations;

/**
* Default {@link KogitoKubeClient} implementation.
*/
public class DefaultKogitoKubeClient implements KogitoKubeClient {

private ServiceOperations serviceOperation;
private IstioGatewayOperations istioGatewayOperations;
private KNativeServiceOperations kNativeServiceOperations;
private KogitoKubeConfig clientConfig;

public DefaultKogitoKubeClient() {
this.clientConfig = new KogitoKubeConfig();
}

@Override
public KogitoKubeConfig getConfig() {
return this.clientConfig;
}

@Override
public DefaultKogitoKubeClient withConfig(KogitoKubeConfig clientConfig) {
this.clientConfig = clientConfig;
return this;
}

/**
* The Services Operations
*/
@Override
public ServiceOperations services() {
if (serviceOperation == null) {
this.serviceOperation = new ServiceOperations(clientConfig);
}
return this.serviceOperation;
}

@Override
public IstioGatewayOperations istioGateway() {
if (istioGatewayOperations == null) {
this.istioGatewayOperations = new IstioGatewayOperations(clientConfig);
}
return this.istioGatewayOperations;
}

@Override
public KNativeServiceOperations knativeService() {
if (kNativeServiceOperations == null) {
this.kNativeServiceOperations = new KNativeServiceOperations(clientConfig);
}
return this.kNativeServiceOperations;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.kogito.cloud.kubernetes.client;

import org.kie.kogito.cloud.kubernetes.client.operations.IstioGatewayOperations;
import org.kie.kogito.cloud.kubernetes.client.operations.KNativeServiceOperations;
import org.kie.kogito.cloud.kubernetes.client.operations.ServiceOperations;

/**
* Main interface to communicate with Kubernetes Cluster API.
*/
public interface KogitoKubeClient {

ServiceOperations services();

IstioGatewayOperations istioGateway();

KNativeServiceOperations knativeService();

KogitoKubeClient withConfig(KogitoKubeConfig config);

KogitoKubeConfig getConfig();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.kogito.cloud.kubernetes.client;

/**
* Generic exception for the Kube Client
*/
public class KogitoKubeClientException extends RuntimeException {

private static final long serialVersionUID = 5121838037390778349L;

public KogitoKubeClientException() {}

public KogitoKubeClientException(String message) {
super(message);
}

public KogitoKubeClientException(Throwable cause) {
super(cause);
}

public KogitoKubeClientException(String message, Throwable cause) {
super(message, cause);
}

public KogitoKubeClientException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.kogito.cloud.kubernetes.client;

import java.net.MalformedURLException;
import java.net.URL;

import io.fabric8.kubernetes.client.BaseClient;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.dsl.base.OperationSupport;
import okhttp3.OkHttpClient;

/**
* Wraps the Kubernetes Client setup and configuration, exposing infrastructure components to connect to a Kubernetes cluster reliably.
* Most used when there's a need to customize the Fabric8 Kubernetes Client.
*/
public final class KogitoKubeConfig {

public static final String KNATIVE_ISTIO_NAMESPACE = "istio-system";
private static final String NAMESPACE_REPLACE = "@ns@";
private static final String KNATIVE_SERVICE_SERVICE_URL = "apis/serving.knative.dev/v1alpha1/namespaces/" + NAMESPACE_REPLACE + "/services";
private static final String KNATIVE_ISTIO_GATEWAY_URL = "api/v1/namespaces/" + KNATIVE_ISTIO_NAMESPACE + "/services/istio-ingressgateway";

private KubernetesClient kubernetesClient;

public KogitoKubeConfig() {
// disable kube config file deserialization due to reflection usage
System.setProperty(Config.KUBERNETES_AUTH_TRYKUBECONFIG_SYSTEM_PROPERTY, "false");
this.kubernetesClient = new DefaultKubernetesClient();
}

/**
* Highly customizable config client. Most used in integration tests. 90% of the time you won't need to use this constructor.
*
* @param kubernetesClient
*/
public KogitoKubeConfig(KubernetesClient kubernetesClient) {
this.kubernetesClient = kubernetesClient;
}

public OkHttpClient getHttpClient() {
return ((BaseClient) this.kubernetesClient).getHttpClient();
}

public URL getMasterUrl() {
return this.kubernetesClient.getMasterUrl();
}

public String getKNativeServiceServiceURL(String namespace) throws MalformedURLException {
if (namespace == null || namespace.isEmpty()) {
throw new IllegalArgumentException("A namespace should be provided when using KNative service operations");
}
final StringBuilder sb = new StringBuilder(this.getMasterUrl().toString());
sb.append(KNATIVE_SERVICE_SERVICE_URL.replaceFirst(NAMESPACE_REPLACE, namespace));
return sb.toString();
}

public String getKNativeIstioGatewayURL() throws MalformedURLException {
final StringBuilder sb = new StringBuilder(this.getMasterUrl().toString());
sb.append(KNATIVE_ISTIO_GATEWAY_URL);
return sb.toString();
}

public URL getServiceOperationURL(final String namespace) throws MalformedURLException {
final OperationSupport services = ((OperationSupport) this.kubernetesClient.services());
return services.getNamespacedUrl(namespace);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2019 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.kie.kogito.cloud.kubernetes.client;

public final class OperationsUtils {

public static final String LABEL_SELECTOR_PARAM = "labelSelector";

private OperationsUtils() {}

}
Loading

0 comments on commit f245caf

Please sign in to comment.