Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ jobs:
uses: actions/setup-java@v5
with:
distribution: 'adopt'
java-version: '25'
java-version: '21'
cache: 'maven'

- name: Build, test and quality scan
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: mvn clean verify org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.organization=hakky54 -Dsonar.host.url=https://sonarcloud.io -Dsonar.login="$SONAR_TOKEN" --no-transfer-progress
run: mvn clean verify -Pjacoco org.sonarsource.scanner.maven:sonar-maven-plugin:sonar -Dsonar.organization=hakky54 -Dsonar.host.url=https://sonarcloud.io -Dsonar.login="$SONAR_TOKEN" --no-transfer-progress
5 changes: 5 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,11 @@ All client examples use the same base ssl configuration created within the [SSLC
* Groovy with Java Net -> [Client Configuration & Example request](https://github.com/Hakky54/mutual-tls-ssl/blob/master/client/src/main/java/nl/altindag/client/service/GroovyJavaNetClientService.groovy)
* [Hyper Poet](https://github.com/tambapps/hyperpoet) -> [Client Configuration & Example request](https://github.com/Hakky54/mutual-tls-ssl/blob/master/client/src/main/java/nl/altindag/client/service/HyperPoetService.groovy)

**Clojure**
* [cj-http](https://github.com/dakrone/clj-http) -> [Client Configuration & Example request](https://github.com/Hakky54/mutual-tls-ssl/blob/master/client/src/main/java/nl/altindag/client/service/ClojureCljHttpClientService.clj)
* JDK Http Client -> [Client Configuration & Example request](https://github.com/Hakky54/mutual-tls-ssl/blob/master/client/src/main/java/nl/altindag/client/service/ClojureJdkHttpClientService.clj)
* Old JDK Http Client -> [Client Configuration & Example request](https://github.com/Hakky54/mutual-tls-ssl/blob/master/client/src/main/java/nl/altindag/client/service/ClojureHttpClientService.clj)

**Other**

This tutorial does not provide examples for the clients listed below, however it is proven to be working with the server provided in this tutorial. To guide you in the right direction you can convert the created java keystore files into pem files which in return can be used with one of the clients listed below. The following Gist page contains the commands to convert a Java keystore to a pem file: [Gist - Curl with Java KeyStore](https://gist.github.com/Hakky54/049299f0874fd4b870257c6458e0dcbd)
Expand Down
34 changes: 34 additions & 0 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@
<artifactId>hyperpoet-groovy</artifactId>
</dependency>

<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
</dependency>
<dependency>
<groupId>clj-http</groupId>
<artifactId>clj-http</artifactId>
</dependency>

<!-- Utilities -->
<dependency>
<groupId>org.awaitility</groupId>
Expand Down Expand Up @@ -362,6 +371,12 @@
<version>${version.gmavenplus-plugin}</version>
</plugin>

<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>${version.clojure-maven-plugin}</version>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
Expand Down Expand Up @@ -553,4 +568,23 @@

</profiles>

<repositories>
<repository>
<id>maven-central</id>
<name>Maven Central Repository</name>
<url>https://repo1.maven.org/maven2</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>clojars-central</id>
<name>Clojars Repository</name>
<url>https://repo.clojars.org/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

</project>
25 changes: 25 additions & 0 deletions client/src/main/java/nl/altindag/client/ClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package nl.altindag.client;

import clojure.java.api.Clojure;
import clojure.lang.IFn;
import com.github.mizosoft.methanol.Methanol;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
Expand All @@ -33,6 +35,7 @@
import jakarta.ws.rs.client.Client;
import jakarta.ws.rs.client.ClientBuilder;
import kong.unirest.Unirest;
import nl.altindag.client.service.RequestService;
import nl.altindag.ssl.SSLFactory;
import nl.altindag.ssl.apache4.util.Apache4SslUtils;
import nl.altindag.ssl.apache5.util.Apache5SslUtils;
Expand Down Expand Up @@ -310,4 +313,26 @@ public io.vertx.ext.web.client.WebClient vertxWebClient(SSLFactory sslFactory) {
return io.vertx.ext.web.client.WebClient.create(Vertx.vertx(), clientOptions);
}

@Bean
public RequestService clojureHttpClientService(SSLFactory sslFactory) {
return instantiateClojureRequestService("nl.altindag.client.service.ClojureHttpClientService", sslFactory);
}

@Bean
public RequestService clojureJdkHttpClientService(SSLFactory sslFactory) {
return instantiateClojureRequestService("nl.altindag.client.service.ClojureJdkHttpClientService", sslFactory);
}

@Bean
public RequestService clojureCijHttpClientService(SSLFactory sslFactory) {
return instantiateClojureRequestService("nl.altindag.client.service.ClojureCijHttpClientService", sslFactory);
}

private RequestService instantiateClojureRequestService(String namespace, SSLFactory sslFactory) {
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read(namespace));
IFn clojureHttpClientService = Clojure.var(namespace, "reify-request-service");
return (RequestService) clojureHttpClientService.invoke(sslFactory);
}

}
3 changes: 3 additions & 0 deletions client/src/main/java/nl/altindag/client/ClientType.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ public enum ClientType {
VERTX("vertx webclient"),
GROOVY_JAVA_NET_CLIENT("groovy java net client"),
HYPER_POET_CLIENT("hyperpoet client"),
CLOJURE_HTTP_CLIENT("clojure httpclient"),
CLOJURE_JDK_HTTP_CLIENT("clojure jdk httpclient"),
CLOJURE_CLJ_HTTP_CLIENT("clojure clj-http client"),
NONE("none");

private final String value;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
;
; Copyright 2018 Thunderberry.
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; https://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.
;

(ns nl.altindag.client.service.ClojureCijHttpClientService
(:gen-class)
(:require [clj-http.client :as http])
(:import
[nl.altindag.client.service RequestService]
[nl.altindag.client.model ClientResponse]
[nl.altindag.client ClientType Constants]
[nl.altindag.ssl SSLFactory]
[nl.altindag.ssl.apache4.util Apache4SslUtils]
[org.apache.http.impl.client HttpClients]))

(defn reify-request-service
[^SSLFactory ssl-factory]
(reify
RequestService
(executeRequest [this url]
(let [http-client (-> (HttpClients/custom)
(.setSSLSocketFactory (Apache4SslUtils/toSocketFactory ssl-factory))
(.build))
response (http/get url {:headers {Constants/HEADER_KEY_CLIENT_TYPE (.getValue (.getClientType this))}
:http-client http-client
:as :string
:throw-exceptions false})]
(ClientResponse. (:body response) (:status response))))
(getClientType [this]
ClientType/CLOJURE_CLJ_HTTP_CLIENT)))

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
;
; Copyright 2018 Thunderberry.
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; https://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.
;

(ns nl.altindag.client.service.ClojureHttpClientService
(:gen-class)
(:import
[nl.altindag.client.service RequestService]
[nl.altindag.client.model ClientResponse]
[nl.altindag.client ClientType Constants ClientException]
[nl.altindag.ssl SSLFactory]
[java.net URL HttpURLConnection]
[java.nio.charset StandardCharsets]
[javax.net.ssl HttpsURLConnection]
[org.apache.commons.io IOUtils]
[org.apache.http.client.methods HttpGet]))

(defn reify-request-service
[^SSLFactory ssl-factory]
(reify
RequestService
(executeRequest [this url]
(let [connection (if (.contains url "https:")
(doto ^HttpsURLConnection (cast HttpsURLConnection (.openConnection (URL. url)))
(.setHostnameVerifier (.getHostnameVerifier ssl-factory))
(.setSSLSocketFactory (.getSslSocketFactory ssl-factory)))
(if (.contains url "http:")
(cast HttpURLConnection (.openConnection (URL. url)))
(throw (ClientException. "Could not create a http client for one of these reasons: invalid url, security is enable while using an url with http or security is disable while using an url with https"))))]
(.setRequestMethod connection HttpGet/METHOD_NAME)
(.setRequestProperty connection Constants/HEADER_KEY_CLIENT_TYPE (.getValue (.getClientType this)))
(ClientResponse. (IOUtils/toString (.getInputStream connection) StandardCharsets/UTF_8)
(.getResponseCode connection))))
(getClientType [this]
ClientType/CLOJURE_HTTP_CLIENT)))
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
;
; Copyright 2018 Thunderberry.
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; https://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.
;

(ns nl.altindag.client.service.ClojureJdkHttpClientService
(:gen-class)
(:import
[nl.altindag.client.service RequestService]
[nl.altindag.client.model ClientResponse]
[nl.altindag.client ClientType Constants]
[nl.altindag.ssl SSLFactory]
[java.net URI]
[java.net.http HttpClient HttpRequest HttpResponse$BodyHandlers]))

(defn reify-request-service
[^SSLFactory ssl-factory]
(let [http-client (-> (HttpClient/newBuilder)
(.sslContext (.getSslContext ssl-factory))
(.sslParameters (.getSslParameters ssl-factory))
(.build))]
(reify
RequestService
(executeRequest [this url]
(let [request (-> (HttpRequest/newBuilder)
(.GET)
(.header Constants/HEADER_KEY_CLIENT_TYPE (.getValue (.getClientType this)))
(.uri (URI/create url))
(.build))
response (.send http-client request (HttpResponse$BodyHandlers/ofString))]
(ClientResponse. (.body response) (.statusCode response))))
(getClientType [this]
ClientType/CLOJURE_JDK_HTTP_CLIENT))))
25 changes: 25 additions & 0 deletions client/src/test/java/nl/altindag/client/ClientConfigShould.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import feign.Feign;
import jakarta.ws.rs.client.Client;
import kong.unirest.Unirest;
import nl.altindag.client.service.RequestService;
import nl.altindag.ssl.SSLFactory;
import okhttp3.OkHttpClient;
import org.apache.http.impl.client.CloseableHttpClient;
Expand Down Expand Up @@ -398,4 +399,28 @@ void createVertxWithSecurity() {
System.clearProperty("url");
}

@Test
void createClojureCijClient() {
SSLFactory sslFactory = createSSLFactory(true, true);
RequestService requestService = victim.clojureCijHttpClientService(sslFactory);
assertThat(requestService).isNotNull();
assertThat(requestService.getClientType()).isEqualTo(ClientType.CLOJURE_CLJ_HTTP_CLIENT);
}

@Test
void createClojureJdkClient() {
SSLFactory sslFactory = createSSLFactory(true, true);
RequestService requestService = victim.clojureJdkHttpClientService(sslFactory);
assertThat(requestService).isNotNull();
assertThat(requestService.getClientType()).isEqualTo(ClientType.CLOJURE_JDK_HTTP_CLIENT);
}

@Test
void createClojureHttpClient() {
SSLFactory sslFactory = createSSLFactory(true, true);
RequestService requestService = victim.clojureHttpClientService(sslFactory);
assertThat(requestService).isNotNull();
assertThat(requestService.getClientType()).isEqualTo(ClientType.CLOJURE_HTTP_CLIENT);
}

}
3 changes: 3 additions & 0 deletions client/src/test/resources/features/Hello.feature
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,6 @@ Feature: Securing the connection between you and the world
| Vertx WebClient |
| Groovy Java Net Client |
| HyperPoet Client |
| Clojure HttpClient |
| Clojure Jdk HttpClient |
| Clojure clj-http Client |
Loading